Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved.
0003  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
0004  *
0005  * This software is available to you under a choice of one of two
0006  * licenses.  You may choose to be licensed under the terms of the GNU
0007  * General Public License (GPL) Version 2, available from the file
0008  * COPYING in the main directory of this source tree, or the
0009  * OpenIB.org BSD license below:
0010  *
0011  *     Redistribution and use in source and binary forms, with or
0012  *     without modification, are permitted provided that the following
0013  *     conditions are met:
0014  *
0015  *      - Redistributions of source code must retain the above
0016  *        copyright notice, this list of conditions and the following
0017  *        disclaimer.
0018  *
0019  *      - Redistributions in binary form must reproduce the above
0020  *        copyright notice, this list of conditions and the following
0021  *        disclaimer in the documentation and/or other materials
0022  *        provided with the distribution.
0023  *
0024  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0025  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0026  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0027  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0028  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0029  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0030  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0031  * SOFTWARE.
0032  */
0033 
0034 #include <linux/mm.h>
0035 #include <linux/sched/signal.h>
0036 #include <linux/device.h>
0037 
0038 #include "qib.h"
0039 
0040 static void __qib_release_user_pages(struct page **p, size_t num_pages,
0041                      int dirty)
0042 {
0043     unpin_user_pages_dirty_lock(p, num_pages, dirty);
0044 }
0045 
0046 /*
0047  * qib_map_page - a safety wrapper around pci_map_page()
0048  *
0049  * A dma_addr of all 0's is interpreted by the chip as "disabled".
0050  * Unfortunately, it can also be a valid dma_addr returned on some
0051  * architectures.
0052  *
0053  * The powerpc iommu assigns dma_addrs in ascending order, so we don't
0054  * have to bother with retries or mapping a dummy page to insure we
0055  * don't just get the same mapping again.
0056  *
0057  * I'm sure we won't be so lucky with other iommu's, so FIXME.
0058  */
0059 int qib_map_page(struct pci_dev *hwdev, struct page *page, dma_addr_t *daddr)
0060 {
0061     dma_addr_t phys;
0062 
0063     phys = dma_map_page(&hwdev->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
0064     if (dma_mapping_error(&hwdev->dev, phys))
0065         return -ENOMEM;
0066 
0067     if (!phys) {
0068         dma_unmap_page(&hwdev->dev, phys, PAGE_SIZE, DMA_FROM_DEVICE);
0069         phys = dma_map_page(&hwdev->dev, page, 0, PAGE_SIZE,
0070                     DMA_FROM_DEVICE);
0071         if (dma_mapping_error(&hwdev->dev, phys))
0072             return -ENOMEM;
0073         /*
0074          * FIXME: If we get 0 again, we should keep this page,
0075          * map another, then free the 0 page.
0076          */
0077     }
0078     *daddr = phys;
0079     return 0;
0080 }
0081 
0082 /**
0083  * qib_get_user_pages - lock user pages into memory
0084  * @start_page: the start page
0085  * @num_pages: the number of pages
0086  * @p: the output page structures
0087  *
0088  * This function takes a given start page (page aligned user virtual
0089  * address) and pins it and the following specified number of pages.  For
0090  * now, num_pages is always 1, but that will probably change at some point
0091  * (because caller is doing expected sends on a single virtually contiguous
0092  * buffer, so we can do all pages at once).
0093  */
0094 int qib_get_user_pages(unsigned long start_page, size_t num_pages,
0095                struct page **p)
0096 {
0097     unsigned long locked, lock_limit;
0098     size_t got;
0099     int ret;
0100 
0101     lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
0102     locked = atomic64_add_return(num_pages, &current->mm->pinned_vm);
0103 
0104     if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
0105         ret = -ENOMEM;
0106         goto bail;
0107     }
0108 
0109     mmap_read_lock(current->mm);
0110     for (got = 0; got < num_pages; got += ret) {
0111         ret = pin_user_pages(start_page + got * PAGE_SIZE,
0112                      num_pages - got,
0113                      FOLL_LONGTERM | FOLL_WRITE | FOLL_FORCE,
0114                      p + got, NULL);
0115         if (ret < 0) {
0116             mmap_read_unlock(current->mm);
0117             goto bail_release;
0118         }
0119     }
0120     mmap_read_unlock(current->mm);
0121 
0122     return 0;
0123 bail_release:
0124     __qib_release_user_pages(p, got, 0);
0125 bail:
0126     atomic64_sub(num_pages, &current->mm->pinned_vm);
0127     return ret;
0128 }
0129 
0130 void qib_release_user_pages(struct page **p, size_t num_pages)
0131 {
0132     __qib_release_user_pages(p, num_pages, 1);
0133 
0134     /* during close after signal, mm can be NULL */
0135     if (current->mm)
0136         atomic64_sub(num_pages, &current->mm->pinned_vm);
0137 }