Skip to contentSkip to conversation

PATCH 2.4.0.1.ac10: a KISS memory pressure callback

PATCH Jeff Garzik 1 participant 2 messages Jun 7, 2000 1 message not in the archive

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Cheesy maybe, effective probably.

Signature · 3 lines
Jeff Garzik              | Liberty is always dangerous, but
Building 1024            | it is the safest thing we have.
MandrakeSoft, Inc.       |      -- Harry Emerson Fosdick

Index: mm/vmscan.c
===================================================================
RCS file: /g/cvslan/linux_2_3/mm/vmscan.c,v
retrieving revision 1.1.1.40

vmscan.c +32 -0
diff -u -r1.1.1.40 vmscan.c
@@ -428,6 +428,31 @@
 }
 
 /*
+ * The freemem notifier list holds a list of functions
+ * that are to be called when trying to free pages.
+ *
+ * Call them...  We don't use notifier_call_chain
+ * because the return code from a freemem notifier
+ * is treated as a shrink_*_memory-style return value.
+ */
+extern struct notifier_block *freemem_notifier_list;
+static int shrink_misc_memory (int priority, unsigned int gfp_mask)
+{
+	int count = 0;
+	struct notifier_block *nb = freemem_notifier_list;
+
+	while (nb) {
+		count += nb->notifier_call(nb,
+			(unsigned long) priority,
+			(void *)(unsigned long) gfp_mask);
+		nb = nb->next;
+	}
+
+	return count;
+}
+
+
+/*
  * We need to make the locks finer granularity, but right
  * now we need this so that we can do page allocations
  * without holding the kernel lock etc.
@@ -476,6 +501,13 @@
 				if (!--count)
 					goto done;
 			}
+		}
+
+		/* call everybody who registered a mem pressure notifier */
+		count -= shrink_misc_memory(priority, gfp_mask);
+		if (count <= 0) {
+			ret = 1;
+			goto done;
 		}
 
 		/*

Index: kernel/ksyms.c
===================================================================
RCS file: /g/cvslan/linux_2_3/kernel/ksyms.c,v
retrieving revision 1.1.1.62

ksyms.c +2 -0
diff -u -r1.1.1.62 ksyms.c
@@ -448,6 +448,8 @@
 EXPORT_SYMBOL(machine_power_off);
 EXPORT_SYMBOL(register_reboot_notifier);
 EXPORT_SYMBOL(unregister_reboot_notifier);
+EXPORT_SYMBOL(register_freemem_notifier);
+EXPORT_SYMBOL(unregister_freemem_notifier);
 EXPORT_SYMBOL(_ctype);
 EXPORT_SYMBOL(secure_tcp_sequence_number);
 EXPORT_SYMBOL(get_random_bytes);

Index: kernel/sys.c
===================================================================
RCS file: /g/cvslan/linux_2_3/kernel/sys.c,v
retrieving revision 1.1.1.19

sys.c +38 -2
diff -u -r1.1.1.19 sys.c
@@ -47,15 +47,51 @@
  */
 
 static struct notifier_block *reboot_notifier_list = NULL;
+struct notifier_block *freemem_notifier_list = NULL;
+static spinlock_t notifier_lock = SPIN_LOCK_UNLOCKED;
 
 int register_reboot_notifier(struct notifier_block * nb)
 {
-	return notifier_chain_register(&reboot_notifier_list, nb);
+	int i;
+
+	spin_lock(&notifier_lock);
+	i = notifier_chain_register(&reboot_notifier_list, nb);
+	spin_unlock(&notifier_lock);
+
+	return i;
 }
 
 int unregister_reboot_notifier(struct notifier_block * nb)
+{
+	int i;
+
+	spin_lock(&notifier_lock);
+	i = notifier_chain_unregister(&reboot_notifier_list, nb);
+	spin_unlock(&notifier_lock);
+
+	return i;
+}
+
+int register_freemem_notifier(struct notifier_block * nb)
 {
-	return notifier_chain_unregister(&reboot_notifier_list, nb);
+	int i;
+
+	spin_lock(&notifier_lock);
+	i = notifier_chain_register(&freemem_notifier_list, nb);
+	spin_unlock(&notifier_lock);
+
+	return i;
+}
+
+int unregister_freemem_notifier(struct notifier_block * nb)
+{
+	int i;
+
+	spin_lock(&notifier_lock);
+	i = notifier_chain_unregister(&freemem_notifier_list, nb);
+	spin_unlock(&notifier_lock);
+
+	return i;
 }
 
 asmlinkage long sys_ni_syscall(void)

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

PATCH 2.4.0.1.ac10: a KISS memory pressure callback (rev 2)

Attached is a patch against 2.4.0-test1-ac10 which adds a VM pressure callback list, and cleans up the notifier chain code in the process. Since the callback occurs in do_try_to_free_pages, it is rather low level, giving other kernel code flexibility when it comes to freeing memory. Kernel code wishing to handle memory pressure should call register_freemem_notifier. Thanks for the suggestions Andi. Goodnight all. :)

Signature · 3 lines
Jeff Garzik              | Liberty is always dangerous, but
Building 1024            | it is the safest thing we have.
MandrakeSoft, Inc.       |      -- Harry Emerson Fosdick
mm/vmscan.c renamed from linux-2.4.0-test1-ac10/mm/vmscan.c +40 -0
diff -ur vanilla/linux-2.4.0-test1-ac10/mm/vmscan.c linux_2_3/mm/vmscan.c
@@ -23,6 +23,9 @@
 
 #include <asm/pgalloc.h>
 
+/* list of funcs to call when memory pressure occurs */
+extern struct notifier_block *freemem_notifier_list;
+
 /*
  * The swap-out functions return 1 if they successfully
  * threw something out, and we got a free page. It returns
@@ -428,6 +431,29 @@
 }
 
 /*
+ * The freemem notifier list holds a list of functions
+ * that are to be called when trying to free pages.
+ *
+ * Call them...  We don't use notifier_call_chain
+ * because the return code from a freemem notifier
+ * is treated as a shrink_*_memory-style return value.
+ */
+static int shrink_misc_memory (int priority, unsigned int gfp_mask)
+{
+	int count = 0;
+	struct notifier_block *nb = freemem_notifier_list;
+
+	while (nb) {
+		count += nb->notifier_call(nb,
+			(unsigned long) priority,
+			(void *)(unsigned long) gfp_mask);
+		nb = nb->next;
+	}
+
+	return count;
+}
+
+/*
  * We need to make the locks finer granularity, but right
  * now we need this so that we can do page allocations
  * without holding the kernel lock etc.
@@ -475,6 +501,20 @@
 				ret = 1;
 				if (!--count)
 					goto done;
+			}
+		}
+
+		/*
+		 * Call everybody who registered a mem pressure notifier.
+		 *
+		 * If freemem_notifier_list will usually be non-NULL
+		 * during normal system operation, remove the non-NULL test.
+		 */
+		if (freemem_notifier_list != NULL) {
+			count -= shrink_misc_memory(priority, gfp_mask);
+			if (count <= 0) {
+				ret = 1;
+				goto done;
 			}
 		}
 
include/linux/mm.h renamed from linux-2.4.0-test1-ac10/include/linux/mm.h +4 -0
diff -ur vanilla/linux-2.4.0-test1-ac10/include/linux/mm.h linux_2_3/include/linux/mm.h
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mmzone.h>
+#include <linux/notifier.h>
 
 extern unsigned long max_mapnr;
 extern unsigned long num_physpages;
@@ -415,6 +416,9 @@
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
 extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
+
+extern int register_freemem_notifier(struct notifier_block *);
+extern int unregister_freemem_notifier(struct notifier_block *);
 
 extern int pgt_cache_water[2];
 extern int check_pgt_cache(void);
include/linux/notifier.h renamed from linux-2.4.0-test1-ac10/include/linux/notifier.h +6 -59

79 lines not on this page · raw message

kernel/Makefile renamed from linux-2.4.0-test1-ac10/kernel/Makefile +2 -2
diff -ur vanilla/linux-2.4.0-test1-ac10/kernel/Makefile linux_2_3/kernel/Makefile
@@ -8,11 +8,11 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 O_TARGET := kernel.o
-O_OBJS    = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
+O_OBJS    = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
 	    sysctl.o acct.o capability.o ptrace.o timer.o
 
-OX_OBJS  += signal.o
+OX_OBJS  += signal.o sys.o
 
 ifeq ($(CONFIG_UID16),y)
 O_OBJS += uid16.o
kernel/ksyms.c renamed from linux-2.4.0-test1-ac10/kernel/ksyms.c +0 -3
diff -ur vanilla/linux-2.4.0-test1-ac10/kernel/ksyms.c linux_2_3/kernel/ksyms.c
@@ -129,7 +129,6 @@
 
 /* filesystem internal functions */
 EXPORT_SYMBOL(def_blk_fops);
-EXPORT_SYMBOL(in_group_p);
 EXPORT_SYMBOL(update_atime);
 EXPORT_SYMBOL(get_super);
 EXPORT_SYMBOL(get_empty_super);
@@ -446,8 +445,6 @@
 EXPORT_SYMBOL(machine_restart);
 EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
-EXPORT_SYMBOL(register_reboot_notifier);
-EXPORT_SYMBOL(unregister_reboot_notifier);
 EXPORT_SYMBOL(_ctype);
 EXPORT_SYMBOL(secure_tcp_sequence_number);
 EXPORT_SYMBOL(get_random_bytes);
kernel/sys.c renamed from linux-2.4.0-test1-ac10/kernel/sys.c +153 -0

179 lines not on this page · raw message