diff options
author | Michael J. Ruhl <michael.j.ruhl@intel.com> | 2017-08-04 13:52:38 -0700 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-08-22 14:22:36 -0400 |
commit | f2a3bc00a03c2cc9caa40c8867de973fd4e48c6a (patch) | |
tree | 509797e5304e6d1e3a5165036582b5e0a6ae2a28 /drivers/infiniband/hw/hfi1/vnic_main.c | |
parent | 64a296f579303322ebec9edae09cf87240b1ad78 (diff) |
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.c | 22 |
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) |