Here's a preview of my patch to give each process a separate list of VMAsunder NOMMU mode, just as under MMU mode. Could you have a look over itplease?

Could you also see if you get a memory leak on the blackfin CPU? I see a leakwhen I use this patch, but I'm not sure whether it's this patch, or whetherit's something else in the arch that is suppressed without this patch.

As far as I can tell by page counting there shouldn't be a leak.

I've taken some of Bernd's patch into this one, and I'll take a bit more whenI've done.

David

[PATCH] NOMMU: Make VMAs per MM as for MMU-mode linux

From: David Howells <dhowells@redhat.com>

Make VMAs per mm_struct as for MMU-mode linux. This solves the nattch problemfor SYSV SHM where nattch for a segment does not reflect the number of shmat's(and forks) done.

/* invoke the file's mapping function so that it can keep track of * shared mappings on devices or memory@@ -754,23 +920,41 @@ static int do_mmap_private(struct vm_area_struct *vma, unsigned long len) * make a private copy of the data and map that instead */ }

+ len = PAGE_ALIGN(len);+ /* allocate some memory to hold the mapping * - note that this may not return a page-aligned address if the object * we're allocating is smaller than a page */- base = kmalloc(len, GFP_KERNEL|__GFP_COMP);- if (!base)+ order = get_order(len);+ _debug("alloc order %d for %lx", order, len);++ pages = alloc_pages(GFP_KERNEL, order);+ if (!pages) goto enomem;

- /* if we want to share, we need to check for VMAs created by other+ if (file) {+ get_file(file);+ get_file(file);+ }++ down_write(&nommu_region_sem);++ /* if we want to share, we need to check for regions created by other * mmap() calls that overlap with our proposed mapping- * - we can only share with an exact match on most regular files+ * - we can only share with a superset match on most regular files * - shared mappings on character devices and memory backed files are * permitted to overlap inexactly as far as we are concerned for in * these cases, sharing is handled in the driver or filesystem rather * than here */ if (vm_flags & VM_MAYSHARE) {- unsigned long pglen = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;- unsigned long vmpglen;+ struct vm_region *pregion;+ unsigned long pglen, rpglen, pgend, rpgend, start;

- dont_share_VMAs:- vma = NULL;- /* obtain the address at which to make a shared mapping * - this is the hook for quasi-memory character devices to * tell us the location of a shared mapping@@ -909,105 +1136,92 @@ unsigned long do_mmap_pgoff(struct file *file, if (IS_ERR((void *) addr)) { ret = addr; if (ret != (unsigned long) -ENOSYS)- goto error;+ goto error_just_free;

/* the driver refused to tell us where to site * the mapping so we'll have to attempt to copy * it */ ret = (unsigned long) -ENODEV; if (!(capabilities & BDI_CAP_MAP_COPY))- goto error;+ goto error_just_free;

- if (atomic_dec_and_test(&vma->vm_usage)) {- delete_nommu_vma(vma);+/*+ * split a vma into two pieces at address 'addr', a new vma is allocated either+ * for the first part or the tail.+ */+int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,+ unsigned long addr, int new_below)+{+ struct vm_area_struct *new;+ struct vm_region *region;+ unsigned long npages;