Merge branches 'sched-core-for-linus' and 'sched-urgent-for-linus' of git://git.kerne...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 May 2011 00:41:22 +0000 (17:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 May 2011 00:41:22 +0000 (17:41 -0700)
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (60 commits)
  sched: Fix and optimise calculation of the weight-inverse
  sched: Avoid going ahead if ->cpus_allowed is not changed
  sched, rt: Update rq clock when unthrottling of an otherwise idle CPU
  sched: Remove unused parameters from sched_fork() and wake_up_new_task()
  sched: Shorten the construction of the span cpu mask of sched domain
  sched: Wrap the 'cfs_rq->nr_spread_over' field with CONFIG_SCHED_DEBUG
  sched: Remove unused 'this_best_prio arg' from balance_tasks()
  sched: Remove noop in alloc_rt_sched_group()
  sched: Get rid of lock_depth
  sched: Remove obsolete comment from scheduler_tick()
  sched: Fix sched_domain iterations vs. RCU
  sched: Next buddy hint on sleep and preempt path
  sched: Make set_*_buddy() work on non-task entities
  sched: Remove need_migrate_task()
  sched: Move the second half of ttwu() to the remote cpu
  sched: Restructure ttwu() some more
  sched: Rename ttwu_post_activation() to ttwu_do_wakeup()
  sched: Remove rq argument from ttwu_stat()
  sched: Remove rq->lock from the first half of ttwu()
  sched: Drop rq->lock from sched_exec()
  ...

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  sched: Fix rt_rq runtime leakage bug

1  2  3 
arch/mips/cavium-octeon/smp.c
arch/mips/mti-malta/malta-int.c
arch/sparc/kernel/smp_32.c
arch/x86/xen/smp.c
init/Kconfig
kernel/sched_rt.c

@@@@ -37,13 -37,15 -37,13 +37,15 @@@@ static irqreturn_t mailbox_interrupt(in
        uint64_t action;
   
        /* Load the mailbox register to figure out what we're supposed to do */
 --     action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid));
 ++     action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
   
        /* Clear the mailbox to clear the interrupt */
        cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
   
        if (action & SMP_CALL_FUNCTION)
                smp_call_function_interrupt();
+ +     if (action & SMP_RESCHEDULE_YOURSELF)
+ +             scheduler_ipi();
   
        /* Check if we've been told to flush the icache */
        if (action & SMP_ICACHE_FLUSH)
@@@@ -200,15 -202,16 -200,16 +202,15 @@@@ void octeon_prepare_cpus(unsigned int m
        if (labi->labi_signature != LABI_SIGNATURE)
                panic("The bootloader version on this board is incorrect.");
   #endif
 --
 --     cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
 ++     /*
 ++      * Only the low order mailbox bits are used for IPIs, leave
 ++      * the other bits alone.
 ++      */
 ++     cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
        if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
 --                     "mailbox0", mailbox_interrupt)) {
 ++                     "SMP-IPI", mailbox_interrupt)) {
                panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
        }
 --     if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_DISABLED,
 --                     "mailbox1", mailbox_interrupt)) {
 --             panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n");
 --     }
   }
   
   /**
@@@@ -56,6 -56,7 -56,6 +56,6 @@@@ static DEFINE_RAW_SPINLOCK(mips_irq_loc
   static inline int mips_pcibios_iack(void)
   {
        int irq;
 -      u32 dummy;
   
        /*
         * Determine highest priority pending interrupt by performing
                BONITO_PCIMAP_CFG = 0x20000;
   
                /* Flush Bonito register block */
 -              dummy = BONITO_PCIMAP_CFG;
 +              (void) BONITO_PCIMAP_CFG;
                iob();    /* sync */
   
                irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg);
@@@@ -308,6 -309,8 -308,6 +308,8 @@@@ static void ipi_call_dispatch(void
   
   static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
   {
+ +     scheduler_ipi();
+ +
        return IRQ_HANDLED;
   }
   
@@@@ -53,7 -53,6 -53,7 +53,7 @@@@ cpumask_t smp_commenced_mask = CPU_MASK
   void __cpuinit smp_store_cpu_info(int id)
   {
        int cpu_node;
 +      int mid;
   
        cpu_data(id).udelay_val = loops_per_jiffy;
   
        cpu_data(id).clock_tick = prom_getintdefault(cpu_node,
                                                     "clock-frequency", 0);
        cpu_data(id).prom_node = cpu_node;
 -      cpu_data(id).mid = cpu_get_hwmid(cpu_node);
 +      mid = cpu_get_hwmid(cpu_node);
   
 -      if (cpu_data(id).mid < 0)
 -              panic("No MID found for CPU%d at node 0x%08d", id, cpu_node);
 +      if (mid < 0) {
 +              printk(KERN_NOTICE "No MID found for CPU%d at node 0x%08d", id, cpu_node);
 +              mid = 0;
 +      }
 +      cpu_data(id).mid = mid;
   }
   
   void __init smp_cpus_done(unsigned int max_cpus)
@@@@ -129,7 -125,9 -129,7 +129,9 @@@@ struct linux_prom_registers smp_penguin
   
   void smp_send_reschedule(int cpu)
   {
- -     /* See sparc64 */
+ +     /*
+ +      * XXX missing reschedule IPI, see scheduler_ipi()
+ +      */
   }
   
   void smp_send_stop(void)
diff --combined arch/x86/xen/smp.c
@@@@ -46,18 -46,17 -46,18 +46,17 @@@@ static irqreturn_t xen_call_function_in
   static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
   
   /*
- - * Reschedule call back. Nothing to do,
- - * all the work is done automatically when
- - * we return from the interrupt.
+ + * Reschedule call back.
    */
   static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
   {
        inc_irq_stat(irq_resched_count);
+ +     scheduler_ipi();
   
        return IRQ_HANDLED;
   }
   
 --static __cpuinit void cpu_bringup(void)
 ++static void __cpuinit cpu_bringup(void)
   {
        int cpu = smp_processor_id();
   
        wmb();                  /* make sure everything is out */
   }
   
 --static __cpuinit void cpu_bringup_and_idle(void)
 ++static void __cpuinit cpu_bringup_and_idle(void)
   {
        cpu_bringup();
        cpu_idle();
@@@@ -242,7 -241,7 -242,7 +241,7 @@@@ static void __init xen_smp_prepare_cpus
        }
   }
   
 --static __cpuinit int
 ++static int __cpuinit
   cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
   {
        struct vcpu_guest_context *ctxt;
@@@@ -486,7 -485,7 -486,7 +485,7 @@@@ static irqreturn_t xen_call_function_si
        return IRQ_HANDLED;
   }
   
 --static const struct smp_ops xen_smp_ops __initdata = {
 ++static const struct smp_ops xen_smp_ops __initconst = {
        .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
        .smp_prepare_cpus = xen_smp_prepare_cpus,
        .smp_cpus_done = xen_smp_cpus_done,
diff --combined init/Kconfig
@@@@ -827,6 -827,11 -827,6 +827,11 @@@@ config SCHED_AUTOGROU
          desktop applications.  Task group autogeneration is currently based
          upon task session.
   
+ +config SCHED_TTWU_QUEUE
+ +     bool
+ +     depends on !SPARC32
+ +     default y
+ +
   config MM_OWNER
        bool
   
@@@@ -1226,6 -1231,7 -1226,6 +1231,6 @@@@ config SLA
          per cpu and per node queues.
   
   config SLUB
 -      depends on BROKEN || NUMA || !DISCONTIGMEM
        bool "SLUB (Unqueued Allocator)"
        help
           SLUB is a slab allocator that minimizes cache line usage
diff --combined kernel/sched_rt.c
@@@@ -183,6 -183,6 -183,14 +183,14 @@@@ static inline u64 sched_rt_period(struc
        return ktime_to_ns(rt_rq->tg->rt_bandwidth.rt_period);
   }
   
++ typedef struct task_group *rt_rq_iter_t;
++ 
++ #define for_each_rt_rq(rt_rq, iter, rq) \
++      for (iter = list_entry_rcu(task_groups.next, typeof(*iter), list); \
++           (&iter->list != &task_groups) && \
++           (rt_rq = iter->rt_rq[cpu_of(rq)]); \
++           iter = list_entry_rcu(iter->list.next, typeof(*iter), list))
++ 
   static inline void list_add_leaf_rt_rq(struct rt_rq *rt_rq)
   {
        list_add_rcu(&rt_rq->leaf_rt_rq_list,
@@@@ -288,6 -288,6 -296,11 +296,11 @@@@ static inline u64 sched_rt_period(struc
        return ktime_to_ns(def_rt_bandwidth.rt_period);
   }
   
++ typedef struct rt_rq *rt_rq_iter_t;
++ 
++ #define for_each_rt_rq(rt_rq, iter, rq) \
++      for ((void) iter, rt_rq = &rq->rt; rt_rq; rt_rq = NULL)
++ 
   static inline void list_add_leaf_rt_rq(struct rt_rq *rt_rq)
   {
   }
@@@@ -402,12 -402,12 -415,13 +415,13 @@@@ next
   static void __disable_runtime(struct rq *rq)
   {
        struct root_domain *rd = rq->rd;
++      rt_rq_iter_t iter;
        struct rt_rq *rt_rq;
   
        if (unlikely(!scheduler_running))
                return;
   
--      for_each_leaf_rt_rq(rt_rq, rq) {
++      for_each_rt_rq(rt_rq, iter, rq) {
                struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
                s64 want;
                int i;
@@@@ -487,6 -487,6 -501,7 +501,7 @@@@ static void disable_runtime(struct rq *
   
   static void __enable_runtime(struct rq *rq)
   {
++      rt_rq_iter_t iter;
        struct rt_rq *rt_rq;
   
        if (unlikely(!scheduler_running))
        /*
         * Reset each runqueue's bandwidth settings
         */
--      for_each_leaf_rt_rq(rt_rq, rq) {
++      for_each_rt_rq(rt_rq, iter, rq) {
                struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
   
                raw_spin_lock(&rt_b->rt_runtime_lock);
@@@@ -562,6 -562,13 -577,6 +577,13 @@@@ static int do_sched_rt_period_timer(str
                        if (rt_rq->rt_throttled && rt_rq->rt_time < runtime) {
                                rt_rq->rt_throttled = 0;
                                enqueue = 1;
+ +
+ +                             /*
+ +                              * Force a clock update if the CPU was idle,
+ +                              * lest wakeup -> unthrottle time accumulate.
+ +                              */
+ +                             if (rt_rq->rt_nr_running && rq->curr == rq->idle)
+ +                                     rq->skip_clock_update = -1;
                        }
                        if (rt_rq->rt_time || rt_rq->rt_nr_running)
                                idle = 0;
@@@@ -977,13 -984,23 -992,13 +999,23 @@@@ static void yield_task_rt(struct rq *rq
   static int find_lowest_rq(struct task_struct *task);
   
   static int
- -select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
+ +select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
   {
+ +     struct task_struct *curr;
+ +     struct rq *rq;
+ +     int cpu;
+ +
        if (sd_flag != SD_BALANCE_WAKE)
                return smp_processor_id();
   
+ +     cpu = task_cpu(p);
+ +     rq = cpu_rq(cpu);
+ +
+ +     rcu_read_lock();
+ +     curr = ACCESS_ONCE(rq->curr); /* unlocked access */
+ +
        /*
- -      * If the current task is an RT task, then
+ +      * If the current task on @p's runqueue is an RT task, then
         * try to see if we can wake this RT task up on another
         * runqueue. Otherwise simply start this RT task
         * on its current runqueue.
         * lock?
         *
         * For equal prio tasks, we just let the scheduler sort it out.
+ +      *
+ +      * Otherwise, just let it ride on the affined RQ and the
+ +      * post-schedule router will push the preempted task away
+ +      *
+ +      * This test is optimistic, if we get it wrong the load-balancer
+ +      * will have to sort it out.
         */
- -     if (unlikely(rt_task(rq->curr)) &&
- -         (rq->curr->rt.nr_cpus_allowed < 2 ||
- -          rq->curr->prio < p->prio) &&
+ +     if (curr && unlikely(rt_task(curr)) &&
+ +         (curr->rt.nr_cpus_allowed < 2 ||
+ +          curr->prio < p->prio) &&
            (p->rt.nr_cpus_allowed > 1)) {
- -             int cpu = find_lowest_rq(p);
+ +             int target = find_lowest_rq(p);
   
- -             return (cpu == -1) ? task_cpu(p) : cpu;
+ +             if (target != -1)
+ +                     cpu = target;
        }
+ +     rcu_read_unlock();
   
- -     /*
- -      * Otherwise, just let it ride on the affined RQ and the
- -      * post-schedule router will push the preempted task away
- -      */
- -     return task_cpu(p);
+ +     return cpu;
   }
   
   static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
@@@@ -1136,7 -1157,7 -1151,7 +1172,7 @@@@ static void put_prev_task_rt(struct rq 
         * The previous task needs to be made eligible for pushing
         * if it is still active
         */
- -     if (p->se.on_rq && p->rt.nr_cpus_allowed > 1)
+ +     if (on_rt_rq(&p->rt) && p->rt.nr_cpus_allowed > 1)
                enqueue_pushable_task(rq, p);
   }
   
@@@@ -1287,7 -1308,7 -1302,7 +1323,7 @@@@ static struct rq *find_lock_lowest_rq(s
                                     !cpumask_test_cpu(lowest_rq->cpu,
                                                       &task->cpus_allowed) ||
                                     task_running(rq, task) ||
- -                                  !task->se.on_rq)) {
+ +                                  !task->on_rq)) {
   
                                raw_spin_unlock(&lowest_rq->lock);
                                lowest_rq = NULL;
@@@@ -1321,7 -1342,7 -1336,7 +1357,7 @@@@ static struct task_struct *pick_next_pu
        BUG_ON(task_current(rq, p));
        BUG_ON(p->rt.nr_cpus_allowed <= 1);
   
- -     BUG_ON(!p->se.on_rq);
+ +     BUG_ON(!p->on_rq);
        BUG_ON(!rt_task(p));
   
        return p;
@@@@ -1467,7 -1488,7 -1482,7 +1503,7 @@@@ static int pull_rt_task(struct rq *this
                 */
                if (p && (p->prio < this_rq->rt.highest_prio.curr)) {
                        WARN_ON(p == src_rq->curr);
- -                     WARN_ON(!p->se.on_rq);
+ +                     WARN_ON(!p->on_rq);
   
                        /*
                         * There's a chance that p is higher in priority
@@@@ -1538,7 -1559,7 -1553,7 +1574,7 @@@@ static void set_cpus_allowed_rt(struct 
         * Update the migration status of the RQ if we have an RT task
         * which is running AND changing its weight value.
         */
- -     if (p->se.on_rq && (weight != p->rt.nr_cpus_allowed)) {
+ +     if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
                struct rq *rq = task_rq(p);
   
                if (!task_current(rq, p)) {
@@@@ -1608,7 -1629,7 -1623,7 +1644,7 @@@@ static void switched_from_rt(struct rq 
         * we may need to handle the pulling of RT tasks
         * now.
         */
- -     if (p->se.on_rq && !rq->rt.rt_nr_running)
+ +     if (p->on_rq && !rq->rt.rt_nr_running)
                pull_rt_task(rq);
   }
   
@@@@ -1638,7 -1659,7 -1653,7 +1674,7 @@@@ static void switched_to_rt(struct rq *r
         * If that current running task is also an RT task
         * then see if we can move to another run queue.
         */
- -     if (p->se.on_rq && rq->curr != p) {
+ +     if (p->on_rq && rq->curr != p) {
   #ifdef CONFIG_SMP
                if (rq->rt.overloaded && push_rt_task(rq) &&
                    /* Don't resched if we changed runqueues */
   static void
   prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
   {
- -     if (!p->se.on_rq)
+ +     if (!p->on_rq)
                return;
   
        if (rq->curr == p) {
@@@@ -1796,10 -1817,10 -1811,11 +1832,11 @@@@ extern void print_rt_rq(struct seq_fil
   
   static void print_rt_stats(struct seq_file *m, int cpu)
   {
++      rt_rq_iter_t iter;
        struct rt_rq *rt_rq;
   
        rcu_read_lock();
--      for_each_leaf_rt_rq(rt_rq, cpu_rq(cpu))
++      for_each_rt_rq(rt_rq, iter, cpu_rq(cpu))
                print_rt_rq(m, cpu, rt_rq);
        rcu_read_unlock();
   }