[linux-sh:03182] Re: Jornada 680 boot failure

Kaz Kojima <[email protected]> Sun, 29 Feb 2004 10:12:20 +0900 (JST)
Newsgroups gmane.linux.ports.sh.general,gmane.linux.ports.sh.devel
Message-ID <[email protected]>
Paul Mundt <[email protected]> wrote:
> On SH-3, SHMLBA will be PAGE_SIZE anyways, so COLOUR_ALIGN() will essentially
> just become PAGE_ALIGN(). This also saves us from having to have multiple
> implementations.
> 
> Is there any reason why the SH-4 implementation isn't using free_area_cache?
> I don't see anything directly that would indicate a problem with using it.

Of course, I also think so.  I'm just testing the patch below
which is based on Ebihara-san's patch.
Does it work for sh3 case?

Regards,
	kaz
--
diff -u3prN linux-2.6.3-orig/arch/sh/kernel/sys_sh.c linux-2.6.3-local/arch/sh/kernel/sys_sh.c
--- linux-2.6.3-orig/arch/sh/kernel/sys_sh.c	Sat Feb 21 13:57:00 2004
+++ linux-2.6.3-local/arch/sh/kernel/sys_sh.c	Sun Feb 28 19:49:02 2004
@@ -43,7 +43,7 @@ asmlinkage int sys_pipe(unsigned long r4
 	return error;
 }
 
-#if defined(CONFIG_CPU_SH4)
+#if defined(HAVE_ARCH_UNMAPPED_AREA)
 /*
  * To avoid cache alias, we map the shard page with same color.
  */
@@ -52,7 +52,9 @@ asmlinkage int sys_pipe(unsigned long r4
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	unsigned long len, unsigned long pgoff, unsigned long flags)
 {
+	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
+	unsigned long start_addr;
 
 	if (flags & MAP_FIXED) {
 		/* We do not accept a shared mapping if it would violate
@@ -65,20 +67,44 @@ unsigned long arch_get_unmapped_area(str
 
 	if (len > TASK_SIZE)
 		return -ENOMEM;
-	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
 
+	if (addr) {
+		if (flags & MAP_PRIVATE)
+			addr = PAGE_ALIGN(addr);
+		else
+			addr = COLOUR_ALIGN(addr);
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			return addr;
+	}
 	if (flags & MAP_PRIVATE)
-		addr = PAGE_ALIGN(addr);
+		addr = PAGE_ALIGN(mm->free_area_cache);
 	else
-		addr = COLOUR_ALIGN(addr);
+		addr = COLOUR_ALIGN(mm->free_area_cache);
+	start_addr = addr;
 
-	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+full_search:
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 		/* At this point:  (!vma || addr < vma->vm_end). */
-		if (TASK_SIZE - len < addr)
+		if (TASK_SIZE - len < addr) {
+			/*
+			 * Start a new search - just in case we missed
+			 * some holes.
+			 */
+			if (start_addr != TASK_UNMAPPED_BASE) {
+				start_addr = addr = TASK_UNMAPPED_BASE;
+				goto full_search;
+			}
 			return -ENOMEM;
-		if (!vma || addr + len <= vma->vm_start)
+		}
+		if (!vma || addr + len <= vma->vm_start) {
+			/*
+			 * Remember the place where we stopped the search:
+			 */
+			mm->free_area_cache = addr + len;
 			return addr;
+		}
 		addr = vma->vm_end;
 		if (!(flags & MAP_PRIVATE))
 			addr = COLOUR_ALIGN(addr);

diff -u3pr linux-2.6.3-orig/include/asm-sh/cpu-sh3/cacheflush.h linux-2.6.3-local/include/asm-sh/cpu-sh3/cacheflush.h
--- linux-2.6.3-orig/include/asm-sh/cpu-sh3/cacheflush.h	Sat Feb 21 13:57:01 2004
+++ linux-2.6.3-local/include/asm-sh/cpu-sh3/cacheflush.h	Sun Feb 28 19:43:35 2004
@@ -37,5 +37,7 @@
 
 #define p3_cache_init()				do { } while (0)
 
+#define HAVE_ARCH_UNMAPPED_AREA
+
 #endif /* __ASM_CPU_SH3_CACHEFLUSH_H */