History

sched: Introduce preempt_count accessor functions

Replace the single preempt_count() 'function' that's an lvalue with two proper functions: preempt_count() - returns the preempt_count value as rvalue preempt_count_set() - Allows setting the preempt-count value Also provide preempt_count_ptr() as a convenience wrapper to implement all modifying operations.

Peter Zijlstra committed 13 years ago

Commit 4a2b4b21 parent ea811747 files · +30 −18Browse files

Unified · Split

7 files
  1. include/linux/preempt.h +19 −6
  2. init/main.c +1 −1
  3. kernel/sched/core.c +2 −2
  4. kernel/softirq.c +2 −2
  5. kernel/timer.c +4 −4
  6. lib/locking-selftest.c +1 −1
  7. lib/smp_processor_id.c +1 −2
include/linux/preempt.h+19−6
@@ -10,19 +10,32 @@ · 9 unmodified lines
1010 #include <linux/linkage.h>
1111 #include <linux/list.h>
1212
13+static __always_inline int preempt_count(void)
14+{
15+ return current_thread_info()->preempt_count;
16+}
17+
18+static __always_inline int *preempt_count_ptr(void)
19+{
20+ return &current_thread_info()->preempt_count;
21+}
22+
23+static __always_inline void preempt_count_set(int pc)
24+{
25+ *preempt_count_ptr() = pc;
26+}
27+
1328 #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
1429 extern void add_preempt_count(int val);
1530 extern void sub_preempt_count(int val);
1631 #else
17−# define add_preempt_count(val) do { preempt_count() += (val); } while (0)
18−# define sub_preempt_count(val) do { preempt_count() -= (val); } while (0)
32+# define add_preempt_count(val) do { *preempt_count_ptr() += (val); } while (0)
33+# define sub_preempt_count(val) do { *preempt_count_ptr() -= (val); } while (0)
1934 #endif
2035
2136 #define inc_preempt_count() add_preempt_count(1)
2237 #define dec_preempt_count() sub_preempt_count(1)
2338
24−#define preempt_count() (current_thread_info()->preempt_count)
25−
2639 #ifdef CONFIG_PREEMPT
2740
2841 asmlinkage void preempt_schedule(void);
@@ -81,9 +94,9 @@ do { \ · 52 unmodified lines
8194
8295 /* For debugging and tracer internals only! */
8396 #define add_preempt_count_notrace(val) \
84− do { preempt_count() += (val); } while (0)
97+ do { *preempt_count_ptr() += (val); } while (0)
8598 #define sub_preempt_count_notrace(val) \
86− do { preempt_count() -= (val); } while (0)
99+ do { *preempt_count_ptr() -= (val); } while (0)
87100 #define inc_preempt_count_notrace() add_preempt_count_notrace(1)
88101 #define dec_preempt_count_notrace() sub_preempt_count_notrace(1)
89102
init/main.c+1−1
@@ -692,7 +692,7 @@ int __init_or_module do_one_initcall(initcall_t fn) · 691 unmodified lines
692692
693693 if (preempt_count() != count) {
694694 sprintf(msgbuf, "preemption imbalance ");
695− preempt_count() = count;
695+ preempt_count_set(count);
696696 }
697697 if (irqs_disabled()) {
698698 strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
kernel/sched/core.c+2−2
@@ -2219,7 +2219,7 @@ void __kprobes add_preempt_count(int val) · 2218 unmodified lines
22192219 if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
22202220 return;
22212221 #endif
2222− preempt_count() += val;
2222+ add_preempt_count_notrace(val);
22232223 #ifdef CONFIG_DEBUG_PREEMPT
22242224 /*
22252225 * Spinlock count overflowing soon?
@@ -2250,7 +2250,7 @@ void __kprobes sub_preempt_count(int val) · 24 unmodified lines
22502250
22512251 if (preempt_count() == val)
22522252 trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
2253− preempt_count() -= val;
2253+ sub_preempt_count_notrace(val);
22542254 }
22552255 EXPORT_SYMBOL(sub_preempt_count);
22562256
kernel/softirq.c+2−2
@@ -106,7 +106,7 @@ static void __local_bh_disable(unsigned long ip, unsigned int cnt) · 105 unmodified lines
106106 * We must manually increment preempt_count here and manually
107107 * call the trace_preempt_off later.
108108 */
109− preempt_count() += cnt;
109+ add_preempt_count_notrace(cnt);
110110 /*
111111 * Were softirqs turned off above:
112112 */
@@ -256,7 +256,7 @@ restart: · 143 unmodified lines
256256 " exited with %08x?\n", vec_nr,
257257 softirq_to_name[vec_nr], h->action,
258258 prev_count, preempt_count());
259− preempt_count() = prev_count;
259+ preempt_count_set(prev_count);
260260 }
261261
262262 rcu_bh_qs(cpu);
kernel/timer.c+4−4
@@ -1092,7 +1092,7 @@ static int cascade(struct tvec_base *base, struct tvec *tv, int index) · 1091 unmodified lines
10921092 static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
10931093 unsigned long data)
10941094 {
1095− int preempt_count = preempt_count();
1095+ int count = preempt_count();
10961096
10971097 #ifdef CONFIG_LOCKDEP
10981098 /*
@@ -1119,16 +1119,16 @@ static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long), · 20 unmodified lines
11191119
11201120 lock_map_release(&lockdep_map);
11211121
1122− if (preempt_count != preempt_count()) {
1122+ if (count != preempt_count()) {
11231123 WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n",
1124− fn, preempt_count, preempt_count());
1124+ fn, count, preempt_count());
11251125 /*
11261126 * Restore the preempt count. That gives us a decent
11271127 * chance to survive and extract information. If the
11281128 * callback kept a lock held, bad luck, but not worse
11291129 * than the BUG() we had.
11301130 */
1131− preempt_count() = preempt_count;
1131+ preempt_count_set(count);
11321132 }
11331133 }
11341134
lib/locking-selftest.c+1−1
@@ -1002,7 +1002,7 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) · 1001 unmodified lines
10021002 * Some tests (e.g. double-unlock) might corrupt the preemption
10031003 * count, so restore it:
10041004 */
1005− preempt_count() = saved_preempt_count;
1005+ preempt_count_set(saved_preempt_count);
10061006 #ifdef CONFIG_TRACE_IRQFLAGS
10071007 if (softirq_count())
10081008 current->softirqs_enabled = 0;
lib/smp_processor_id.c+1−2
@@ -9,10 +9,9 @@ · 8 unmodified lines
99
1010 notrace unsigned int debug_smp_processor_id(void)
1111 {
12− unsigned long preempt_count = preempt_count();
1312 int this_cpu = raw_smp_processor_id();
1413
15− if (likely(preempt_count))
14+ if (likely(preempt_count()))
1615 goto out;
1716
1817 if (irqs_disabled())

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t