[IA64] fix personality(PER_LINUX32) performance issue

The patch aims to fix a performance issue for the syscall
personality(PER_LINUX32).

On IA-64 box, the syscall personality (PER_LINUX32) has poor performance
because it failed to find the Linux/x86 execution domain. Then it tried
to load the kernel module however it failed always and it used the default
execution domain PER_LINUX instead. Requesting kernel modules is very
expensive. It caused the performance issue. (see the function
lookup_exec_domain in kernel/exec_domain.c).

To resolve the issue, execution domain Linux/x86 is always registered in
initialization time for IA-64 architecture.

Signed-off-by: Xiaolan Huang <xiaolan.huang@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by Huang, Xiaolan and committed by Tony Luck 839052d2 3fb2c74e

+25 -10
-10
arch/ia64/ia32/ia32_support.c
··· 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/mm.h> 18 - #include <linux/personality.h> 19 #include <linux/sched.h> 20 21 #include <asm/intrinsics.h> ··· 28 29 extern int die_if_kernel (char *str, struct pt_regs *regs, long err); 30 31 - struct exec_domain ia32_exec_domain; 32 struct page *ia32_shared_page[NR_CPUS]; 33 unsigned long *ia32_boot_gdt; 34 unsigned long *cpu_gdt_table[NR_CPUS]; ··· 238 static int __init 239 ia32_init (void) 240 { 241 - ia32_exec_domain.name = "Linux/x86"; 242 - ia32_exec_domain.handler = NULL; 243 - ia32_exec_domain.pers_low = PER_LINUX32; 244 - ia32_exec_domain.pers_high = PER_LINUX32; 245 - ia32_exec_domain.signal_map = default_exec_domain.signal_map; 246 - ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; 247 - register_exec_domain(&ia32_exec_domain); 248 - 249 #if PAGE_SHIFT > IA32_PAGE_SHIFT 250 { 251 extern struct kmem_cache *ia64_partial_page_cachep;
··· 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/mm.h> 18 #include <linux/sched.h> 19 20 #include <asm/intrinsics.h> ··· 29 30 extern int die_if_kernel (char *str, struct pt_regs *regs, long err); 31 32 struct page *ia32_shared_page[NR_CPUS]; 33 unsigned long *ia32_boot_gdt; 34 unsigned long *cpu_gdt_table[NR_CPUS]; ··· 240 static int __init 241 ia32_init (void) 242 { 243 #if PAGE_SHIFT > IA32_PAGE_SHIFT 244 { 245 extern struct kmem_cache *ia64_partial_page_cachep;
+25
arch/ia64/mm/init.c
··· 719 EXPORT_SYMBOL_GPL(remove_memory); 720 #endif /* CONFIG_MEMORY_HOTREMOVE */ 721 #endif
··· 719 EXPORT_SYMBOL_GPL(remove_memory); 720 #endif /* CONFIG_MEMORY_HOTREMOVE */ 721 #endif 722 + 723 + /* 724 + * Even when CONFIG_IA32_SUPPORT is not enabled it is 725 + * useful to have the Linux/x86 domain registered to 726 + * avoid an attempted module load when emulators call 727 + * personality(PER_LINUX32). This saves several milliseconds 728 + * on each such call. 729 + */ 730 + static struct exec_domain ia32_exec_domain; 731 + 732 + static int __init 733 + per_linux32_init(void) 734 + { 735 + ia32_exec_domain.name = "Linux/x86"; 736 + ia32_exec_domain.handler = NULL; 737 + ia32_exec_domain.pers_low = PER_LINUX32; 738 + ia32_exec_domain.pers_high = PER_LINUX32; 739 + ia32_exec_domain.signal_map = default_exec_domain.signal_map; 740 + ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; 741 + register_exec_domain(&ia32_exec_domain); 742 + 743 + return 0; 744 + } 745 + 746 + __initcall(per_linux32_init);