No objections? Then I assume this is OK... Helge On 04/17/2014 10:45 PM, Helge Deller wrote: > Would the following patch be acceptable? > It adds an additional field to struct address_space which will most likely only > be used by the parisc arch. > > If it's acceptable, I would like to push it through the parisc tree, if not, > I'm of course open to other ideas too. > > Thanks, > Helge > > PATCH: > [RFC,PATCH] mm,parisc: keep track of last mmap'ed address > > Because of parisc's cache aliasing constraints we need to map shared pages at a > multiple of 4MB while most other architectures can map files at any multiple of > PAGE_SIZE. In the past this constraint was ensured by calculating a virtual > offset into this 4MB region which is based on the physical address of the > kernel mapping variable (right-shift value of filp->f_mapping by 8 bits). > Since we only have a 32bit userspace (even when running on a 64bit kernel) this > often leads to large gaps in the maps of the userspace processes and to out of > memory situations even if physical memory was still free. Of course I did > played with other variants of shifting the f_mapping value to find better > offsets but this didn't helped either. > > This patch chooses a different approach. > It adds the additional field i_mmap_lastmmap to the address_space struct to > keep track of the last mapping of a shared file. With this bookkeeping it's > possible for the parisc memory allocator to > a) choose a new mapping offset if the file hasn't been mapped yet, and > b) take the last-used mapping if it was already mapped by another process. > > Overall this approach leads to a more condensed memory usage on parisc because > the shared files will now be mapped much closer to each other. This is e.g. > visible with shared libraries which are now not any longer cluttered around > in the userspace process but close to each other at the top of the userspace > memory. > > Signed-off-by: Helge Deller <deller@xxxxxx> > > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 81048f9..f757a5c 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -416,6 +416,9 @@ struct address_space { > unsigned int i_mmap_writable;/* count VM_SHARED mappings */ > struct rb_root i_mmap; /* tree of private and shared mappings */ > struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ > +#ifdef CONFIG_MMAP_TRACKING > + unsigned long i_mmap_lastmmap; /* address of last mmap */ > +#endif > struct mutex i_mmap_mutex; /* protect tree, count, list */ > /* Protected by tree_lock together with the radix tree */ > unsigned long nrpages; /* number of total pages */ > diff --git a/mm/mmap.c b/mm/mmap.c > index b1202cf..e2659c3 100644 > --- a/mm/mmap.c > +++ b/mm/mmap.c > @@ -212,8 +212,13 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma, > { > if (vma->vm_flags & VM_DENYWRITE) > atomic_inc(&file_inode(file)->i_writecount); > - if (vma->vm_flags & VM_SHARED) > + if (vma->vm_flags & VM_SHARED) { > mapping->i_mmap_writable--; > +#ifdef CONFIG_MMAP_TRACKING > + if (mapping->i_mmap_writable == 0) > + mapping->i_mmap_lastmmap = 0; > +#endif > + } > > flush_dcache_mmap_lock(mapping); > if (unlikely(vma->vm_flags & VM_NONLINEAR)) > diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig > index bb2a8ec..9518361 100644 > --- a/arch/parisc/Kconfig > +++ b/arch/parisc/Kconfig > @@ -38,6 +38,9 @@ config PARISC > config MMU > def_bool y > > +config MMAP_TRACKING > + def_bool y > + > config STACK_GROWSUP > def_bool y > > diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c > index 31ffa9b..7d8cbd1 100644 > --- a/arch/parisc/kernel/sys_parisc.c > +++ b/arch/parisc/kernel/sys_parisc.c > @@ -36,12 +36,12 @@ > #include <linux/personality.h> > #include <linux/random.h> > > -/* we construct an artificial offset for the mapping based on the physical > - * address of the kernel mapping variable */ > +/* the address_space struct holds a field i_mmap_lastmmap with the last mapping > + * of this file for us */ > #define GET_LAST_MMAP(filp) \ > - (filp ? ((unsigned long) filp->f_mapping) >> 8 : 0UL) > + (filp ? filp->f_mapping->i_mmap_lastmmap : 0UL) > #define SET_LAST_MMAP(filp, val) \ > - { /* nothing */ } > + { if (filp) filp->f_mapping->i_mmap_lastmmap = (val); } > > static int get_offset(unsigned int last_mmap) > { -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>