Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rcu: Refactor rcu_barrier() empty-list handling

This commit saves a few lines by checking first for an empty callback
list. If the callback list is empty, then that CPU is taken care of,
regardless of its online or nocb state. Also simplify tracing accordingly
and fold a few lines together.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>

+12 -22
+4 -5
include/trace/events/rcu.h
··· 794 794 * Tracepoint for rcu_barrier() execution. The string "s" describes 795 795 * the rcu_barrier phase: 796 796 * "Begin": rcu_barrier() started. 797 + * "CB": An rcu_barrier_callback() invoked a callback, not the last. 797 798 * "EarlyExit": rcu_barrier() piggybacked, thus early exit. 798 799 * "Inc1": rcu_barrier() piggyback check counter incremented. 799 - * "OfflineNoCBQ": rcu_barrier() found offline no-CBs CPU with callbacks. 800 - * "OnlineQ": rcu_barrier() found online CPU with callbacks. 801 - * "OnlineNQ": rcu_barrier() found online CPU, no callbacks. 800 + * "Inc2": rcu_barrier() piggyback check counter incremented. 802 801 * "IRQ": An rcu_barrier_callback() callback posted on remote CPU. 803 802 * "IRQNQ": An rcu_barrier_callback() callback found no callbacks. 804 - * "CB": An rcu_barrier_callback() invoked a callback, not the last. 805 803 * "LastCB": An rcu_barrier_callback() invoked the last callback. 806 - * "Inc2": rcu_barrier() piggyback check counter incremented. 804 + * "NQ": rcu_barrier() found a CPU with no callbacks. 805 + * "OnlineQ": rcu_barrier() found online CPU with callbacks. 807 806 * The "cpu" argument is the CPU or -1 if meaningless, the "cnt" argument 808 807 * is the count of remaining callbacks, and "done" is the piggybacking count. 809 808 */
+8 -17
kernel/rcu/tree.c
··· 4030 4030 4031 4031 /* Did someone else do our work for us? */ 4032 4032 if (rcu_seq_done(&rcu_state.barrier_sequence, s)) { 4033 - rcu_barrier_trace(TPS("EarlyExit"), -1, 4034 - rcu_state.barrier_sequence); 4033 + rcu_barrier_trace(TPS("EarlyExit"), -1, rcu_state.barrier_sequence); 4035 4034 smp_mb(); /* caller's subsequent code after above check. */ 4036 4035 mutex_unlock(&rcu_state.barrier_mutex); 4037 4036 return; ··· 4058 4059 */ 4059 4060 for_each_possible_cpu(cpu) { 4060 4061 rdp = per_cpu_ptr(&rcu_data, cpu); 4061 - if (cpu_is_offline(cpu) && 4062 - !rcu_rdp_is_offloaded(rdp)) 4062 + if (!rcu_segcblist_n_cbs(&rdp->cblist)) { 4063 + rcu_barrier_trace(TPS("NQ"), cpu, rcu_state.barrier_sequence); 4063 4064 continue; 4064 - if (rcu_segcblist_n_cbs(&rdp->cblist) && cpu_online(cpu)) { 4065 - rcu_barrier_trace(TPS("OnlineQ"), cpu, 4066 - rcu_state.barrier_sequence); 4065 + } 4066 + if (cpu_online(cpu)) { 4067 + rcu_barrier_trace(TPS("OnlineQ"), cpu, rcu_state.barrier_sequence); 4067 4068 smp_call_function_single(cpu, rcu_barrier_func, (void *)cpu, 1); 4068 - } else if (rcu_segcblist_n_cbs(&rdp->cblist) && 4069 - cpu_is_offline(cpu)) { 4070 - rcu_barrier_trace(TPS("OfflineNoCBQ"), cpu, 4071 - rcu_state.barrier_sequence); 4069 + } else { 4070 + rcu_barrier_trace(TPS("OfflineNoCBQ"), cpu, rcu_state.barrier_sequence); 4072 4071 local_irq_disable(); 4073 4072 rcu_barrier_func((void *)cpu); 4074 4073 local_irq_enable(); 4075 - } else if (cpu_is_offline(cpu)) { 4076 - rcu_barrier_trace(TPS("OfflineNoCBNoQ"), cpu, 4077 - rcu_state.barrier_sequence); 4078 - } else { 4079 - rcu_barrier_trace(TPS("OnlineNQ"), cpu, 4080 - rcu_state.barrier_sequence); 4081 4074 } 4082 4075 } 4083 4076 cpus_read_unlock();