From: VMware, Inc <> Date: Tue, 26 Apr 2011 20:26:33 +0000 (-0700) Subject: Stop using kmap for VMCI queue pair host side headers X-Git-Tag: 2011.04.25-402641~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=350a79ba1fbc291d2d253c901b2d86b6411d7d28;p=thirdparty%2Fopen-vm-tools.git Stop using kmap for VMCI queue pair host side headers The VMCI host driver for Linux does two kmaps for each active queue pair. Since there is a limited number of kmap entries for mapping high memory, convert the code to use vmap instead. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c index 21516980b..a4aa6e1f9 100644 --- a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c +++ b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c @@ -1466,6 +1466,40 @@ VMCIHost_FreeQueue(VMCIQueue *queue, // IN: } +/* + *----------------------------------------------------------------------------- + * + * VMCIReleasePageStorePages -- + * + * Helper function to release pages in the PageStoreAttachInfo + * previously obtained using get_user_pages. + * + * Results: + * None. + * + * Side Effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static void +VMCIReleasePages(struct page **pages, // IN + uint64 numPages, // IN + Bool dirty) // IN +{ + int i; + + for (i = 0; i < numPages; i++) { + ASSERT(pages[i]); + if (dirty) { + set_page_dirty(pages[i]); + } + page_cache_release(pages[i]); + } +} + + /* *----------------------------------------------------------------------------- * @@ -1516,12 +1550,7 @@ VMCIHost_GetUserMemory(PageStoreAttachInfo *attach, // IN/OUT NULL); if (retval < attach->numProducePages) { Log("get_user_pages(produce) failed: %d\n", retval); - if (retval > 0) { - int i; - for (i = 0; i < retval; i++) { - page_cache_release(attach->producePages[i]); - } - } + VMCIReleasePages(attach->producePages, retval, FALSE); err = VMCI_ERROR_NO_MEM; goto out; } @@ -1534,16 +1563,9 @@ VMCIHost_GetUserMemory(PageStoreAttachInfo *attach, // IN/OUT attach->consumePages, NULL); if (retval < attach->numConsumePages) { - int i; Log("get_user_pages(consume) failed: %d\n", retval); - if (retval > 0) { - for (i = 0; i < retval; i++) { - page_cache_release(attach->consumePages[i]); - } - } - for (i = 0; i < attach->numProducePages; i++) { - page_cache_release(attach->producePages[i]); - } + VMCIReleasePages(attach->consumePages, retval, FALSE); + VMCIReleasePages(attach->producePages, attach->numProducePages, FALSE); err = VMCI_ERROR_NO_MEM; } @@ -1551,10 +1573,23 @@ out: up_write(¤t->mm->mmap_sem); if (err == VMCI_SUCCESS) { - produceQ->qHeader = kmap(attach->producePages[0]); - produceQ->kernelIf->page = &attach->producePages[1]; - consumeQ->qHeader = kmap(attach->consumePages[0]); - consumeQ->kernelIf->page = &attach->consumePages[1]; + struct page *headers[2]; + + headers[0] = attach->producePages[0]; + headers[1] = attach->consumePages[0]; + + produceQ->qHeader = vmap(headers, 2, VM_MAP, PAGE_KERNEL); + if (produceQ->qHeader != NULL) { + consumeQ->qHeader = + (VMCIQueueHeader *)((uint8 *)produceQ->qHeader + PAGE_SIZE); + produceQ->kernelIf->page = &attach->producePages[1]; + consumeQ->kernelIf->page = &attach->consumePages[1]; + } else { + Log("vmap failed\n"); + VMCIReleasePages(attach->producePages, attach->numProducePages, FALSE); + VMCIReleasePages(attach->consumePages, attach->numConsumePages, FALSE); + err = VMCI_ERROR_NO_MEM; + } } errorDealloc: @@ -1597,27 +1632,14 @@ VMCIHost_ReleaseUserMemory(PageStoreAttachInfo *attach, // IN/OUT VMCIQueue *produceQ, // OUT VMCIQueue *consumeQ) // OUT { - int i; - ASSERT(attach->producePages); ASSERT(attach->consumePages); + ASSERT(produceQ->qHeader); - kunmap(attach->producePages[0]); - kunmap(attach->consumePages[0]); - - for (i = 0; i < attach->numProducePages; i++) { - ASSERT(attach->producePages[i]); + vunmap(produceQ->qHeader); - set_page_dirty(attach->producePages[i]); - page_cache_release(attach->producePages[i]); - } - - for (i = 0; i < attach->numConsumePages; i++) { - ASSERT(attach->consumePages[i]); - - set_page_dirty(attach->consumePages[i]); - page_cache_release(attach->consumePages[i]); - } + VMCIReleasePages(attach->producePages, attach->numProducePages, TRUE); + VMCIReleasePages(attach->consumePages, attach->numConsumePages, TRUE); VMCI_FreeKernelMem(attach->producePages, attach->numProducePages * diff --git a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h index d6c96f434..c47022ba3 100644 --- a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h +++ b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h @@ -25,8 +25,8 @@ #ifndef _VMCI_VERSION_H_ #define _VMCI_VERSION_H_ -#define VMCI_DRIVER_VERSION 9.1.13.0 -#define VMCI_DRIVER_VERSION_COMMAS 9,1,13,0 -#define VMCI_DRIVER_VERSION_STRING "9.1.13.0" +#define VMCI_DRIVER_VERSION 9.1.14.0 +#define VMCI_DRIVER_VERSION_COMMAS 9,1,14,0 +#define VMCI_DRIVER_VERSION_STRING "9.1.14.0" #endif /* _VMCI_VERSION_H_ */