Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 9 Aug 2007 15:27:25 +0000 (08:27 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 9 Aug 2007 15:27:25 +0000 (08:27 -0700)
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Fix memory leak when cpu hotplugging.
  [SPARC64]: Do not assume sun4v chips have load-twin/store-init support.
  [SPARC64]: Fix hard-coding of cpu type output in /proc/cpuinfo on sun4v.
  [SPARC]: Centralize find_in_proplist() instead of duplicating N times.

35 files changed:
Documentation/lguest/Makefile
Documentation/sched-design-CFS.txt
Documentation/sched-nice-design.txt [new file with mode: 0644]
drivers/lguest/core.c
drivers/lguest/interrupts_and_traps.c
drivers/lguest/lguest.c
drivers/lguest/segments.c
drivers/lguest/switcher.S
drivers/mmc/card/queue.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/wbsd.c
drivers/net/atl1/atl1_main.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/ibmveth.c
drivers/net/ibmveth.h
drivers/net/phy/phy.c
drivers/net/r8169.c
drivers/net/sis190.c
drivers/net/smc91x.h
drivers/net/ucc_geth_ethtool.c
drivers/net/ucc_geth_mii.c
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/zd1211rw/zd_mac.c
fs/compat_ioctl.c
include/linux/sched.h
kernel/auditsc.c
kernel/irq/resend.c
kernel/sched.c
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_idletask.c
kernel/sched_rt.c
net/ieee80211/softmac/ieee80211softmac_wx.c

index 31e794ef5f98ad7ce428444e4bc73f540b0fe718..c0b7a4556390e7c15e3f088ab1368c5db3cb9cca 100644 (file)
@@ -13,7 +13,9 @@ LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
 
 CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
 LDLIBS:=-lz
-
+# Removing this works for some versions of ld.so (eg. Ubuntu Feisty) and
+# not others (eg. FC7).
+LDFLAGS+=-static
 all: lguest.lds lguest
 
 # The linker script on x86 is so complex the only way of creating one
index 16feebb7bdc077f334964443235996a187a4cf90..84901e7c05084e1f767d024b7f06cde1f19d6854 100644 (file)
@@ -83,7 +83,7 @@ Some implementation details:
    CFS uses nanosecond granularity accounting and does not rely on any
    jiffies or other HZ detail. Thus the CFS scheduler has no notion of
    'timeslices' and has no heuristics whatsoever. There is only one
-   central tunable:
+   central tunable (you have to switch on CONFIG_SCHED_DEBUG):
 
          /proc/sys/kernel/sched_granularity_ns
 
diff --git a/Documentation/sched-nice-design.txt b/Documentation/sched-nice-design.txt
new file mode 100644 (file)
index 0000000..e2bae5a
--- /dev/null
@@ -0,0 +1,108 @@
+This document explains the thinking about the revamped and streamlined
+nice-levels implementation in the new Linux scheduler.
+
+Nice levels were always pretty weak under Linux and people continuously
+pestered us to make nice +19 tasks use up much less CPU time.
+
+Unfortunately that was not that easy to implement under the old
+scheduler, (otherwise we'd have done it long ago) because nice level
+support was historically coupled to timeslice length, and timeslice
+units were driven by the HZ tick, so the smallest timeslice was 1/HZ.
+
+In the O(1) scheduler (in 2003) we changed negative nice levels to be
+much stronger than they were before in 2.4 (and people were happy about
+that change), and we also intentionally calibrated the linear timeslice
+rule so that nice +19 level would be _exactly_ 1 jiffy. To better
+understand it, the timeslice graph went like this (cheesy ASCII art
+alert!):
+
+
+                   A
+             \     | [timeslice length]
+              \    |
+               \   |
+                \  |
+                 \ |
+                  \|___100msecs
+                   |^ . _
+                   |      ^ . _
+                   |            ^ . _
+ -*----------------------------------*-----> [nice level]
+ -20               |                +19
+                   |
+                   |
+
+So that if someone wanted to really renice tasks, +19 would give a much
+bigger hit than the normal linear rule would do. (The solution of
+changing the ABI to extend priorities was discarded early on.)
+
+This approach worked to some degree for some time, but later on with
+HZ=1000 it caused 1 jiffy to be 1 msec, which meant 0.1% CPU usage which
+we felt to be a bit excessive. Excessive _not_ because it's too small of
+a CPU utilization, but because it causes too frequent (once per
+millisec) rescheduling. (and would thus trash the cache, etc. Remember,
+this was long ago when hardware was weaker and caches were smaller, and
+people were running number crunching apps at nice +19.)
+
+So for HZ=1000 we changed nice +19 to 5msecs, because that felt like the
+right minimal granularity - and this translates to 5% CPU utilization.
+But the fundamental HZ-sensitive property for nice+19 still remained,
+and we never got a single complaint about nice +19 being too _weak_ in
+terms of CPU utilization, we only got complaints about it (still) being
+too _strong_ :-)
+
+To sum it up: we always wanted to make nice levels more consistent, but
+within the constraints of HZ and jiffies and their nasty design level
+coupling to timeslices and granularity it was not really viable.
+
+The second (less frequent but still periodically occuring) complaint
+about Linux's nice level support was its assymetry around the origo
+(which you can see demonstrated in the picture above), or more
+accurately: the fact that nice level behavior depended on the _absolute_
+nice level as well, while the nice API itself is fundamentally
+"relative":
+
+   int nice(int inc);
+
+   asmlinkage long sys_nice(int increment)
+
+(the first one is the glibc API, the second one is the syscall API.)
+Note that the 'inc' is relative to the current nice level. Tools like
+bash's "nice" command mirror this relative API.
+
+With the old scheduler, if you for example started a niced task with +1
+and another task with +2, the CPU split between the two tasks would
+depend on the nice level of the parent shell - if it was at nice -10 the
+CPU split was different than if it was at +5 or +10.
+
+A third complaint against Linux's nice level support was that negative
+nice levels were not 'punchy enough', so lots of people had to resort to
+run audio (and other multimedia) apps under RT priorities such as
+SCHED_FIFO. But this caused other problems: SCHED_FIFO is not starvation
+proof, and a buggy SCHED_FIFO app can also lock up the system for good.
+
+The new scheduler in v2.6.23 addresses all three types of complaints:
+
+To address the first complaint (of nice levels being not "punchy"
+enough), the scheduler was decoupled from 'time slice' and HZ concepts
+(and granularity was made a separate concept from nice levels) and thus
+it was possible to implement better and more consistent nice +19
+support: with the new scheduler nice +19 tasks get a HZ-independent
+1.5%, instead of the variable 3%-5%-9% range they got in the old
+scheduler.
+
+To address the second complaint (of nice levels not being consistent),
+the new scheduler makes nice(1) have the same CPU utilization effect on
+tasks, regardless of their absolute nice levels. So on the new
+scheduler, running a nice +10 and a nice 11 task has the same CPU
+utilization "split" between them as running a nice -5 and a nice -4
+task. (one will get 55% of the CPU, the other 45%.) That is why nice
+levels were changed to be "multiplicative" (or exponential) - that way
+it does not matter which nice level you start out from, the 'relative
+result' will always be the same.
+
+The third complaint (of negative nice levels not being "punchy" enough
+and forcing audio apps to run under the more dangerous SCHED_FIFO
+scheduling policy) is addressed by the new scheduler almost
+automatically: stronger negative nice levels are an automatic
+side-effect of the recalibrated dynamic range of nice levels.
index 0a46e8837d9a01629d708db246953a4af3f4600b..4a315f08a567d40a15735fa9091118a7b96f60eb 100644 (file)
@@ -453,6 +453,11 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
         * lguest_pages". */
        copy_in_guest_info(lg, pages);
 
+       /* Set the trap number to 256 (impossible value).  If we fault while
+        * switching to the Guest (bad segment registers or bug), this will
+        * cause us to abort the Guest. */
+       lg->regs->trapnum = 256;
+
        /* Now: we push the "eflags" register on the stack, then do an "lcall".
         * This is how we change from using the kernel code segment to using
         * the dedicated lguest code segment, as well as jumping into the
index 49787e964a0dfcae6b03fa044aaf2c0a03fd2a04..49aa55577d0dec0e2543c2a8801b91ebc98b1359 100644 (file)
@@ -195,13 +195,16 @@ static int has_err(unsigned int trap)
 /* deliver_trap() returns true if it could deliver the trap. */
 int deliver_trap(struct lguest *lg, unsigned int num)
 {
-       u32 lo = lg->idt[num].a, hi = lg->idt[num].b;
+       /* Trap numbers are always 8 bit, but we set an impossible trap number
+        * for traps inside the Switcher, so check that here. */
+       if (num >= ARRAY_SIZE(lg->idt))
+               return 0;
 
        /* Early on the Guest hasn't set the IDT entries (or maybe it put a
         * bogus one in): if we fail here, the Guest will be killed. */
-       if (!idt_present(lo, hi))
+       if (!idt_present(lg->idt[num].a, lg->idt[num].b))
                return 0;
-       set_guest_interrupt(lg, lo, hi, has_err(num));
+       set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
        return 1;
 }
 
index 1bc1546c7fd03c1fbb2a07bad1ffd5e15d498e13..524beea7fb19b7fe659436dcbbdf3844619fe519 100644 (file)
@@ -323,9 +323,12 @@ static void lguest_write_gdt_entry(struct desc_struct *dt,
  * __thread variables).  So we have a hypercall specifically for this case. */
 static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
 {
+       /* There's one problem which normal hardware doesn't have: the Host
+        * can't handle us removing entries we're currently using.  So we clear
+        * the GS register here: if it's needed it'll be reloaded anyway. */
+       loadsegment(gs, 0);
        lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
 }
-/*:*/
 
 /*G:038 That's enough excitement for now, back to ploughing through each of
  * the paravirt_ops (we're about 1/3 of the way through).
@@ -687,7 +690,8 @@ static struct clocksource lguest_clock = {
        .rating         = 400,
        .read           = lguest_clock_read,
        .mask           = CLOCKSOURCE_MASK(64),
-       .mult           = 1,
+       .mult           = 1 << 22,
+       .shift          = 22,
 };
 
 /* The "scheduler clock" is just our real clock, adjusted to start at zero */
@@ -770,7 +774,6 @@ static void lguest_time_init(void)
         * way, the "rating" is initialized so high that it's always chosen
         * over any other clocksource. */
        if (lguest_data.tsc_khz) {
-               lguest_clock.shift = 22;
                lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
                                                         lguest_clock.shift);
                lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS;
index f675a41a80da57cdc11d5d4825d2c7ce84a9254f..9b81119f46e937ce9b9639fe4e74f65139288a51 100644 (file)
  * begin.
  */
 
-/* Is the descriptor the Guest wants us to put in OK?
- *
- * The flag which Intel says must be zero: must be zero.  The descriptor must
- * be present, (this is actually checked earlier but is here for thorougness),
- * and the descriptor type must be 1 (a memory segment).  */
-static int desc_ok(const struct desc_struct *gdt)
-{
-       return ((gdt->b & 0x00209000) == 0x00009000);
-}
-
-/* Is the segment present?  (Otherwise it can't be used by the Guest). */
-static int segment_present(const struct desc_struct *gdt)
-{
-       return gdt->b & 0x8000;
-}
-
 /* There are several entries we don't let the Guest set.  The TSS entry is the
  * "Task State Segment" which controls all kinds of delicate things.  The
  * LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
@@ -71,37 +55,11 @@ static int ignored_gdt(unsigned int num)
                || num == GDT_ENTRY_DOUBLEFAULT_TSS);
 }
 
-/* If the Guest asks us to remove an entry from the GDT, we have to be careful.
- * If one of the segment registers is pointing at that entry the Switcher will
- * crash when it tries to reload the segment registers for the Guest.
- *
- * It doesn't make much sense for the Guest to try to remove its own code, data
- * or stack segments while they're in use: assume that's a Guest bug.  If it's
- * one of the lesser segment registers using the removed entry, we simply set
- * that register to 0 (unusable). */
-static void check_segment_use(struct lguest *lg, unsigned int desc)
-{
-       /* GDT entries are 8 bytes long, so we divide to get the index and
-        * ignore the bottom bits. */
-       if (lg->regs->gs / 8 == desc)
-               lg->regs->gs = 0;
-       if (lg->regs->fs / 8 == desc)
-               lg->regs->fs = 0;
-       if (lg->regs->es / 8 == desc)
-               lg->regs->es = 0;
-       if (lg->regs->ds / 8 == desc
-           || lg->regs->cs / 8 == desc
-           || lg->regs->ss / 8 == desc)
-               kill_guest(lg, "Removed live GDT entry %u", desc);
-}
-/*:*/
-/*M:009 We wouldn't need to check for removal of in-use segments if we handled
- * faults in the Switcher.  However, it's probably not a worthwhile
- * optimization. :*/
-
-/*H:610 Once the GDT has been changed, we look through the changed entries and
- * see if they're OK.  If not, we'll call kill_guest() and the Guest will never
- * get to use the invalid entries. */
+/*H:610 Once the GDT has been changed, we fix the new entries up a little.  We
+ * don't care if they're invalid: the worst that can happen is a General
+ * Protection Fault in the Switcher when it restores a Guest segment register
+ * which tries to use that entry.  Then we kill the Guest for causing such a
+ * mess: the message will be "unhandled trap 256". */
 static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
 {
        unsigned int i;
@@ -112,16 +70,6 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
                if (ignored_gdt(i))
                        continue;
 
-               /* We could fault in switch_to_guest if they are using
-                * a removed segment. */
-               if (!segment_present(&lg->gdt[i])) {
-                       check_segment_use(lg, i);
-                       continue;
-               }
-
-               if (!desc_ok(&lg->gdt[i]))
-                       kill_guest(lg, "Bad GDT descriptor %i", i);
-
                /* Segment descriptors contain a privilege level: the Guest is
                 * sometimes careless and leaves this as 0, even though it's
                 * running at privilege level 1.  If so, we fix it here. */
index d418179ea6b50a56fc4d488815aff51e7b3322c7..7c9c230cc845f184973e6eebea5beb9a41568735 100644 (file)
@@ -47,6 +47,7 @@
 // Down here in the depths of assembler code.
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include "lg.h"
 
 // We mark the start of the code to copy
@@ -182,13 +183,15 @@ ENTRY(switch_to_guest)
        movl    $(LGUEST_DS), %eax;                                     \
        movl    %eax, %ds;                                              \
        /* So where are we?  Which CPU, which struct?                   \
-        * The stack is our clue: our TSS sets                          \
-        * It at the end of "struct lguest_pages"                       \
-        * And we then pushed and pushed and pushed Guest regs:         \
-        * Now stack points atop the "struct lguest_regs".              \
-        * Subtract that offset, and we find our struct. */             \
+        * The stack is our clue: our TSS starts                        \
+        * It at the end of "struct lguest_pages".                      \
+        * Or we may have stumbled while restoring                      \
+        * Our Guest segment regs while in switch_to_guest,             \
+        * The fault pushed atop that part-unwound stack.               \
+        * If we round the stack down to the page start                 \
+        * We're at the start of "struct lguest_pages". */              \
        movl    %esp, %eax;                                             \
-       subl    $LGUEST_PAGES_regs, %eax;                               \
+       andl    $(~(1 << PAGE_SHIFT - 1)), %eax;                        \
        /* Save our trap number: the switch will obscure it             \
         * (The Guest regs are not mapped here in the Host)             \
         * %ebx holds it safe for deliver_to_host */                    \
index c9a289c6c1391326c9fe19d26f4f6c5b55afd99d..b0abc7d928051274f5168fe4d1e85fcbabc31b9b 100644 (file)
@@ -117,7 +117,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        struct mmc_host *host = card->host;
        u64 limit = BLK_BOUNCE_HIGH;
        int ret;
-       unsigned int bouncesz;
 
        if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
                limit = *mmc_dev(host)->dma_mask;
@@ -134,6 +133,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 
 #ifdef CONFIG_MMC_BLOCK_BOUNCE
        if (host->max_hw_segs == 1) {
+               unsigned int bouncesz;
+
                bouncesz = MMC_QUEUE_BOUNCESZ;
 
                if (bouncesz > host->max_req_size)
@@ -156,14 +157,14 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
                                GFP_KERNEL);
                        if (!mq->sg) {
                                ret = -ENOMEM;
-                               goto free_bounce_buf;
+                               goto cleanup_queue;
                        }
 
                        mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
                                bouncesz / 512, GFP_KERNEL);
                        if (!mq->bounce_sg) {
                                ret = -ENOMEM;
-                               goto free_sg;
+                               goto cleanup_queue;
                        }
                }
        }
@@ -197,14 +198,13 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        if (mq->bounce_sg)
                kfree(mq->bounce_sg);
        mq->bounce_sg = NULL;
- free_sg:
-       kfree(mq->sg);
+ cleanup_queue:
+       if (mq->sg)
+               kfree(mq->sg);
        mq->sg = NULL;
- free_bounce_buf:
        if (mq->bounce_buf)
                kfree(mq->bounce_buf);
        mq->bounce_buf = NULL;
- cleanup_queue:
        blk_cleanup_queue(mq->queue);
        return ret;
 }
index 62564ccde03a0ae6e87b6834312b1248dcd6e584..bfebd2fa7ada9a50c9359fe463f68565e492adae 100644 (file)
@@ -83,7 +83,7 @@
 
 #define AT91_MCI_ERRORS        (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE       \
                | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE               \
-               | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)                        
+               | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
 
 #define at91_mci_read(host, reg)       __raw_readl((host)->baseaddr + (reg))
 #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
@@ -676,15 +676,15 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
 
        int_status = at91_mci_read(host, AT91_MCI_SR);
        int_mask = at91_mci_read(host, AT91_MCI_IMR);
-       
+
        pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
                int_status & int_mask);
-       
+
        int_status = int_status & int_mask;
 
        if (int_status & AT91_MCI_ERRORS) {
                completed = 1;
-               
+
                if (int_status & AT91_MCI_UNRE)
                        pr_debug("MMC: Underrun error\n");
                if (int_status & AT91_MCI_OVRE)
index e0c9808fd424deaba2449daef91a0b4d9ba0e74c..9bf2a877113bf0a55cf8bc21904158990c24ca39 100644 (file)
@@ -1266,7 +1266,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
        return 0;
 }
 
-static void __devexit wbsd_free_mmc(struct device *dev)
+static void wbsd_free_mmc(struct device *dev)
 {
        struct mmc_host *mmc;
        struct wbsd_host *host;
@@ -1358,7 +1358,7 @@ static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
        return 0;
 }
 
-static void __devexit wbsd_release_regions(struct wbsd_host *host)
+static void wbsd_release_regions(struct wbsd_host *host)
 {
        if (host->base)
                release_region(host->base, 8);
@@ -1434,7 +1434,7 @@ err:
                "Falling back on FIFO.\n", dma);
 }
 
-static void __devexit wbsd_release_dma(struct wbsd_host *host)
+static void wbsd_release_dma(struct wbsd_host *host)
 {
        if (host->dma_addr) {
                dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
@@ -1484,7 +1484,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
        return 0;
 }
 
-static void __devexit wbsd_release_irq(struct wbsd_host *host)
+static void  wbsd_release_irq(struct wbsd_host *host)
 {
        if (!host->irq)
                return;
@@ -1535,7 +1535,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host *host,
  * Release all resources for the host.
  */
 
-static void __devexit wbsd_release_resources(struct wbsd_host *host)
+static void wbsd_release_resources(struct wbsd_host *host)
 {
        wbsd_release_dma(host);
        wbsd_release_irq(host);
index 56f6389a300eb3c18a50b7b636cb9965118b49cb..3c1984ecf36ca7a0331748f5d488dbed8838149f 100644 (file)
@@ -1704,10 +1704,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                }
        }
 
-       local_irq_save(flags);
-       if (!spin_trylock(&adapter->lock)) {
+       if (!spin_trylock_irqsave(&adapter->lock, flags)) {
                /* Can't get lock - tell upper layer to requeue */
-               local_irq_restore(flags);
                dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n");
                return NETDEV_TX_LOCKED;
        }
index 8ee2c2c86b423ce74bfe9e924da508cb38675672..d67f97bfa3a442b6d93f6938e5c5fc1d2f8fa249 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0072"
+#define DRV_VERSION    "EHEA_0073"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
index 58702f54c3fbed67ce311cf3290487f73f46910a..9756211e83cef666cd244f1f7c330d2810d31b33 100644 (file)
@@ -1326,7 +1326,6 @@ static void write_swqe2_TSO(struct sk_buff *skb,
        u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
        int skb_data_size = skb->len - skb->data_len;
        int headersize;
-       u64 tmp_addr;
 
        /* Packet is TCP with TSO enabled */
        swqe->tx_control |= EHEA_SWQE_TSO;
@@ -1347,9 +1346,8 @@ static void write_swqe2_TSO(struct sk_buff *skb,
                        /* set sg1entry data */
                        sg1entry->l_key = lkey;
                        sg1entry->len = skb_data_size - headersize;
-
-                       tmp_addr = (u64)(skb->data + headersize);
-                       sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+                       sg1entry->vaddr =
+                               ehea_map_vaddr(skb->data + headersize);
                        swqe->descriptors++;
                }
        } else
@@ -1362,7 +1360,6 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
        int skb_data_size = skb->len - skb->data_len;
        u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
        struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry;
-       u64 tmp_addr;
 
        /* Packet is any nonTSO type
         *
@@ -1379,8 +1376,8 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
                        /* copy sg1entry data */
                        sg1entry->l_key = lkey;
                        sg1entry->len = skb_data_size - SWQE2_MAX_IMM;
-                       tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM);
-                       sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+                       sg1entry->vaddr =
+                               ehea_map_vaddr(skb->data + SWQE2_MAX_IMM);
                        swqe->descriptors++;
                }
        } else {
@@ -1395,7 +1392,6 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
        struct ehea_vsgentry *sg_list, *sg1entry, *sgentry;
        skb_frag_t *frag;
        int nfrags, sg1entry_contains_frag_data, i;
-       u64 tmp_addr;
 
        nfrags = skb_shinfo(skb)->nr_frags;
        sg1entry = &swqe->u.immdata_desc.sg_entry;
@@ -1417,9 +1413,9 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
                        /* copy sg1entry data */
                        sg1entry->l_key = lkey;
                        sg1entry->len = frag->size;
-                       tmp_addr =  (u64)(page_address(frag->page)
-                                         + frag->page_offset);
-                       sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+                       sg1entry->vaddr =
+                               ehea_map_vaddr(page_address(frag->page)
+                                              + frag->page_offset);
                        swqe->descriptors++;
                        sg1entry_contains_frag_data = 1;
                }
@@ -1431,10 +1427,9 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
 
                        sgentry->l_key = lkey;
                        sgentry->len = frag->size;
-
-                       tmp_addr = (u64)(page_address(frag->page)
-                                        + frag->page_offset);
-                       sgentry->vaddr = ehea_map_vaddr(tmp_addr);
+                       sgentry->vaddr =
+                               ehea_map_vaddr(page_address(frag->page)
+                                              + frag->page_offset);
                        swqe->descriptors++;
                }
        }
@@ -2165,24 +2160,18 @@ static int ehea_clean_all_portres(struct ehea_port *port)
        return ret;
 }
 
-static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
+static void ehea_remove_adapter_mr(struct ehea_adapter *adapter)
 {
-       int i;
-
-       for (i=0; i < EHEA_MAX_PORTS; i++)
-               if (adapter->port[i])
-                       return;
+       if (adapter->active_ports)
+               return;
 
        ehea_rem_mr(&adapter->mr);
 }
 
-static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
+static int ehea_add_adapter_mr(struct ehea_adapter *adapter)
 {
-       int i;
-
-       for (i=0; i < EHEA_MAX_PORTS; i++)
-               if (adapter->port[i])
-                       return 0;
+       if (adapter->active_ports)
+               return 0;
 
        return ehea_reg_kernel_mr(adapter, &adapter->mr);
 }
@@ -3099,6 +3088,7 @@ out:
 
 static void __exit ehea_module_exit(void)
 {
+       destroy_workqueue(ehea_driver_wq);
        driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
        ibmebus_unregister_driver(&ehea_driver);
        ehea_destroy_busmap();
index d96eb72295488fe486136df191a3a0f8c8b6b96d..acba90f1638e7596edc6fe7e14bc11240f029197 100644 (file)
@@ -963,7 +963,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
 {
        int rc, i;
        struct net_device *netdev;
-       struct ibmveth_adapter *adapter = NULL;
+       struct ibmveth_adapter *adapter;
 
        unsigned char *mac_addr_p;
        unsigned int *mcastFilterSize_p;
@@ -997,7 +997,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
        SET_MODULE_OWNER(netdev);
 
        adapter = netdev->priv;
-       memset(adapter, 0, sizeof(adapter));
        dev->dev.driver_data = netdev;
 
        adapter->vdev = dev;
@@ -1280,24 +1279,28 @@ const char * buf, size_t count)
                        int i;
                        /* Make sure there is a buffer pool with buffers that
                           can hold a packet of the size of the MTU */
-                       for(i = 0; i<IbmVethNumBufferPools; i++) {
+                       for (i = 0; i < IbmVethNumBufferPools; i++) {
                                if (pool == &adapter->rx_buff_pool[i])
                                        continue;
                                if (!adapter->rx_buff_pool[i].active)
                                        continue;
-                               if (mtu < adapter->rx_buff_pool[i].buff_size) {
-                                       pool->active = 0;
-                                       h_free_logical_lan_buffer(adapter->
-                                                                 vdev->
-                                                                 unit_address,
-                                                                 pool->
-                                                                 buff_size);
-                               }
+                               if (mtu <= adapter->rx_buff_pool[i].buff_size)
+                                       break;
                        }
-                       if (pool->active) {
+
+                       if (i == IbmVethNumBufferPools) {
                                ibmveth_error_printk("no active pool >= MTU\n");
                                return -EPERM;
                        }
+
+                       pool->active = 0;
+                       if (netif_running(netdev)) {
+                               adapter->pool_config = 1;
+                               ibmveth_close(netdev);
+                               adapter->pool_config = 0;
+                               if ((rc = ibmveth_open(netdev)))
+                                       return rc;
+                       }
                }
        } else if (attr == &veth_num_attr) {
                if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
index bb69ccae8aceaac5b478efb24fa94f1516b366ae..72cc15a6cab745b3a2a273b6be7e4d085bfd08cb 100644 (file)
@@ -73,9 +73,6 @@ static inline long h_send_logical_lan(unsigned long unit_address,
 #define h_change_logical_lan_mac(ua, mac) \
   plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
 
-#define h_free_logical_lan_buffer(ua, bufsize) \
-  plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
-
 #define IbmVethNumBufferPools 5
 #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
 #define IBMVETH_MAX_MTU 68
index f71dab347667cd3fc33b408aaa55c0fdf7e4e570..e323efd4ed18dda72f1903ed36cb7058b891e558 100644 (file)
@@ -261,7 +261,7 @@ void phy_sanitize_settings(struct phy_device *phydev)
 
        /* Sanitize settings based on PHY capabilities */
        if ((features & SUPPORTED_Autoneg) == 0)
-               phydev->autoneg = 0;
+               phydev->autoneg = AUTONEG_DISABLE;
 
        idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex),
                        features);
@@ -374,7 +374,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
                if (mii_data->phy_id == phydev->addr) {
                        switch(mii_data->reg_num) {
                        case MII_BMCR:
-                               if (val & (BMCR_RESET|BMCR_ANENABLE))
+                               if ((val & (BMCR_RESET|BMCR_ANENABLE)) == 0)
                                        phydev->autoneg = AUTONEG_DISABLE;
                                else
                                        phydev->autoneg = AUTONEG_ENABLE;
index c9333b9dd51aac98c7f17c8406da30c9366bc7a7..b85ab4a8f2a3377354bf357940334be642f4a6ef 100644 (file)
@@ -725,6 +725,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 
        auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 
+       if (tp->mac_version == RTL_GIGA_MAC_VER_12) {
+               /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
+               mdio_write(ioaddr, 0x1f, 0x0000);
+               mdio_write(ioaddr, 0x0e, 0x0000);
+       }
+
        tp->phy_auto_nego_reg = auto_nego;
        tp->phy_1000_ctrl_reg = giga_ctrl;
 
@@ -2760,14 +2766,16 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                        rtl8169_check_link_status(dev, tp, ioaddr);
 
 #ifdef CONFIG_R8169_NAPI
-               RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-               tp->intr_mask = ~tp->napi_event;
-
-               if (likely(netif_rx_schedule_prep(dev)))
-                       __netif_rx_schedule(dev);
-               else if (netif_msg_intr(tp)) {
-                       printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
-                              dev->name, status);
+               if (status & tp->napi_event) {
+                       RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+                       tp->intr_mask = ~tp->napi_event;
+
+                       if (likely(netif_rx_schedule_prep(dev)))
+                               __netif_rx_schedule(dev);
+                       else if (netif_msg_intr(tp)) {
+                               printk(KERN_INFO "%s: interrupt %04x in poll\n",
+                                      dev->name, status);
+                       }
                }
                break;
 #else
index ec2ad9f0efa25bcbc46509149920bdd8a6a4ec5a..d470b19c08107a9f603686f1c45ffd48d7159366 100644 (file)
@@ -1593,6 +1593,9 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
                  pci_name(pdev));
 
        isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
+       if (!isa_bridge)
+               isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0966, NULL);
+
        if (!isa_bridge) {
                net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
                          pci_name(pdev));
index f8429449dc1ebf0e28a3de7e7184f72dbca38f8f..6ff3a1627af87112ea87cca3f7ca7dd952c3a2e7 100644 (file)
@@ -299,7 +299,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 
 #define SMC_CAN_USE_8BIT       1
 #define SMC_CAN_USE_16BIT      1
-#define SMC_CAN_USE_32BIT      1
+#define SMC_CAN_USE_32BIT      0
 
 #define SMC_inb(a, r)          inb((a) + (r))
 #define SMC_inw(a, r)          inw((a) + (r))
@@ -310,8 +310,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 
 #endif  /* BOARDS */
 
-#define set_irq_type(irq, type) do {} while (0)
-
 #elif   defined(CONFIG_M32R)
 
 #define SMC_CAN_USE_8BIT       0
index a8994c7b8583f204e4db8e2ebea2073c8a2b5f7e..64bef7c123654529b5a46864f872717fdde8623f 100644 (file)
@@ -379,7 +379,6 @@ static const struct ethtool_ops uec_ethtool_ops = {
        .get_stats_count        = uec_get_stats_count,
        .get_strings            = uec_get_strings,
        .get_ethtool_stats      = uec_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 void uec_set_ethtool_ops(struct net_device *netdev)
index 5f8c2d30a328f0342b45faff7341adfb385af7ea..6c257b88ce51ed8fc7206407e351f3c9f431c0ff 100644 (file)
@@ -272,7 +272,8 @@ int __init uec_mdio_init(void)
        return of_register_platform_driver(&uec_mdio_driver);
 }
 
-void __exit uec_mdio_exit(void)
+/* called from __init ucc_geth_init, therefore can not be __exit */
+void uec_mdio_exit(void)
 {
        of_unregister_platform_driver(&uec_mdio_driver);
 }
index d779199c30d056d707ea341530ce453472f09bc2..b37f1e348700c9c775dce61695bd2bde12101b6e 100644 (file)
@@ -1638,7 +1638,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
                return;
        }
 
-       if (phy->analog == 1) {
+       if (phy->analog > 1) {
                value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
                value |= (baseband_attenuation << 2) & 0x003C;
        } else {
index cea85894b7f2d1882a2951313073d5c39c638f9a..e61c6d5ba1a93d26261369dfacffde1c8c5231da 100644 (file)
@@ -466,7 +466,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
                return -EOPNOTSUPP;
        }
 
-       priv->hwaddr = conf->mac_addr;
+       priv->hwaddr = conf->mac_addr ? conf->mac_addr : dev->wiphy->perm_addr;
 
        return 0;
 }
index f6c487aa8246ac12a2143f9c891801659dd8acaf..26869d107e52acbc4c04b322272b0806cea74ca2 100644 (file)
@@ -822,7 +822,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
                cs->control |= ZD_CS_MULTICAST;
 
        /* PS-POLL */
-       if (stype == IEEE80211_STYPE_PSPOLL)
+       if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL)
                cs->control |= ZD_CS_PS_POLL_FRAME;
 
        /* Unicast data frames over the threshold should have RTS */
index 2bc1428d621c919f4a3bf48e46ec9325d1b2d3fe..a6c9078af124b1af134c1adb6d0d229ae55e9c12 100644 (file)
@@ -3161,12 +3161,9 @@ COMPATIBLE_IOCTL(SIOCSIWSENS)
 COMPATIBLE_IOCTL(SIOCGIWSENS)
 COMPATIBLE_IOCTL(SIOCSIWRANGE)
 COMPATIBLE_IOCTL(SIOCSIWPRIV)
-COMPATIBLE_IOCTL(SIOCGIWPRIV)
 COMPATIBLE_IOCTL(SIOCSIWSTATS)
-COMPATIBLE_IOCTL(SIOCGIWSTATS)
 COMPATIBLE_IOCTL(SIOCSIWAP)
 COMPATIBLE_IOCTL(SIOCGIWAP)
-COMPATIBLE_IOCTL(SIOCSIWSCAN)
 COMPATIBLE_IOCTL(SIOCSIWRATE)
 COMPATIBLE_IOCTL(SIOCGIWRATE)
 COMPATIBLE_IOCTL(SIOCSIWRTS)
index 17249fae501450ab42843ac2c53ffd2b536b064c..682ef87da6eb953348986927598eeaf8b2264ec4 100644 (file)
@@ -139,7 +139,7 @@ struct cfs_rq;
 extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m);
 extern void proc_sched_set_task(struct task_struct *p);
 extern void
-print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now);
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq);
 #else
 static inline void
 proc_sched_show_task(struct task_struct *p, struct seq_file *m)
@@ -149,7 +149,7 @@ static inline void proc_sched_set_task(struct task_struct *p)
 {
 }
 static inline void
-print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 {
 }
 #endif
@@ -855,26 +855,24 @@ struct sched_domain;
 struct sched_class {
        struct sched_class *next;
 
-       void (*enqueue_task) (struct rq *rq, struct task_struct *p,
-                             int wakeup, u64 now);
-       void (*dequeue_task) (struct rq *rq, struct task_struct *p,
-                             int sleep, u64 now);
+       void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup);
+       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
        void (*yield_task) (struct rq *rq, struct task_struct *p);
 
        void (*check_preempt_curr) (struct rq *rq, struct task_struct *p);
 
-       struct task_struct * (*pick_next_task) (struct rq *rq, u64 now);
-       void (*put_prev_task) (struct rq *rq, struct task_struct *p, u64 now);
+       struct task_struct * (*pick_next_task) (struct rq *rq);
+       void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
-       int (*load_balance) (struct rq *this_rq, int this_cpu,
+       unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
                        struct rq *busiest,
                        unsigned long max_nr_move, unsigned long max_load_move,
                        struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, unsigned long *total_load_moved);
+                       int *all_pinned, int *this_best_prio);
 
        void (*set_curr_task) (struct rq *rq);
        void (*task_tick) (struct rq *rq, struct task_struct *p);
-       void (*task_new) (struct rq *rq, struct task_struct *p, u64 now);
+       void (*task_new) (struct rq *rq, struct task_struct *p);
 };
 
 struct load_weight {
index a777d376141696dc7bc779b5ecc0d2bb58a6961c..3401293359e82f7bff1c9b3beb3d87e3e23707ae 100644 (file)
@@ -1992,19 +1992,19 @@ int __audit_signal_info(int sig, struct task_struct *t)
        extern uid_t audit_sig_uid;
        extern u32 audit_sig_sid;
 
-       if (audit_pid && t->tgid == audit_pid &&
-           (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1)) {
-               audit_sig_pid = tsk->pid;
-               if (ctx)
-                       audit_sig_uid = ctx->loginuid;
-               else
-                       audit_sig_uid = tsk->uid;
-               selinux_get_task_sid(tsk, &audit_sig_sid);
+       if (audit_pid && t->tgid == audit_pid) {
+               if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
+                       audit_sig_pid = tsk->pid;
+                       if (ctx)
+                               audit_sig_uid = ctx->loginuid;
+                       else
+                               audit_sig_uid = tsk->uid;
+                       selinux_get_task_sid(tsk, &audit_sig_sid);
+               }
+               if (!audit_signals || audit_dummy_context())
+                       return 0;
        }
 
-       if (!audit_signals) /* audit_context checked in wrapper */
-               return 0;
-
        /* optimize the common case by putting first signal recipient directly
         * in audit_context */
        if (!ctx->target_pid) {
index c382727468876dbd84c2ba6b9e89ae5a6464de1e..5bfeaed7e4872850049d40aef740d24b983adebf 100644 (file)
@@ -62,15 +62,6 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
         */
        desc->chip->enable(irq);
 
-       /*
-        * Temporary hack to figure out more about the problem, which
-        * is causing the ancient network cards to die.
-        */
-       if (desc->handle_irq != handle_edge_irq) {
-               WARN_ON_ONCE(1);
-               return;
-       }
-
        if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
                desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY;
 
index 72bb9483d9492422eef9a0b4f88bd49e00cfe857..b0afd8db13963200eedfbb2109d56202f50295cb 100644 (file)
@@ -318,15 +318,19 @@ static inline int cpu_of(struct rq *rq)
 }
 
 /*
- * Per-runqueue clock, as finegrained as the platform can give us:
+ * Update the per-runqueue clock, as finegrained as the platform can give
+ * us, but without assuming monotonicity, etc.:
  */
-static unsigned long long __rq_clock(struct rq *rq)
+static void __update_rq_clock(struct rq *rq)
 {
        u64 prev_raw = rq->prev_clock_raw;
        u64 now = sched_clock();
        s64 delta = now - prev_raw;
        u64 clock = rq->clock;
 
+#ifdef CONFIG_SCHED_DEBUG
+       WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
+#endif
        /*
         * Protect against sched_clock() occasionally going backwards:
         */
@@ -349,18 +353,12 @@ static unsigned long long __rq_clock(struct rq *rq)
 
        rq->prev_clock_raw = now;
        rq->clock = clock;
-
-       return clock;
 }
 
-static inline unsigned long long rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
 {
-       int this_cpu = smp_processor_id();
-
-       if (this_cpu == cpu_of(rq))
-               return __rq_clock(rq);
-
-       return rq->clock;
+       if (likely(smp_processor_id() == cpu_of(rq)))
+               __update_rq_clock(rq);
 }
 
 /*
@@ -386,9 +384,12 @@ unsigned long long cpu_clock(int cpu)
 {
        unsigned long long now;
        unsigned long flags;
+       struct rq *rq;
 
        local_irq_save(flags);
-       now = rq_clock(cpu_rq(cpu));
+       rq = cpu_rq(cpu);
+       update_rq_clock(rq);
+       now = rq->clock;
        local_irq_restore(flags);
 
        return now;
@@ -637,6 +638,11 @@ static u64 div64_likely32(u64 divident, unsigned long divisor)
 
 #define WMULT_SHIFT    32
 
+/*
+ * Shift right and round:
+ */
+#define RSR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
+
 static unsigned long
 calc_delta_mine(unsigned long delta_exec, unsigned long weight,
                struct load_weight *lw)
@@ -644,18 +650,17 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight,
        u64 tmp;
 
        if (unlikely(!lw->inv_weight))
-               lw->inv_weight = WMULT_CONST / lw->weight;
+               lw->inv_weight = (WMULT_CONST - lw->weight/2) / lw->weight + 1;
 
        tmp = (u64)delta_exec * weight;
        /*
         * Check whether we'd overflow the 64-bit multiplication:
         */
-       if (unlikely(tmp > WMULT_CONST)) {
-               tmp = ((tmp >> WMULT_SHIFT/2) * lw->inv_weight)
-                               >> (WMULT_SHIFT/2);
-       } else {
-               tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT;
-       }
+       if (unlikely(tmp > WMULT_CONST))
+               tmp = RSR(RSR(tmp, WMULT_SHIFT/2) * lw->inv_weight,
+                       WMULT_SHIFT/2);
+       else
+               tmp = RSR(tmp * lw->inv_weight, WMULT_SHIFT);
 
        return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
 }
@@ -703,11 +708,14 @@ static void update_load_sub(struct load_weight *lw, unsigned long dec)
  * the relative distance between them is ~25%.)
  */
 static const int prio_to_weight[40] = {
-/* -20 */ 88818, 71054, 56843, 45475, 36380, 29104, 23283, 18626, 14901, 11921,
-/* -10 */  9537,  7629,  6103,  4883,  3906,  3125,  2500,  2000,  1600,  1280,
-/*   0 */  NICE_0_LOAD /* 1024 */,
-/*   1 */          819,   655,   524,   419,   336,   268,   215,   172,   137,
-/*  10 */   110,    87,    70,    56,    45,    36,    29,    23,    18,    15,
+ /* -20 */     88761,     71755,     56483,     46273,     36291,
+ /* -15 */     29154,     23254,     18705,     14949,     11916,
+ /* -10 */      9548,      7620,      6100,      4904,      3906,
+ /*  -5 */      3121,      2501,      1991,      1586,      1277,
+ /*   0 */      1024,       820,       655,       526,       423,
+ /*   5 */       335,       272,       215,       172,       137,
+ /*  10 */       110,        87,        70,        56,        45,
+ /*  15 */        36,        29,        23,        18,        15,
 };
 
 /*
@@ -718,14 +726,14 @@ static const int prio_to_weight[40] = {
  * into multiplications:
  */
 static const u32 prio_to_wmult[40] = {
-/* -20 */     48356,     60446,     75558,     94446,    118058,
-/* -15 */    147573,    184467,    230589,    288233,    360285,
-/* -10 */    450347,    562979,    703746,    879575,   1099582,
-/*  -5 */   1374389,   1717986,   2147483,   2684354,   3355443,
-/*   0 */   4194304,   5244160,   6557201,   8196502,  10250518,
-/*   5 */  12782640,  16025997,  19976592,  24970740,  31350126,
-/*  10 */  39045157,  49367440,  61356675,  76695844,  95443717,
-/*  15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
+ /* -20 */     48388,     59856,     76040,     92818,    118348,
+ /* -15 */    147320,    184698,    229616,    287308,    360437,
+ /* -10 */    449829,    563644,    704093,    875809,   1099582,
+ /*  -5 */   1376151,   1717300,   2157191,   2708050,   3363326,
+ /*   0 */   4194304,   5237765,   6557202,   8165337,  10153587,
+ /*   5 */  12820798,  15790321,  19976592,  24970740,  31350126,
+ /*  10 */  39045157,  49367440,  61356676,  76695844,  95443717,
+ /*  15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
 };
 
 static void activate_task(struct rq *rq, struct task_struct *p, int wakeup);
@@ -745,8 +753,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator);
+                     int *this_best_prio, struct rq_iterator *iterator);
 
 #include "sched_stats.h"
 #include "sched_rt.c"
@@ -782,14 +789,14 @@ static void __update_curr_load(struct rq *rq, struct load_stat *ls)
  * This function is called /before/ updating rq->ls.load
  * and when switching tasks.
  */
-static void update_curr_load(struct rq *rq, u64 now)
+static void update_curr_load(struct rq *rq)
 {
        struct load_stat *ls = &rq->ls;
        u64 start;
 
        start = ls->load_update_start;
-       ls->load_update_start = now;
-       ls->delta_stat += now - start;
+       ls->load_update_start = rq->clock;
+       ls->delta_stat += rq->clock - start;
        /*
         * Stagger updates to ls->delta_fair. Very frequent updates
         * can be expensive.
@@ -798,30 +805,28 @@ static void update_curr_load(struct rq *rq, u64 now)
                __update_curr_load(rq, ls);
 }
 
-static inline void
-inc_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void inc_load(struct rq *rq, const struct task_struct *p)
 {
-       update_curr_load(rq, now);
+       update_curr_load(rq);
        update_load_add(&rq->ls.load, p->se.load.weight);
 }
 
-static inline void
-dec_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void dec_load(struct rq *rq, const struct task_struct *p)
 {
-       update_curr_load(rq, now);
+       update_curr_load(rq);
        update_load_sub(&rq->ls.load, p->se.load.weight);
 }
 
-static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now)
+static void inc_nr_running(struct task_struct *p, struct rq *rq)
 {
        rq->nr_running++;
-       inc_load(rq, p, now);
+       inc_load(rq, p);
 }
 
-static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now)
+static void dec_nr_running(struct task_struct *p, struct rq *rq)
 {
        rq->nr_running--;
-       dec_load(rq, p, now);
+       dec_load(rq, p);
 }
 
 static void set_load_weight(struct task_struct *p)
@@ -848,18 +853,16 @@ static void set_load_weight(struct task_struct *p)
        p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
 }
 
-static void
-enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
 {
        sched_info_queued(p);
-       p->sched_class->enqueue_task(rq, p, wakeup, now);
+       p->sched_class->enqueue_task(rq, p, wakeup);
        p->se.on_rq = 1;
 }
 
-static void
-dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
 {
-       p->sched_class->dequeue_task(rq, p, sleep, now);
+       p->sched_class->dequeue_task(rq, p, sleep);
        p->se.on_rq = 0;
 }
 
@@ -914,13 +917,11 @@ static int effective_prio(struct task_struct *p)
  */
 static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
 {
-       u64 now = rq_clock(rq);
-
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible--;
 
-       enqueue_task(rq, p, wakeup, now);
-       inc_nr_running(p, rq, now);
+       enqueue_task(rq, p, wakeup);
+       inc_nr_running(p, rq);
 }
 
 /*
@@ -928,13 +929,13 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
  */
 static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
 {
-       u64 now = rq_clock(rq);
+       update_rq_clock(rq);
 
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible--;
 
-       enqueue_task(rq, p, 0, now);
-       inc_nr_running(p, rq, now);
+       enqueue_task(rq, p, 0);
+       inc_nr_running(p, rq);
 }
 
 /*
@@ -942,13 +943,11 @@ static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
  */
 static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
 {
-       u64 now = rq_clock(rq);
-
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible++;
 
-       dequeue_task(rq, p, sleep, now);
-       dec_nr_running(p, rq, now);
+       dequeue_task(rq, p, sleep);
+       dec_nr_running(p, rq);
 }
 
 /**
@@ -1516,6 +1515,7 @@ out_set_cpu:
 
 out_activate:
 #endif /* CONFIG_SMP */
+       update_rq_clock(rq);
        activate_task(rq, p, 1);
        /*
         * Sync wakeups (i.e. those types of wakeups where the waker
@@ -1647,12 +1647,11 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
        unsigned long flags;
        struct rq *rq;
        int this_cpu;
-       u64 now;
 
        rq = task_rq_lock(p, &flags);
        BUG_ON(p->state != TASK_RUNNING);
        this_cpu = smp_processor_id(); /* parent's CPU */
-       now = rq_clock(rq);
+       update_rq_clock(rq);
 
        p->prio = effective_prio(p);
 
@@ -1666,8 +1665,8 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
                 * Let the scheduling class do new task startup
                 * management (if any):
                 */
-               p->sched_class->task_new(rq, p, now);
-               inc_nr_running(p, rq, now);
+               p->sched_class->task_new(rq, p);
+               inc_nr_running(p, rq);
        }
        check_preempt_curr(rq, p);
        task_rq_unlock(rq, &flags);
@@ -1954,7 +1953,6 @@ static void update_cpu_load(struct rq *this_rq)
        unsigned long total_load = this_rq->ls.load.weight;
        unsigned long this_load =  total_load;
        struct load_stat *ls = &this_rq->ls;
-       u64 now = __rq_clock(this_rq);
        int i, scale;
 
        this_rq->nr_load_updates++;
@@ -1962,7 +1960,7 @@ static void update_cpu_load(struct rq *this_rq)
                goto do_avg;
 
        /* Update delta_fair/delta_exec fields first */
-       update_curr_load(this_rq, now);
+       update_curr_load(this_rq);
 
        fair_delta64 = ls->delta_fair + 1;
        ls->delta_fair = 0;
@@ -1970,8 +1968,8 @@ static void update_cpu_load(struct rq *this_rq)
        exec_delta64 = ls->delta_exec + 1;
        ls->delta_exec = 0;
 
-       sample_interval64 = now - ls->load_update_last;
-       ls->load_update_last = now;
+       sample_interval64 = this_rq->clock - ls->load_update_last;
+       ls->load_update_last = this_rq->clock;
 
        if ((s64)sample_interval64 < (s64)TICK_NSEC)
                sample_interval64 = TICK_NSEC;
@@ -2026,6 +2024,8 @@ static void double_rq_lock(struct rq *rq1, struct rq *rq2)
                        spin_lock(&rq1->lock);
                }
        }
+       update_rq_clock(rq1);
+       update_rq_clock(rq2);
 }
 
 /*
@@ -2166,8 +2166,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator)
+                     int *this_best_prio, struct rq_iterator *iterator)
 {
        int pulled = 0, pinned = 0, skip_for_load;
        struct task_struct *p;
@@ -2192,12 +2191,8 @@ next:
         */
        skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
                                                         SCHED_LOAD_SCALE_FUZZ;
-       if (skip_for_load && p->prio < this_best_prio)
-               skip_for_load = !best_prio_seen && p->prio == best_prio;
-       if (skip_for_load ||
+       if ((skip_for_load && p->prio >= *this_best_prio) ||
            !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
-
-               best_prio_seen |= p->prio == best_prio;
                p = iterator->next(iterator->arg);
                goto next;
        }
@@ -2211,8 +2206,8 @@ next:
         * and the prescribed amount of weighted load.
         */
        if (pulled < max_nr_move && rem_load_move > 0) {
-               if (p->prio < this_best_prio)
-                       this_best_prio = p->prio;
+               if (p->prio < *this_best_prio)
+                       *this_best_prio = p->prio;
                p = iterator->next(iterator->arg);
                goto next;
        }
@@ -2231,32 +2226,52 @@ out:
 }
 
 /*
- * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
- * load from busiest to this_rq, as part of a balancing operation within
- * "domain". Returns the number of tasks moved.
+ * move_tasks tries to move up to max_load_move weighted load from busiest to
+ * this_rq, as part of a balancing operation within domain "sd".
+ * Returns 1 if successful and 0 otherwise.
  *
  * Called with both runqueues locked.
  */
 static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                     unsigned long max_nr_move, unsigned long max_load_move,
+                     unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned)
 {
        struct sched_class *class = sched_class_highest;
-       unsigned long load_moved, total_nr_moved = 0, nr_moved;
-       long rem_load_move = max_load_move;
+       unsigned long total_load_moved = 0;
+       int this_best_prio = this_rq->curr->prio;
 
        do {
-               nr_moved = class->load_balance(this_rq, this_cpu, busiest,
-                               max_nr_move, (unsigned long)rem_load_move,
-                               sd, idle, all_pinned, &load_moved);
-               total_nr_moved += nr_moved;
-               max_nr_move -= nr_moved;
-               rem_load_move -= load_moved;
+               total_load_moved +=
+                       class->load_balance(this_rq, this_cpu, busiest,
+                               ULONG_MAX, max_load_move - total_load_moved,
+                               sd, idle, all_pinned, &this_best_prio);
                class = class->next;
-       } while (class && max_nr_move && rem_load_move > 0);
+       } while (class && max_load_move > total_load_moved);
 
-       return total_nr_moved;
+       return total_load_moved > 0;
+}
+
+/*
+ * move_one_task tries to move exactly one task from busiest to this_rq, as
+ * part of active balancing operations within "domain".
+ * Returns 1 if successful and 0 otherwise.
+ *
+ * Called with both runqueues locked.
+ */
+static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                        struct sched_domain *sd, enum cpu_idle_type idle)
+{
+       struct sched_class *class;
+       int this_best_prio = MAX_PRIO;
+
+       for (class = sched_class_highest; class; class = class->next)
+               if (class->load_balance(this_rq, this_cpu, busiest,
+                                       1, ULONG_MAX, sd, idle, NULL,
+                                       &this_best_prio))
+                       return 1;
+
+       return 0;
 }
 
 /*
@@ -2588,11 +2603,6 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
  */
 #define MAX_PINNED_INTERVAL    512
 
-static inline unsigned long minus_1_or_zero(unsigned long n)
-{
-       return n > 0 ? n - 1 : 0;
-}
-
 /*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
@@ -2601,7 +2611,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
                        struct sched_domain *sd, enum cpu_idle_type idle,
                        int *balance)
 {
-       int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
+       int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
        struct sched_group *group;
        unsigned long imbalance;
        struct rq *busiest;
@@ -2642,18 +2652,17 @@ redo:
 
        schedstat_add(sd, lb_imbalance[idle], imbalance);
 
-       nr_moved = 0;
+       ld_moved = 0;
        if (busiest->nr_running > 1) {
                /*
                 * Attempt to move tasks. If find_busiest_group has found
                 * an imbalance but busiest->nr_running <= 1, the group is
-                * still unbalanced. nr_moved simply stays zero, so it is
+                * still unbalanced. ld_moved simply stays zero, so it is
                 * correctly treated as an imbalance.
                 */
                local_irq_save(flags);
                double_rq_lock(this_rq, busiest);
-               nr_moved = move_tasks(this_rq, this_cpu, busiest,
-                                     minus_1_or_zero(busiest->nr_running),
+               ld_moved = move_tasks(this_rq, this_cpu, busiest,
                                      imbalance, sd, idle, &all_pinned);
                double_rq_unlock(this_rq, busiest);
                local_irq_restore(flags);
@@ -2661,7 +2670,7 @@ redo:
                /*
                 * some other cpu did the load balance for us.
                 */
-               if (nr_moved && this_cpu != smp_processor_id())
+               if (ld_moved && this_cpu != smp_processor_id())
                        resched_cpu(this_cpu);
 
                /* All tasks on this runqueue were pinned by CPU affinity */
@@ -2673,7 +2682,7 @@ redo:
                }
        }
 
-       if (!nr_moved) {
+       if (!ld_moved) {
                schedstat_inc(sd, lb_failed[idle]);
                sd->nr_balance_failed++;
 
@@ -2722,10 +2731,10 @@ redo:
                        sd->balance_interval *= 2;
        }
 
-       if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
+       if (!ld_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                return -1;
-       return nr_moved;
+       return ld_moved;
 
 out_balanced:
        schedstat_inc(sd, lb_balanced[idle]);
@@ -2757,7 +2766,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
        struct sched_group *group;
        struct rq *busiest = NULL;
        unsigned long imbalance;
-       int nr_moved = 0;
+       int ld_moved = 0;
        int sd_idle = 0;
        int all_pinned = 0;
        cpumask_t cpus = CPU_MASK_ALL;
@@ -2792,12 +2801,13 @@ redo:
 
        schedstat_add(sd, lb_imbalance[CPU_NEWLY_IDLE], imbalance);
 
-       nr_moved = 0;
+       ld_moved = 0;
        if (busiest->nr_running > 1) {
                /* Attempt to move tasks */
                double_lock_balance(this_rq, busiest);
-               nr_moved = move_tasks(this_rq, this_cpu, busiest,
-                                       minus_1_or_zero(busiest->nr_running),
+               /* this_rq->clock is already updated */
+               update_rq_clock(busiest);
+               ld_moved = move_tasks(this_rq, this_cpu, busiest,
                                        imbalance, sd, CPU_NEWLY_IDLE,
                                        &all_pinned);
                spin_unlock(&busiest->lock);
@@ -2809,7 +2819,7 @@ redo:
                }
        }
 
-       if (!nr_moved) {
+       if (!ld_moved) {
                schedstat_inc(sd, lb_failed[CPU_NEWLY_IDLE]);
                if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
                    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
@@ -2817,7 +2827,7 @@ redo:
        } else
                sd->nr_balance_failed = 0;
 
-       return nr_moved;
+       return ld_moved;
 
 out_balanced:
        schedstat_inc(sd, lb_balanced[CPU_NEWLY_IDLE]);
@@ -2894,6 +2904,8 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
 
        /* move a task from busiest_rq to target_rq */
        double_lock_balance(busiest_rq, target_rq);
+       update_rq_clock(busiest_rq);
+       update_rq_clock(target_rq);
 
        /* Search for an sd spanning us and the target CPU. */
        for_each_domain(target_cpu, sd) {
@@ -2905,8 +2917,8 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
        if (likely(sd)) {
                schedstat_inc(sd, alb_cnt);
 
-               if (move_tasks(target_rq, target_cpu, busiest_rq, 1,
-                              ULONG_MAX, sd, CPU_IDLE, NULL))
+               if (move_one_task(target_rq, target_cpu, busiest_rq,
+                                 sd, CPU_IDLE))
                        schedstat_inc(sd, alb_pushed);
                else
                        schedstat_inc(sd, alb_failed);
@@ -3175,8 +3187,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator)
+                     int *this_best_prio, struct rq_iterator *iterator)
 {
        *load_moved = 0;
 
@@ -3202,7 +3213,8 @@ unsigned long long task_sched_runtime(struct task_struct *p)
        rq = task_rq_lock(p, &flags);
        ns = p->se.sum_exec_runtime;
        if (rq->curr == p) {
-               delta_exec = rq_clock(rq) - p->se.exec_start;
+               update_rq_clock(rq);
+               delta_exec = rq->clock - p->se.exec_start;
                if ((s64)delta_exec > 0)
                        ns += delta_exec;
        }
@@ -3298,9 +3310,10 @@ void scheduler_tick(void)
        struct task_struct *curr = rq->curr;
 
        spin_lock(&rq->lock);
+       __update_rq_clock(rq);
+       update_cpu_load(rq);
        if (curr != rq->idle) /* FIXME: needed? */
                curr->sched_class->task_tick(rq, curr);
-       update_cpu_load(rq);
        spin_unlock(&rq->lock);
 
 #ifdef CONFIG_SMP
@@ -3382,7 +3395,7 @@ static inline void schedule_debug(struct task_struct *prev)
  * Pick up the highest-prio task:
  */
 static inline struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
+pick_next_task(struct rq *rq, struct task_struct *prev)
 {
        struct sched_class *class;
        struct task_struct *p;
@@ -3392,14 +3405,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
         * the fair class we can call that function directly:
         */
        if (likely(rq->nr_running == rq->cfs.nr_running)) {
-               p = fair_sched_class.pick_next_task(rq, now);
+               p = fair_sched_class.pick_next_task(rq);
                if (likely(p))
                        return p;
        }
 
        class = sched_class_highest;
        for ( ; ; ) {
-               p = class->pick_next_task(rq, now);
+               p = class->pick_next_task(rq);
                if (p)
                        return p;
                /*
@@ -3418,7 +3431,6 @@ asmlinkage void __sched schedule(void)
        struct task_struct *prev, *next;
        long *switch_count;
        struct rq *rq;
-       u64 now;
        int cpu;
 
 need_resched:
@@ -3436,6 +3448,7 @@ need_resched_nonpreemptible:
 
        spin_lock_irq(&rq->lock);
        clear_tsk_need_resched(prev);
+       __update_rq_clock(rq);
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
@@ -3450,9 +3463,8 @@ need_resched_nonpreemptible:
        if (unlikely(!rq->nr_running))
                idle_balance(cpu, rq);
 
-       now = __rq_clock(rq);
-       prev->sched_class->put_prev_task(rq, prev, now);
-       next = pick_next_task(rq, prev, now);
+       prev->sched_class->put_prev_task(rq, prev);
+       next = pick_next_task(rq, prev);
 
        sched_info_switch(prev, next);
 
@@ -3895,17 +3907,16 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        unsigned long flags;
        int oldprio, on_rq;
        struct rq *rq;
-       u64 now;
 
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
        rq = task_rq_lock(p, &flags);
-       now = rq_clock(rq);
+       update_rq_clock(rq);
 
        oldprio = p->prio;
        on_rq = p->se.on_rq;
        if (on_rq)
-               dequeue_task(rq, p, 0, now);
+               dequeue_task(rq, p, 0);
 
        if (rt_prio(prio))
                p->sched_class = &rt_sched_class;
@@ -3915,7 +3926,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        p->prio = prio;
 
        if (on_rq) {
-               enqueue_task(rq, p, 0, now);
+               enqueue_task(rq, p, 0);
                /*
                 * Reschedule if we are currently running on this runqueue and
                 * our priority decreased, or if we are not currently running on
@@ -3938,7 +3949,6 @@ void set_user_nice(struct task_struct *p, long nice)
        int old_prio, delta, on_rq;
        unsigned long flags;
        struct rq *rq;
-       u64 now;
 
        if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
                return;
@@ -3947,7 +3957,7 @@ void set_user_nice(struct task_struct *p, long nice)
         * the task might be in the middle of scheduling on another CPU.
         */
        rq = task_rq_lock(p, &flags);
-       now = rq_clock(rq);
+       update_rq_clock(rq);
        /*
         * The RT priorities are set via sched_setscheduler(), but we still
         * allow the 'normal' nice value to be set - but as expected
@@ -3960,8 +3970,8 @@ void set_user_nice(struct task_struct *p, long nice)
        }
        on_rq = p->se.on_rq;
        if (on_rq) {
-               dequeue_task(rq, p, 0, now);
-               dec_load(rq, p, now);
+               dequeue_task(rq, p, 0);
+               dec_load(rq, p);
        }
 
        p->static_prio = NICE_TO_PRIO(nice);
@@ -3971,8 +3981,8 @@ void set_user_nice(struct task_struct *p, long nice)
        delta = p->prio - old_prio;
 
        if (on_rq) {
-               enqueue_task(rq, p, 0, now);
-               inc_load(rq, p, now);
+               enqueue_task(rq, p, 0);
+               inc_load(rq, p);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@ -4208,6 +4218,7 @@ recheck:
                spin_unlock_irqrestore(&p->pi_lock, flags);
                goto recheck;
        }
+       update_rq_clock(rq);
        on_rq = p->se.on_rq;
        if (on_rq)
                deactivate_task(rq, p, 0);
@@ -4463,10 +4474,8 @@ long sched_getaffinity(pid_t pid, cpumask_t *mask)
 out_unlock:
        read_unlock(&tasklist_lock);
        mutex_unlock(&sched_hotcpu_mutex);
-       if (retval)
-               return retval;
 
-       return 0;
+       return retval;
 }
 
 /**
@@ -4966,6 +4975,7 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
        on_rq = p->se.on_rq;
        if (on_rq)
                deactivate_task(rq_src, p, 0);
+
        set_task_cpu(p, dest_cpu);
        if (on_rq) {
                activate_task(rq_dest, p, 0);
@@ -5198,7 +5208,8 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
        for ( ; ; ) {
                if (!rq->nr_running)
                        break;
-               next = pick_next_task(rq, rq->curr, rq_clock(rq));
+               update_rq_clock(rq);
+               next = pick_next_task(rq, rq->curr);
                if (!next)
                        break;
                migrate_dead(dead_cpu, next);
@@ -5210,12 +5221,19 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
 #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
 
 static struct ctl_table sd_ctl_dir[] = {
-       {CTL_UNNUMBERED, "sched_domain", NULL, 0, 0755, NULL, },
+       {
+               .procname       = "sched_domain",
+               .mode           = 0755,
+       },
        {0,},
 };
 
 static struct ctl_table sd_ctl_root[] = {
-       {CTL_UNNUMBERED, "kernel", NULL, 0, 0755, sd_ctl_dir, },
+       {
+               .procname       = "kernel",
+               .mode           = 0755,
+               .child          = sd_ctl_dir,
+       },
        {0,},
 };
 
@@ -5231,11 +5249,10 @@ static struct ctl_table *sd_alloc_ctl_entry(int n)
 }
 
 static void
-set_table_entry(struct ctl_table *entry, int ctl_name,
+set_table_entry(struct ctl_table *entry,
                const char *procname, void *data, int maxlen,
                mode_t mode, proc_handler *proc_handler)
 {
-       entry->ctl_name = ctl_name;
        entry->procname = procname;
        entry->data = data;
        entry->maxlen = maxlen;
@@ -5248,28 +5265,28 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
 {
        struct ctl_table *table = sd_alloc_ctl_entry(14);
 
-       set_table_entry(&table[0], 1, "min_interval", &sd->min_interval,
+       set_table_entry(&table[0], "min_interval", &sd->min_interval,
                sizeof(long), 0644, proc_doulongvec_minmax);
-       set_table_entry(&table[1], 2, "max_interval", &sd->max_interval,
+       set_table_entry(&table[1], "max_interval", &sd->max_interval,
                sizeof(long), 0644, proc_doulongvec_minmax);
-       set_table_entry(&table[2], 3, "busy_idx", &sd->busy_idx,
+       set_table_entry(&table[2], "busy_idx", &sd->busy_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[3], 4, "idle_idx", &sd->idle_idx,
+       set_table_entry(&table[3], "idle_idx", &sd->idle_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[4], 5, "newidle_idx", &sd->newidle_idx,
+       set_table_entry(&table[4], "newidle_idx", &sd->newidle_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[5], 6, "wake_idx", &sd->wake_idx,
+       set_table_entry(&table[5], "wake_idx", &sd->wake_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[6], 7, "forkexec_idx", &sd->forkexec_idx,
+       set_table_entry(&table[6], "forkexec_idx", &sd->forkexec_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[7], 8, "busy_factor", &sd->busy_factor,
+       set_table_entry(&table[7], "busy_factor", &sd->busy_factor,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[8], 9, "imbalance_pct", &sd->imbalance_pct,
+       set_table_entry(&table[8], "imbalance_pct", &sd->imbalance_pct,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[10], 11, "cache_nice_tries",
+       set_table_entry(&table[10], "cache_nice_tries",
                &sd->cache_nice_tries,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[12], 13, "flags", &sd->flags,
+       set_table_entry(&table[12], "flags", &sd->flags,
                sizeof(int), 0644, proc_dointvec_minmax);
 
        return table;
@@ -5289,7 +5306,6 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
        i = 0;
        for_each_domain(cpu, sd) {
                snprintf(buf, 32, "domain%d", i);
-               entry->ctl_name = i + 1;
                entry->procname = kstrdup(buf, GFP_KERNEL);
                entry->mode = 0755;
                entry->child = sd_alloc_ctl_domain_table(sd);
@@ -5310,7 +5326,6 @@ static void init_sched_domain_sysctl(void)
 
        for (i = 0; i < cpu_num; i++, entry++) {
                snprintf(buf, 32, "cpu%d", i);
-               entry->ctl_name = i + 1;
                entry->procname = kstrdup(buf, GFP_KERNEL);
                entry->mode = 0755;
                entry->child = sd_alloc_ctl_cpu_table(i);
@@ -5379,6 +5394,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                rq = task_rq_lock(rq->idle, &flags);
+               update_rq_clock(rq);
                deactivate_task(rq, rq->idle, 0);
                rq->idle->static_prio = MAX_PRIO;
                __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
@@ -6616,12 +6632,13 @@ void normalize_rt_tasks(void)
                        goto out_unlock;
 #endif
 
+               update_rq_clock(rq);
                on_rq = p->se.on_rq;
                if (on_rq)
-                       deactivate_task(task_rq(p), p, 0);
+                       deactivate_task(rq, p, 0);
                __setscheduler(rq, p, SCHED_NORMAL, 0);
                if (on_rq) {
-                       activate_task(task_rq(p), p, 0);
+                       activate_task(rq, p, 0);
                        resched_task(rq->curr);
                }
 #ifdef CONFIG_SMP
index 8421b9399e109f9795e70c5854026f89d428b098..3da32156394e9e172075038f35242c77e025a6f1 100644 (file)
@@ -29,7 +29,7 @@
  } while (0)
 
 static void
-print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now)
+print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
 {
        if (rq->curr == p)
                SEQ_printf(m, "R");
@@ -56,7 +56,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now)
 #endif
 }
 
-static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now)
+static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
 {
        struct task_struct *g, *p;
 
@@ -77,7 +77,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now)
                if (!p->se.on_rq || task_cpu(p) != rq_cpu)
                        continue;
 
-               print_task(m, rq, p, now);
+               print_task(m, rq, p);
        } while_each_thread(g, p);
 
        read_unlock_irq(&tasklist_lock);
@@ -106,7 +106,7 @@ print_cfs_rq_runtime_sum(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
                (long long)wait_runtime_rq_sum);
 }
 
-void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 {
        SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq);
 
@@ -124,7 +124,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
        print_cfs_rq_runtime_sum(m, cpu, cfs_rq);
 }
 
-static void print_cpu(struct seq_file *m, int cpu, u64 now)
+static void print_cpu(struct seq_file *m, int cpu)
 {
        struct rq *rq = &per_cpu(runqueues, cpu);
 
@@ -166,9 +166,9 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
        P(cpu_load[4]);
 #undef P
 
-       print_cfs_stats(m, cpu, now);
+       print_cfs_stats(m, cpu);
 
-       print_rq(m, rq, cpu, now);
+       print_rq(m, rq, cpu);
 }
 
 static int sched_debug_show(struct seq_file *m, void *v)
@@ -184,7 +184,7 @@ static int sched_debug_show(struct seq_file *m, void *v)
        SEQ_printf(m, "now at %Lu nsecs\n", (unsigned long long)now);
 
        for_each_online_cpu(cpu)
-               print_cpu(m, cpu, now);
+               print_cpu(m, cpu);
 
        SEQ_printf(m, "\n");
 
index 6f579ff5a9bc93abd215cda93d9d7b9617ce7f4c..e91db32cadfd63538d4977eb705a0fe142e51353 100644 (file)
@@ -222,21 +222,25 @@ niced_granularity(struct sched_entity *curr, unsigned long granularity)
 {
        u64 tmp;
 
+       if (likely(curr->load.weight == NICE_0_LOAD))
+               return granularity;
        /*
-        * Negative nice levels get the same granularity as nice-0:
+        * Positive nice levels get the same granularity as nice-0:
         */
-       if (likely(curr->load.weight >= NICE_0_LOAD))
-               return granularity;
+       if (likely(curr->load.weight < NICE_0_LOAD)) {
+               tmp = curr->load.weight * (u64)granularity;
+               return (long) (tmp >> NICE_0_SHIFT);
+       }
        /*
-        * Positive nice level tasks get linearly finer
+        * Negative nice level tasks get linearly finer
         * granularity:
         */
-       tmp = curr->load.weight * (u64)granularity;
+       tmp = curr->load.inv_weight * (u64)granularity;
 
        /*
         * It will always fit into 'long':
         */
-       return (long) (tmp >> NICE_0_SHIFT);
+       return (long) (tmp >> WMULT_SHIFT);
 }
 
 static inline void
@@ -281,26 +285,25 @@ add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta)
  * are not in our scheduling class.
  */
 static inline void
-__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now)
+__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 {
-       unsigned long delta, delta_exec, delta_fair;
-       long delta_mine;
+       unsigned long delta, delta_exec, delta_fair, delta_mine;
        struct load_weight *lw = &cfs_rq->load;
        unsigned long load = lw->weight;
 
-       if (unlikely(!load))
-               return;
-
        delta_exec = curr->delta_exec;
        schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
 
        curr->sum_exec_runtime += delta_exec;
        cfs_rq->exec_clock += delta_exec;
 
+       if (unlikely(!load))
+               return;
+
        delta_fair = calc_delta_fair(delta_exec, lw);
        delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw);
 
-       if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) {
+       if (cfs_rq->sleeper_bonus > sysctl_sched_granularity) {
                delta = calc_delta_mine(cfs_rq->sleeper_bonus,
                                        curr->load.weight, lw);
                if (unlikely(delta > cfs_rq->sleeper_bonus))
@@ -321,7 +324,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now)
        add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec);
 }
 
-static void update_curr(struct cfs_rq *cfs_rq, u64 now)
+static void update_curr(struct cfs_rq *cfs_rq)
 {
        struct sched_entity *curr = cfs_rq_curr(cfs_rq);
        unsigned long delta_exec;
@@ -334,22 +337,22 @@ static void update_curr(struct cfs_rq *cfs_rq, u64 now)
         * since the last time we changed load (this cannot
         * overflow on 32 bits):
         */
-       delta_exec = (unsigned long)(now - curr->exec_start);
+       delta_exec = (unsigned long)(rq_of(cfs_rq)->clock - curr->exec_start);
 
        curr->delta_exec += delta_exec;
 
        if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) {
-               __update_curr(cfs_rq, curr, now);
+               __update_curr(cfs_rq, curr);
                curr->delta_exec = 0;
        }
-       curr->exec_start = now;
+       curr->exec_start = rq_of(cfs_rq)->clock;
 }
 
 static inline void
-update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        se->wait_start_fair = cfs_rq->fair_clock;
-       schedstat_set(se->wait_start, now);
+       schedstat_set(se->wait_start, rq_of(cfs_rq)->clock);
 }
 
 /*
@@ -377,8 +380,7 @@ calc_weighted(unsigned long delta, unsigned long weight, int shift)
 /*
  * Task is being enqueued - update stats:
  */
-static void
-update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        s64 key;
 
@@ -387,7 +389,7 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
         * a dequeue/enqueue event is a NOP)
         */
        if (se != cfs_rq_curr(cfs_rq))
-               update_stats_wait_start(cfs_rq, se, now);
+               update_stats_wait_start(cfs_rq, se);
        /*
         * Update the key:
         */
@@ -407,7 +409,8 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
                                        (WMULT_SHIFT - NICE_0_SHIFT);
                } else {
                        tmp = se->wait_runtime;
-                       key -= (tmp * se->load.weight) >> NICE_0_SHIFT;
+                       key -= (tmp * se->load.inv_weight) >>
+                                       (WMULT_SHIFT - NICE_0_SHIFT);
                }
        }
 
@@ -418,11 +421,12 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
  * Note: must be called with a freshly updated rq->fair_clock.
  */
 static inline void
-__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        unsigned long delta_fair = se->delta_fair_run;
 
-       schedstat_set(se->wait_max, max(se->wait_max, now - se->wait_start));
+       schedstat_set(se->wait_max, max(se->wait_max,
+                       rq_of(cfs_rq)->clock - se->wait_start));
 
        if (unlikely(se->load.weight != NICE_0_LOAD))
                delta_fair = calc_weighted(delta_fair, se->load.weight,
@@ -432,7 +436,7 @@ __update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
 }
 
 static void
-update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        unsigned long delta_fair;
 
@@ -442,7 +446,7 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
        se->delta_fair_run += delta_fair;
        if (unlikely(abs(se->delta_fair_run) >=
                                sysctl_sched_stat_granularity)) {
-               __update_stats_wait_end(cfs_rq, se, now);
+               __update_stats_wait_end(cfs_rq, se);
                se->delta_fair_run = 0;
        }
 
@@ -451,34 +455,34 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
 }
 
 static inline void
-update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       update_curr(cfs_rq, now);
+       update_curr(cfs_rq);
        /*
         * Mark the end of the wait period if dequeueing a
         * waiting task:
         */
        if (se != cfs_rq_curr(cfs_rq))
-               update_stats_wait_end(cfs_rq, se, now);
+               update_stats_wait_end(cfs_rq, se);
 }
 
 /*
  * We are picking a new current task - update its stats:
  */
 static inline void
-update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        /*
         * We are starting a new run period:
         */
-       se->exec_start = now;
+       se->exec_start = rq_of(cfs_rq)->clock;
 }
 
 /*
  * We are descheduling a task - update its stats:
  */
 static inline void
-update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        se->exec_start = 0;
 }
@@ -487,8 +491,7 @@ update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
  * Scheduling class queueing methods:
  */
 
-static void
-__enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        unsigned long load = cfs_rq->load.weight, delta_fair;
        long prev_runtime;
@@ -522,8 +525,7 @@ __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
        schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
 }
 
-static void
-enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        struct task_struct *tsk = task_of(se);
        unsigned long delta_fair;
@@ -538,7 +540,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
        se->delta_fair_sleep += delta_fair;
        if (unlikely(abs(se->delta_fair_sleep) >=
                                sysctl_sched_stat_granularity)) {
-               __enqueue_sleeper(cfs_rq, se, now);
+               __enqueue_sleeper(cfs_rq, se);
                se->delta_fair_sleep = 0;
        }
 
@@ -546,7 +548,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
 
 #ifdef CONFIG_SCHEDSTATS
        if (se->sleep_start) {
-               u64 delta = now - se->sleep_start;
+               u64 delta = rq_of(cfs_rq)->clock - se->sleep_start;
 
                if ((s64)delta < 0)
                        delta = 0;
@@ -558,7 +560,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
                se->sum_sleep_runtime += delta;
        }
        if (se->block_start) {
-               u64 delta = now - se->block_start;
+               u64 delta = rq_of(cfs_rq)->clock - se->block_start;
 
                if ((s64)delta < 0)
                        delta = 0;
@@ -573,26 +575,24 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
 }
 
 static void
-enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
-              int wakeup, u64 now)
+enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
 {
        /*
         * Update the fair clock.
         */
-       update_curr(cfs_rq, now);
+       update_curr(cfs_rq);
 
        if (wakeup)
-               enqueue_sleeper(cfs_rq, se, now);
+               enqueue_sleeper(cfs_rq, se);
 
-       update_stats_enqueue(cfs_rq, se, now);
+       update_stats_enqueue(cfs_rq, se);
        __enqueue_entity(cfs_rq, se);
 }
 
 static void
-dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
-              int sleep, u64 now)
+dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
 {
-       update_stats_dequeue(cfs_rq, se, now);
+       update_stats_dequeue(cfs_rq, se);
        if (sleep) {
                se->sleep_start_fair = cfs_rq->fair_clock;
 #ifdef CONFIG_SCHEDSTATS
@@ -600,9 +600,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
                        struct task_struct *tsk = task_of(se);
 
                        if (tsk->state & TASK_INTERRUPTIBLE)
-                               se->sleep_start = now;
+                               se->sleep_start = rq_of(cfs_rq)->clock;
                        if (tsk->state & TASK_UNINTERRUPTIBLE)
-                               se->block_start = now;
+                               se->block_start = rq_of(cfs_rq)->clock;
                }
                cfs_rq->wait_runtime -= se->wait_runtime;
 #endif
@@ -629,7 +629,7 @@ __check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se,
 }
 
 static inline void
-set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
        /*
         * Any task has to be enqueued before it get to execute on
@@ -638,49 +638,46 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
         * done a put_prev_task_fair() shortly before this, which
         * updated rq->fair_clock - used by update_stats_wait_end())
         */
-       update_stats_wait_end(cfs_rq, se, now);
-       update_stats_curr_start(cfs_rq, se, now);
+       update_stats_wait_end(cfs_rq, se);
+       update_stats_curr_start(cfs_rq, se);
        set_cfs_rq_curr(cfs_rq, se);
 }
 
-static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now)
+static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
 {
        struct sched_entity *se = __pick_next_entity(cfs_rq);
 
-       set_next_entity(cfs_rq, se, now);
+       set_next_entity(cfs_rq, se);
 
        return se;
 }
 
-static void
-put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now)
+static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
 {
        /*
         * If still on the runqueue then deactivate_task()
         * was not called and update_curr() has to be done:
         */
        if (prev->on_rq)
-               update_curr(cfs_rq, now);
+               update_curr(cfs_rq);
 
-       update_stats_curr_end(cfs_rq, prev, now);
+       update_stats_curr_end(cfs_rq, prev);
 
        if (prev->on_rq)
-               update_stats_wait_start(cfs_rq, prev, now);
+               update_stats_wait_start(cfs_rq, prev);
        set_cfs_rq_curr(cfs_rq, NULL);
 }
 
 static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 {
-       struct rq *rq = rq_of(cfs_rq);
        struct sched_entity *next;
-       u64 now = __rq_clock(rq);
 
        /*
         * Dequeue and enqueue the task to update its
         * position within the tree:
         */
-       dequeue_entity(cfs_rq, curr, 0, now);
-       enqueue_entity(cfs_rq, curr, 0, now);
+       dequeue_entity(cfs_rq, curr, 0);
+       enqueue_entity(cfs_rq, curr, 0);
 
        /*
         * Reschedule if another task tops the current one.
@@ -785,8 +782,7 @@ static inline int is_same_group(struct task_struct *curr, struct task_struct *p)
  * increased. Here we update the fair scheduling stats and
  * then put the task into the rbtree:
  */
-static void
-enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
@@ -795,7 +791,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
                if (se->on_rq)
                        break;
                cfs_rq = cfs_rq_of(se);
-               enqueue_entity(cfs_rq, se, wakeup, now);
+               enqueue_entity(cfs_rq, se, wakeup);
        }
 }
 
@@ -804,15 +800,14 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
  * decreased. We remove the task from the rbtree and
  * update the fair scheduling stats:
  */
-static void
-dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
 
        for_each_sched_entity(se) {
                cfs_rq = cfs_rq_of(se);
-               dequeue_entity(cfs_rq, se, sleep, now);
+               dequeue_entity(cfs_rq, se, sleep);
                /* Don't dequeue parent if it has other entities besides us */
                if (cfs_rq->load.weight)
                        break;
@@ -825,14 +820,14 @@ dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now)
 static void yield_task_fair(struct rq *rq, struct task_struct *p)
 {
        struct cfs_rq *cfs_rq = task_cfs_rq(p);
-       u64 now = __rq_clock(rq);
 
+       __update_rq_clock(rq);
        /*
         * Dequeue and enqueue the task to update its
         * position within the tree:
         */
-       dequeue_entity(cfs_rq, &p->se, 0, now);
-       enqueue_entity(cfs_rq, &p->se, 0, now);
+       dequeue_entity(cfs_rq, &p->se, 0);
+       enqueue_entity(cfs_rq, &p->se, 0);
 }
 
 /*
@@ -845,7 +840,8 @@ static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p)
        unsigned long gran;
 
        if (unlikely(rt_prio(p->prio))) {
-               update_curr(cfs_rq, rq_clock(rq));
+               update_rq_clock(rq);
+               update_curr(cfs_rq);
                resched_task(curr);
                return;
        }
@@ -861,7 +857,7 @@ static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p)
                __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran);
 }
 
-static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_fair(struct rq *rq)
 {
        struct cfs_rq *cfs_rq = &rq->cfs;
        struct sched_entity *se;
@@ -870,7 +866,7 @@ static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
                return NULL;
 
        do {
-               se = pick_next_entity(cfs_rq, now);
+               se = pick_next_entity(cfs_rq);
                cfs_rq = group_cfs_rq(se);
        } while (cfs_rq);
 
@@ -880,14 +876,14 @@ static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
 /*
  * Account for a descheduled task:
  */
-static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now)
+static void put_prev_task_fair(struct rq *rq, struct task_struct *prev)
 {
        struct sched_entity *se = &prev->se;
        struct cfs_rq *cfs_rq;
 
        for_each_sched_entity(se) {
                cfs_rq = cfs_rq_of(se);
-               put_prev_entity(cfs_rq, se, now);
+               put_prev_entity(cfs_rq, se);
        }
 }
 
@@ -930,6 +926,7 @@ static struct task_struct *load_balance_next_fair(void *arg)
        return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
 }
 
+#ifdef CONFIG_FAIR_GROUP_SCHED
 static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
 {
        struct sched_entity *curr;
@@ -943,12 +940,13 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
 
        return p->prio;
 }
+#endif
 
-static int
+static unsigned long
 load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                       unsigned long max_nr_move, unsigned long max_load_move,
-                       struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, unsigned long *total_load_moved)
+                 unsigned long max_nr_move, unsigned long max_load_move,
+                 struct sched_domain *sd, enum cpu_idle_type idle,
+                 int *all_pinned, int *this_best_prio)
 {
        struct cfs_rq *busy_cfs_rq;
        unsigned long load_moved, total_nr_moved = 0, nr_moved;
@@ -959,10 +957,10 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
        cfs_rq_iterator.next = load_balance_next_fair;
 
        for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+#ifdef CONFIG_FAIR_GROUP_SCHED
                struct cfs_rq *this_cfs_rq;
-               long imbalance;
+               long imbalances;
                unsigned long maxload;
-               int this_best_prio, best_prio, best_prio_seen = 0;
 
                this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
 
@@ -976,27 +974,17 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
                imbalance /= 2;
                maxload = min(rem_load_move, imbalance);
 
-               this_best_prio = cfs_rq_best_prio(this_cfs_rq);
-               best_prio = cfs_rq_best_prio(busy_cfs_rq);
-
-               /*
-                * Enable handling of the case where there is more than one task
-                * with the best priority. If the current running task is one
-                * of those with prio==best_prio we know it won't be moved
-                * and therefore it's safe to override the skip (based on load)
-                * of any task we find with that prio.
-                */
-               if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se)
-                       best_prio_seen = 1;
-
+               *this_best_prio = cfs_rq_best_prio(this_cfs_rq);
+#else
+#define maxload rem_load_move
+#endif
                /* pass busy_cfs_rq argument into
                 * load_balance_[start|next]_fair iterators
                 */
                cfs_rq_iterator.arg = busy_cfs_rq;
                nr_moved = balance_tasks(this_rq, this_cpu, busiest,
                                max_nr_move, maxload, sd, idle, all_pinned,
-                               &load_moved, this_best_prio, best_prio,
-                               best_prio_seen, &cfs_rq_iterator);
+                               &load_moved, this_best_prio, &cfs_rq_iterator);
 
                total_nr_moved += nr_moved;
                max_nr_move -= nr_moved;
@@ -1006,9 +994,7 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
                        break;
        }
 
-       *total_load_moved = max_load_move - rem_load_move;
-
-       return total_nr_moved;
+       return max_load_move - rem_load_move;
 }
 
 /*
@@ -1032,14 +1018,14 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr)
  * monopolize the CPU. Note: the parent runqueue is locked,
  * the child is not running yet.
  */
-static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now)
+static void task_new_fair(struct rq *rq, struct task_struct *p)
 {
        struct cfs_rq *cfs_rq = task_cfs_rq(p);
        struct sched_entity *se = &p->se;
 
        sched_info_queued(p);
 
-       update_stats_enqueue(cfs_rq, se, now);
+       update_stats_enqueue(cfs_rq, se);
        /*
         * Child runs first: we let it run before the parent
         * until it reschedules once. We set up the key so that
@@ -1072,15 +1058,10 @@ static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now)
  */
 static void set_curr_task_fair(struct rq *rq)
 {
-       struct task_struct *curr = rq->curr;
-       struct sched_entity *se = &curr->se;
-       u64 now = rq_clock(rq);
-       struct cfs_rq *cfs_rq;
+       struct sched_entity *se = &rq->curr.se;
 
-       for_each_sched_entity(se) {
-               cfs_rq = cfs_rq_of(se);
-               set_next_entity(cfs_rq, se, now);
-       }
+       for_each_sched_entity(se)
+               set_next_entity(cfs_rq_of(se), se);
 }
 #else
 static void set_curr_task_fair(struct rq *rq)
@@ -1109,12 +1090,11 @@ struct sched_class fair_sched_class __read_mostly = {
 };
 
 #ifdef CONFIG_SCHED_DEBUG
-void print_cfs_stats(struct seq_file *m, int cpu, u64 now)
+static void print_cfs_stats(struct seq_file *m, int cpu)
 {
-       struct rq *rq = cpu_rq(cpu);
        struct cfs_rq *cfs_rq;
 
-       for_each_leaf_cfs_rq(rq, cfs_rq)
-               print_cfs_rq(m, cpu, cfs_rq, now);
+       for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq)
+               print_cfs_rq(m, cpu, cfs_rq);
 }
 #endif
index 41841e741c4a097fa3db58f2222308af64b6ca34..3503fb2d9f96caa0ee690ddbfaa722a573997ec0 100644 (file)
@@ -13,7 +13,7 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p)
        resched_task(rq->idle);
 }
 
-static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_idle(struct rq *rq)
 {
        schedstat_inc(rq, sched_goidle);
 
@@ -25,7 +25,7 @@ static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now)
  * message if some code attempts to do it:
  */
 static void
-dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep)
 {
        spin_unlock_irq(&rq->lock);
        printk(KERN_ERR "bad: scheduling from the idle thread!\n");
@@ -33,15 +33,15 @@ dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now)
        spin_lock_irq(&rq->lock);
 }
 
-static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, u64 now)
+static void put_prev_task_idle(struct rq *rq, struct task_struct *prev)
 {
 }
 
-static int
+static unsigned long
 load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
                        unsigned long max_nr_move, unsigned long max_load_move,
                        struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, unsigned long *total_load_moved)
+                       int *all_pinned, int *this_best_prio)
 {
        return 0;
 }
index 002fcf8d3f64997983cc3b2ff83931d93dae5e47..dcdcad632fd9c8a9d9e603f28e70db2acb03fbc5 100644 (file)
@@ -7,7 +7,7 @@
  * Update the current task's runtime statistics. Skip current tasks that
  * are not in our scheduling class.
  */
-static inline void update_curr_rt(struct rq *rq, u64 now)
+static inline void update_curr_rt(struct rq *rq)
 {
        struct task_struct *curr = rq->curr;
        u64 delta_exec;
@@ -15,18 +15,17 @@ static inline void update_curr_rt(struct rq *rq, u64 now)
        if (!task_has_rt_policy(curr))
                return;
 
-       delta_exec = now - curr->se.exec_start;
+       delta_exec = rq->clock - curr->se.exec_start;
        if (unlikely((s64)delta_exec < 0))
                delta_exec = 0;
 
        schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
-       curr->se.exec_start = now;
+       curr->se.exec_start = rq->clock;
 }
 
-static void
-enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
 {
        struct rt_prio_array *array = &rq->rt.active;
 
@@ -37,12 +36,11 @@ enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
 /*
  * Adding/removing a task to/from a priority array:
  */
-static void
-dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
 {
        struct rt_prio_array *array = &rq->rt.active;
 
-       update_curr_rt(rq, now);
+       update_curr_rt(rq);
 
        list_del(&p->run_list);
        if (list_empty(array->queue + p->prio))
@@ -75,7 +73,7 @@ static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p)
                resched_task(rq->curr);
 }
 
-static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_rt(struct rq *rq)
 {
        struct rt_prio_array *array = &rq->rt.active;
        struct task_struct *next;
@@ -89,14 +87,14 @@ static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now)
        queue = array->queue + idx;
        next = list_entry(queue->next, struct task_struct, run_list);
 
-       next->se.exec_start = now;
+       next->se.exec_start = rq->clock;
 
        return next;
 }
 
-static void put_prev_task_rt(struct rq *rq, struct task_struct *p, u64 now)
+static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
 {
-       update_curr_rt(rq, now);
+       update_curr_rt(rq);
        p->se.exec_start = 0;
 }
 
@@ -172,28 +170,15 @@ static struct task_struct *load_balance_next_rt(void *arg)
        return p;
 }
 
-static int
+static unsigned long
 load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
                        unsigned long max_nr_move, unsigned long max_load_move,
                        struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, unsigned long *load_moved)
+                       int *all_pinned, int *this_best_prio)
 {
-       int this_best_prio, best_prio, best_prio_seen = 0;
        int nr_moved;
        struct rq_iterator rt_rq_iterator;
-
-       best_prio = sched_find_first_bit(busiest->rt.active.bitmap);
-       this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap);
-
-       /*
-        * Enable handling of the case where there is more than one task
-        * with the best priority.   If the current running task is one
-        * of those with prio==best_prio we know it won't be moved
-        * and therefore it's safe to override the skip (based on load)
-        * of any task we find with that prio.
-        */
-       if (busiest->curr->prio == best_prio)
-               best_prio_seen = 1;
+       unsigned long load_moved;
 
        rt_rq_iterator.start = load_balance_start_rt;
        rt_rq_iterator.next = load_balance_next_rt;
@@ -203,11 +188,10 @@ load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
        rt_rq_iterator.arg = busiest;
 
        nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
-                       max_load_move, sd, idle, all_pinned, load_moved,
-                       this_best_prio, best_prio, best_prio_seen,
-                       &rt_rq_iterator);
+                       max_load_move, sd, idle, all_pinned, &load_moved,
+                       this_best_prio, &rt_rq_iterator);
 
-       return nr_moved;
+       return load_moved;
 }
 
 static void task_tick_rt(struct rq *rq, struct task_struct *p)
index f13937bf9e8ce20f3b2c171948593795d082b8ee..d054e9224b3e270110790f08f540df208cbc0556 100644 (file)
@@ -74,8 +74,8 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
        struct ieee80211softmac_auth_queue_item *authptr;
        int length = 0;
 
+check_assoc_again:
        mutex_lock(&sm->associnfo.mutex);
-
        /* Check if we're already associating to this or another network
         * If it's another network, cancel and start over with our new network
         * If it's our network, ignore the change, we're already doing it!
@@ -98,13 +98,18 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
                                cancel_delayed_work(&authptr->work);
                        sm->associnfo.bssvalid = 0;
                        sm->associnfo.bssfixed = 0;
-                       flush_scheduled_work();
                        sm->associnfo.associating = 0;
                        sm->associnfo.associated = 0;
+                       /* We must unlock to avoid deadlocks with the assoc workqueue
+                        * on the associnfo.mutex */
+                       mutex_unlock(&sm->associnfo.mutex);
+                       flush_scheduled_work();
+                       /* Avoid race! Check assoc status again. Maybe someone started an
+                        * association while we flushed. */
+                       goto check_assoc_again;
                }
        }
 
-
        sm->associnfo.static_essid = 0;
        sm->associnfo.assoc_wait = 0;