summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/hfi1/vnic_main.c
diff options
context:
space:
mode:
authorMichael J. Ruhl <michael.j.ruhl@intel.com>2017-08-04 13:52:38 -0700
committerDoug Ledford <dledford@redhat.com>2017-08-22 14:22:36 -0400
commitf2a3bc00a03c2cc9caa40c8867de973fd4e48c6a (patch)
tree509797e5304e6d1e3a5165036582b5e0a6ae2a28 /drivers/infiniband/hw/hfi1/vnic_main.c
parent64a296f579303322ebec9edae09cf87240b1ad78 (diff)
downloadlinux-f2a3bc00a03c2cc9caa40c8867de973fd4e48c6a.tar.bz2
IB/hfi1: Protect context array set/clear with spinlock
The rcd array can be accessed from user context or during interrupts. Protecting this with a mutex isn't a good idea because the mutex should not be used from an IRQ. Protect the allocation and freeing of rcd array elements with a spinlock. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Sebastian Sanchez <sebastian.sanchez@intel.com> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw/hfi1/vnic_main.c')
-rw-r--r--drivers/infiniband/hw/hfi1/vnic_main.c22
1 files changed, 6 insertions, 16 deletions
diff --git a/drivers/infiniband/hw/hfi1/vnic_main.c b/drivers/infiniband/hw/hfi1/vnic_main.c
index 89b056489769..c91456c16cdb 100644
--- a/drivers/infiniband/hw/hfi1/vnic_main.c
+++ b/drivers/infiniband/hw/hfi1/vnic_main.c
@@ -106,22 +106,13 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd,
struct hfi1_ctxtdata **vnic_ctxt)
{
struct hfi1_ctxtdata *uctxt;
- u16 ctxt;
int ret;
if (dd->flags & HFI1_FROZEN)
return -EIO;
- for (ctxt = dd->first_dyn_alloc_ctxt;
- ctxt < dd->num_rcv_contexts; ctxt++)
- if (!dd->rcd[ctxt])
- break;
-
- if (ctxt == dd->num_rcv_contexts)
- return -EBUSY;
-
- uctxt = hfi1_create_ctxtdata(dd->pport, ctxt, dd->node);
- if (!uctxt) {
+ ret = hfi1_create_ctxtdata(dd->pport, dd->node, &uctxt);
+ if (ret < 0) {
dd_dev_err(dd, "Unable to create ctxtdata, failing open\n");
return -ENOMEM;
}
@@ -156,11 +147,10 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd,
return ret;
bail:
/*
- * hfi1_rcd_put() will call hfi1_free_ctxtdata(), which will
+ * hfi1_free_ctxt() will call hfi1_free_ctxtdata(), which will
* release send_context structure if uctxt->sc is not null
*/
- dd->rcd[uctxt->ctxt] = NULL;
- hfi1_rcd_put(uctxt);
+ hfi1_free_ctxt(dd, uctxt);
dd_dev_dbg(dd, "vnic allocation failed. rc %d\n", ret);
return ret;
}
@@ -201,14 +191,14 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
dd->send_contexts[uctxt->sc->sw_index].type = SC_USER;
spin_unlock_irqrestore(&dd->uctxt_lock, flags);
- dd->rcd[uctxt->ctxt] = NULL;
uctxt->event_flags = 0;
hfi1_clear_tids(uctxt);
hfi1_clear_ctxt_pkey(dd, uctxt);
hfi1_stats.sps_ctxts--;
- hfi1_rcd_put(uctxt);
+
+ hfi1_free_ctxt(dd, uctxt);
}
void hfi1_vnic_setup(struct hfi1_devdata *dd)