- Make pfn_valid more precise for SGI Altix systems
PATCH 1/1 - Make pfn_valid more precise for SGI Altix systems
A single SGI Altix system can be divided into multiple partitions, each running their own instance of the Linux kernel. pfn_valid() is currently not optimal for any but the first partition, since it does not compare the pfn with min_low_pfn before calling the more costly ia64_pfn_valid().
Index: linux-ia64-test/arch/ia64/kernel/ia64_ksyms.c
=================================--- linux-ia64-test.orig/arch/ia64/kernel/ia64_ksyms.c 2005-11-09 14:10:17.473464250 -0600
+++ linux-ia64-test/arch/ia64/kernel/ia64_ksyms.c 2005-11-09 14:10:50.800226042 -0600
@@ -42,6 +42,7 @@
#ifdef CONFIG_VIRTUAL_MEM_MAP
#include <linux/bootmem.h>
+EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */
EXPORT_SYMBOL(max_low_pfn); /* defined by bootmem.c, but not exported by generic code */
#endif
Index: linux-ia64-test/include/asm-ia64/page.h
=================================--- linux-ia64-test.orig/include/asm-ia64/page.h 2005-11-09 14:10:17.484205369 -0600
+++ linux-ia64-test/include/asm-ia64/page.h 2005-11-09 14:10:50.803155438 -0600
@@ -112,8 +112,9 @@
# define pfn_to_page(pfn) (mem_map + (pfn)) #elif defined(CONFIG_DISCONTIGMEM) extern struct page *vmem_map; +extern unsigned long min_low_pfn; extern unsigned long max_low_pfn; -# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) +# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map)) # define pfn_to_page(pfn) (vmem_map + (pfn)) #endif
It looks like the existing pfn_valid() returns bogus values on platforms where memory doesn't start at 0x0 (which is essentially all ia64 platforms as even those with memory at 0x0 usually can't use it because of cacheing issues with providing a WB mapping for the VGA mem at 0xc0000).
-# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
+# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
There's another pfn_valid() definition a few lines earlier in this file for the CONFIG_FLATMEM case. Does it need this treatment too? I'd guess not as Altix is far from flat.
Yet another pfn_valid() in linux/mmzone.h (for CONFIG_SPARSEMEM). That one does table lookups ... presumably also safe.
-Tony
Ignore earlier message ... I thought I saw a || when you really just have && all the way through this:
+# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
Doesn't that mean that you are optimizing for the case where some one passed in a bad pfn ... does that really happen a lot?
-Tony
Quoted 9 lines · Tony
Ignore earlier message ... I thought I saw a || when you really just have && all the way through this:
+# define
pfn_valid(pfn)(((pfn) >=min_low_pfn) && ((pfn) <max_low_pfn) &&ia64_pfn_valid(pfn))Doesn't that mean that you are optimizing for the case where some one passed in a bad pfn ... does that really happen a lot?
-Tony
Well, as much as the check against max_low_pfn was optimizing for the other end. This does occur on Altix systems when processes access memory on other partitions (you probably saw Jack and Robin's comments about this in the 4-level page table thread today). I'm not sure if there are many cases other than that, although I did notice that some of the other architecture definitions do a similar check.
Dean
Signature · 3 lines
Dean Roe Silicon Graphics, Inc. [email protected]