diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-12-31 18:42:26 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-12-31 18:42:26 -0500 |
commit | bd232f97b30f6bb630efa136a777647545db3039 (patch) | |
tree | 0dd55c07abfee9e1f4c83f9e8cbf853f817ff226 /kernel | |
parent | d036e67b40f52bdd95392390108defbac7e53837 (diff) |
cpumask: convert RCU implementations
Impact: use new cpumask API.
rcu_ctrlblk contains a cpumask, and it's highly optimized so I don't want
a cpumask_var_t (ie. a pointer) for the CONFIG_CPUMASK_OFFSTACK case. It
could use a dangling bitmap, and be allocated in __rcu_init to save memory,
but for the moment we use a bitmap.
(Eventually 'struct cpumask' will be undefined for CONFIG_CPUMASK_OFFSTACK,
so we use a bitmap here to show we really mean it).
We remove on-stack cpumasks, using cpumask_var_t for
rcu_torture_shuffle_tasks() and for_each_cpu_and in force_quiescent_state().
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/rcuclassic.c | 32 | ||||
-rw-r--r-- | kernel/rcupreempt.c | 19 | ||||
-rw-r--r-- | kernel/rcutorture.c | 27 |
3 files changed, 42 insertions, 36 deletions
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index e503a002f330..0ff9b05706a6 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c | |||
@@ -63,14 +63,14 @@ static struct rcu_ctrlblk rcu_ctrlblk = { | |||
63 | .completed = -300, | 63 | .completed = -300, |
64 | .pending = -300, | 64 | .pending = -300, |
65 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), | 65 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), |
66 | .cpumask = CPU_MASK_NONE, | 66 | .cpumask = CPU_BITS_NONE, |
67 | }; | 67 | }; |
68 | static struct rcu_ctrlblk rcu_bh_ctrlblk = { | 68 | static struct rcu_ctrlblk rcu_bh_ctrlblk = { |
69 | .cur = -300, | 69 | .cur = -300, |
70 | .completed = -300, | 70 | .completed = -300, |
71 | .pending = -300, | 71 | .pending = -300, |
72 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), | 72 | .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), |
73 | .cpumask = CPU_MASK_NONE, | 73 | .cpumask = CPU_BITS_NONE, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; | 76 | DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; |
@@ -85,7 +85,6 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
85 | struct rcu_ctrlblk *rcp) | 85 | struct rcu_ctrlblk *rcp) |
86 | { | 86 | { |
87 | int cpu; | 87 | int cpu; |
88 | cpumask_t cpumask; | ||
89 | unsigned long flags; | 88 | unsigned long flags; |
90 | 89 | ||
91 | set_need_resched(); | 90 | set_need_resched(); |
@@ -96,10 +95,10 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
96 | * Don't send IPI to itself. With irqs disabled, | 95 | * Don't send IPI to itself. With irqs disabled, |
97 | * rdp->cpu is the current cpu. | 96 | * rdp->cpu is the current cpu. |
98 | * | 97 | * |
99 | * cpu_online_map is updated by the _cpu_down() | 98 | * cpu_online_mask is updated by the _cpu_down() |
100 | * using __stop_machine(). Since we're in irqs disabled | 99 | * using __stop_machine(). Since we're in irqs disabled |
101 | * section, __stop_machine() is not exectuting, hence | 100 | * section, __stop_machine() is not exectuting, hence |
102 | * the cpu_online_map is stable. | 101 | * the cpu_online_mask is stable. |
103 | * | 102 | * |
104 | * However, a cpu might have been offlined _just_ before | 103 | * However, a cpu might have been offlined _just_ before |
105 | * we disabled irqs while entering here. | 104 | * we disabled irqs while entering here. |
@@ -107,13 +106,14 @@ static void force_quiescent_state(struct rcu_data *rdp, | |||
107 | * notification, leading to the offlined cpu's bit | 106 | * notification, leading to the offlined cpu's bit |
108 | * being set in the rcp->cpumask. | 107 | * being set in the rcp->cpumask. |
109 | * | 108 | * |
110 | * Hence cpumask = (rcp->cpumask & cpu_online_map) to prevent | 109 | * Hence cpumask = (rcp->cpumask & cpu_online_mask) to prevent |
111 | * sending smp_reschedule() to an offlined CPU. | 110 | * sending smp_reschedule() to an offlined CPU. |
112 | */ | 111 | */ |
113 | cpus_and(cpumask, rcp->cpumask, cpu_online_map); | 112 | for_each_cpu_and(cpu, |
114 | cpu_clear(rdp->cpu, cpumask); | 113 | to_cpumask(rcp->cpumask), cpu_online_mask) { |
115 | for_each_cpu_mask_nr(cpu, cpumask) | 114 | if (cpu != rdp->cpu) |
116 | smp_send_reschedule(cpu); | 115 | smp_send_reschedule(cpu); |
116 | } | ||
117 | } | 117 | } |
118 | spin_unlock_irqrestore(&rcp->lock, flags); | 118 | spin_unlock_irqrestore(&rcp->lock, flags); |
119 | } | 119 | } |
@@ -193,7 +193,7 @@ static void print_other_cpu_stall(struct rcu_ctrlblk *rcp) | |||
193 | 193 | ||
194 | printk(KERN_ERR "INFO: RCU detected CPU stalls:"); | 194 | printk(KERN_ERR "INFO: RCU detected CPU stalls:"); |
195 | for_each_possible_cpu(cpu) { | 195 | for_each_possible_cpu(cpu) { |
196 | if (cpu_isset(cpu, rcp->cpumask)) | 196 | if (cpumask_test_cpu(cpu, to_cpumask(rcp->cpumask))) |
197 | printk(" %d", cpu); | 197 | printk(" %d", cpu); |
198 | } | 198 | } |
199 | printk(" (detected by %d, t=%ld jiffies)\n", | 199 | printk(" (detected by %d, t=%ld jiffies)\n", |
@@ -221,7 +221,8 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp) | |||
221 | long delta; | 221 | long delta; |
222 | 222 | ||
223 | delta = jiffies - rcp->jiffies_stall; | 223 | delta = jiffies - rcp->jiffies_stall; |
224 | if (cpu_isset(smp_processor_id(), rcp->cpumask) && delta >= 0) { | 224 | if (cpumask_test_cpu(smp_processor_id(), to_cpumask(rcp->cpumask)) && |
225 | delta >= 0) { | ||
225 | 226 | ||
226 | /* We haven't checked in, so go dump stack. */ | 227 | /* We haven't checked in, so go dump stack. */ |
227 | print_cpu_stall(rcp); | 228 | print_cpu_stall(rcp); |
@@ -393,7 +394,8 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp) | |||
393 | * unnecessarily. | 394 | * unnecessarily. |
394 | */ | 395 | */ |
395 | smp_mb(); | 396 | smp_mb(); |
396 | cpus_andnot(rcp->cpumask, cpu_online_map, nohz_cpu_mask); | 397 | cpumask_andnot(to_cpumask(rcp->cpumask), |
398 | cpu_online_mask, &nohz_cpu_mask); | ||
397 | 399 | ||
398 | rcp->signaled = 0; | 400 | rcp->signaled = 0; |
399 | } | 401 | } |
@@ -406,8 +408,8 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp) | |||
406 | */ | 408 | */ |
407 | static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp) | 409 | static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp) |
408 | { | 410 | { |
409 | cpu_clear(cpu, rcp->cpumask); | 411 | cpumask_clear_cpu(cpu, to_cpumask(rcp->cpumask)); |
410 | if (cpus_empty(rcp->cpumask)) { | 412 | if (cpumask_empty(to_cpumask(rcp->cpumask))) { |
411 | /* batch completed ! */ | 413 | /* batch completed ! */ |
412 | rcp->completed = rcp->cur; | 414 | rcp->completed = rcp->cur; |
413 | rcu_start_batch(rcp); | 415 | rcu_start_batch(rcp); |
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 04982659875a..f9dc8f3720f6 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c | |||
@@ -164,7 +164,8 @@ static char *rcu_try_flip_state_names[] = | |||
164 | { "idle", "waitack", "waitzero", "waitmb" }; | 164 | { "idle", "waitack", "waitzero", "waitmb" }; |
165 | #endif /* #ifdef CONFIG_RCU_TRACE */ | 165 | #endif /* #ifdef CONFIG_RCU_TRACE */ |
166 | 166 | ||
167 | static cpumask_t rcu_cpu_online_map __read_mostly = CPU_MASK_NONE; | 167 | static DECLARE_BITMAP(rcu_cpu_online_map, NR_CPUS) __read_mostly |
168 | = CPU_BITS_NONE; | ||
168 | 169 | ||
169 | /* | 170 | /* |
170 | * Enum and per-CPU flag to determine when each CPU has seen | 171 | * Enum and per-CPU flag to determine when each CPU has seen |
@@ -758,7 +759,7 @@ rcu_try_flip_idle(void) | |||
758 | 759 | ||
759 | /* Now ask each CPU for acknowledgement of the flip. */ | 760 | /* Now ask each CPU for acknowledgement of the flip. */ |
760 | 761 | ||
761 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) { | 762 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) { |
762 | per_cpu(rcu_flip_flag, cpu) = rcu_flipped; | 763 | per_cpu(rcu_flip_flag, cpu) = rcu_flipped; |
763 | dyntick_save_progress_counter(cpu); | 764 | dyntick_save_progress_counter(cpu); |
764 | } | 765 | } |
@@ -776,7 +777,7 @@ rcu_try_flip_waitack(void) | |||
776 | int cpu; | 777 | int cpu; |
777 | 778 | ||
778 | RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); | 779 | RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); |
779 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 780 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
780 | if (rcu_try_flip_waitack_needed(cpu) && | 781 | if (rcu_try_flip_waitack_needed(cpu) && |
781 | per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { | 782 | per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { |
782 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); | 783 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); |
@@ -808,7 +809,7 @@ rcu_try_flip_waitzero(void) | |||
808 | /* Check to see if the sum of the "last" counters is zero. */ | 809 | /* Check to see if the sum of the "last" counters is zero. */ |
809 | 810 | ||
810 | RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); | 811 | RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); |
811 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 812 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
812 | sum += RCU_DATA_CPU(cpu)->rcu_flipctr[lastidx]; | 813 | sum += RCU_DATA_CPU(cpu)->rcu_flipctr[lastidx]; |
813 | if (sum != 0) { | 814 | if (sum != 0) { |
814 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); | 815 | RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); |
@@ -823,7 +824,7 @@ rcu_try_flip_waitzero(void) | |||
823 | smp_mb(); /* ^^^^^^^^^^^^ */ | 824 | smp_mb(); /* ^^^^^^^^^^^^ */ |
824 | 825 | ||
825 | /* Call for a memory barrier from each CPU. */ | 826 | /* Call for a memory barrier from each CPU. */ |
826 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) { | 827 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) { |
827 | per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; | 828 | per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; |
828 | dyntick_save_progress_counter(cpu); | 829 | dyntick_save_progress_counter(cpu); |
829 | } | 830 | } |
@@ -843,7 +844,7 @@ rcu_try_flip_waitmb(void) | |||
843 | int cpu; | 844 | int cpu; |
844 | 845 | ||
845 | RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); | 846 | RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); |
846 | for_each_cpu_mask_nr(cpu, rcu_cpu_online_map) | 847 | for_each_cpu(cpu, to_cpumask(rcu_cpu_online_map)) |
847 | if (rcu_try_flip_waitmb_needed(cpu) && | 848 | if (rcu_try_flip_waitmb_needed(cpu) && |
848 | per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { | 849 | per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { |
849 | RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); | 850 | RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); |
@@ -1032,7 +1033,7 @@ void rcu_offline_cpu(int cpu) | |||
1032 | RCU_DATA_CPU(cpu)->rcu_flipctr[0] = 0; | 1033 | RCU_DATA_CPU(cpu)->rcu_flipctr[0] = 0; |
1033 | RCU_DATA_CPU(cpu)->rcu_flipctr[1] = 0; | 1034 | RCU_DATA_CPU(cpu)->rcu_flipctr[1] = 0; |
1034 | 1035 | ||
1035 | cpu_clear(cpu, rcu_cpu_online_map); | 1036 | cpumask_clear_cpu(cpu, to_cpumask(rcu_cpu_online_map)); |
1036 | 1037 | ||
1037 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); | 1038 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); |
1038 | 1039 | ||
@@ -1072,7 +1073,7 @@ void __cpuinit rcu_online_cpu(int cpu) | |||
1072 | struct rcu_data *rdp; | 1073 | struct rcu_data *rdp; |
1073 | 1074 | ||
1074 | spin_lock_irqsave(&rcu_ctrlblk.fliplock, flags); | 1075 | spin_lock_irqsave(&rcu_ctrlblk.fliplock, flags); |
1075 | cpu_set(cpu, rcu_cpu_online_map); | 1076 | cpumask_set_cpu(cpu, to_cpumask(rcu_cpu_online_map)); |
1076 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); | 1077 | spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); |
1077 | 1078 | ||
1078 | /* | 1079 | /* |
@@ -1430,7 +1431,7 @@ void __init __rcu_init(void) | |||
1430 | * We don't need protection against CPU-Hotplug here | 1431 | * We don't need protection against CPU-Hotplug here |
1431 | * since | 1432 | * since |
1432 | * a) If a CPU comes online while we are iterating over the | 1433 | * a) If a CPU comes online while we are iterating over the |
1433 | * cpu_online_map below, we would only end up making a | 1434 | * cpu_online_mask below, we would only end up making a |
1434 | * duplicate call to rcu_online_cpu() which sets the corresponding | 1435 | * duplicate call to rcu_online_cpu() which sets the corresponding |
1435 | * CPU's mask in the rcu_cpu_online_map. | 1436 | * CPU's mask in the rcu_cpu_online_map. |
1436 | * | 1437 | * |
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index b31065522104..3245b40952c6 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
@@ -868,49 +868,52 @@ static int rcu_idle_cpu; /* Force all torture tasks off this CPU */ | |||
868 | */ | 868 | */ |
869 | static void rcu_torture_shuffle_tasks(void) | 869 | static void rcu_torture_shuffle_tasks(void) |
870 | { | 870 | { |
871 | cpumask_t tmp_mask; | 871 | cpumask_var_t tmp_mask; |
872 | int i; | 872 | int i; |
873 | 873 | ||
874 | cpus_setall(tmp_mask); | 874 | if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)) |
875 | BUG(); | ||
876 | |||
877 | cpumask_setall(tmp_mask); | ||
875 | get_online_cpus(); | 878 | get_online_cpus(); |
876 | 879 | ||
877 | /* No point in shuffling if there is only one online CPU (ex: UP) */ | 880 | /* No point in shuffling if there is only one online CPU (ex: UP) */ |
878 | if (num_online_cpus() == 1) { | 881 | if (num_online_cpus() == 1) |
879 | put_online_cpus(); | 882 | goto out; |
880 | return; | ||
881 | } | ||
882 | 883 | ||
883 | if (rcu_idle_cpu != -1) | 884 | if (rcu_idle_cpu != -1) |
884 | cpu_clear(rcu_idle_cpu, tmp_mask); | 885 | cpumask_clear_cpu(rcu_idle_cpu, tmp_mask); |
885 | 886 | ||
886 | set_cpus_allowed_ptr(current, &tmp_mask); | 887 | set_cpus_allowed_ptr(current, tmp_mask); |
887 | 888 | ||
888 | if (reader_tasks) { | 889 | if (reader_tasks) { |
889 | for (i = 0; i < nrealreaders; i++) | 890 | for (i = 0; i < nrealreaders; i++) |
890 | if (reader_tasks[i]) | 891 | if (reader_tasks[i]) |
891 | set_cpus_allowed_ptr(reader_tasks[i], | 892 | set_cpus_allowed_ptr(reader_tasks[i], |
892 | &tmp_mask); | 893 | tmp_mask); |
893 | } | 894 | } |
894 | 895 | ||
895 | if (fakewriter_tasks) { | 896 | if (fakewriter_tasks) { |
896 | for (i = 0; i < nfakewriters; i++) | 897 | for (i = 0; i < nfakewriters; i++) |
897 | if (fakewriter_tasks[i]) | 898 | if (fakewriter_tasks[i]) |
898 | set_cpus_allowed_ptr(fakewriter_tasks[i], | 899 | set_cpus_allowed_ptr(fakewriter_tasks[i], |
899 | &tmp_mask); | 900 | tmp_mask); |
900 | } | 901 | } |
901 | 902 | ||
902 | if (writer_task) | 903 | if (writer_task) |
903 | set_cpus_allowed_ptr(writer_task, &tmp_mask); | 904 | set_cpus_allowed_ptr(writer_task, tmp_mask); |
904 | 905 | ||
905 | if (stats_task) | 906 | if (stats_task) |
906 | set_cpus_allowed_ptr(stats_task, &tmp_mask); | 907 | set_cpus_allowed_ptr(stats_task, tmp_mask); |
907 | 908 | ||
908 | if (rcu_idle_cpu == -1) | 909 | if (rcu_idle_cpu == -1) |
909 | rcu_idle_cpu = num_online_cpus() - 1; | 910 | rcu_idle_cpu = num_online_cpus() - 1; |
910 | else | 911 | else |
911 | rcu_idle_cpu--; | 912 | rcu_idle_cpu--; |
912 | 913 | ||
914 | out: | ||
913 | put_online_cpus(); | 915 | put_online_cpus(); |
916 | free_cpumask_var(tmp_mask); | ||
914 | } | 917 | } |
915 | 918 | ||
916 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the | 919 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the |