lkml.org 
[lkml]   [1997]   [Jan]   [8]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateTue, 7 Jan 1997 20:08:59 +0100 (MET)
FromIngo Molnar <>
SubjectSince no one else has stepped forward: 'ZeroD' patch
Here is a patch that implements 'ZeroD', a simple kernel thread that uses
up CPU idle time to keep a pool of pre-zeroed pages around. Almost
anything that doesnt burn 100% CPU time all the time should benefit from
this. 

the patch is against a clean 2.1.20. Comments, ideas, flames welcome.

--mingo

diff -u --recursive --new-file --exclude-from=exclude_from linux-2.1.20_orig/include/linux/mm.h linux/include/linux/mm.h
--- linux-2.1.20_orig/include/linux/mm.h	Thu Jan  2 14:34:30 1997
+++ linux/include/linux/mm.h	Tue Jan  7 18:26:31 1997
@@ -230,10 +230,14 @@
 #define __get_free_page(priority) __get_free_pages((priority),0,0)
 #define __get_dma_pages(priority, order) __get_free_pages((priority),(order),1)
 extern unsigned long __get_free_pages(int priority, unsigned long gfporder, int dma);
+extern unsigned long get_precleared_page (void);
 
 extern inline unsigned long get_free_page(int priority)
 {
 	unsigned long page;
+
+	if ((page=get_precleared_page()))
+		return page;
 
 	page = __get_free_page(priority);
 	if (page)
diff -u --recursive --new-file --exclude-from=exclude_from linux-2.1.20_orig/init/main.c linux/init/main.c
--- linux-2.1.20_orig/init/main.c	Thu Jan  2 14:13:27 1997
+++ linux/init/main.c	Tue Jan  7 20:05:51 1997
@@ -58,6 +58,7 @@
 extern int console_loglevel;
 
 static int init(void *);
+extern int zerod(void *);
 extern int bdflush(void *);
 extern int kswapd(void *);
 
@@ -905,6 +906,11 @@
 	 *	make syscalls (and thus be locked).
 	 */
 	kernel_thread(init, NULL, 0);
+
+	/* 
+	 * start up ZeroD:
+	 */
+	kernel_thread(zerod, NULL, 0);
 /*
  * task[0] is meant to be used as an "idle" task: it may not sleep, but
  * it might do some general things like count free pages or it could be
diff -u --recursive --new-file --exclude-from=exclude_from linux-2.1.20_orig/mm/Makefile linux/mm/Makefile
--- linux-2.1.20_orig/mm/Makefile	Fri Mar 22 11:56:56 1996
+++ linux/mm/Makefile	Tue Jan  7 18:22:48 1997
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
+O_OBJS	 := zerod.o memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    kmalloc.o vmalloc.o \
 	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
 
diff -u --recursive --new-file --exclude-from=exclude_from linux-2.1.20_orig/mm/zerod.c linux/mm/zerod.c
--- linux-2.1.20_orig/mm/zerod.c	Thu Jan  1 01:00:00 1970
+++ linux/mm/zerod.c	Tue Jan  7 19:44:31 1997
@@ -0,0 +1,99 @@
+/*
+ *  linux/mm/zerod.c
+ *
+ *  Copyright (C) 1997  Ingo Molnar
+ *
+ *  This kernel thread keeps a pool of pre-zeroed pages. It runs at
+ *  lowest possible process priority, so it will use up only idle time.
+ *  It's a simple 'idle time' --> 'cleared page' converter.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+
+#define DEBUG_ZEROD
+#ifdef DEBUG_ZEROD
+#define dprintk(args...)        printk(## args)
+#else
+#define dprintk(args...)        { ; }/* nothing */
+#endif
+
+/*
+ * This one must be power of 2.
+ */
+#define ZEROD_POOLSIZE 32
+
+static struct wait_queue *zerod_wait = NULL;
+unsigned long nr_cleared_pages;
+
+unsigned long cleared_pages [ZEROD_POOLSIZE];
+
+int first_page, last_page;
+
+int zerod(void * unused)
+{
+        unsigned long page;
+	int i;
+
+	printk("zerod started.\n");
+
+        current->session = 1;
+        current->pgrp = 1;
+        sprintf(current->comm, "zerod");
+
+	/*
+	 * Set to the lowest possible priority:
+	 */
+        current->priority = 0;
+
+	last_page = first_page = 0;
+
+	for (i=0; i<ZEROD_POOLSIZE; i++)
+		cleared_pages[i]=0;
+
+	/*
+	 * Never ending loop, clearing pages all the time:
+	 */
+	for (;;) {
+		while (!cleared_pages[last_page]) {
+
+        		page = __get_free_page(GFP_KERNEL);
+        		if (page) {
+				clear_page(page);
+				cli();
+				cleared_pages[last_page++]=page;
+				last_page &= ZEROD_POOLSIZE-1;
+				sti();
+				continue;
+			}
+			break;
+		}
+		sleep_on (&zerod_wait);
+	}
+}
+
+unsigned long get_precleared_page (void)
+{
+	unsigned long flags;
+	unsigned long page=0;
+
+	save_flags(flags);
+	cli();
+
+	if (cleared_pages[first_page]) {
+		page=cleared_pages[first_page];
+		cleared_pages[first_page++]=0;
+		first_page &= ZEROD_POOLSIZE-1;
+
+		wake_up (&zerod_wait);
+	}
+
+	restore_flags(flags);
+	return page;
+}
+
+
+
+
+

\
 
 \ /
  Last update: 2005-03-22 12:38    [from the cache]
©2003-2008