]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.1.127pre1 2.1.127pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:03 +0000 (15:17 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:03 +0000 (15:17 -0500)
I have an alternate patch for low memory circumstances that I'd like you
to test out.
The problem with the old kswapd setup was at least partly that kswapd was
woken up too late - by the time kswapd was woken up, it really had to work
fairly hard. Also, kswapd really shouldn't be real-time at all: normally
it should just be a fairly low-priority process, and the priority should
grow as there is more urgent need for memory.
This alternate approach seems to work for me, and is designed to avoid the
"spikes" of heavy real-time kswapd activity during which the machine is
fairly unusable in the old scheme.

                Linus

16 files changed:
Documentation/cdrom/ide-cd
MAINTAINERS
Makefile
drivers/block/ide-cd.c
drivers/block/ide-cd.h
drivers/cdrom/cdrom.c
drivers/net/de4x5.c
drivers/net/eepro100.c
include/linux/cdrom.h
include/linux/mm.h
include/linux/soundcard.h
kernel/acct.c
kernel/sched.c
mm/page_alloc.c
mm/slab.c
mm/vmscan.c

index ee12e856dbee6d04bf76e73b729f9296b2f053d5..5633ac80cb7ead508ed5005099719a1284a79b49 100644 (file)
@@ -1,6 +1,8 @@
 IDE-CD driver documentation
 Originally by scott snyder  <snyder@fnald0.fnal.gov> (19 May 1996)
 Carrying on the torch is: Erik Andersen <andersee@debian.org>
+New maintainers (19 Oct 1998): Jens Axboe <axboe@image.dk>
+                               Chris Zwilling <chris@cloudnet.com>
 
 1. Introduction
 ---------------
index 88ad68111d861013b307f91c4fb5ab6cb90758f0..15c52423e1d39aa78c9ed65af35daea3d306e824 100644 (file)
@@ -328,8 +328,10 @@ L: linux-kernel@vger.rutgers.edu
 S:     Odd Fixes
 
 IDE/ATAPI CDROM DRIVER 
-P:     Erik Andersen
-M:     andersee@debian.org
+P:     Jens Axboe
+M:     axboe@image.dk
+P:     Chris Zwilling
+M:     chris@cloudnet.com
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
@@ -671,8 +673,10 @@ L: linux-kernel@vger.rutgers.edu
 S:     Maintained
 
 UNIFORM CDROM DRIVER 
-P:     Erik Andersen
-M:     andersee@debian.org
+P:     Jens Axboe
+M:     axboe@image.dk
+P:     Chris Zwilling
+M:     chris@cloudnet.com
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
index e30e1589a4b641431898f4de99bf222195cce5af..a357515468ecdb8774c9ed0198ecdb68d9ecefd0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 126
+SUBLEVEL = 127
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index 58b574bd485083fd4a2f517553539bdea5c9e741..b13433edefba4e09426bfd91ffe0fdeed96dc290 100644 (file)
@@ -3,6 +3,7 @@
  * linux/drivers/block/ide-cd.c
  * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1998 Jens Axboe and Chris Zwilling
  *
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
  * 4.15  Aug 25, 1998  -- Updated ide-cd.h to respect mechine endianess, 
  *                         patch thanks to "Eddie C. Dost" <ecd@skynet.be>
  *
+ * 4.50  Oct 19, 1998  -- New maintainers!
+ *                         Jens Axboe <axboe@image.dk>
+ *                         Chris Zwilling <chris@cloudnet.com>
+ *
  *************************************************************************/
 
-#define IDECD_VERSION "4.15"
+#define IDECD_VERSION "4.50"
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -2632,7 +2637,7 @@ int ide_cdrom_select_disc (struct cdrom_device_info *cdi, int slot)
                if (was_locked)
                        (void) cdrom_lockdoor (drive, 1, NULL);
 
-               return stat;
+               return slot;
        }
 }
 
index 149595117aec0fb056bae4396ff84d210bea044e..e72777fddd92673edfadef63b1698f8d1728695e 100644 (file)
@@ -4,6 +4,7 @@
  *  linux/drivers/block/ide_modes.h
  *
  *  Copyright (C) 1996  Erik Andersen
+ *  Copyright (C) 1998  Jens Axboe and Chris Zwilling
  */
 
 #include <asm/byteorder.h>
index 4a82489dae11e78d3f10bd7348333ea985962ab2..eaf67e4aacba5a8c67e440d1f0a5a80a7eb8a908 100644 (file)
@@ -1,6 +1,7 @@
 /* linux/drivers/cdrom/cdrom.c. 
    Copyright (c) 1996, 1997 David A. van Leeuwen.
    Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
+   Copyright (c) 1998 Jens Axboe and Chris Zwilling
 
    May be copied or modified under the terms of the GNU General Public
    License.  See linux/COPYING for more information.
   Thanks to Grant R. Guenther <grant@torque.net> for spotting this bug.
   -- Made a few things more pedanticly correct.
 
+ 2.50  Oct 19, 1998 - Jens Axboe <axboe@image.dk>
+  -- New maintainers! Erik was too busy to continue the work on the driver,
+  so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
+  will do their best to follow in his footsteps
+
 -------------------------------------------------------------------------*/
 
-#define REVISION "Revision: 2.14"
-#define VERSION "Id: cdrom.c 2.14 1998/08/17 erik"
+#define REVISION "Revision: 2.50"
+#define VERSION "Id: cdrom.c 2.50 1998/10/19"
 
 /* I use an error-log mask to give fine grain control over the type of
    messages dumped to the system logs.  The available masks include: */
index 0049e6ebe32ddb2e7dbe0d55a0ef24f212ed4b86..bbc86f2a2c14aae208ca47d418c088c5ffcbcf86 100644 (file)
@@ -972,7 +972,7 @@ static int     get_hw_addr(struct device *dev);
 static void    srom_repair(struct device *dev, int card);
 static int     test_bad_enet(struct device *dev, int status);
 static int     an_exception(struct bus_type *lp);
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 static void    eisa_probe(struct device *dev, u_long iobase);
 #endif
 static void    pci_probe(struct device *dev, u_long iobase);
@@ -1021,7 +1021,7 @@ static int loading_module = 0;
 #endif /* MODULE */
 
 static char name[DE4X5_NAME_LENGTH + 1];
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
 static int lastEISA = 0;
 #else
@@ -1095,7 +1095,7 @@ de4x5_probe(struct device *dev))
 {
     u_long iobase = dev->base_addr;
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
     eisa_probe(dev, iobase);
 #endif
     if (lastEISA == MAX_EISA_SLOTS) {
@@ -2028,7 +2028,7 @@ SetMulticastFilter(struct device *dev)
     return;
 }
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 /*
 ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
 ** the motherboard. Upto 15 EISA devices are supported.
@@ -2096,7 +2096,7 @@ eisa_probe(struct device *dev, u_long ioaddr))
 
     return;
 }
-#endif                         /* !(__sparc_v9__) && !(__powerpc__) */
+#endif          /* !(__sparc_v9__) && !(__powerpc__) && !defined(__alpha__) */
 
 /*
 ** PCI bus I/O device probe
@@ -5826,7 +5826,7 @@ count_adapters(void)
     u_int class = DE4X5_CLASS_CODE;
     u_int device;
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
     char name[DE4X5_STRLEN];
     u_long iobase = 0x1000;
 
index 847c58b8c470a1beb193cb1c4e24d59ff07dffe1..14354fd1a10e18f2ccb3979aa7041bf162484473 100644 (file)
@@ -1384,7 +1384,7 @@ static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd)
                data[3] = mdio_read(ioaddr, data[0], data[1]);
                return 0;
        case SIOCDEVPRIVATE+2:          /* Write the specified MII register */
-               if (!suser())
+               if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                mdio_write(ioaddr, data[0], data[1], data[2]);
                return 0;
index 2f04c9dc2c55f6af9354ea3b931037fb2afa22d6..9b8a9c3c605201d6ea71027e5c5c42882a5ab02c 100644 (file)
@@ -5,6 +5,8 @@
  *               1994, 1995   Eberhard Moenkeberg, emoenke@gwdg.de
  *               1996         David van Leeuwen, david@tm.tno.nl
  *               1997, 1998   Erik Andersen, andersee@debian.org
+ *               1998         Jens Axboe, axboe@image.dk and
+ *                            Chris Zwilling, chris@cloudnet.com
  */
  
 #ifndef        _LINUX_CDROM_H
index 29692b65cf0a7213ae247acad03ee3d13403cc6c..18abb15fc0fa17ce76d7907c928c3c5a81470148 100644 (file)
@@ -254,12 +254,6 @@ extern inline unsigned long get_free_page(int gfp_mask)
 
 /* memory.c & swap.c*/
 
-/*
- * Decide if we should try to do some swapout..
- */
-extern int free_memory_available(void);
-extern struct wait_queue * kswapd_wait;
-
 #define free_page(addr) free_pages((addr),0)
 extern void FASTCALL(free_pages(unsigned long addr, unsigned long order));
 extern void FASTCALL(__free_page(struct page *));
@@ -330,6 +324,23 @@ extern void put_cached_page(unsigned long);
 
 #define GFP_DMA                __GFP_DMA
 
+/*
+ * Decide if we should try to do some swapout..
+ */
+extern int free_memory_available(void);
+extern struct task_struct * kswapd_task;
+
+extern inline void kswapd_notify(unsigned int gfp_mask)
+{
+       if (kswapd_task) {
+               wake_up_process(kswapd_task);
+               if (gfp_mask & __GFP_WAIT) {
+                       current->policy |= SCHED_YIELD;
+                       schedule();
+               }
+       }
+}
+
 /* vma is the first one with  address < vma->vm_end,
  * and even  address < vma->vm_start. Have to extend vma. */
 static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
@@ -380,11 +391,6 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
        return vma;
 }
 
-extern __inline__ void kswapd_wakeup(void)
-{
-       wake_up(&kswapd_wait);
-}
-
 #define buffer_under_min()     ((buffermem >> PAGE_SHIFT) * 100 < \
                                buffer_mem.min_percent * num_physpages)
 #define buffer_under_borrow()  ((buffermem >> PAGE_SHIFT) * 100 < \
index deb73e6fd6cadaedc480a2c4b8a8b150cccf61aa..52ff06b5f7ad1f20d876daaf12b552fd04b32f55 100644 (file)
@@ -771,6 +771,8 @@ typedef struct copr_msg {
 #define SOUND_MIXER_CAPS       0xfc
 #      define SOUND_CAP_EXCL_INPUT     0x00000001      /* Only one recording source at a time */
 #define SOUND_MIXER_STEREODEVS 0xfb    /* Mixer channels supporting stereo */
+#define SOUND_MIXER_OUTSRC     0xfa    /* Arg contains a bit for each input source to output */
+#define SOUND_MIXER_OUTMASK    0xf9    /* Arg contains a bit for each supported input source to output */
 
 /*     Device mask bits        */
 
index 83870b578b2f705aa67da903823fb6b44769072d..17669321832226dadb748d0b236fc9677888c027 100644 (file)
@@ -87,7 +87,7 @@ static void check_free_space(void)
        if (!acct_file || !acct_needcheck)
                return;
 
-       sb = acct_file->f_dentry->f_inode->i_sb;
+       sb = acct_file->f_dentry->d_inode->i_sb;
        if (!sb->s_op || !sb->s_op->statfs)
                return;
 
index a9a7a6b64ef7a92b96f0c65b6f45cf7db8c5de3d..fc97b245d00de9e7f4aa461a2bdc13af0c9b9d54 100644 (file)
@@ -1488,7 +1488,8 @@ asmlinkage int sys_sched_yield(void)
 {
        spin_lock(&scheduler_lock);
        spin_lock_irq(&runqueue_lock);
-       current->policy |= SCHED_YIELD;
+       if (current->policy == SCHED_OTHER)
+               current->policy |= SCHED_YIELD;
        current->need_resched = 1;
        move_last_runqueue(current);
        spin_unlock_irq(&runqueue_lock);
index 1461578669f3e701f3b12ede285c195f7bb41efb..4340911f840cafff8b98f401b3ea2c850cbe3e38 100644 (file)
@@ -269,13 +269,11 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
 
        /*
         * If we failed to find anything, we'll return NULL, but we'll
-        * wake up kswapd _now_ ad even wait for it synchronously if
+        * wake up kswapd _now_ and even wait for it synchronously if
         * we can.. This way we'll at least make some forward progress
         * over time.
         */
-       wake_up(&kswapd_wait);
-       if (gfp_mask & __GFP_WAIT)
-               schedule();
+       kswapd_notify(gfp_mask);
 nopage:
        return 0;
 }
index 5dcd8f33449b19a690e7996c5b81e6f70ad3ba08..76ecab846a766bb594fb8707b5088662659a8c95 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1190,7 +1190,6 @@ kmem_cache_grow(kmem_cache_t * cachep, int flags)
        cachep->c_dflags = SLAB_CFLGS_GROWN;
 
        cachep->c_growing++;
-re_try:
        spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
 
        /* A series of memory allocations for a new slab.
@@ -1257,15 +1256,6 @@ opps1:
        kmem_freepages(cachep, objp); 
 failed:
        spin_lock_irq(&cachep->c_spinlock);
-       if (local_flags != SLAB_ATOMIC && cachep->c_gfporder) {
-               /* For large order (>0) slabs, we try again.
-                * Needed because the gfp() functions are not good at giving
-                * out contiguous pages unless pushed (but do not push too hard).
-                */
-               if (cachep->c_failures++ < 4 && cachep->c_freep == kmem_slab_end(cachep))
-                       goto re_try;
-               cachep->c_failures = 1; /* Memory is low, don't try as hard next time. */
-       }
        cachep->c_growing--;
        spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
        return 0;
index ca0b7303bf83ca74c4b95cb2ceefa625f6f421bc..64263c79e3ee26dfcd3849babb274dcfebf1e256 100644 (file)
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
 
-/* 
- * When are we next due for a page scan? 
- */
-static unsigned long next_swap_jiffies = 0;
-
 /* 
  * How often do we do a pageout scan during normal conditions?
  * Default is four times a second.
@@ -42,7 +37,7 @@ int swapout_interval = HZ / 4;
 /* 
  * The wait queue for waking up the pageout daemon:
  */
-struct wait_queue * kswapd_wait = NULL;
+struct task_struct * kswapd_task = NULL;
 
 static void init_swap_timer(void);
 
@@ -509,8 +504,6 @@ void __init kswapd_setup(void)
  */
 int kswapd(void *unused)
 {
-       struct wait_queue wait = { current, NULL };
-
        current->session = 1;
        current->pgrp = 1;
        strcpy(current->comm, "kswapd");
@@ -523,11 +516,12 @@ int kswapd(void *unused)
         */
        lock_kernel();
 
-       /* Give kswapd a realtime priority. */
-       current->policy = SCHED_FIFO;
-       current->rt_priority = 32;  /* Fixme --- we need to standardise our
-                                   namings for POSIX.4 realtime scheduling
-                                   priorities.  */
+       /*
+        * Set the base priority to something smaller than a
+        * regular process. We will scale up the priority
+        * dynamically depending on how much memory we need.
+        */
+       current->priority = (DEF_PRIORITY * 2) / 3;
 
        /*
         * Tell the memory management that we're a "memory allocator",
@@ -544,7 +538,7 @@ int kswapd(void *unused)
        current->flags |= PF_MEMALLOC;
 
        init_swap_timer();
-       add_wait_queue(&kswapd_wait, &wait);
+       kswapd_task = current;
        while (1) {
                int tries;
 
@@ -586,7 +580,7 @@ int kswapd(void *unused)
                } while (--tries > 0);
        }
        /* As if we could ever get here - maybe we want to make this killable */
-       remove_wait_queue(&kswapd_wait, &wait);
+       kswapd_task = NULL;
        unlock_kernel();
        return 0;
 }
@@ -620,41 +614,58 @@ int try_to_free_pages(unsigned int gfp_mask, int count)
        return retval;
 }
 
+/*
+ * Wake up kswapd according to the priority
+ *     0 - no wakeup
+ *     1 - wake up as a low-priority process
+ *     2 - wake up as a normal process
+ *     3 - wake up as an almost real-time process
+ *
+ * This plays mind-games with the "goodness()"
+ * function in kernel/sched.c.
+ */
+static inline void kswapd_wakeup(int priority)
+{
+       if (priority) {
+               struct task_struct *p = kswapd_task;
+               if (p) {
+                       p->counter = p->priority << priority;
+                       wake_up_process(p);
+               }
+       }
+}
+
 /* 
  * The swap_tick function gets called on every clock tick.
  */
 void swap_tick(void)
 {
-       unsigned long now, want;
-       int want_wakeup = 0;
-
-       want = next_swap_jiffies;
-       now = jiffies;
+       unsigned int pages;
+       int want_wakeup;
 
        /*
-        * Examine the memory queues. Mark memory low
-        * if there is nothing available in the three
-        * highest queues.
-        *
         * Schedule for wakeup if there isn't lots
-        * of free memory.
+        * of free memory or if there is too much
+        * of it used for buffers or pgcache.
+        *
+        * "want_wakeup" is our priority: 0 means
+        * not to wake anything up, while 3 means
+        * that we'd better give kswapd a realtime
+        * priority.
         */
-       switch (free_memory_available()) {
-       case 0:
-               want = now;
-               /* Fall through */
-       case 1:
+       want_wakeup = 0;
+       if (buffer_over_max() || pgcache_over_max())
                want_wakeup = 1;
-       default:
-       }
-       if ((long) (now - want) >= 0) {
-               if (want_wakeup || buffer_over_max() || pgcache_over_max()) {
-                       /* Set the next wake-up time */
-                       next_swap_jiffies = now + swapout_interval;
-                       kswapd_wakeup();
-               }
-       }
+       pages = nr_free_pages;
+       if (pages < freepages.high)
+               want_wakeup = 1;
+       if (pages < freepages.low)
+               want_wakeup = 2;
+       if (pages < freepages.min)
+               want_wakeup = 3;
+
+       kswapd_wakeup(want_wakeup);
+
        timer_active |= (1<<SWAP_TIMER);
 }