Re: alpha 2.4.13: fix taso osf emulation

From: Ivan Kokshaysky (ink@jurassic.park.msu.ru)
Date: Fri Oct 26 2001 - 05:45:22 EST


On Fri, Oct 26, 2001 at 12:01:10PM +0200, Maciej W. Rozycki wrote:
> On Fri, 26 Oct 2001, Richard Henderson wrote:
> > Thoughts on changing all ports such that a mmap with a non-zero,
> > non-MAP_FIXED address starts the vma search at that address,
> > rather than looking for that exact address then checking the
> > regular unmapped base?
>
> It used to do so. It breaks things such as dynamic linking of shared
> objects linked at high load address. It breaks mmap() in principle, as it
> shouldn't fail when invoked with a non-zero, non-MAP_FIXED, invalid
> address if there is still address space available elsewhere.

Maciej and I discussed all this a while back, and I had a patch
which did exactly that that Richard suggested, plus:
 as far as I can tell, it conforms to any existing mmap(2) documentation;
 is more effective than current implementation, as I call the second
 find_vma() only after VM wraparound, which is extremely rare;
 keeps osf /sbin/loader happy, so no need for alpha-specific routine.
Patch appended, comments?

Ivan.

P.S. Just noticed missing closing brace in the patch from my previous post...
     Sorry.

--- 2.4.13/mm/mmap.c Sun Sep 30 22:05:40 2001
+++ linux/mm/mmap.c Fri Oct 26 13:36:47 2001
@@ -590,27 +590,38 @@ free_vma:
 static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
 {
         struct vm_area_struct *vma;
+ unsigned long addr_limit = TASK_SIZE - len;
+ unsigned long addr1 = 0;
 
         if (len > TASK_SIZE)
                 return -ENOMEM;
 
         if (addr) {
                 addr = PAGE_ALIGN(addr);
- vma = find_vma(current->mm, addr);
- if (TASK_SIZE - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
- return addr;
+ if (addr > TASK_UNMAPPED_BASE)
+ addr1 = addr;
+ goto find_free_area;
         }
+
+default_area:
         addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
 
+find_free_area:
         for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
                 /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr)
- return -ENOMEM;
+ if (addr_limit < addr)
+ break;
                 if (!vma || addr + len <= vma->vm_start)
                         return addr;
                 addr = vma->vm_end;
         }
+ if (addr1) {
+ /* No unmapped areas above addr; try below it */
+ addr_limit = addr1;
+ addr1 = 0;
+ goto default_area;
+ }
+ return -ENOMEM;
 }
 #else
 extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Oct 31 2001 - 21:00:30 EST