diff -purN -X /home/mbligh/.diff.exclude 420-sysfs_vs_dcache/include/linux/sysctl.h 430-imcplicit_large_page/include/linux/sysctl.h
--- 420-sysfs_vs_dcache/include/linux/sysctl.h	2003-11-18 12:02:00.000000000 -0800
+++ 430-imcplicit_large_page/include/linux/sysctl.h	2003-11-21 12:42:15.000000000 -0800
@@ -128,6 +128,8 @@ enum
 	KERN_PANIC_ON_OOPS=57,  /* int: whether we will panic on an oops */
 	KERN_HPPA_PWRSW=58,	/* int: hppa soft-power enable */
 	KERN_HPPA_UNALIGNED=59,	/* int: hppa unaligned-trap enable */
+       KERN_SHMUSEHUGEPAGES=60,	/* int: use bigpages wherever possible */
+	KERN_HPAGES_PER_FILE=61,	/* int: max bigpages per file */
 };
 
 
diff -purN -X /home/mbligh/.diff.exclude 420-sysfs_vs_dcache/ipc/shm.c 430-imcplicit_large_page/ipc/shm.c
--- 420-sysfs_vs_dcache/ipc/shm.c	2003-11-18 12:03:16.000000000 -0800
+++ 430-imcplicit_large_page/ipc/shm.c	2003-11-21 12:42:15.000000000 -0800
@@ -32,6 +32,9 @@
 
 #define shm_flags	shm_perm.mode
 
+extern int shm_use_hugepages;
+extern int shm_hugepages_per_file;
+
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
@@ -194,8 +197,13 @@ static int newseg (key_t key, int shmflg
 		return error;
 	}
 
-	if (shmflg & SHM_HUGETLB)
+	if (shm_use_hugepages && !(size & ~HPAGE_MASK) &&
+		((size >> HPAGE_SHIFT) <= shm_hugepages_per_file))
+			shmflg |= SHM_HUGETLB;
+	
+	if (shmflg & SHM_HUGETLB) {
 		file = hugetlb_zero_setup(size);
+	}
 	else {
 		sprintf (name, "SYSV%08x", key);
 		file = shmem_file_setup(name, size, VM_ACCOUNT);
diff -purN -X /home/mbligh/.diff.exclude 420-sysfs_vs_dcache/kernel/sysctl.c 430-imcplicit_large_page/kernel/sysctl.c
--- 420-sysfs_vs_dcache/kernel/sysctl.c	2003-11-18 12:03:37.000000000 -0800
+++ 430-imcplicit_large_page/kernel/sysctl.c	2003-11-21 12:42:57.000000000 -0800
@@ -60,6 +60,7 @@ extern int cad_pid;
 extern int pid_max;
 extern int sysctl_lower_zone_protection;
 extern int min_free_kbytes;
+extern int shm_use_hugepages, shm_hugepages_per_file;
 extern int min_timeslice;
 extern int max_timeslice;
 extern int child_penalty;
@@ -596,6 +597,24 @@ static ctl_table kern_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+#ifdef CONFIG_HUGETLBFS
+	{
+		.ctl_name	= KERN_SHMUSEHUGEPAGES,
+		.procname	= "shm-use-bigpages",
+		.data		= &shm_use_hugepages,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= KERN_HPAGES_PER_FILE,
+		.procname	= "shm-bigpages-per-file",
+		.data		= &shm_hugepages_per_file,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
 	{ .ctl_name = 0 }
 };
 
diff -purN -X /home/mbligh/.diff.exclude 420-sysfs_vs_dcache/mm/shmem.c 430-imcplicit_large_page/mm/shmem.c
--- 420-sysfs_vs_dcache/mm/shmem.c	2003-10-27 10:41:16.000000000 -0800
+++ 430-imcplicit_large_page/mm/shmem.c	2003-11-21 12:42:15.000000000 -0800
@@ -40,6 +40,27 @@
 #include <asm/uaccess.h>
 #include <asm/div64.h>
 
+int shm_use_hugepages;
+
+/*
+ * On 64bit archs the vmalloc area is very large,
+ * so we allocate the array in vmalloc on 64bit archs.
+ *
+ * Assuming 2M pages (x86 and x86-64) those default setting
+ * will allow up to 128G of bigpages in a single file on
+ * 64bit archs and 64G on 32bit archs using the max
+ * kmalloc size of 128k. So tweaking in practice is needed
+ * only to go past 128G of bigpages per file on 64bit archs.
+ *
+ * This sysctl is in page units (each page large BIGPAGE_SIZE).
+ */
+#if BITS_PER_LONG == 64
+int shm_hugepages_per_file = 128UL << (30 - HPAGE_SHIFT);
+#else
+int shm_hugepages_per_file = 131072 / sizeof(struct page *);
+#endif
+
+
 /* This magic number is used in glibc for posix shared memory */
 #define TMPFS_MAGIC	0x01021994