On Fri, 2007-10-12 at 20:16 -0400, Gregory Haskins wrote:
> In theory, tasks will be most efficient if they are allowed to re-wake to
> the CPU that they last ran on due to cache affinity.  Short of that, it is
> cheaper to wake up the current CPU.  If neither of those two are options,
> than the lowest CPU will do. 
> 
> Signed-off-by: Gregory Haskins <[EMAIL PROTECTED]>
> ---
> 
>  kernel/sched.c |   72 
> +++++++++++++++++++++++++++++++++++++++++---------------
>  1 files changed, 53 insertions(+), 19 deletions(-)
> 
> diff --git a/kernel/sched.c b/kernel/sched.c
> index 3c71156..b79b968 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -1511,6 +1511,15 @@ static int double_lock_balance(struct rq *this_rq, 
> struct rq *busiest);
>  /* Only try this algorithm three times */
>  #define RT_PUSH_MAX_TRIES 3
>  
> +static int non_rt_cpu(cpumask_t *mask, int cpu)
> +{
> +     if (!rt_prio(cpu_rq(cpu)->curr_prio) &&
> +         cpu_isset(cpu, *mask))
> +             return 1;
> +
> +     return 0;
> +}
> +
>  /* Will lock the rq it finds */
>  static int find_lowest_cpu(cpumask_t *cpu_mask, struct task_struct *task,
>                                struct rq *this_rq)
> @@ -1519,32 +1528,57 @@ static int find_lowest_cpu(cpumask_t *cpu_mask, 
> struct task_struct *task,
>       int dst_cpu = -1;
>       int cpu;
>       int tries;
> +     int this_cpu = smp_processor_id();
>  
>       for (tries = 0; tries < RT_PUSH_MAX_TRIES; tries++) {
> +
>               /*
> -              * Scan each rq for the lowest prio.
> +              * We select a CPU in the following priority:
> +              *
> +              *       task_cpu, this_cpu, first_cpu
> +              *
> +              * for efficiency.
> +              *
> +              * - task_cpu preserves cache affinity

After thinking about this over the weekend, the task_cpu optimization
doesn't make sense.  It made sense in my original design before I
integrated with Steve's series, but not here.  I think the second
optimization (this_cpu) still makes sense though, so I will update this
patch for the next drop.

> +              * - this_cpu is (presumably) cheaper to preempt
> +              *   (note that sometimes task_cpu and this_cpu
> +              *   are the same).
> +              * - Finally, we will take whatever is available
> +              *   if the first two don't pan out by scanning.
>                */
> -             for_each_cpu_mask(cpu, *cpu_mask) {
> -                     struct rq *rq = &per_cpu(runqueues, cpu);
> -
> -                     if (cpu == smp_processor_id())
> -                             continue;
> -
> -                     /* We look for lowest RT prio or non-rt CPU */
> -                     if (rq->curr_prio >= MAX_RT_PRIO) {
> -                             lowest_rq = rq;
> -                             dst_cpu = cpu;
> -                             break;
> -                     }
> +             if (non_rt_cpu(cpu_mask, task_cpu(task))) {
> +                     lowest_rq = task_rq(task);      
> +                     dst_cpu = lowest_rq->cpu;
> +             } else if (non_rt_cpu(cpu_mask, this_cpu)) {
> +                     dst_cpu = this_cpu;
> +                     lowest_rq = cpu_rq(this_cpu);   
> +             } else {
>  
> -                     /* no locking for now */
> -                     if (rq->curr_prio > task->prio &&
> -                         (!lowest_rq || rq->curr_prio < 
> lowest_rq->curr_prio)) {
> -                             dst_cpu = cpu;
> -                             lowest_rq = rq;
> +                     /*
> +                      * Scan each rq for the lowest prio.
> +                      */
> +                     for_each_cpu_mask(cpu, *cpu_mask) {
> +                             struct rq *rq = &per_cpu(runqueues, cpu);
> +                             
> +                             if (cpu == this_cpu)
> +                                     continue;
> +                             
> +                             /* We look for lowest RT prio or non-rt CPU */
> +                             if (rq->curr_prio >= MAX_RT_PRIO) {
> +                                     lowest_rq = rq;
> +                                     dst_cpu = cpu;
> +                                     break;
> +                             }
> +                             
> +                             /* no locking for now */
> +                             if (rq->curr_prio > task->prio &&
> +                                 (!lowest_rq || rq->curr_prio < 
> lowest_rq->curr_prio)) {
> +                                     dst_cpu = cpu;
> +                                     lowest_rq = rq;
> +                             }
>                       }
>               }
> -
> +                     
>               if (!lowest_rq) {
>                       dst_cpu = -1;
>                       break;
> 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to