From: Sean Hefty Date: Tue, 13 Jul 2010 18:51:32 +0000 (-0700) Subject: winverbs: add mr interface X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=8ef0b769632c6302405722244163cb752e14f47e;p=~shefty%2Frdma-win.git winverbs: add mr interface The lkey isn't guaranteed to be unique. To ensure that we track memory registrations properly, associate MRs with their own data structure. Deregistration will reference the data structure, rather than just the lkey from the registration. Signed-off-by: Sean Hefty --- diff --git a/trunk/core/winverbs/kernel/wv_pd.c b/trunk/core/winverbs/kernel/wv_pd.c index af9a5509..de6e75d6 100644 --- a/trunk/core/winverbs/kernel/wv_pd.c +++ b/trunk/core/winverbs/kernel/wv_pd.c @@ -85,7 +85,7 @@ static NTSTATUS WvPdAlloc(WV_DEVICE *pDevice, WV_PROTECTION_DOMAIN **ppPd, InitializeListHead(&pd->SrqList); InitializeListHead(&pd->MwList); InitializeListHead(&pd->AhList); - cl_qmap_init(&pd->MrMap); + InitializeListHead(&pd->MrList); KeInitializeGuardedMutex(&pd->Lock); ib_status = pDevice->pVerbs->allocate_pd(pDevice->hVerbsDevice, IB_PDT_NORMAL, @@ -225,16 +225,16 @@ void WvPdFree(WV_PROTECTION_DOMAIN *pPd) KeWaitForSingleObject(&pPd->Event, Executive, KernelMode, FALSE, NULL); } - for (item = cl_qmap_head(&pPd->MrMap); item != cl_qmap_end(&pPd->MrMap); - item = cl_qmap_head(&pPd->MrMap)) { - mr = CONTAINING_RECORD(item, WV_MEMORY_REGION, Item); - if (mr->hVerbsMr != NULL) { - pPd->pVerbs->deregister_mr(mr->hVerbsMr); - } + //for (item = cl_qmap_head(&pPd->MrMap); item != cl_qmap_end(&pPd->MrMap); + // item = cl_qmap_head(&pPd->MrMap)) { + // mr = CONTAINING_RECORD(item, WV_MEMORY_REGION, Item); + // if (mr->hVerbsMr != NULL) { + // pPd->pVerbs->deregister_mr(mr->hVerbsMr); + // } - cl_qmap_remove_item(&pPd->MrMap, &mr->Item); - ExFreePoolWithTag(mr, 'rmvw'); - } + // cl_qmap_remove_item(&pPd->MrMap, &mr->Item); + // ExFreePoolWithTag(mr, 'rmvw'); + //} if (pPd->hVerbsPd != NULL) { pPd->pVerbs->deallocate_pd(pPd->hVerbsPd); @@ -266,9 +266,8 @@ void WvPdRemoveHandler(WV_PROTECTION_DOMAIN *pPd) ah->hVerbsAh = NULL; } - for (item = cl_qmap_head(&pPd->MrMap); item != cl_qmap_end(&pPd->MrMap); - item = cl_qmap_next(item)) { - mr = CONTAINING_RECORD(item, WV_MEMORY_REGION, Item); + for (entry = pPd->MrList.Flink; entry != &pPd->MrList; entry = entry->Flink) { + mr = CONTAINING_RECORD(entry, WV_MEMORY_REGION, Entry); pPd->pVerbs->deregister_mr(mr->hVerbsMr); mr->hVerbsMr = NULL; } @@ -323,6 +322,9 @@ void WvMrRegister(WV_PROVIDER *pProvider, WDFREQUEST Request) goto err2; } + WvPdGet(pd); + mr->pPd = pd; + attr.access_ctrl = reg->AccessFlags; attr.length = reg->BufferLength; attr.vaddr = (void *) (ULONG_PTR) reg->Address; @@ -333,16 +335,23 @@ void WvMrRegister(WV_PROVIDER *pProvider, WDFREQUEST Request) goto err3; } - KeAcquireGuardedMutex(&pd->Lock); - cl_qmap_insert(&pd->MrMap, keys->Lkey, &mr->Item); - KeReleaseGuardedMutex(&pd->Lock); + KeAcquireGuardedMutex(&pProvider->Lock); + keys->Id = IndexListInsertHead(&pProvider->MrIndex, mr); + if (keys->Id == 0) { + status = STATUS_NO_MEMORY; + goto err4; + } + InsertHeadList(&pd->MrList, &mr->Entry); + KeReleaseGuardedMutex(&pProvider->Lock); WvPdRelease(pd); WdfRequestCompleteWithInformation(Request, status, sizeof(WV_IO_MEMORY_KEYS)); return; +err4: + KeReleaseGuardedMutex(&pProvider->Lock); err3: - ExFreePoolWithTag(mr, 'rmvw'); + WvMrFree(mr); err2: WvPdRelease(pd); err1: @@ -351,49 +360,43 @@ err1: void WvMrDeregister(WV_PROVIDER *pProvider, WDFREQUEST Request) { - WV_IO_ID *id; - WV_PROTECTION_DOMAIN *pd; - WV_MEMORY_REGION *mr; - cl_map_item_t *item; - NTSTATUS status; - ib_api_status_t ib_status; + WV_MEMORY_REGION *mr; + UINT64 *id; + NTSTATUS status; - status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &id, NULL); + status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL); if (!NT_SUCCESS(status)) { goto complete; } - pd = WvPdAcquire(pProvider, id->Id); - if (pd == NULL) { + KeAcquireGuardedMutex(&pProvider->Lock); + WvProviderDisableRemove(pProvider); + mr = IndexListAt(&pProvider->MrIndex, (SIZE_T) *id); + if (mr == NULL) { status = STATUS_NOT_FOUND; - goto complete; + } else { + IndexListRemove(&pProvider->MrIndex, (SIZE_T) *id); + RemoveEntryList(&mr->Entry); + status = STATUS_SUCCESS; } + KeReleaseGuardedMutex(&pProvider->Lock); - KeAcquireGuardedMutex(&pd->Lock); - item = cl_qmap_remove(&pd->MrMap, id->Data); - KeReleaseGuardedMutex(&pd->Lock); - - if (item == cl_qmap_end(&pd->MrMap)) { - status = STATUS_NOT_FOUND; - goto release; + if (NT_SUCCESS(status)) { + WvMrFree(mr); } + WvProviderEnableRemove(pProvider); +out: + WdfRequestComplete(Request, status); +} - mr = CONTAINING_RECORD(item, WV_MEMORY_REGION, Item); - - ib_status = pd->pVerbs->deregister_mr(mr->hVerbsMr); - if (ib_status != IB_SUCCESS) { - status = STATUS_UNSUCCESSFUL; - KeAcquireGuardedMutex(&pd->Lock); - cl_qmap_insert(&pd->MrMap, id->Data, &mr->Item); - KeReleaseGuardedMutex(&pd->Lock); - goto release; +void WvMrFree(WV_MEMORY_REGION *pMr) +{ + if (pMr->hVerbsMr != NULL) { + pMr->pPd->pVerbs->deregister_mr(pMr->hVerbsMr); } - ExFreePoolWithTag(mr, 'rmvw'); -release: - WvPdRelease(pd); -complete: - WdfRequestComplete(Request, status); + WvPdPut(pMr->pPd); + ExFreePoolWithTag(pMr, 'rmvw'); } void WvMwAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request) diff --git a/trunk/core/winverbs/kernel/wv_pd.h b/trunk/core/winverbs/kernel/wv_pd.h index f30cf4e5..10abd495 100644 --- a/trunk/core/winverbs/kernel/wv_pd.h +++ b/trunk/core/winverbs/kernel/wv_pd.h @@ -49,10 +49,10 @@ typedef struct _WV_PROTECTION_DOMAIN LIST_ENTRY QpList; LIST_ENTRY SrqList; + LIST_ENTRY MrList; LIST_ENTRY MwList; LIST_ENTRY AhList; KGUARDED_MUTEX Lock; - cl_qmap_t MrMap; KEVENT Event; LONG Ref; @@ -73,13 +73,15 @@ void WvPdRemoveHandler(WV_PROTECTION_DOMAIN *pPd); typedef struct _WV_MEMORY_REGION { + WV_PROTECTION_DOMAIN *pPd; ib_mr_handle_t hVerbsMr; - cl_map_item_t Item; + LIST_ENTRY Entry; } WV_MEMORY_REGION; void WvMrRegister(WV_PROVIDER *pProvider, WDFREQUEST Request); void WvMrDeregister(WV_PROVIDER *pProvider, WDFREQUEST Request); +void WvMrFree(WV_MEMORY_REGION *pMr); typedef struct _WV_MEMORY_WINDOW diff --git a/trunk/core/winverbs/wv_ioctl.h b/trunk/core/winverbs/wv_ioctl.h index ce091d10..7717ad51 100644 --- a/trunk/core/winverbs/wv_ioctl.h +++ b/trunk/core/winverbs/wv_ioctl.h @@ -162,7 +162,7 @@ enum { #define WV_IOCTL_MEMORY_REGISTER WV_IOCTL(WV_IO_FUNCTION_BASE + \ WV_IO_FUNCTION_MEMORY_REGISTER) -// WV_IO_ID / none +// UINT64 Id / none #define WV_IOCTL_MEMORY_DEREGISTER WV_IOCTL(WV_IO_FUNCTION_BASE + \ WV_IO_FUNCTION_MEMORY_DEREGISTER) @@ -478,6 +478,7 @@ typedef struct _WV_IO_MEMORY_REGISTER typedef struct _WV_IO_MEMORY_KEYS { + UINT64 Id; UINT32 Lkey; NET32 Rkey;