IB/hfi1: Fix resource release in context allocation
authorJakub Pawlak <jakub.pawlak@intel.com>
Sun, 25 Sep 2016 14:42:23 +0000 (07:42 -0700)
committerDoug Ledford <dledford@redhat.com>
Sun, 2 Oct 2016 12:42:17 +0000 (08:42 -0400)
Correct resource free in allocate_ctxt() function.
When context creation fails allocated resources are properly
released and pointer in receive context data table is set back
to NULL.

Reviewed-by: Dean Luick <dean.luick@intel.com>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Jakub Pawlak <jakub.pawlak@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/file_ops.c
drivers/infiniband/hw/hfi1/init.c

index 335796f..13bb6a5 100644 (file)
@@ -978,14 +978,16 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,
         */
        uctxt->sc = sc_alloc(dd, SC_USER, uctxt->rcvhdrqentsize,
                             uctxt->dd->node);
-       if (!uctxt->sc)
-               return -ENOMEM;
-
+       if (!uctxt->sc) {
+               ret = -ENOMEM;
+               goto ctxdata_free;
+       }
        hfi1_cdbg(PROC, "allocated send context %u(%u)\n", uctxt->sc->sw_index,
                  uctxt->sc->hw_context);
        ret = sc_enable(uctxt->sc);
        if (ret)
-               return ret;
+               goto ctxdata_free;
+
        /*
         * Setup shared context resources if the user-level has requested
         * shared contexts and this is the 'master' process.
@@ -999,7 +1001,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,
                 * send context because it will be done during file close
                 */
                if (ret)
-                       return ret;
+                       goto ctxdata_free;
        }
        uctxt->userversion = uinfo->userversion;
        uctxt->flags = hfi1_cap_mask; /* save current flag state */
@@ -1019,6 +1021,11 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,
        fd->uctxt = uctxt;
 
        return 0;
+
+ctxdata_free:
+       dd->rcd[ctxt] = NULL;
+       hfi1_free_ctxtdata(dd, uctxt);
+       return ret;
 }
 
 static int init_subctxts(struct hfi1_ctxtdata *uctxt,
index ab2f221..60db615 100644 (file)
@@ -336,6 +336,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
        }
        return rcd;
 bail:
+       dd->rcd[ctxt] = NULL;
        kfree(rcd->egrbufs.rcvtids);
        kfree(rcd->egrbufs.buffers);
        kfree(rcd);