* [patch 0/4] remove nopfn
@ 2008-05-02 3:19 Nick Piggin
2008-05-02 3:20 ` [patch 1/4] mm: allow pfnmap ->fault()s Nick Piggin
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Nick Piggin @ 2008-05-02 3:19 UTC (permalink / raw)
To: Andrew Morton
Cc: Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw
Hi,
Can we pretty please get this into the current merge window? All it takes
is a quick review and test ;) I think mspec was already tested, but it
wouldn't hurt to verify again...
It shaves about .5K off mm/memory.o so it is pretty significant.
Mispredicted branches are also actually a significant cost in the fault
path which I'm trying to reduce (merging fault with page_mkwrite should
help with this further).
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 14+ messages in thread* [patch 1/4] mm: allow pfnmap ->fault()s 2008-05-02 3:19 [patch 0/4] remove nopfn Nick Piggin @ 2008-05-02 3:20 ` Nick Piggin 2008-05-02 3:21 ` [patch 2/4] mspec: convert nopfn to fault Nick Piggin ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Nick Piggin @ 2008-05-02 3:20 UTC (permalink / raw) To: Andrew Morton Cc: Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw Take out an assertion to allow ->fault handlers to service PFNMAP regions. This is required to reimplement .nopfn handlers with .fault handlers and subsequently remove nopfn. Signed-off-by: Nick Piggin <npiggin@suse.de> Acked-by: Jes Sorensen <jes@sgi.com> --- mm/memory.c | 2 -- 1 file changed, 2 deletions(-) Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c +++ linux-2.6/mm/memory.c @@ -2275,8 +2275,6 @@ static int __do_fault(struct mm_struct * vmf.flags = flags; vmf.page = NULL; - BUG_ON(vma->vm_flags & VM_PFNMAP); - ret = vma->vm_ops->fault(vma, &vmf); if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) return ret; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [patch 2/4] mspec: convert nopfn to fault 2008-05-02 3:19 [patch 0/4] remove nopfn Nick Piggin 2008-05-02 3:20 ` [patch 1/4] mm: allow pfnmap ->fault()s Nick Piggin @ 2008-05-02 3:21 ` Nick Piggin 2008-05-06 12:27 ` Robin Holt 2008-05-02 3:22 ` [patch 3/4] spufs: " Nick Piggin 2008-05-02 3:23 ` [patch 4/4] mm: remove nopfn Nick Piggin 3 siblings, 1 reply; 14+ messages in thread From: Nick Piggin @ 2008-05-02 3:21 UTC (permalink / raw) To: Andrew Morton Cc: Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw --- drivers/char/mspec.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) Index: linux-2.6/drivers/char/mspec.c =================================================================== --- linux-2.6.orig/drivers/char/mspec.c +++ linux-2.6/drivers/char/mspec.c @@ -193,25 +193,24 @@ mspec_close(struct vm_area_struct *vma) } /* - * mspec_nopfn + * mspec_fault * * Creates a mspec page and maps it to user space. */ -static unsigned long -mspec_nopfn(struct vm_area_struct *vma, unsigned long address) +static int +mspec_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { unsigned long paddr, maddr; unsigned long pfn; + pgoff_t index = vmf->pgoff; int index; struct vma_data *vdata = vma->vm_private_data; - BUG_ON(address < vdata->vm_start || address >= vdata->vm_end); - index = (address - vdata->vm_start) >> PAGE_SHIFT; maddr = (volatile unsigned long) vdata->maddr[index]; if (maddr == 0) { maddr = uncached_alloc_page(numa_node_id(), 1); if (maddr == 0) - return NOPFN_OOM; + return VM_FAULT_OOM; spin_lock(&vdata->lock); if (vdata->maddr[index] == 0) { @@ -231,13 +230,20 @@ mspec_nopfn(struct vm_area_struct *vma, pfn = paddr >> PAGE_SHIFT; - return pfn; + /* + * vm_insert_pfn can fail with -EBUSY, but in that case it will + * be because another thread has installed the pte first, so it + * is no problem. + */ + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); + + return VM_FAULT_NOPAGE; } static struct vm_operations_struct mspec_vm_ops = { .open = mspec_open, .close = mspec_close, - .nopfn = mspec_nopfn + .fault = mspec_fault, }; /* -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 2/4] mspec: convert nopfn to fault 2008-05-02 3:21 ` [patch 2/4] mspec: convert nopfn to fault Nick Piggin @ 2008-05-06 12:27 ` Robin Holt 0 siblings, 0 replies; 14+ messages in thread From: Robin Holt @ 2008-05-06 12:27 UTC (permalink / raw) To: Nick Piggin Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw Sorry, I missed this original post. Saw the add this morning and went back to the archives. > -static unsigned long > -mspec_nopfn(struct vm_area_struct *vma, unsigned long address) > +static int > +mspec_fault(struct vm_area_struct *vma, struct vm_fault *vmf) > { > unsigned long paddr, maddr; > unsigned long pfn; > + pgoff_t index = vmf->pgoff; > int index; I think this will cause problems. Two definitions of index. I removed the int index and tested. This appears to work fine. Sorry for the delay. Thanks, Robin Index: remove_nopfn/drivers/char/mspec.c =================================================================== --- remove_nopfn.orig/drivers/char/mspec.c 2008-05-06 07:07:30.000000000 -0500 +++ remove_nopfn/drivers/char/mspec.c 2008-05-06 07:17:01.784314587 -0500 @@ -203,7 +203,6 @@ mspec_fault(struct vm_area_struct *vma, unsigned long paddr, maddr; unsigned long pfn; pgoff_t index = vmf->pgoff; - int index; struct vma_data *vdata = vma->vm_private_data; maddr = (volatile unsigned long) vdata->maddr[index]; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [patch 3/4] spufs: convert nopfn to fault 2008-05-02 3:19 [patch 0/4] remove nopfn Nick Piggin 2008-05-02 3:20 ` [patch 1/4] mm: allow pfnmap ->fault()s Nick Piggin 2008-05-02 3:21 ` [patch 2/4] mspec: convert nopfn to fault Nick Piggin @ 2008-05-02 3:22 ` Nick Piggin 2008-05-02 4:06 ` Jeremy Kerr 2008-05-02 3:23 ` [patch 4/4] mm: remove nopfn Nick Piggin 3 siblings, 1 reply; 14+ messages in thread From: Nick Piggin @ 2008-05-02 3:22 UTC (permalink / raw) To: Andrew Morton Cc: Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw --- arch/powerpc/platforms/cell/spufs/file.c | 91 ++++++++++++--------------- arch/powerpc/platforms/cell/spufs/sputrace.c | 8 +- 2 files changed, 46 insertions(+), 53 deletions(-) Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c @@ -237,11 +237,10 @@ spufs_mem_write(struct file *file, const return size; } -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long pfn, offset, addr0 = address; + unsigned long pfn, offset, address = (unsigned long)vmf->virtual_address; #ifdef CONFIG_SPU_FS_64K_LS struct spu_state *csa = &ctx->csa; int psize; @@ -259,15 +258,14 @@ static unsigned long spufs_mem_mmap_nopf } #endif /* CONFIG_SPU_FS_64K_LS */ - offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); + offset = vmf->pgoff << PAGE_SHIFT; if (offset >= LS_SIZE) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; - pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", - addr0, address, offset); + pr_debug("spufs_mem_mmap_fault address=0x%lx, offset=0x%lx\n", address, offset); if (spu_acquire(ctx)) - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; if (ctx->state == SPU_STATE_SAVED) { vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) @@ -278,16 +276,16 @@ static unsigned long spufs_mem_mmap_nopf | _PAGE_NO_CACHE); pfn = (ctx->spu->local_store_phys + offset) >> PAGE_SHIFT; } - vm_insert_pfn(vma, address, pfn); + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); spu_release(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } static struct vm_operations_struct spufs_mem_mmap_vmops = { - .nopfn = spufs_mem_mmap_nopfn, + .fault = spufs_mem_mmap_fault, }; static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) @@ -350,20 +348,19 @@ static const struct file_operations spuf #endif }; -static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, - unsigned long address, +static int spufs_ps_fault(struct vm_area_struct *vma, + struct vm_fault *vmf, unsigned long ps_offs, unsigned long ps_size) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long area, offset = address - vma->vm_start; + unsigned long area, offset = vmf->pgoff << PAGE_SHIFT; int ret = 0; - spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx); + spu_context_nospu_trace(spufs_ps_fault__enter, ctx); - offset += vma->vm_pgoff << PAGE_SHIFT; if (offset >= ps_size) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; /* * Because we release the mmap_sem, the context may be destroyed while @@ -377,7 +374,7 @@ static unsigned long spufs_ps_nopfn(stru * pages to hand out to the user, but we don't want to wait * with the mmap_sem held. * It is possible to drop the mmap_sem here, but then we need - * to return NOPFN_REFAULT because the mappings may have + * to return VM_FAULT_NOPAGE because the mappings may have * hanged. */ if (spu_acquire(ctx)) @@ -385,14 +382,15 @@ static unsigned long spufs_ps_nopfn(stru if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); - spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx); + spu_context_nospu_trace(spufs_ps_fault__sleep, ctx); ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); - spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu); + spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu); down_read(¤t->mm->mmap_sem); } else { area = ctx->spu->problem_phys + ps_offs; - vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); - spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu); + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, + (area + offset) >> PAGE_SHIFT); + spu_context_trace(spufs_ps_fault__insert, ctx, ctx->spu); } if (!ret) @@ -400,18 +398,18 @@ static unsigned long spufs_ps_nopfn(stru refault: put_spu_context(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } #if SPUFS_MMAP_4K -static unsigned long spufs_cntl_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_cntl_mmap_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x4000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x4000, 0x1000); } static struct vm_operations_struct spufs_cntl_mmap_vmops = { - .nopfn = spufs_cntl_mmap_nopfn, + .fault = spufs_cntl_mmap_fault, }; /* @@ -1096,23 +1094,22 @@ static ssize_t spufs_signal1_write(struc return 4; } -static unsigned long spufs_signal1_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_signal1_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { #if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x14000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x14000, 0x1000); #elif PAGE_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal1_mmap_vmops = { - .nopfn = spufs_signal1_mmap_nopfn, + .fault = spufs_signal1_mmap_fault, }; static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) @@ -1233,23 +1230,22 @@ static ssize_t spufs_signal2_write(struc } #if SPUFS_MMAP_4K -static unsigned long spufs_signal2_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_signal2_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { #if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x1c000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x1c000, 0x1000); #elif PAGE_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal2_mmap_vmops = { - .nopfn = spufs_signal2_mmap_nopfn, + .fault = spufs_signal2_mmap_fault, }; static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) @@ -1361,14 +1357,13 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_typ spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE); #if SPUFS_MMAP_4K -static unsigned long spufs_mss_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_mss_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x0000, 0x1000); } static struct vm_operations_struct spufs_mss_mmap_vmops = { - .nopfn = spufs_mss_mmap_nopfn, + .fault = spufs_mss_mmap_fault, }; /* @@ -1423,14 +1418,13 @@ static const struct file_operations spuf .mmap = spufs_mss_mmap, }; -static unsigned long spufs_psmap_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_psmap_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x20000); + return spufs_ps_fault(vma, vmf, 0x0000, 0x20000); } static struct vm_operations_struct spufs_psmap_mmap_vmops = { - .nopfn = spufs_psmap_mmap_nopfn, + .fault = spufs_psmap_mmap_fault, }; /* @@ -1483,14 +1477,13 @@ static const struct file_operations spuf #if SPUFS_MMAP_4K -static unsigned long spufs_mfc_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_mfc_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x3000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x3000, 0x1000); } static struct vm_operations_struct spufs_mfc_mmap_vmops = { - .nopfn = spufs_mfc_mmap_nopfn, + .fault = spufs_mfc_mmap_fault, }; /* Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sputrace.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -182,10 +182,10 @@ struct spu_probe spu_probes[] = { { "spu_yield__enter", "ctx %p", spu_context_nospu_event }, { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event }, { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__enter", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__sleep", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__wake", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__insert", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event }, { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event }, { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event }, { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event }, -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 3:22 ` [patch 3/4] spufs: " Nick Piggin @ 2008-05-02 4:06 ` Jeremy Kerr 2008-05-02 4:47 ` Nick Piggin 2008-05-02 5:06 ` Nick Piggin 0 siblings, 2 replies; 14+ messages in thread From: Jeremy Kerr @ 2008-05-02 4:06 UTC (permalink / raw) To: Nick Piggin Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw Hi Nick, > -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct > *vma, - unsigned long address) Aside from the > 80 character lines, all is OK here. Acked-by: Jeremy Kerr <jk@ozlabs.org> Cheers, Jeremy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 4:06 ` Jeremy Kerr @ 2008-05-02 4:47 ` Nick Piggin 2008-05-02 9:43 ` Jeremy Kerr 2008-05-02 5:06 ` Nick Piggin 1 sibling, 1 reply; 14+ messages in thread From: Nick Piggin @ 2008-05-02 4:47 UTC (permalink / raw) To: Jeremy Kerr Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw On Fri, May 02, 2008 at 02:06:38PM +1000, Jeremy Kerr wrote: > Hi Nick, > > > -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct > > *vma, - unsigned long address) > > Aside from the > 80 character lines, all is OK here. > > Acked-by: Jeremy Kerr <jk@ozlabs.org> Great, thanks very much! -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 4:47 ` Nick Piggin @ 2008-05-02 9:43 ` Jeremy Kerr 2008-05-03 5:41 ` Nick Piggin 0 siblings, 1 reply; 14+ messages in thread From: Jeremy Kerr @ 2008-05-02 9:43 UTC (permalink / raw) To: Nick Piggin Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw Hi Nick, > > Acked-by: Jeremy Kerr <jk@ozlabs.org> > > Great, thanks very much! After more testing, it looks like these patches cause a huge increase in load (ie, system is unresponsive for large amounts of time) for various tests which depend on the fault path. I need to get some quantitative numbers, but it looks like oprofile is broken at the moment. More debugging coming.. Cheers, Jeremy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 9:43 ` Jeremy Kerr @ 2008-05-03 5:41 ` Nick Piggin 2008-05-06 3:01 ` Jeremy Kerr 0 siblings, 1 reply; 14+ messages in thread From: Nick Piggin @ 2008-05-03 5:41 UTC (permalink / raw) To: Jeremy Kerr Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw On Fri, May 02, 2008 at 07:43:53PM +1000, Jeremy Kerr wrote: > Hi Nick, > > > > Acked-by: Jeremy Kerr <jk@ozlabs.org> > > > > Great, thanks very much! > > After more testing, it looks like these patches cause a huge increase in > load (ie, system is unresponsive for large amounts of time) for various > tests which depend on the fault path. > > I need to get some quantitative numbers, but it looks like oprofile is > broken at the moment. More debugging coming.. OK, thanks for testing that... It _should_ be 100% equivalent really, so it must be some problem in the conversion. Don't worry too much about getting exact numbers because any noticable difference would be a bug. Hmm, in spufs_mem_mmap_fault, vm_insert_pfn should just take address (corrected for 64K), rather than the uncorrected address I gave it... Can't see any other problems though. Is it getting stuck looping in faults somehow? Thanks, Nick -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-03 5:41 ` Nick Piggin @ 2008-05-06 3:01 ` Jeremy Kerr 2008-05-06 8:38 ` Nick Piggin 0 siblings, 1 reply; 14+ messages in thread From: Jeremy Kerr @ 2008-05-06 3:01 UTC (permalink / raw) To: Nick Piggin Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw Hi Nick, > Hmm, in spufs_mem_mmap_fault, vm_insert_pfn should just take > address (corrected for 64K), rather than the uncorrected address I > gave it... Yep, using the 'address' var for vm_insert_pfn fixes the problem for me. Cheers, Jeremy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-06 3:01 ` Jeremy Kerr @ 2008-05-06 8:38 ` Nick Piggin 0 siblings, 0 replies; 14+ messages in thread From: Nick Piggin @ 2008-05-06 8:38 UTC (permalink / raw) To: Jeremy Kerr Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw On Tue, May 06, 2008 at 01:01:26PM +1000, Jeremy Kerr wrote: > Hi Nick, > > > Hmm, in spufs_mem_mmap_fault, vm_insert_pfn should just take > > address (corrected for 64K), rather than the uncorrected address I > > gave it... > > Yep, using the 'address' var for vm_insert_pfn fixes the problem for me. Ah, thanks for testing. Will send an updated patch also with the warning you noticed fixed. Thanks, Nick -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 4:06 ` Jeremy Kerr 2008-05-02 4:47 ` Nick Piggin @ 2008-05-02 5:06 ` Nick Piggin 2008-05-02 6:45 ` Jeremy Kerr 1 sibling, 1 reply; 14+ messages in thread From: Nick Piggin @ 2008-05-02 5:06 UTC (permalink / raw) To: Jeremy Kerr Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw On Fri, May 02, 2008 at 02:06:38PM +1000, Jeremy Kerr wrote: > Hi Nick, > > > -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct > > *vma, - unsigned long address) > > Aside from the > 80 character lines, all is OK here. And here is an update with <= 80 column lines... spufs: convert nopfn to fault From: Nick Piggin <npiggin@suse.de> Signed-off-by: Nick Piggin <npiggin@suse.de> Acked-by: Jeremy Kerr <jk@ozlabs.org> --- arch/powerpc/platforms/cell/spufs/file.c | 91 ++++++++++++--------------- arch/powerpc/platforms/cell/spufs/sputrace.c | 8 +- 2 files changed, 46 insertions(+), 53 deletions(-) Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c @@ -237,11 +237,14 @@ spufs_mem_write(struct file *file, const return size; } -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long pfn, offset, addr0 = address; + unsigned long pfn, offset, address; + + address = (unsigned long)vmf->virtual_address; + #ifdef CONFIG_SPU_FS_64K_LS struct spu_state *csa = &ctx->csa; int psize; @@ -259,15 +262,15 @@ static unsigned long spufs_mem_mmap_nopf } #endif /* CONFIG_SPU_FS_64K_LS */ - offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); + offset = vmf->pgoff << PAGE_SHIFT; if (offset >= LS_SIZE) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; - pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", - addr0, address, offset); + pr_debug("spufs_mem_mmap_fault address=0x%lx, offset=0x%lx\n", + address, offset); if (spu_acquire(ctx)) - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; if (ctx->state == SPU_STATE_SAVED) { vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) @@ -278,16 +281,16 @@ static unsigned long spufs_mem_mmap_nopf | _PAGE_NO_CACHE); pfn = (ctx->spu->local_store_phys + offset) >> PAGE_SHIFT; } - vm_insert_pfn(vma, address, pfn); + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); spu_release(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } static struct vm_operations_struct spufs_mem_mmap_vmops = { - .nopfn = spufs_mem_mmap_nopfn, + .fault = spufs_mem_mmap_fault, }; static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) @@ -350,20 +353,19 @@ static const struct file_operations spuf #endif }; -static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, - unsigned long address, +static int spufs_ps_fault(struct vm_area_struct *vma, + struct vm_fault *vmf, unsigned long ps_offs, unsigned long ps_size) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long area, offset = address - vma->vm_start; + unsigned long area, offset = vmf->pgoff << PAGE_SHIFT; int ret = 0; - spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx); + spu_context_nospu_trace(spufs_ps_fault__enter, ctx); - offset += vma->vm_pgoff << PAGE_SHIFT; if (offset >= ps_size) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; /* * Because we release the mmap_sem, the context may be destroyed while @@ -377,7 +379,7 @@ static unsigned long spufs_ps_nopfn(stru * pages to hand out to the user, but we don't want to wait * with the mmap_sem held. * It is possible to drop the mmap_sem here, but then we need - * to return NOPFN_REFAULT because the mappings may have + * to return VM_FAULT_NOPAGE because the mappings may have * hanged. */ if (spu_acquire(ctx)) @@ -385,14 +387,15 @@ static unsigned long spufs_ps_nopfn(stru if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); - spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx); + spu_context_nospu_trace(spufs_ps_fault__sleep, ctx); ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); - spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu); + spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu); down_read(¤t->mm->mmap_sem); } else { area = ctx->spu->problem_phys + ps_offs; - vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); - spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu); + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, + (area + offset) >> PAGE_SHIFT); + spu_context_trace(spufs_ps_fault__insert, ctx, ctx->spu); } if (!ret) @@ -400,18 +403,18 @@ static unsigned long spufs_ps_nopfn(stru refault: put_spu_context(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } #if SPUFS_MMAP_4K -static unsigned long spufs_cntl_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_cntl_mmap_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x4000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x4000, 0x1000); } static struct vm_operations_struct spufs_cntl_mmap_vmops = { - .nopfn = spufs_cntl_mmap_nopfn, + .fault = spufs_cntl_mmap_fault, }; /* @@ -1096,23 +1099,23 @@ static ssize_t spufs_signal1_write(struc return 4; } -static unsigned long spufs_signal1_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_signal1_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { #if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x14000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x14000, 0x1000); #elif PAGE_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal1_mmap_vmops = { - .nopfn = spufs_signal1_mmap_nopfn, + .fault = spufs_signal1_mmap_fault, }; static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) @@ -1233,23 +1236,23 @@ static ssize_t spufs_signal2_write(struc } #if SPUFS_MMAP_4K -static unsigned long spufs_signal2_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_signal2_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { #if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x1c000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x1c000, 0x1000); #elif PAGE_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal2_mmap_vmops = { - .nopfn = spufs_signal2_mmap_nopfn, + .fault = spufs_signal2_mmap_fault, }; static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) @@ -1361,14 +1364,14 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_typ spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE); #if SPUFS_MMAP_4K -static unsigned long spufs_mss_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mss_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x0000, 0x1000); } static struct vm_operations_struct spufs_mss_mmap_vmops = { - .nopfn = spufs_mss_mmap_nopfn, + .fault = spufs_mss_mmap_fault, }; /* @@ -1423,14 +1426,14 @@ static const struct file_operations spuf .mmap = spufs_mss_mmap, }; -static unsigned long spufs_psmap_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_psmap_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x20000); + return spufs_ps_fault(vma, vmf, 0x0000, 0x20000); } static struct vm_operations_struct spufs_psmap_mmap_vmops = { - .nopfn = spufs_psmap_mmap_nopfn, + .fault = spufs_psmap_mmap_fault, }; /* @@ -1483,14 +1486,14 @@ static const struct file_operations spuf #if SPUFS_MMAP_4K -static unsigned long spufs_mfc_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mfc_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x3000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x3000, 0x1000); } static struct vm_operations_struct spufs_mfc_mmap_vmops = { - .nopfn = spufs_mfc_mmap_nopfn, + .fault = spufs_mfc_mmap_fault, }; /* Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sputrace.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -182,10 +182,10 @@ struct spu_probe spu_probes[] = { { "spu_yield__enter", "ctx %p", spu_context_nospu_event }, { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event }, { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__enter", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__sleep", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__wake", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__insert", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event }, { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event }, { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event }, { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event }, -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch 3/4] spufs: convert nopfn to fault 2008-05-02 5:06 ` Nick Piggin @ 2008-05-02 6:45 ` Jeremy Kerr 0 siblings, 0 replies; 14+ messages in thread From: Jeremy Kerr @ 2008-05-02 6:45 UTC (permalink / raw) To: Nick Piggin Cc: Andrew Morton, Linux Memory Management List, Benjamin Herrenschmidt, jes, cpw Hi Nick, > -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct > *vma, - unsigned long address) > +static int > +spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault > *vmf) { > struct spu_context *ctx = vma->vm_file->private_data; > - unsigned long pfn, offset, addr0 = address; > + unsigned long pfn, offset, address; > + > + address = (unsigned long)vmf->virtual_address; > + > #ifdef CONFIG_SPU_FS_64K_LS > struct spu_state *csa = &ctx->csa; > int psize; This will add a warning (you're "mixing declarations and code") if CONFIG_SPU_FS_64K_LS. Cheers, Jeremy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [patch 4/4] mm: remove nopfn 2008-05-02 3:19 [patch 0/4] remove nopfn Nick Piggin ` (2 preceding siblings ...) 2008-05-02 3:22 ` [patch 3/4] spufs: " Nick Piggin @ 2008-05-02 3:23 ` Nick Piggin 3 siblings, 0 replies; 14+ messages in thread From: Nick Piggin @ 2008-05-02 3:23 UTC (permalink / raw) To: Andrew Morton Cc: Linux Memory Management List, Benjamin Herrenschmidt, jk, jes, cpw There are no users of nopfn in the tree. Remove it. Signed-off-by: Nick Piggin <npiggin@suse.de> --- include/linux/mm.h | 9 ------- mm/memory.c | 61 ++++------------------------------------------------- 2 files changed, 5 insertions(+), 65 deletions(-) Index: linux-2.6/include/linux/mm.h =================================================================== --- linux-2.6.orig/include/linux/mm.h +++ linux-2.6/include/linux/mm.h @@ -165,8 +165,6 @@ struct vm_operations_struct { void (*open)(struct vm_area_struct * area); void (*close)(struct vm_area_struct * area); int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf); - unsigned long (*nopfn)(struct vm_area_struct *area, - unsigned long address); /* notification that a previously read-only page is about to become * writable, if an error is returned it will cause a SIGBUS */ @@ -674,13 +672,6 @@ static inline int page_mapped(struct pag } /* - * Error return values for the *_nopfn functions - */ -#define NOPFN_SIGBUS ((unsigned long) -1) -#define NOPFN_OOM ((unsigned long) -2) -#define NOPFN_REFAULT ((unsigned long) -3) - -/* * Different kinds of faults, as returned by handle_mm_fault(). * Used to decide whether a process gets delivered SIGBUS or * just gets major/minor fault counters bumped up. Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c +++ linux-2.6/mm/memory.c @@ -1290,6 +1290,11 @@ out: * * This function should only be called from a vm_ops->fault handler, and * in that case the handler should return NULL. + * + * vma cannot be a COW mapping. + * + * As this is called only for pages that do not currently exist, we + * do not need to flush old virtual caches or the TLB. */ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) @@ -2416,59 +2421,6 @@ static int do_linear_fault(struct mm_str return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte); } - -/* - * do_no_pfn() tries to create a new page mapping for a page without - * a struct_page backing it - * - * As this is called only for pages that do not currently exist, we - * do not need to flush old virtual caches or the TLB. - * - * We enter with non-exclusive mmap_sem (to exclude vma changes, - * but allow concurrent faults), and pte mapped but not yet locked. - * We return with mmap_sem still held, but pte unmapped and unlocked. - * - * It is expected that the ->nopfn handler always returns the same pfn - * for a given virtual mapping. - * - * Mark this `noinline' to prevent it from bloating the main pagefault code. - */ -static noinline int do_no_pfn(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long address, pte_t *page_table, pmd_t *pmd, - int write_access) -{ - spinlock_t *ptl; - pte_t entry; - unsigned long pfn; - - pte_unmap(page_table); - BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))); - BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags)); - - pfn = vma->vm_ops->nopfn(vma, address & PAGE_MASK); - - BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn)); - - if (unlikely(pfn == NOPFN_OOM)) - return VM_FAULT_OOM; - else if (unlikely(pfn == NOPFN_SIGBUS)) - return VM_FAULT_SIGBUS; - else if (unlikely(pfn == NOPFN_REFAULT)) - return 0; - - page_table = pte_offset_map_lock(mm, pmd, address, &ptl); - - /* Only go through if we didn't race with anybody else... */ - if (pte_none(*page_table)) { - entry = pfn_pte(pfn, vma->vm_page_prot); - if (write_access) - entry = maybe_mkwrite(pte_mkdirty(entry), vma); - set_pte_at(mm, address, page_table, entry); - } - pte_unmap_unlock(page_table, ptl); - return 0; -} - /* * Fault of a previously existing named mapping. Repopulate the pte * from the encoded file_pte if possible. This enables swappable @@ -2529,9 +2481,6 @@ static inline int handle_pte_fault(struc if (likely(vma->vm_ops->fault)) return do_linear_fault(mm, vma, address, pte, pmd, write_access, entry); - if (unlikely(vma->vm_ops->nopfn)) - return do_no_pfn(mm, vma, address, pte, - pmd, write_access); } return do_anonymous_page(mm, vma, address, pte, pmd, write_access); -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2008-05-06 12:27 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-05-02 3:19 [patch 0/4] remove nopfn Nick Piggin 2008-05-02 3:20 ` [patch 1/4] mm: allow pfnmap ->fault()s Nick Piggin 2008-05-02 3:21 ` [patch 2/4] mspec: convert nopfn to fault Nick Piggin 2008-05-06 12:27 ` Robin Holt 2008-05-02 3:22 ` [patch 3/4] spufs: " Nick Piggin 2008-05-02 4:06 ` Jeremy Kerr 2008-05-02 4:47 ` Nick Piggin 2008-05-02 9:43 ` Jeremy Kerr 2008-05-03 5:41 ` Nick Piggin 2008-05-06 3:01 ` Jeremy Kerr 2008-05-06 8:38 ` Nick Piggin 2008-05-02 5:06 ` Nick Piggin 2008-05-02 6:45 ` Jeremy Kerr 2008-05-02 3:23 ` [patch 4/4] mm: remove nopfn Nick Piggin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox