]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] get/put_cpu methods
authorRobert Love <rml@tech9.net>
Tue, 21 May 2002 10:21:43 +0000 (03:21 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 21 May 2002 10:21:43 +0000 (03:21 -0700)
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.

Documentation/preempt-locking.txt
include/linux/smp.h
mm/page-writeback.c

index 08e2b4719a237ef9081528aca8aaac513bcb9ec4..a9eac1c15718b514ac76ccfae0734da281dfbf2a 100644 (file)
@@ -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
 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.
 
index 85c6273694c9b3bdd4c71344d7cdacac21aec349..b61435d369c8a162babfc36eba7c9130e1f8b264 100644 (file)
@@ -96,5 +96,9 @@ static inline void smp_send_reschedule_all(void) { }
 #define per_cpu(var, cpu)                      var
 #define this_cpu(var)                          var
 
-#endif
-#endif
+#endif /* !SMP */
+
+#define get_cpu()      ({ preempt_disable(); smp_processor_id(); })
+#define put_cpu()      preempt_enable()
+
+#endif /* __LINUX_SMP_H */
index 725a4bdb60e103aeaf59d79e3d19bc08621a89c2..3918260b0c6abe1bf5d817b68bdb504600b4689f 100644 (file)
@@ -117,15 +117,14 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping)
        } ____cacheline_aligned ratelimits[NR_CPUS];
        int cpu;
 
-       preempt_disable();
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        if (ratelimits[cpu].count++ >= 1000) {
                ratelimits[cpu].count = 0;
-               preempt_enable();
+               put_cpu();
                balance_dirty_pages(mapping);
                return;
        }
-       preempt_enable();
+       put_cpu();
 }
 
 /*