Re: XSHM/shared-pixmap fix Was: Linux Shared Memory Issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> On Mon, 6 May 2002 13:04:58 +0200 (MET DST), "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> said:
macro>  Check it doesn't break static executables -- there were a few
macro> arch_get_unmapped_area() updates in mm/mmap.c that you don't
macro> include in the patch it would seem.

I have yet another arch_get_unmapped_area which includes it.

My arch_get_unmapped_area is a hybrid of one in mm/mmap.c and one in
arch/sparc64/sys_sparc64.c.  Also, I am using MY_SHMLBA to avoid
wasting address space.  I got following comments from Ralf when I
posted my previous patch.

>>>>> On Tue, 14 Aug 2001 10:49:41 +0200, Ralf Baechle <ralf@oss.sgi.com> said:
ralf> It's wasting huge amounts of address space.  That can be
ralf> prohibitive if you want to run something such as electric fence.
ralf> Technically the worst case of any CPU that's required is 32kb on
ralf> R4000 / R4400 SC and MC versions, so I don't want to go beyond
ralf> that.


Here is my arch_get_unmapped_area.

#ifdef HAVE_ARCH_UNMAPPED_AREA
/* solve cache aliasing problem (see Documentation/cachetlb.txt and
   arch/sparc64/kernel/sys_sparc.c */
#if SHMLBA > 0x10000
/* avoid overkill... */
#define MY_SHMLBA	0x10000
#else
#define MY_SHMLBA	SHMLBA
#endif
#define COLOUR_ALIGN(addr,pgoff)		\
	((((addr)+MY_SHMLBA-1)&~(MY_SHMLBA-1)) +	\
	 (((pgoff)<<PAGE_SHIFT) & (MY_SHMLBA-1)))

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 * vmm;
	int do_color_align;

	if (flags & MAP_FIXED) {
		/* We do not accept a shared mapping if it would violate
		 * cache aliasing constraints.
		 */
		if ((flags & MAP_SHARED) && (addr & (MY_SHMLBA - 1)))
			return -EINVAL;
		return addr;
	}

	if (len > TASK_SIZE)
		return -ENOMEM;
	do_color_align = 0;
	if (filp || (flags & MAP_SHARED))
		do_color_align = 1;
	if (addr) {
		if (do_color_align)
			addr = COLOUR_ALIGN(addr, pgoff);
		else
			addr = PAGE_ALIGN(addr);
		vmm = find_vma(current->mm, addr);
		if (TASK_SIZE - len >= addr &&
		    (!vmm || addr + len <= vmm->vm_start))
			return addr;
	}
	addr = TASK_UNMAPPED_BASE;
	if (do_color_align)
		addr = COLOUR_ALIGN(addr, pgoff);
	else
		addr = PAGE_ALIGN(addr);

	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
		/* At this point:  (!vmm || addr < vmm->vm_end). */
		if (TASK_SIZE - len < addr)
			return -ENOMEM;
		if (!vmm || addr + len <= vmm->vm_start)
			return addr;
		addr = vmm->vm_end;
		if (do_color_align)
			addr = COLOUR_ALIGN(addr, pgoff);
	}
}
#endif /* HAVE_ARCH_UNMAPPED_AREA */

---
Atsushi Nemoto

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux