From 9b6ec945194ee6497e228a8d6b385d906ba6db22 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] --- yaml --- r: 40927 b: refs/heads/master c: 9446868b5383eb87f76b2d4389dea4bb968a6657 h: refs/heads/master i: 40925: 6d183d6a56bcf6e1688c8d424ab0902cd58f12ae 40923: 7669173fe540ee67c2bfb2d2f03bf64ee49a2fef 40919: 9e7e1f6e56c60815fbe0211665dae94069b1a0ed 40911: d1f5127b2958b97e2ef12fde07058ce70265e83f 40895: 8a2e5c6757b803bd63d30d2d45277a21298e09fa v: v3 --- [refs] | 2 +- trunk/arch/x86_64/kernel/process.c | 3 +-- trunk/include/asm-x86_64/pda.h | 9 +++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index c92ff7bc4a6a..4377dd86c1ab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8c131af1db510793f87dc43edbc8950a35370df3 +refs/heads/master: 9446868b5383eb87f76b2d4389dea4bb968a6657 diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index 49f7fac6229e..f6226055d53d 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -88,9 +88,8 @@ void enter_idle(void) static void __exit_idle(void) { - if (read_pda(isidle) == 0) + if (test_and_clear_bit_pda(0, isidle) == 0) return; - write_pda(isidle, 0); atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } diff --git a/trunk/include/asm-x86_64/pda.h b/trunk/include/asm-x86_64/pda.h index 14996d962bac..5642634843c4 100644 --- a/trunk/include/asm-x86_64/pda.h +++ b/trunk/include/asm-x86_64/pda.h @@ -109,6 +109,15 @@ extern struct x8664_pda _proxy_pda; #define sub_pda(field,val) pda_to_op("sub",field,val) #define or_pda(field,val) pda_to_op("or",field,val) +/* This is not atomic against other CPUs -- CPU preemption needs to be off */ +#define test_and_clear_bit_pda(bit,field) ({ \ + int old__; \ + asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ + : "=r" (old__), "+m" (_proxy_pda.field) \ + : "dIr" (bit), "i" (pda_offset(field)) : "memory"); \ + old__; \ +}) + #endif #define PDA_STACKOFFSET (5*8)