Commit 79eb6a12 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] get/put_cpu methods

This implements a get_cpu() and matching put_cpu() to safely hand out
the current CPU to avoid preempt races.  Andrew and I have been bitching
about the need for such a method.

I also went ahead and replaced an example of current explicit
preempt-off with the new methods, as a case in point.
parent 8e93dcc8
...@@ -31,6 +31,8 @@ require it otherwise. Second, when a preempted task is finally rescheduled, ...@@ -31,6 +31,8 @@ require it otherwise. Second, when a preempted task is finally rescheduled,
the previous value of smp_processor_id may not equal the current. You must the previous value of smp_processor_id may not equal the current. You must
protect these situations by disabling preemption around them. protect these situations by disabling preemption around them.
You can also use put_cpu() and get_cpu(), which will disable preemption.
RULE #2: CPU state must be protected. RULE #2: CPU state must be protected.
......
...@@ -96,5 +96,9 @@ static inline void smp_send_reschedule_all(void) { } ...@@ -96,5 +96,9 @@ static inline void smp_send_reschedule_all(void) { }
#define per_cpu(var, cpu) var #define per_cpu(var, cpu) var
#define this_cpu(var) var #define this_cpu(var) var
#endif #endif /* !SMP */
#endif
#define get_cpu() ({ preempt_disable(); smp_processor_id(); })
#define put_cpu() preempt_enable()
#endif /* __LINUX_SMP_H */
...@@ -117,15 +117,14 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping) ...@@ -117,15 +117,14 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping)
} ____cacheline_aligned ratelimits[NR_CPUS]; } ____cacheline_aligned ratelimits[NR_CPUS];
int cpu; int cpu;
preempt_disable(); cpu = get_cpu();
cpu = smp_processor_id();
if (ratelimits[cpu].count++ >= 1000) { if (ratelimits[cpu].count++ >= 1000) {
ratelimits[cpu].count = 0; ratelimits[cpu].count = 0;
preempt_enable(); put_cpu();
balance_dirty_pages(mapping); balance_dirty_pages(mapping);
return; return;
} }
preempt_enable(); put_cpu();
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment