lkml.org 
[lkml]   [1997]   [Jan]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    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 13:38    [W:0.022 / U:1.416 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site