From owner-svn-src-projects@FreeBSD.ORG Wed Aug 25 01:50:13 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2206410656A8; Wed, 25 Aug 2010 01:50:13 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 112EA8FC22; Wed, 25 Aug 2010 01:50:13 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7P1oCld095816; Wed, 25 Aug 2010 01:50:12 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7P1oCo5095814; Wed, 25 Aug 2010 01:50:12 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201008250150.o7P1oCo5095814@svn.freebsd.org> From: Jeff Roberson Date: Wed, 25 Aug 2010 01:50:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211791 - projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Aug 2010 01:50:13 -0000 Author: jeff Date: Wed Aug 25 01:50:12 2010 New Revision: 211791 URL: http://svn.freebsd.org/changeset/base/211791 Log: - Add an implementation of mthca_map_user_db() Sponsored by: Isilon Systems, iX Systems, and Panasas Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c ============================================================================== --- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c Wed Aug 25 00:36:06 2010 (r211790) +++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c Wed Aug 25 01:50:12 2010 (r211791) @@ -448,6 +448,13 @@ static u64 mthca_uarc_virt(struct mthca_ page * MTHCA_ICM_PAGE_SIZE; } +#include +#include +#include + +#include +#include + int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, struct mthca_user_db_table *db_tab, int index, u64 uaddr) { @@ -510,14 +517,99 @@ out: mutex_unlock(&db_tab->mutex); return ret; #else - return -EINVAL; + struct proc *proc; + vm_offset_t start; + vm_paddr_t paddr; + pmap_t pmap; + vm_page_t m; + int ret = 0; + u8 status; + int i; + + if (!mthca_is_memfree(dev)) + return 0; + + if (index < 0 || index > dev->uar_table.uarc_size / 8) + return -EINVAL; + + mutex_lock(&db_tab->mutex); + + i = index / MTHCA_DB_REC_PER_PAGE; + start = 0; + + if ((db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE) || + (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr) || + (uaddr & 4095)) { + ret = -EINVAL; + goto out; + } + + if (db_tab->page[i].refcount) { + ++db_tab->page[i].refcount; + goto out; + } + + proc = curproc; + pmap = vm_map_pmap(&proc->p_vmspace->vm_map); + PROC_LOCK(proc); + if (ptoa(pmap_wired_count(pmap) + 1) > lim_cur(proc, RLIMIT_MEMLOCK)) { + PROC_UNLOCK(proc); + ret = -ENOMEM; + goto out; + } + PROC_UNLOCK(proc); + if (cnt.v_wire_count + 1 > vm_page_max_wired) { + ret = -EAGAIN; + goto out; + } + start = uaddr & PAGE_MASK; + ret = vm_map_wire(&proc->p_vmspace->vm_map, start, start + PAGE_SIZE, + VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES /* | VM_MAP_WIRE_READ | + VM_MAP_WIRE_WRITE */); + if (ret != KERN_SUCCESS) { + start = 0; + ret = -ENOMEM; + goto out; + } + paddr = pmap_extract(pmap, uaddr); + if (paddr == 0) { + ret = -EFAULT; + goto out; + } + m = PHYS_TO_VM_PAGE(paddr); + + sg_set_page(&db_tab->page[i].mem, m, MTHCA_ICM_PAGE_SIZE, + uaddr & ~PAGE_MASK); + + ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); + if (ret < 0) + goto out; + + ret = mthca_MAP_ICM_page(dev, sg_dma_address(&db_tab->page[i].mem), + mthca_uarc_virt(dev, uar, i), &status); + if (!ret && status) + ret = -EINVAL; + if (ret) { + pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); + goto out; + } + + db_tab->page[i].uvirt = uaddr; + db_tab->page[i].refcount = 1; + +out: + if (ret < 0 && start) + vm_map_unwire(&curthread->td_proc->p_vmspace->vm_map, + start, start + PAGE_SIZE, + VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); + mutex_unlock(&db_tab->mutex); + return ret; #endif } void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar, struct mthca_user_db_table *db_tab, int index) { -#ifdef __linux__ if (!mthca_is_memfree(dev)) return; @@ -531,7 +623,6 @@ void mthca_unmap_user_db(struct mthca_de --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount; mutex_unlock(&db_tab->mutex); -#endif } struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) @@ -573,6 +664,13 @@ void mthca_cleanup_user_db_tab(struct mt pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); #ifdef __linux__ put_page(sg_page(&db_tab->page[i].mem)); +#else + vm_offset_t start; + + start = db_tab->page[i].uvirt & PAGE_MASK; + vm_map_unwire(&curthread->td_proc->p_vmspace->vm_map, + start, start + PAGE_SIZE, + VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); #endif } }