Messages in this thread Patch in this message | | | Date | Tue, 23 Apr 2002 23:52:40 +0200 (MET DST) | From | Mikael Pettersson <> | Subject | [PATCH] UP CPU number microoptimisation, updated |
| |
This is an update to the ->thread_info->cpu microoptimisation patch posted last week. The main change is that the optimised access macros now are defined in <linux/thread_info.h>, which should allow this to work on all architectures, not just x86.
The patch eliminates ->thread_info->cpu accesses in UP configs, since ->cpu is known to be zero. This primarily affects the scheduler: in my 2.5.9 kernel it eliminated 256 bytes of code from kernel/sched.o.
/Mikael
diff -ruN linux-2.5.9/fs/proc/array.c linux-2.5.9.up-opt-v3/fs/proc/array.c --- linux-2.5.9/fs/proc/array.c Mon Apr 15 00:32:53 2002 +++ linux-2.5.9.up-opt-v3/fs/proc/array.c Tue Apr 23 22:38:57 2002 @@ -389,7 +389,7 @@ task->nswap, task->cnswap, task->exit_signal, - task->thread_info->cpu); + thread_info_cpu(task->thread_info)); if(mm) mmput(mm); return res; diff -ruN linux-2.5.9/include/asm-i386/thread_info.h linux-2.5.9.up-opt-v3/include/asm-i386/thread_info.h --- linux-2.5.9/include/asm-i386/thread_info.h Mon Apr 15 00:32:54 2002 +++ linux-2.5.9.up-opt-v3/include/asm-i386/thread_info.h Tue Apr 23 22:38:57 2002 @@ -24,26 +24,34 @@ struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ - __u32 cpu; /* current CPU */ - __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ - mm_segment_t addr_limit; /* thread address space: 0-0xBFFFFFFF for user-thead 0-0xFFFFFFFF for kernel-thread */ - + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ +#ifdef CONFIG_SMP + __u32 cpu; /* current CPU */ +#endif __u8 supervisor_stack[0]; }; +#ifdef CONFIG_SMP +#define TI_CPU_INIT cpu: 0, +#else +#define TI_CPU_INIT /*empty*/ +#endif + #else /* !__ASSEMBLY__ */ /* offsets into the thread_info struct for assembly code access */ #define TI_TASK 0x00000000 #define TI_EXEC_DOMAIN 0x00000004 #define TI_FLAGS 0x00000008 -#define TI_CPU 0x0000000C +#define TI_ADDR_LIMIT 0x0000000C #define TI_PRE_COUNT 0x00000010 -#define TI_ADDR_LIMIT 0x00000014 +#ifdef CONFIG_SMP +#define TI_CPU 0x00000014 +#endif #endif @@ -58,8 +66,8 @@ task: &tsk, \ exec_domain: &default_exec_domain, \ flags: 0, \ - cpu: 0, \ addr_limit: KERNEL_DS, \ + TI_CPU_INIT \ } #define init_thread_info (init_thread_union.thread_info) diff -ruN linux-2.5.9/include/linux/thread_info.h linux-2.5.9.up-opt-v3/include/linux/thread_info.h --- linux-2.5.9/include/linux/thread_info.h Tue Apr 23 13:51:19 2002 +++ linux-2.5.9.up-opt-v3/include/linux/thread_info.h Tue Apr 23 22:39:38 2002 @@ -13,6 +13,33 @@ #ifdef __KERNEL__ /* + * wrappers for thread_info->cpu accesses + * optimised away on UP (cpu == 0 is an invariant) + */ +#ifdef CONFIG_SMP +static inline unsigned int thread_info_cpu(const struct thread_info *ti) +{ + return ti->cpu; +} + +static inline void set_thread_info_cpu(struct thread_info *ti, unsigned int cpu) +{ + ti->cpu = cpu; +} + +#else /* !CONFIG_SMP */ + +static inline unsigned int thread_info_cpu(const struct thread_info *ti) +{ + return 0; +} + +static inline void set_thread_info_cpu(struct thread_info *ti, unsigned int cpu) +{ +} +#endif /* CONFIG_SMP */ + +/* * flag set/clear/test wrappers * - pass TIF_xxxx constants to these functions */ diff -ruN linux-2.5.9/kernel/sched.c linux-2.5.9.up-opt-v3/kernel/sched.c --- linux-2.5.9/kernel/sched.c Tue Apr 23 13:51:19 2002 +++ linux-2.5.9.up-opt-v3/kernel/sched.c Tue Apr 23 22:38:57 2002 @@ -153,7 +153,7 @@ #define cpu_rq(cpu) (runqueues + (cpu)) #define this_rq() cpu_rq(smp_processor_id()) -#define task_rq(p) cpu_rq((p)->thread_info->cpu) +#define task_rq(p) cpu_rq(thread_info_cpu((p)->thread_info)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) #define rt_task(p) ((p)->prio < MAX_RT_PRIO) @@ -264,8 +264,8 @@ need_resched = test_and_set_tsk_thread_flag(p,TIF_NEED_RESCHED); nrpolling |= test_tsk_thread_flag(p,TIF_POLLING_NRFLAG); - if (!need_resched && !nrpolling && (p->thread_info->cpu != smp_processor_id())) - smp_send_reschedule(p->thread_info->cpu); + if (!need_resched && !nrpolling && (thread_info_cpu(p->thread_info) != smp_processor_id())) + smp_send_reschedule(thread_info_cpu(p->thread_info)); preempt_enable(); #else set_tsk_need_resched(p); @@ -366,7 +366,7 @@ p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100; p->prio = effective_prio(p); } - p->thread_info->cpu = smp_processor_id(); + set_thread_info_cpu(p->thread_info, smp_processor_id()); activate_task(p, rq); spin_unlock_irq(&rq->lock); @@ -609,7 +609,7 @@ */ dequeue_task(next, array); busiest->nr_running--; - next->thread_info->cpu = this_cpu; + set_thread_info_cpu(next->thread_info, this_cpu); this_rq->nr_running++; enqueue_task(next, this_rq->active); if (next->prio < current->prio) @@ -1535,7 +1535,7 @@ void __init init_idle(task_t *idle, int cpu) { - runqueue_t *idle_rq = cpu_rq(cpu), *rq = cpu_rq(idle->thread_info->cpu); + runqueue_t *idle_rq = cpu_rq(cpu), *rq = cpu_rq(thread_info_cpu(idle->thread_info)); unsigned long flags; __save_flags(flags); @@ -1547,7 +1547,7 @@ idle->array = NULL; idle->prio = MAX_PRIO; idle->state = TASK_RUNNING; - idle->thread_info->cpu = cpu; + set_thread_info_cpu(idle->thread_info, cpu); double_rq_unlock(idle_rq, rq); set_tsk_need_resched(idle); __restore_flags(flags); @@ -1656,7 +1656,7 @@ * Can the task run on the task's current CPU? If not then * migrate the process off to a proper CPU. */ - if (new_mask & (1UL << p->thread_info->cpu)) { + if (new_mask & (1UL << thread_info_cpu(p->thread_info))) { task_rq_unlock(rq, &flags); goto out; } @@ -1723,18 +1723,18 @@ cpu_dest = __ffs(p->cpus_allowed); rq_dest = cpu_rq(cpu_dest); repeat: - cpu_src = p->thread_info->cpu; + cpu_src = thread_info_cpu(p->thread_info); rq_src = cpu_rq(cpu_src); local_irq_save(flags); double_rq_lock(rq_src, rq_dest); - if (p->thread_info->cpu != cpu_src) { + if (thread_info_cpu(p->thread_info) != cpu_src) { double_rq_unlock(rq_src, rq_dest); local_irq_restore(flags); goto repeat; } if (rq_src == rq) { - p->thread_info->cpu = cpu_dest; + set_thread_info_cpu(p->thread_info, cpu_dest); if (p->array) { deactivate_task(p, rq_src); activate_task(p, rq_dest); diff -ruN linux-2.5.9/kernel/signal.c linux-2.5.9.up-opt-v3/kernel/signal.c --- linux-2.5.9/kernel/signal.c Tue Mar 19 01:10:08 2002 +++ linux-2.5.9.up-opt-v3/kernel/signal.c Tue Apr 23 22:38:57 2002 @@ -508,7 +508,7 @@ * process of changing - but no harm is done by that * other than doing an extra (lightweight) IPI interrupt. */ - if ((t->state == TASK_RUNNING) && (t->thread_info->cpu != smp_processor_id())) + if ((t->state == TASK_RUNNING) && (thread_info_cpu(t->thread_info) != smp_processor_id())) kick_if_running(t); #endif if (t->state & TASK_INTERRUPTIBLE) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |