Message ID | 20081107003841.GE7533@us.ibm.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Sonny Rao writes: > Fix the BSR driver to allow small BSR devices, which are limited to a > single 4k space, on a 64k page kernel. Previously the driver would > reject the mmap since the size was smaller than PAGESIZE (or because > the size was greater than the size of the device). Now, we check for > this case use remap_4k_pfn(). Also, take out code to set vm_flags, > as the remap_pfn functions will do this for us. Thanks. Do we know that the BSR size will always be 4k if it's not a multiple of 64k? Is it possible that we could get 8k, 16k or 32k or BSRs? If it is possible, what does the user need to be able to do? Do they just want to map 4k, or might then want to map the whole thing? Paul.
On Fri, Nov 07, 2008 at 04:28:29PM +1100, Paul Mackerras wrote: > Sonny Rao writes: > > > Fix the BSR driver to allow small BSR devices, which are limited to a > > single 4k space, on a 64k page kernel. Previously the driver would > > reject the mmap since the size was smaller than PAGESIZE (or because > > the size was greater than the size of the device). Now, we check for > > this case use remap_4k_pfn(). Also, take out code to set vm_flags, > > as the remap_pfn functions will do this for us. > > Thanks. > > Do we know that the BSR size will always be 4k if it's not a multiple > of 64k? Is it possible that we could get 8k, 16k or 32k or BSRs? > If it is possible, what does the user need to be able to do? Do they > just want to map 4k, or might then want to map the whole thing? Hi Paul, the BSR comes in 4 different sizes, 8, 16, 64, 128. The 8 byte BSR registers are always contained to 4k pages and are always representing a piece of a larger BSR, but can be assigned to individual LPARs. The 16 byte BSR is contained in two 4k pages, and so the code as patched would not allow both 4k pages to be mapped. However, I don't see any reason for the user to need both 4k pages. To give some background as to why the BSR exists in multiple pages at all I'll say that one proposed way to use the BSR is to have each participating cpu "own" a cache-line sized piece of the BSR mapped page and write only to that piece. The reasoning is that using this approach, software could use either a BSR or regular cachable memory for the barrier operation, and I would not need to know which it is actually using. So in this type of scenario, there should be enough cache-lines sized pieces mappable. In the case of the 16 byte BSR, one 4k page contains 32 128byte cache-line pieces. So this is enough to still use the BSR in this way. The 64 byte BSR is contained in 16 4k-pages -- so one 64k page works there, and the 128 byte BSR is contained in 32 4k pages. The case of the 16 byte BSR is the only one where it matters, I can change the code to map both 4k pages if the user requests it, but I don't see any extra utility. For consistency though, maybe we should reject a request to map more than 4k but less than 64k on a 64k kernel? Sonny
Index: common/drivers/char/bsr.c =================================================================== --- common.orig/drivers/char/bsr.c 2008-11-06 16:43:58.000000000 -0600 +++ common/drivers/char/bsr.c 2008-11-06 18:30:41.000000000 -0600 @@ -27,6 +27,7 @@ #include <linux/cdev.h> #include <linux/list.h> #include <linux/mm.h> +#include <asm/pgtable.h> #include <asm/io.h> /* @@ -115,15 +116,23 @@ { unsigned long size = vma->vm_end - vma->vm_start; struct bsr_dev *dev = filp->private_data; + int ret; - if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) - return -EINVAL; + /* This is legal where we have a BSR on a 4k page but a 64k kernel */ + if (size > dev->bsr_len) + size = dev->bsr_len; - vma->vm_flags |= (VM_IO | VM_DONTEXPAND); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, - size, vma->vm_page_prot)) + if (dev->bsr_len < PAGE_SIZE) + ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12, + vma->vm_page_prot); + else + ret = io_remap_pfn_range(vma, vma->vm_start, + dev->bsr_addr >> PAGE_SHIFT, + size, vma->vm_page_prot); + + if (ret) return -EAGAIN; return 0;
Fix the BSR driver to allow small BSR devices, which are limited to a single 4k space, on a 64k page kernel. Previously the driver would reject the mmap since the size was smaller than PAGESIZE (or because the size was greater than the size of the device). Now, we check for this case use remap_4k_pfn(). Also, take out code to set vm_flags, as the remap_pfn functions will do this for us. Signed-off-by: Sonny Rao <sonnyrao@us.ibm.com>