winverbs: fix cleanup in error handling cases
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 31 Jul 2009 16:50:21 +0000 (16:50 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 31 Jul 2009 16:50:21 +0000 (16:50 +0000)
Running the ndmw test results in a crash in the winverbs driver.  The
crash is caused by improper cleanup in the winverbs driver as a result
of a failure trying to allocate a memory window.

In studying the crash, the same situation could arise if other objects
also fail to be created (QPs, CQs, PDs, etc.)  To fix the crash and
simplify the code, explicit calls to used to increment the reference
count on referenced objects, rather than simply holding onto the
reference that was acquired when the object was validated.  (The latter
is slightly more efficient, but results in less maintainable code
once any fix is applied.)

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2320 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

core/winverbs/kernel/wv_pd.c
core/winverbs/kernel/wv_qp.c
core/winverbs/kernel/wv_srq.c

index 5ae2629..304588d 100644 (file)
@@ -94,6 +94,7 @@ static NTSTATUS WvPdAlloc(WV_DEVICE *pDevice, WV_PROTECTION_DOMAIN **ppPd,
                goto err;\r
        }\r
 \r
+       WvDeviceGet(pDevice);\r
        pd->pDevice = pDevice;\r
        pd->pVerbs = pDevice->pVerbs;\r
        *ppPd = pd;\r
@@ -144,7 +145,7 @@ void WvPdAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
        InsertHeadList(&dev->PdList, &pd->Entry);\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
 \r
-       WvProviderEnableRemove(pProvider);\r
+       WvDeviceRelease(dev);\r
        outid->VerbInfo = verbsData.status;\r
        WdfRequestCompleteWithInformation(Request, status, outlen);\r
        return;\r
@@ -426,6 +427,9 @@ void WvMwAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
                goto err2;\r
        }\r
 \r
+       WvPdGet(pd);\r
+       mw->pPd = pd;\r
+\r
        WvInitVerbsData(&verbsData, inid->VerbInfo, inlen - sizeof(WV_IO_ID),\r
                                        outlen - sizeof(WV_IO_ID), inid + 1);\r
        ib_status = pd->pVerbs->create_mw(pd->hVerbsPd, &outid->Data, &mw->hVerbsMw,\r
@@ -439,20 +443,19 @@ void WvMwAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
        outid->Id = IndexListInsertHead(&pProvider->MwIndex, mw);\r
        if (outid->Id == 0) {\r
                status = STATUS_NO_MEMORY;\r
-               goto err3;\r
+               goto err4;\r
        }\r
        InsertHeadList(&pd->MwList, &mw->Entry);\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
 \r
-       mw->pPd = pd;\r
-\r
-       WvProviderEnableRemove(pProvider);\r
+       WvPdRelease(pd);\r
        outid->VerbInfo = verbsData.status;\r
        WdfRequestCompleteWithInformation(Request, status, outlen);\r
        return;\r
 \r
-err3:\r
+err4:\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
+err3:\r
        WvMwFree(mw);\r
 err2:\r
        WvPdRelease(pd);\r
@@ -553,6 +556,9 @@ void WvAhCreate(WV_PROVIDER *pProvider, WDFREQUEST Request)
                goto err2;\r
        }\r
 \r
+       WvPdGet(pd);\r
+       ah->pPd = pd;\r
+\r
        WvVerbsConvertAv(&av, &pinAv->AddressVector);\r
        WvInitVerbsData(&verbsData, pinAv->Id.VerbInfo, inlen - sizeof(WV_IO_AH_CREATE),\r
                                        outlen - sizeof(WV_IO_AH_CREATE), pinAv + 1);\r
@@ -566,20 +572,19 @@ void WvAhCreate(WV_PROVIDER *pProvider, WDFREQUEST Request)
        poutAv->Id.Id = IndexListInsertHead(&pProvider->AhIndex, ah);\r
        if (poutAv->Id.Id == 0) {\r
                status = STATUS_NO_MEMORY;\r
-               goto err3;\r
+               goto err4;\r
        }\r
        InsertHeadList(&pd->AhList, &ah->Entry);\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
 \r
-       ah->pPd = pd;\r
-\r
-       WvProviderEnableRemove(pProvider);\r
+       WvPdRelease(pd);\r
        poutAv->Id.VerbInfo = verbsData.status;\r
        WdfRequestCompleteWithInformation(Request, status, outlen);\r
        return;\r
 \r
-err3:\r
+err4:\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
+err3:\r
        WvAhFree(ah);\r
 err2:\r
        WvPdRelease(pd);\r
index 26aec27..c5da3e0 100644 (file)
@@ -528,7 +528,6 @@ void WvQpFree(WV_QUEUE_PAIR *pQp)
                if (mc->hVerbsMc != NULL) {\r
                        pQp->pVerbs->detach_mcast(mc->hVerbsMc);\r
                }\r
-               WvQpPut(pQp);\r
                ExFreePool(mc);\r
        }\r
 \r
@@ -663,7 +662,7 @@ void WvQpAttach(WV_PROVIDER *pProvider, WDFREQUEST Request)
        InsertHeadList(&qp->McList, &pmc->Entry);\r
        KeReleaseGuardedMutex(&qp->pPd->Lock);\r
 \r
-       WvProviderEnableRemove(pProvider);\r
+       WvQpRelease(qp);\r
        WdfRequestComplete(Request, STATUS_SUCCESS);\r
        return;\r
 \r
@@ -707,18 +706,17 @@ void WvQpDetach(WV_PROVIDER *pProvider, WDFREQUEST Request)
                        if (pmc->hVerbsMc != NULL) {\r
                                qp->pVerbs->detach_mcast(pmc->hVerbsMc);\r
                        }\r
-                       WvQpPut(qp);\r
-                       WvQpRelease(qp);\r
 \r
                        ExFreePool(pmc);\r
                        status = STATUS_SUCCESS;\r
-                       goto complete;\r
+                       goto release;\r
                }\r
        }\r
        KeReleaseGuardedMutex(&qp->pPd->Lock);\r
-       WvQpRelease(qp);\r
        status = STATUS_NOT_FOUND;\r
 \r
+release:\r
+       WvQpRelease(qp);\r
 complete:\r
        WdfRequestComplete(Request, status);\r
 }\r
index e2379ee..b0877ab 100644 (file)
@@ -123,6 +123,7 @@ static NTSTATUS WvSrqAlloc(WV_PROTECTION_DOMAIN *pPd, WV_IO_SRQ_ATTRIBUTES *pAtt
                goto err2;\r
        }\r
 \r
+       WvPdGet(pPd);\r
        srq->pPd = pPd;\r
        srq->pProvider = pPd->pDevice->pProvider;\r
        srq->pVerbs = pPd->pVerbs;\r
@@ -178,7 +179,7 @@ void WvSrqCreate(WV_PROVIDER *pProvider, WDFREQUEST Request)
        InsertHeadList(&pd->SrqList, &srq->Entry);\r
        KeReleaseGuardedMutex(&pProvider->Lock);\r
 \r
-       WvProviderEnableRemove(pProvider);\r
+       WvPdRelease(pd);\r
        outAttr->Id.VerbInfo = verbsData.status;\r
        WdfRequestCompleteWithInformation(Request, status, outlen);\r
        return;\r