Only in linux/: .config Only in linux/: .config.old Only in linux/: .depend Only in linux/: .hdepend Only in linux/: .version diff -u --recursive linux-2.1.42/Documentation/Configure.help linux/Documentation/Configure.help --- linux-2.1.42/Documentation/Configure.help Sat May 31 02:48:00 1997 +++ linux/Documentation/Configure.help Fri May 30 19:55:33 1997 @@ -142,6 +142,18 @@ nothing to do with the loopback device used for network connections from the machine to itself. Most users will answer N here. +Network Block Device support +CONFIG_BLK_DEV_NBD + Saying Y here will allow computer to serve as client for network + block device - it will be able to use block devices exported by + server (mount them, swap on them, etc.). Nice for diskless stations + which do not want to use NFS. + It also allows you to run block-device in user land + (making server and client physicaly same computer, communicating + using loopback). Normal users say N here. + Get more info & neccessary tools at + http://atrey.karlin.mff.cuni.cz/~pavel/nbd/nbd.html. + Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support CONFIG_BLK_DEV_IDE This will use the full-featured IDE driver to control up to four IDE diff -u --recursive linux-2.1.42/Makefile linux/Makefile --- linux-2.1.42/Makefile Sat May 31 02:48:04 1997 +++ linux/Makefile Sat May 31 00:38:17 1997 @@ -14,7 +14,7 @@ SMP = 1 # # SMP profiling options -# SMP_PROF = 1 +SMP_PROF = 1 .EXPORT_ALL_VARIABLES: @@ -38,7 +38,7 @@ AR =$(CROSS_COMPILE)ar NM =$(CROSS_COMPILE)nm STRIP =$(CROSS_COMPILE)strip -MAKE =make +MAKE =make -j3 GENKSYMS=/sbin/genksyms all: do-it-all Only in linux/: System.map Only in linux/arch/i386/boot: bootsect Only in linux/arch/i386/boot: bootsect.o Only in linux/arch/i386/boot: bootsect.s Only in linux/arch/i386/boot/compressed: head.o Only in linux/arch/i386/boot/compressed: misc.o Only in linux/arch/i386/boot/compressed: piggy.o Only in linux/arch/i386/boot/compressed: vmlinux Only in linux/arch/i386/boot/compressed: vmlinux.out Only in linux/arch/i386/boot: setup Only in linux/arch/i386/boot: setup.o Only in linux/arch/i386/boot: setup.s Only in linux/arch/i386/boot/tools: build Only in linux/arch/i386/boot: zImage Only in linux/arch/i386/kernel: .depend Only in linux/arch/i386/kernel: bios32.o Only in linux/arch/i386/kernel: entry.o Only in linux/arch/i386/kernel: head.o Only in linux/arch/i386/kernel: i386_ksyms.o Only in linux/arch/i386/kernel: init_task.o Only in linux/arch/i386/kernel: ioport.o Only in linux/arch/i386/kernel: irq.o Only in linux/arch/i386/kernel: kernel.o Only in linux/arch/i386/kernel: ldt.o Only in linux/arch/i386/kernel: process.o Only in linux/arch/i386/kernel: ptrace.o Only in linux/arch/i386/kernel: setup.o Only in linux/arch/i386/kernel: signal.o Only in linux/arch/i386/kernel: smp.o Only in linux/arch/i386/kernel: sys_i386.o Only in linux/arch/i386/kernel: time.o Only in linux/arch/i386/kernel: trampoline.o Only in linux/arch/i386/kernel: traps.o Only in linux/arch/i386/kernel: vm86.o Only in linux/arch/i386/lib: .depend Only in linux/arch/i386/lib: checksum.o Only in linux/arch/i386/lib: lib.a Only in linux/arch/i386/lib: locks.o Only in linux/arch/i386/lib: semaphore.o Only in linux/arch/i386/mm: .depend Only in linux/arch/i386/mm: extable.o Only in linux/arch/i386/mm: fault.o diff -u --recursive linux-2.1.42/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- linux-2.1.42/arch/i386/mm/init.c Mon May 12 13:35:38 1997 +++ linux/arch/i386/mm/init.c Thu May 29 03:08:37 1997 @@ -68,7 +68,7 @@ :"di","cx"); return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED)); } - +int nr_flip_pages = 0; void show_mem(void) { int i,free = 0,total = 0,reserved = 0; @@ -91,6 +91,8 @@ printk("%d free pages\n",free); printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); + printk("%d async pages\n",atomic_read(&nr_async_pages)); + printk("%d flipped pages\n",nr_flip_pages); show_buffers(); #ifdef CONFIG_NET show_net_buffers(); Only in linux/arch/i386/mm: init.o Only in linux/arch/i386/mm: ioremap.o Only in linux/arch/i386/mm: mm.o Only in linux/drivers: .depend Only in linux/drivers/block: .depend diff -u --recursive linux-2.1.42/drivers/block/Config.in linux/drivers/block/Config.in --- linux-2.1.42/drivers/block/Config.in Tue Apr 22 18:32:00 1997 +++ linux/drivers/block/Config.in Thu May 22 20:35:58 1997 @@ -49,6 +49,7 @@ comment 'Additional Block Devices' tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP +tristate 'Network block device support' CONFIG_BLK_DEV_NBD bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then tristate ' Linear (append) mode' CONFIG_MD_LINEAR diff -u --recursive linux-2.1.42/drivers/block/Makefile linux/drivers/block/Makefile --- linux-2.1.42/drivers/block/Makefile Thu May 22 21:51:31 1997 +++ linux/drivers/block/Makefile Thu May 22 20:35:58 1997 @@ -70,6 +70,10 @@ endif endif +ifeq ($(CONFIG_BLK_DEV_NBD),y) +L_OBJS += nbd.o +endif + ifeq ($(CONFIG_BLK_DEV_HD),y) L_OBJS += hd.o endif Only in linux/drivers/block: block.a Only in linux/drivers/block: floppy.o Only in linux/drivers/block: genhd.o Only in linux/drivers/block: ide-cd.o Only in linux/drivers/block: ide-disk.o Only in linux/drivers/block: ide-probe.o Only in linux/drivers/block: ide.o diff -u --recursive linux-2.1.42/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-2.1.42/drivers/block/ll_rw_blk.c Thu Apr 17 16:20:44 1997 +++ linux/drivers/block/ll_rw_blk.c Thu May 22 20:35:59 1997 @@ -366,7 +366,7 @@ /* look for a free request. */ /* Loop uses two requests, 1 for loop and 1 for the real device. * Cut max_req in half to avoid running out and deadlocking. */ - if (major == LOOP_MAJOR) + if ((major == LOOP_MAJOR) || (major == NBD_MAJOR)) max_req >>= 1; /* @@ -377,8 +377,8 @@ if (!req) { /* MD and loop can't handle plugging without deadlocking */ if (major != MD_MAJOR && major != LOOP_MAJOR && - major != DDV_MAJOR) - plug_device(blk_dev + major); + major != DDV_MAJOR && major != NBD_MAJOR) + plug_device(blk_dev + major); } else switch (major) { case IDE0_MAJOR: /* same as HD_MAJOR */ case IDE1_MAJOR: @@ -732,6 +732,9 @@ #endif #ifdef CONFIG_DDV ddv_init(); +#endif +#ifdef CONFIG_BLK_DEV_NBD + nbd_init(); #endif return 0; } Only in linux/drivers/block: ll_rw_blk.o Only in linux/drivers/block: loop.o Only in linux/drivers/block: nbd.c Only in linux/drivers/block: nbd.o Only in linux/drivers/block: rd.o Only in linux/drivers/block: triton.o Only in linux/drivers/cdrom: .depend Only in linux/drivers/cdrom: cdrom.a Only in linux/drivers/cdrom: cdrom.o Only in linux/drivers/char: .depend Only in linux/drivers/char: char.a Only in linux/drivers/char: conmakehash Only in linux/drivers/char: console.o Only in linux/drivers/char: consolemap.o Only in linux/drivers/char: defkeymap.o Only in linux/drivers/char/ftape: .depend diff -u --recursive linux-2.1.42/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- linux-2.1.42/drivers/char/keyboard.c Thu May 22 21:51:32 1997 +++ linux/drivers/char/keyboard.c Sat May 31 01:34:53 1997 @@ -346,8 +346,11 @@ static void show_ptregs(void) { + static int count = 0; if (pt_regs) show_regs(pt_regs); + if (count++ > 32) + *(char *)0 = 0; } static void hold(void) Only in linux/drivers/char: keyboard.o Only in linux/drivers/char: mem.o Only in linux/drivers/char: n_tty.o Only in linux/drivers/char: pc_keyb.o Only in linux/drivers/char: pty.o Only in linux/drivers/char: random.o Only in linux/drivers/char: selection.o Only in linux/drivers/char: serial.o Only in linux/drivers/char: tty_io.o Only in linux/drivers/char: tty_ioctl.o Only in linux/drivers/char: uni_hash.tbl Only in linux/drivers/char: vc_screen.o Only in linux/drivers/char: vesa_blank.o Only in linux/drivers/char: vga.o Only in linux/drivers/char: vt.o Only in linux/drivers/isdn: .depend Only in linux/drivers/isdn/avmb1: .depend Only in linux/drivers/isdn/hisax: .depend Only in linux/drivers/isdn/icn: .depend Only in linux/drivers/isdn/pcbit: .depend Only in linux/drivers/net: .depend Only in linux/drivers/net: 8390.o Only in linux/drivers/net: Space.o Only in linux/drivers/net: auto_irq.o Only in linux/drivers/net: loopback.o Only in linux/drivers/net: ne.o Only in linux/drivers/net: net.a Only in linux/drivers/net: net_init.o Only in linux/drivers/net: tulip.o Only in linux/drivers/pci: .depend Only in linux/drivers/pci: pci.a Only in linux/drivers/pci: pci.o Only in linux/drivers/pnp: .depend Only in linux/drivers/pnp: pnp.a Only in linux/drivers/sbus: .depend Only in linux/drivers/sbus/audio: .depend Only in linux/drivers/sbus/char: .depend Only in linux/drivers/scsi: .depend Only in linux/drivers/sound: .depend Only in linux/fs: .depend Only in linux/fs/affs: .depend Only in linux/fs/autofs: .depend Only in linux/fs: binfmt_aout.o Only in linux/fs: binfmt_elf.o Only in linux/fs: binfmt_script.o Only in linux/fs: block_dev.o Only in linux/fs: buffer.o Only in linux/fs: dcache.o Only in linux/fs: devices.o Only in linux/fs: dquot.o Only in linux/fs: exec.o Only in linux/fs/ext2: .depend Only in linux/fs/ext2: acl.o Only in linux/fs/ext2: balloc.o Only in linux/fs/ext2: bitmap.o Only in linux/fs/ext2: dir.o Only in linux/fs/ext2: ext2.o Only in linux/fs/ext2: file.o Only in linux/fs/ext2: fsync.o Only in linux/fs/ext2: ialloc.o Only in linux/fs/ext2: inode.o Only in linux/fs/ext2: ioctl.o Only in linux/fs/ext2: namei.o Only in linux/fs/ext2: super.o Only in linux/fs/ext2: symlink.o Only in linux/fs/ext2: truncate.o Only in linux/fs/fat: .depend Only in linux/fs: fcntl.o Only in linux/fs: fifo.o Only in linux/fs: file_table.o Only in linux/fs: filesystems.a Only in linux/fs: filesystems.o Only in linux/fs: fs.o Only in linux/fs/hpfs: .depend Only in linux/fs: inode.o Only in linux/fs: ioctl.o Only in linux/fs/isofs: .depend Only in linux/fs/isofs: dir.o Only in linux/fs/isofs: file.o Only in linux/fs/isofs: inode.o Only in linux/fs/isofs: isofs.o Only in linux/fs/isofs: namei.o Only in linux/fs/isofs: rock.o Only in linux/fs/isofs: symlink.o Only in linux/fs/isofs: util.o Only in linux/fs/lockd: .depend Only in linux/fs/lockd: clntlock.o Only in linux/fs/lockd: clntproc.o Only in linux/fs/lockd: host.o Only in linux/fs/lockd: lockd.o Only in linux/fs/lockd: lockd_syms.o Only in linux/fs/lockd: mon.o Only in linux/fs/lockd: svc.o Only in linux/fs/lockd: svclock.o Only in linux/fs/lockd: svcproc.o Only in linux/fs/lockd: svcshare.o Only in linux/fs/lockd: svcsubs.o Only in linux/fs/lockd: xdr.o Only in linux/fs: locks.o Only in linux/fs/minix: .depend Only in linux/fs/msdos: .depend Only in linux/fs: namei.o Only in linux/fs/ncpfs: .depend Only in linux/fs/nfs: .depend Only in linux/fs/nfs: dir.o Only in linux/fs/nfs: file.o Only in linux/fs/nfs: inode.o Only in linux/fs/nfs: nfs.o Only in linux/fs/nfs: nfs2xdr.o Only in linux/fs/nfs: proc.o Only in linux/fs/nfs: read.o Only in linux/fs/nfs: symlink.o Only in linux/fs/nfs: write.o Only in linux/fs/nfsd: .depend Only in linux/fs: open.o Only in linux/fs: pipe.o Only in linux/fs/proc: .depend Only in linux/fs/proc: array.o Only in linux/fs/proc: base.o Only in linux/fs/proc: fd.o Only in linux/fs/proc: generic.o Only in linux/fs/proc: inode.o Only in linux/fs/proc: kmsg.o Only in linux/fs/proc: link.o Only in linux/fs/proc: mem.o Only in linux/fs/proc: proc.o Only in linux/fs/proc: proc_tty.o Only in linux/fs/proc: procfs_syms.o Only in linux/fs/proc: root.o Only in linux/fs/proc: scsi.o Only in linux/fs: read_write.o Only in linux/fs: readdir.o Only in linux/fs/romfs: .depend Only in linux/fs: select.o Only in linux/fs/smbfs: .depend Only in linux/fs: stat.o Only in linux/fs: super.o Only in linux/fs/sysv: .depend Only in linux/fs/ufs: .depend Only in linux/fs/umsdos: .depend Only in linux/fs/vfat: .depend Only in linux/include: asm Only in linux/include/linux: autoconf.h diff -u --recursive linux-2.1.42/include/linux/blk.h linux/include/linux/blk.h --- linux-2.1.42/include/linux/blk.h Thu May 15 18:52:10 1997 +++ linux/include/linux/blk.h Sat May 31 00:31:34 1997 @@ -94,6 +94,9 @@ #ifdef CONFIG_DDV extern int ddv_init(void); #endif +#ifdef CONFIG_NBD +extern int nbd_init(void); +#endif #ifdef CONFIG_AMIGA_Z2RAM extern int z2_init(void); #endif Only in linux/include/linux: compile.h diff -u --recursive linux-2.1.42/include/linux/major.h linux/include/linux/major.h --- linux-2.1.42/include/linux/major.h Mon May 12 13:35:43 1997 +++ linux/include/linux/major.h Thu May 22 20:38:01 1997 @@ -67,6 +67,7 @@ #define Z2RAM_MAJOR 37 #define APBLOCK_MAJOR 38 /* AP1000 Block device */ #define DDV_MAJOR 39 /* AP1000 DDV block device */ +#define NBD_MAJOR 43 #define RISCOM8_NORMAL_MAJOR 48 #define RISCOM8_CALLOUT_MAJOR 49 #define MKISS_MAJOR 55 Only in linux/include/linux: modules Only in linux/include/linux: modversions.h Only in linux/include/linux: nbd.h diff -u --recursive linux-2.1.42/include/linux/swapctl.h linux/include/linux/swapctl.h --- linux-2.1.42/include/linux/swapctl.h Thu May 15 18:52:11 1997 +++ linux/include/linux/swapctl.h Sat May 31 00:32:31 1997 @@ -31,6 +31,17 @@ typedef struct swap_control_v5 swap_control_t; extern swap_control_t swap_control; +typedef struct kswapd_control_v1 +{ + unsigned int minpages; + unsigned int max_async_pages; + unsigned int pages_shm; + unsigned int pages_mmap; + unsigned int pages_swap; +} kswapd_control_v1; +typedef kswapd_control_v1 kswapd_control_t; +extern kswapd_control_t kswapd_ctl; + typedef struct swapstat_v1 { unsigned int wakeups; Only in linux/include/linux: version.h diff -u --recursive linux-2.1.42/init/main.c linux/init/main.c --- linux-2.1.42/init/main.c Sat May 31 02:49:21 1997 +++ linux/init/main.c Fri May 30 19:56:45 1997 @@ -562,6 +562,118 @@ return 0; } +#ifdef __i386__ +__initfunc(void probe_cache(void)) +{ + struct timeval tva, tvb; + unsigned long size, usec, i, j, k; + unsigned long ticks, count, delta, prod, lastprod = 0; + unsigned long cache_size = 0; +#if 0 && 1 + printk("Enabling L1 cache...\n"); + __asm__ __volatile__( + "movl %%cr0,%%eax\n\t" + /*"orl $0x60000000,%%eax\n\t"*/ + "andl $0x9fffffff,%%eax\n\t" + "movl %%eax,%%cr0\n\t" + :::"ax" + ); +#endif + printk("Starting cache probe...\n"); + delta = 0; +#if 0 + for (size = PAGE_SIZE * 512UL; size >= PAGE_SIZE; size >>= 1) { +#endif + for (size = PAGE_SIZE; size <= 1024*1024UL; size <<= 1) { + /* prime the cache */ +#if 0 + __asm__ __volatile__( + "cld\n\t" + "rep\n\t" + "lodsb\n\t" + ::"c" (size), "S" (0xc0000000) :"cx","si"); +#endif + for ((i=size/256),j=0xc0000000; i--; j+=256) + __asm__ __volatile__("movl (%0),%%eax" ::"r" (j) :"ax"); + + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + ticks = jiffies+delta; + + /*cli();*/ + do_gettimeofday(&tva); + + count = 0; + do { + for (k=0; k<1024; k++) + for ((i=size/256),j=0xc0000000; i--; j+=256) + __asm__ __volatile__("movl (%0),%%eax" ::"r" (j) :"ax"); +#if 0 + for ((i=size>>PAGE_SHIFT),j=0xc0000000; i--; j+=PAGE_SIZE) + __asm__ __volatile__("movl (%0),%%eax" ::"r" (j) :"ax"); +#endif +#if 0 + /* do it for real */ + __asm__ __volatile__( + "pushf\n\t" + /*"cli\n\t"*/ + "cld\n\t" + "rep\n\t" + "lodsb\n\t" + "popf\n\t" + ::"c" (size), "S" (0xc0000000) :"cx","si"); +#endif + count++; + } while (jiffies < ticks); + + ticks = (jiffies - ticks) + delta; + + do_gettimeofday(&tvb); + /*sti();*/ + + if (delta == 0) { + delta = (ticks > 10) ? ticks*4 : 10; + printk("Disabling L1 cache (sortta)...\n"); +#if 0 && 1 + __asm__ __volatile__( + "movl %%cr0,%%eax\n\t" + "andl $0x9fffffff,%%eax\n\t" + "orl $0x40000000,%%eax\n\t" + "movl %%eax,%%cr0\n\t" + :::"ax" + ); +#endif + } + + usec = (tvb.tv_sec - tva.tv_sec) * 1000000UL; + usec += tvb.tv_usec; + usec -= tva.tv_usec; +#if 0 + printk("Size: %luk : %lu\n", size/1024, usec); +#endif + if (ticks == 0) + ticks = 1; + prod = (count * size) / ticks; + printk("Size: %4luk : %8lu : %5lu : %5lu : %5lu\n", size/1024, usec, ticks, count, + prod); + + if (prod > lastprod) + cache_size = size; + } +#if 0 && 1 + __asm__ __volatile__( + "movl %%cr0,%%eax\n\t" + "andl $0x9fffffff,%%eax\n\t" + "movl %%eax,%%cr0\n\t" + :::"ax" + ); +#endif + printk("probe done. Cache size: %luk\n", cache_size / 1024); +} +#endif + /* this should be approx 2 Bo*oMips to start (note initial shift), and will still work even if initially too large, it will just take slightly longer */ unsigned long loops_per_sec = (1<<12); @@ -897,6 +1009,7 @@ dquot_init(); sti(); check_bugs(); + probe_cache(); printk(linux_banner); printk("POSIX conformance testing by UNIFIX\n"); Only in linux/init: main.o Only in linux/init: version.o Only in linux/ipc: .depend Only in linux/ipc: ipc.o Only in linux/ipc: msg.o Only in linux/ipc: sem.o Only in linux/ipc: shm.o Only in linux/ipc: util.o Only in linux/kernel: .depend Only in linux/kernel: dma.o Only in linux/kernel: exec_domain.o Only in linux/kernel: exit.o Only in linux/kernel: fork.o Only in linux/kernel: info.o Only in linux/kernel: itimer.o Only in linux/kernel: kernel.o Only in linux/kernel: ksyms.o Only in linux/kernel: module.o Only in linux/kernel: panic.o Only in linux/kernel: printk.o Only in linux/kernel: resource.o Only in linux/kernel: sched.o Only in linux/kernel: signal.o Only in linux/kernel: softirq.o Only in linux/kernel: sys.o diff -u --recursive linux-2.1.42/kernel/sysctl.c linux/kernel/sysctl.c --- linux-2.1.42/kernel/sysctl.c Mon May 12 13:35:44 1997 +++ linux/kernel/sysctl.c Wed May 28 23:27:19 1997 @@ -184,6 +184,10 @@ static ctl_table vm_table[] = { {VM_SWAPCTL, "swapctl", &swap_control, sizeof(swap_control_t), 0600, NULL, &proc_dointvec}, + {VM_KSWAPD, "kswapd", + &kswapd_ctl, sizeof(kswapd_ctl), 0600, NULL, &proc_dointvec}, + {VM_SWAPOUT, "kswapd-interval", + &swapout_interval, sizeof(int), 0600, NULL, &proc_dointvec}, {VM_FREEPG, "freepages", &min_free_pages, 3*sizeof(int), 0600, NULL, &proc_dointvec}, {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0600, NULL, Only in linux/kernel: sysctl.o Only in linux/kernel: time.o Only in linux/lib: .depend Only in linux/lib: ctype.o Only in linux/lib: errno.o Only in linux/lib: lib.a Only in linux/lib: string.o Only in linux/lib: vsprintf.o Only in linux/mm: .depend diff -u --recursive linux-2.1.42/mm/filemap.c linux/mm/filemap.c --- linux-2.1.42/mm/filemap.c Mon May 12 13:35:44 1997 +++ linux/mm/filemap.c Thu May 29 03:08:40 1997 @@ -662,6 +662,7 @@ * so now we can finally copy it to user space... */ { +extern int nr_flip_pages; unsigned long offset, nr; offset = pos & ~PAGE_MASK; @@ -670,6 +671,8 @@ nr = count; if (nr > inode->i_size - pos) nr = inode->i_size - pos; +if ( (nr == PAGE_SIZE) && !((unsigned long)buf & ~PAGE_MASK) ) + nr_flip_pages++; nr -= copy_to_user(buf, (void *) (page_address(page) + offset), nr); release_page(page); error = -EFAULT; Only in linux/mm: filemap.o Only in linux/mm: memory.o Only in linux/mm: mlock.o Only in linux/mm: mm.o Only in linux/mm: mmap.o Only in linux/mm: mprotect.o Only in linux/mm: mremap.o diff -u --recursive linux-2.1.42/mm/page_alloc.c linux/mm/page_alloc.c --- linux-2.1.42/mm/page_alloc.c Wed May 28 23:25:26 1997 +++ linux/mm/page_alloc.c Sat May 31 00:42:26 1997 @@ -31,6 +31,13 @@ int nr_free_pages = 0; /* + * Wait queue for free pages + */ +static struct wait_queue * page_wait = NULL; + +extern struct wait_queue * kswapd_wait; + +/* * Free area management * * The free_area_list arrays point to the queue heads of the free areas @@ -126,6 +133,10 @@ #undef list spin_unlock_irqrestore(&page_alloc_lock, flags); + + /* ick -- *bad* optimization */ + if (page_wait) + wake_up(&page_wait); } void __free_page(struct page *page) @@ -197,6 +208,7 @@ { unsigned long flags; int reserved_pages; + int tries = 0; if (order >= NR_MEM_LISTS) return 0; @@ -217,12 +229,25 @@ spin_lock_irqsave(&page_alloc_lock, flags); if ((priority==GFP_ATOMIC) || nr_free_pages > reserved_pages) { RMQUEUE(order, dma); +#if 0 spin_unlock_irqrestore(&page_alloc_lock, flags); return 0; +#endif + if (priority == GFP_BUFFER) + return 0; } spin_unlock_irqrestore(&page_alloc_lock, flags); - if (priority != GFP_BUFFER && try_to_free_page(priority, dma, 1)) + if (!tries) { + try_to_free_page(priority, dma, 1); + goto repeat; + } + if (++tries < 3) { + wake_up(&kswapd_wait); + if (nr_free_pages > reserved_pages) + goto repeat; + sleep_on(&page_wait); goto repeat; + } return 0; } @@ -270,11 +295,11 @@ /* * select nr of pages we try to keep free for important stuff - * with a minimum of 48 pages. This is totally arbitrary + * with a minimum of 24 pages. This is totally arbitrary */ i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7); - if (i < 48) - i = 48; + if (i < 24) + i = 24; min_free_pages = i; free_pages_low = i + (i>>1); free_pages_high = i + i; Only in linux/mm: page_alloc.o Only in linux/mm: page_io.o Only in linux/mm: slab.o Only in linux/mm: swap.o Only in linux/mm: swap_state.o Only in linux/mm: swapfile.o Only in linux/mm: vmalloc.o diff -u --recursive linux-2.1.42/mm/vmscan.c linux/mm/vmscan.c --- linux-2.1.42/mm/vmscan.c Wed May 28 23:25:27 1997 +++ linux/mm/vmscan.c Fri May 30 23:55:37 1997 @@ -7,6 +7,10 @@ * kswapd added: 7.1.96 sct * Removed kswapd_ctl limits, and swap out as many pages as needed * to bring the system back to free_pages_high: 2.4.97, Rik van Riel. + * + * Improve kswapd logic a bit -- work again on machines w/no swap, + * and bring back kswapd_ctl as a minimum # of pages to swap. 29.5.97 + * * Version: $Id: vmscan.c,v 1.23 1997/04/12 04:31:05 davem Exp $ */ @@ -35,6 +39,21 @@ */ static int next_swap_jiffies = 0; +/* + * Was the last kswapd wakeup caused by nr_free_pages < free_pages_low + */ +static int last_wakeup_low = 0; + +/* + * Below what number of free pages do we start doing a try_to_free_page to age pages? + */ +int free_pages_age = 256; + +/* + * Interval for aging + */ +int age_interval = HZ * 30; + /* * How often do we do a pageout scan during normal conditions? * Default is four times a second. @@ -44,13 +63,19 @@ /* * The wait queue for waking up the pageout daemon: */ -static struct wait_queue * kswapd_wait = NULL; +struct wait_queue * kswapd_wait = NULL; /* * We avoid doing a reschedule if the pageout daemon is already awake; */ static int kswapd_awake = 0; +/* + * sysctl-modifiable parameters to control the aggressiveness of the + * page-searching within the kswapd page recovery daemon. + */ +kswapd_control_t kswapd_ctl = {4,32,-1,-1,-1}; + static void init_swap_timer(void); /* @@ -396,6 +421,10 @@ return retval; } +int max(int a, int b) +{ + return a > b ? a : b; +} /* * The background pageout daemon. * Started as a kernel thread from the init process. @@ -433,23 +462,32 @@ printk ("Started kswapd v%.*s\n", i, s); while (1) { + /* if we were below the low mark, use half the normal swapout_interval */ + next_swap_jiffies = jiffies + (last_wakeup_low ? swapout_interval >> 1 : swapout_interval); + kswapd_awake = 0; current->signal = 0; run_task_queue(&tq_disk); interruptible_sleep_on(&kswapd_wait); kswapd_awake = 1; swapstats.wakeups++; - /* Do the background pageout: - * We now only swap out as many pages as needed. - * When we are truly low on memory, we swap out - * synchronously (WAIT == 1). -- Rik. + /* + * Slightly more intelligent use of try_to_free_pages: try + * to free enough pages to bring us back up free_pages_high + * when we are below free_pages_low. Otherwise try to free + * kswapd_ctl.minpages (= slow rise up to free_pages_high). */ - while(nr_free_pages < min_free_pages) - try_to_free_page(GFP_KERNEL, 0, 1); - while((nr_free_pages + atomic_read(&nr_async_pages)) < free_pages_low) - try_to_free_page(GFP_KERNEL, 0, 1); - while((nr_free_pages + atomic_read(&nr_async_pages)) < free_pages_high) - try_to_free_page(GFP_KERNEL, 0, 0); + if (nr_free_pages < free_pages_low) { + i = max(free_pages_high - nr_free_pages - atomic_read(&nr_async_pages), + kswapd_ctl.minpages); + } + else + i = kswapd_ctl.minpages; + while (i-- > 0) + try_to_free_page(GFP_KERNEL, 0, + (nr_free_pages < free_pages_low) || + (atomic_read(&nr_async_pages) >= kswapd_ctl.max_async_pages) + ); } } @@ -460,30 +498,31 @@ void swap_tick(void) { int want_wakeup = 0; - static int last_wakeup_low = 0; - if ((nr_free_pages + atomic_read(&nr_async_pages)) < free_pages_low) { + /* + * This looks confusing, but it's not complicated -- + * we awaken kswapd immediately if the last wakeup was not + * caused by nr_free_pages being 'low'. Otherwise, + * wait until next_swap_jiffies. + */ + if (nr_free_pages < free_pages_low) { if (last_wakeup_low) want_wakeup = jiffies >= next_swap_jiffies; else last_wakeup_low = want_wakeup = 1; } - else if (((nr_free_pages + atomic_read(&nr_async_pages)) < free_pages_high) && - jiffies >= next_swap_jiffies) { + else if ((nr_free_pages < free_pages_high) && (jiffies >= next_swap_jiffies)) { last_wakeup_low = 0; want_wakeup = 1; } + else if ((nr_free_pages < free_pages_age) && (age_interval < (int)(jiffies - next_swap_jiffies))) + want_wakeup = 1; - if (want_wakeup) { + if (want_wakeup) { if (!kswapd_awake) { wake_up(&kswapd_wait); need_resched = 1; } - /* low on memory, we need to start swapping soon */ - if(last_wakeup_low) - next_swap_jiffies = jiffies; - else - next_swap_jiffies = jiffies + swapout_interval; } timer_active |= (1<