소스 검색

IB/hfi1: Fix resource release in context allocation

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>
Jakub Pawlak 9 년 전
부모
커밋
3a6982dfd3
2개의 변경된 파일13개의 추가작업 그리고 5개의 파일을 삭제
  1. 12 5
      drivers/infiniband/hw/hfi1/file_ops.c
  2. 1 0
      drivers/infiniband/hw/hfi1/init.c

+ 12 - 5
drivers/infiniband/hw/hfi1/file_ops.c

@@ -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->sc = sc_alloc(dd, SC_USER, uctxt->rcvhdrqentsize,
 			     uctxt->dd->node);
 			     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,
 	hfi1_cdbg(PROC, "allocated send context %u(%u)\n", uctxt->sc->sw_index,
 		  uctxt->sc->hw_context);
 		  uctxt->sc->hw_context);
 	ret = sc_enable(uctxt->sc);
 	ret = sc_enable(uctxt->sc);
 	if (ret)
 	if (ret)
-		return ret;
+		goto ctxdata_free;
+
 	/*
 	/*
 	 * Setup shared context resources if the user-level has requested
 	 * Setup shared context resources if the user-level has requested
 	 * shared contexts and this is the 'master' process.
 	 * 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
 		 * send context because it will be done during file close
 		 */
 		 */
 		if (ret)
 		if (ret)
-			return ret;
+			goto ctxdata_free;
 	}
 	}
 	uctxt->userversion = uinfo->userversion;
 	uctxt->userversion = uinfo->userversion;
 	uctxt->flags = hfi1_cap_mask; /* save current flag state */
 	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;
 	fd->uctxt = uctxt;
 
 
 	return 0;
 	return 0;
+
+ctxdata_free:
+	dd->rcd[ctxt] = NULL;
+	hfi1_free_ctxtdata(dd, uctxt);
+	return ret;
 }
 }
 
 
 static int init_subctxts(struct hfi1_ctxtdata *uctxt,
 static int init_subctxts(struct hfi1_ctxtdata *uctxt,

+ 1 - 0
drivers/infiniband/hw/hfi1/init.c

@@ -336,6 +336,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt,
 	}
 	}
 	return rcd;
 	return rcd;
 bail:
 bail:
+	dd->rcd[ctxt] = NULL;
 	kfree(rcd->egrbufs.rcvtids);
 	kfree(rcd->egrbufs.rcvtids);
 	kfree(rcd->egrbufs.buffers);
 	kfree(rcd->egrbufs.buffers);
 	kfree(rcd);
 	kfree(rcd);