aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-06-26 07:59:11 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 13:48:21 -0400
commit495ab9c045e1b0e5c82951b762257fe1c9d81564 (patch)
treef95c376015d340794f64f36fd52f8fa80a1daab7
parentd9005b52de7bc9b20afa93e06d3e15843bafc12f (diff)
[PATCH] i386/x86-64/ia64: Move polling flag into thread_info_status
During some profiling I noticed that default_idle causes a lot of memory traffic. I think that is caused by the atomic operations to clear/set the polling flag in thread_info. There is actually no reason to make this atomic - only the idle thread does it to itself, other CPUs only read it. So I moved it into ti->status. Converted i386/x86-64/ia64 for now because that was the easiest way to fix ACPI which also manipulates these flags in its idle function. Cc: Nick Piggin <npiggin@novell.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Len Brown <len.brown@intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/apm.c6
-rw-r--r--arch/i386/kernel/process.c6
-rw-r--r--arch/ia64/kernel/process.c4
-rw-r--r--arch/x86_64/kernel/process.c7
-rw-r--r--drivers/acpi/processor_idle.c12
-rw-r--r--include/asm-i386/thread_info.h7
-rw-r--r--include/asm-ia64/thread_info.h5
-rw-r--r--include/asm-x86_64/thread_info.h6
-rw-r--r--kernel/sched.c9
9 files changed, 37 insertions, 25 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 9e819eb68229..7c5729d1fd06 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -764,9 +764,9 @@ static int apm_do_idle(void)
764 int idled = 0; 764 int idled = 0;
765 int polling; 765 int polling;
766 766
767 polling = test_thread_flag(TIF_POLLING_NRFLAG); 767 polling = !!(current_thread_info()->status & TS_POLLING);
768 if (polling) { 768 if (polling) {
769 clear_thread_flag(TIF_POLLING_NRFLAG); 769 current_thread_info()->status &= ~TS_POLLING;
770 smp_mb__after_clear_bit(); 770 smp_mb__after_clear_bit();
771 } 771 }
772 if (!need_resched()) { 772 if (!need_resched()) {
@@ -774,7 +774,7 @@ static int apm_do_idle(void)
774 ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); 774 ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
775 } 775 }
776 if (polling) 776 if (polling)
777 set_thread_flag(TIF_POLLING_NRFLAG); 777 current_thread_info()->status |= TS_POLLING;
778 778
779 if (!idled) 779 if (!idled)
780 return 0; 780 return 0;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 525432e3fef7..6946b06e2784 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -102,7 +102,7 @@ void default_idle(void)
102 local_irq_enable(); 102 local_irq_enable();
103 103
104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
105 clear_thread_flag(TIF_POLLING_NRFLAG); 105 current_thread_info()->status &= ~TS_POLLING;
106 smp_mb__after_clear_bit(); 106 smp_mb__after_clear_bit();
107 while (!need_resched()) { 107 while (!need_resched()) {
108 local_irq_disable(); 108 local_irq_disable();
@@ -111,7 +111,7 @@ void default_idle(void)
111 else 111 else
112 local_irq_enable(); 112 local_irq_enable();
113 } 113 }
114 set_thread_flag(TIF_POLLING_NRFLAG); 114 current_thread_info()->status |= TS_POLLING;
115 } else { 115 } else {
116 while (!need_resched()) 116 while (!need_resched())
117 cpu_relax(); 117 cpu_relax();
@@ -174,7 +174,7 @@ void cpu_idle(void)
174{ 174{
175 int cpu = smp_processor_id(); 175 int cpu = smp_processor_id();
176 176
177 set_thread_flag(TIF_POLLING_NRFLAG); 177 current_thread_info()->status |= TS_POLLING;
178 178
179 /* endless idle loop with no priority at all */ 179 /* endless idle loop with no priority at all */
180 while (1) { 180 while (1) {
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 355d57970ba3..b045c279136c 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -272,9 +272,9 @@ cpu_idle (void)
272 /* endless idle loop with no priority at all */ 272 /* endless idle loop with no priority at all */
273 while (1) { 273 while (1) {
274 if (can_do_pal_halt) 274 if (can_do_pal_halt)
275 clear_thread_flag(TIF_POLLING_NRFLAG); 275 current_thread_info()->status &= ~TS_POLLING;
276 else 276 else
277 set_thread_flag(TIF_POLLING_NRFLAG); 277 current_thread_info()->status |= TS_POLLING;
278 278
279 if (!need_resched()) { 279 if (!need_resched()) {
280 void (*idle)(void); 280 void (*idle)(void);
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index d6fa41459c80..b596837a1527 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -110,7 +110,7 @@ static void default_idle(void)
110{ 110{
111 local_irq_enable(); 111 local_irq_enable();
112 112
113 clear_thread_flag(TIF_POLLING_NRFLAG); 113 current_thread_info()->status &= ~TS_POLLING;
114 smp_mb__after_clear_bit(); 114 smp_mb__after_clear_bit();
115 while (!need_resched()) { 115 while (!need_resched()) {
116 local_irq_disable(); 116 local_irq_disable();
@@ -119,7 +119,7 @@ static void default_idle(void)
119 else 119 else
120 local_irq_enable(); 120 local_irq_enable();
121 } 121 }
122 set_thread_flag(TIF_POLLING_NRFLAG); 122 current_thread_info()->status |= TS_POLLING;
123} 123}
124 124
125/* 125/*
@@ -202,8 +202,7 @@ static inline void play_dead(void)
202 */ 202 */
203void cpu_idle (void) 203void cpu_idle (void)
204{ 204{
205 set_thread_flag(TIF_POLLING_NRFLAG); 205 current_thread_info()->status |= TS_POLLING;
206
207 /* endless idle loop with no priority at all */ 206 /* endless idle loop with no priority at all */
208 while (1) { 207 while (1) {
209 while (!need_resched()) { 208 while (!need_resched()) {
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 3b97a5eae9e8..74173ce6aaf4 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -206,11 +206,11 @@ acpi_processor_power_activate(struct acpi_processor *pr,
206 206
207static void acpi_safe_halt(void) 207static void acpi_safe_halt(void)
208{ 208{
209 clear_thread_flag(TIF_POLLING_NRFLAG); 209 current_thread_info()->status &= ~TS_POLLING;
210 smp_mb__after_clear_bit(); 210 smp_mb__after_clear_bit();
211 if (!need_resched()) 211 if (!need_resched())
212 safe_halt(); 212 safe_halt();
213 set_thread_flag(TIF_POLLING_NRFLAG); 213 current_thread_info()->status |= TS_POLLING;
214} 214}
215 215
216static atomic_t c3_cpu_count; 216static atomic_t c3_cpu_count;
@@ -330,10 +330,10 @@ static void acpi_processor_idle(void)
330 * Invoke the current Cx state to put the processor to sleep. 330 * Invoke the current Cx state to put the processor to sleep.
331 */ 331 */
332 if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { 332 if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
333 clear_thread_flag(TIF_POLLING_NRFLAG); 333 current_thread_info()->status &= ~TS_POLLING;
334 smp_mb__after_clear_bit(); 334 smp_mb__after_clear_bit();
335 if (need_resched()) { 335 if (need_resched()) {
336 set_thread_flag(TIF_POLLING_NRFLAG); 336 current_thread_info()->status |= TS_POLLING;
337 local_irq_enable(); 337 local_irq_enable();
338 return; 338 return;
339 } 339 }
@@ -371,7 +371,7 @@ static void acpi_processor_idle(void)
371 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 371 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
372 /* Re-enable interrupts */ 372 /* Re-enable interrupts */
373 local_irq_enable(); 373 local_irq_enable();
374 set_thread_flag(TIF_POLLING_NRFLAG); 374 current_thread_info()->status |= TS_POLLING;
375 /* Compute time (ticks) that we were actually asleep */ 375 /* Compute time (ticks) that we were actually asleep */
376 sleep_ticks = 376 sleep_ticks =
377 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; 377 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
@@ -411,7 +411,7 @@ static void acpi_processor_idle(void)
411 411
412 /* Re-enable interrupts */ 412 /* Re-enable interrupts */
413 local_irq_enable(); 413 local_irq_enable();
414 set_thread_flag(TIF_POLLING_NRFLAG); 414 current_thread_info()->status |= TS_POLLING;
415 /* Compute time (ticks) that we were actually asleep */ 415 /* Compute time (ticks) that we were actually asleep */
416 sleep_ticks = 416 sleep_ticks =
417 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; 417 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 8420ed12491e..fdbc7f422ea5 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -140,8 +140,7 @@ register unsigned long current_stack_pointer asm("esp") __attribute_used__;
140#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ 140#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
141#define TIF_SECCOMP 8 /* secure computing */ 141#define TIF_SECCOMP 8 /* secure computing */
142#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ 142#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
143#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 143#define TIF_MEMDIE 16
144#define TIF_MEMDIE 17
145 144
146#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 145#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
147#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 146#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -153,7 +152,6 @@ register unsigned long current_stack_pointer asm("esp") __attribute_used__;
153#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 152#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
154#define _TIF_SECCOMP (1<<TIF_SECCOMP) 153#define _TIF_SECCOMP (1<<TIF_SECCOMP)
155#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 154#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
156#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
157 155
158/* work to do on interrupt/exception return */ 156/* work to do on interrupt/exception return */
159#define _TIF_WORK_MASK \ 157#define _TIF_WORK_MASK \
@@ -170,6 +168,9 @@ register unsigned long current_stack_pointer asm("esp") __attribute_used__;
170 * have to worry about atomic accesses. 168 * have to worry about atomic accesses.
171 */ 169 */
172#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */ 170#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
171#define TS_POLLING 0x0002 /* True if in idle loop and not sleeping */
172
173#define tsk_is_polling(t) ((t)->thread_info->status & TS_POLLING)
173 174
174#endif /* __KERNEL__ */ 175#endif /* __KERNEL__ */
175 176
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index e5392c4d30c6..8bc9869e5765 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -27,6 +27,7 @@ struct thread_info {
27 __u32 flags; /* thread_info flags (see TIF_*) */ 27 __u32 flags; /* thread_info flags (see TIF_*) */
28 __u32 cpu; /* current CPU */ 28 __u32 cpu; /* current CPU */
29 __u32 last_cpu; /* Last CPU thread ran on */ 29 __u32 last_cpu; /* Last CPU thread ran on */
30 __u32 status; /* Thread synchronous flags */
30 mm_segment_t addr_limit; /* user-level address space limit */ 31 mm_segment_t addr_limit; /* user-level address space limit */
31 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ 32 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
32 struct restart_block restart_block; 33 struct restart_block restart_block;
@@ -103,4 +104,8 @@ struct thread_info {
103/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */ 104/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */
104#define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)) 105#define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
105 106
107#define TS_POLLING 1 /* true if in idle loop and not sleeping */
108
109#define tsk_is_polling(t) ((t)->thread_info->status & TS_POLLING)
110
106#endif /* _ASM_IA64_THREAD_INFO_H */ 111#endif /* _ASM_IA64_THREAD_INFO_H */
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index 4ac0e0a36934..b5e88216fd80 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -101,7 +101,7 @@ static inline struct thread_info *stack_thread_info(void)
101#define TIF_IRET 5 /* force IRET */ 101#define TIF_IRET 5 /* force IRET */
102#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ 102#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
103#define TIF_SECCOMP 8 /* secure computing */ 103#define TIF_SECCOMP 8 /* secure computing */
104#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 104/* 16 free */
105#define TIF_IA32 17 /* 32bit process */ 105#define TIF_IA32 17 /* 32bit process */
106#define TIF_FORK 18 /* ret_from_fork */ 106#define TIF_FORK 18 /* ret_from_fork */
107#define TIF_ABI_PENDING 19 107#define TIF_ABI_PENDING 19
@@ -115,7 +115,6 @@ static inline struct thread_info *stack_thread_info(void)
115#define _TIF_IRET (1<<TIF_IRET) 115#define _TIF_IRET (1<<TIF_IRET)
116#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 116#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
117#define _TIF_SECCOMP (1<<TIF_SECCOMP) 117#define _TIF_SECCOMP (1<<TIF_SECCOMP)
118#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
119#define _TIF_IA32 (1<<TIF_IA32) 118#define _TIF_IA32 (1<<TIF_IA32)
120#define _TIF_FORK (1<<TIF_FORK) 119#define _TIF_FORK (1<<TIF_FORK)
121#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) 120#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
@@ -137,6 +136,9 @@ static inline struct thread_info *stack_thread_info(void)
137 */ 136 */
138#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */ 137#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
139#define TS_COMPAT 0x0002 /* 32bit syscall active */ 138#define TS_COMPAT 0x0002 /* 32bit syscall active */
139#define TS_POLLING 0x0004 /* true if in idle loop and not sleeping */
140
141#define tsk_is_polling(t) ((t)->thread_info->status & TS_POLLING)
140 142
141#endif /* __KERNEL__ */ 143#endif /* __KERNEL__ */
142 144
diff --git a/kernel/sched.c b/kernel/sched.c
index f06d059edef5..7d1027a4dd21 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -818,6 +818,11 @@ static void deactivate_task(struct task_struct *p, runqueue_t *rq)
818 * the target CPU. 818 * the target CPU.
819 */ 819 */
820#ifdef CONFIG_SMP 820#ifdef CONFIG_SMP
821
822#ifndef tsk_is_polling
823#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
824#endif
825
821static void resched_task(task_t *p) 826static void resched_task(task_t *p)
822{ 827{
823 int cpu; 828 int cpu;
@@ -833,9 +838,9 @@ static void resched_task(task_t *p)
833 if (cpu == smp_processor_id()) 838 if (cpu == smp_processor_id())
834 return; 839 return;
835 840
836 /* NEED_RESCHED must be visible before we test POLLING_NRFLAG */ 841 /* NEED_RESCHED must be visible before we test polling */
837 smp_mb(); 842 smp_mb();
838 if (!test_tsk_thread_flag(p, TIF_POLLING_NRFLAG)) 843 if (!tsk_is_polling(p))
839 smp_send_reschedule(cpu); 844 smp_send_reschedule(cpu);
840} 845}
841#else 846#else