Commit 996abf0a authored by Ismail, Mustafa's avatar Ismail, Mustafa Committed by Doug Ledford

RDMA/i40iw: Add qp table lock around AE processing

QP may be freed during Async Event processing.
Add a lock around QP table to prevent it.
Signed-off-by: default avatarMustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: default avatarFaisal Latif <faisal.latif@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 36a47933
...@@ -254,6 +254,7 @@ struct i40iw_device { ...@@ -254,6 +254,7 @@ struct i40iw_device {
u32 arp_table_size; u32 arp_table_size;
u32 next_arp_index; u32 next_arp_index;
spinlock_t resource_lock; /* hw resource access */ spinlock_t resource_lock; /* hw resource access */
spinlock_t qptable_lock;
u32 vendor_id; u32 vendor_id;
u32 vendor_part_id; u32 vendor_part_id;
u32 of_device_registered; u32 of_device_registered;
......
...@@ -106,6 +106,7 @@ u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev) ...@@ -106,6 +106,7 @@ u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev)
set_bit(2, iwdev->allocated_pds); set_bit(2, iwdev->allocated_pds);
spin_lock_init(&iwdev->resource_lock); spin_lock_init(&iwdev->resource_lock);
spin_lock_init(&iwdev->qptable_lock);
mrdrvbits = 24 - get_count_order(iwdev->max_mr); mrdrvbits = 24 - get_count_order(iwdev->max_mr);
iwdev->mr_stagmask = ~(((1 << mrdrvbits) - 1) << (32 - mrdrvbits)); iwdev->mr_stagmask = ~(((1 << mrdrvbits) - 1) << (32 - mrdrvbits));
return 0; return 0;
...@@ -301,11 +302,15 @@ void i40iw_process_aeq(struct i40iw_device *iwdev) ...@@ -301,11 +302,15 @@ void i40iw_process_aeq(struct i40iw_device *iwdev)
"%s ae_id = 0x%x bool qp=%d qp_id = %d\n", "%s ae_id = 0x%x bool qp=%d qp_id = %d\n",
__func__, info->ae_id, info->qp, info->qp_cq_id); __func__, info->ae_id, info->qp, info->qp_cq_id);
if (info->qp) { if (info->qp) {
spin_lock_irqsave(&iwdev->qptable_lock, flags);
iwqp = iwdev->qp_table[info->qp_cq_id]; iwqp = iwdev->qp_table[info->qp_cq_id];
if (!iwqp) { if (!iwqp) {
spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
i40iw_pr_err("qp_id %d is already freed\n", info->qp_cq_id); i40iw_pr_err("qp_id %d is already freed\n", info->qp_cq_id);
continue; continue;
} }
i40iw_add_ref(&iwqp->ibqp);
spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
qp = &iwqp->sc_qp; qp = &iwqp->sc_qp;
spin_lock_irqsave(&iwqp->lock, flags); spin_lock_irqsave(&iwqp->lock, flags);
iwqp->hw_tcp_state = info->tcp_state; iwqp->hw_tcp_state = info->tcp_state;
...@@ -411,6 +416,8 @@ void i40iw_process_aeq(struct i40iw_device *iwdev) ...@@ -411,6 +416,8 @@ void i40iw_process_aeq(struct i40iw_device *iwdev)
i40iw_terminate_connection(qp, info); i40iw_terminate_connection(qp, info);
break; break;
} }
if (info->qp)
i40iw_rem_ref(&iwqp->ibqp);
} while (1); } while (1);
if (aeqcnt) if (aeqcnt)
......
...@@ -506,14 +506,19 @@ void i40iw_rem_ref(struct ib_qp *ibqp) ...@@ -506,14 +506,19 @@ void i40iw_rem_ref(struct ib_qp *ibqp)
struct cqp_commands_info *cqp_info; struct cqp_commands_info *cqp_info;
struct i40iw_device *iwdev; struct i40iw_device *iwdev;
u32 qp_num; u32 qp_num;
unsigned long flags;
iwqp = to_iwqp(ibqp); iwqp = to_iwqp(ibqp);
if (!atomic_dec_and_test(&iwqp->refcount)) iwdev = iwqp->iwdev;
spin_lock_irqsave(&iwdev->qptable_lock, flags);
if (!atomic_dec_and_test(&iwqp->refcount)) {
spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
return; return;
}
iwdev = iwqp->iwdev;
qp_num = iwqp->ibqp.qp_num; qp_num = iwqp->ibqp.qp_num;
iwdev->qp_table[qp_num] = NULL; iwdev->qp_table[qp_num] = NULL;
spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false); cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false);
if (!cqp_request) if (!cqp_request)
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment