Eliminate redundant rcu_sysidle_state variable
RFC PATCH 1/2 Eliminate redundant rcu_sysidle_state variable
Now that we have rcu_state_p, which references rcu_preempt_state for TREE_PREEMPT_RCU and rcu_sched_state for TREE_RCU, we don't need a separate rcu_sysidle_state variable. This commit therefore eliminates rcu_preempt_state in favor of rcu_state_p.
kernel/rcu/tree_plugin.h +6 -17
@@ -2662,16 +2662,6 @@ static void __maybe_unused rcu_kick_nohz_cpu(int cpu)#ifdef CONFIG_NO_HZ_FULL_SYSIDLE -/* -* Define RCU flavor that holds sysidle state. This needs to be the -* most active flavor of RCU. -*/ -#ifdef CONFIG_PREEMPT_RCU -static struct rcu_state *rcu_sysidle_state = &rcu_preempt_state; -#else /* #ifdef CONFIG_PREEMPT_RCU */ -static struct rcu_state *rcu_sysidle_state = &rcu_sched_state; -#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ -static int full_sysidle_state;/* Current system-idle state. */ #define RCU_SYSIDLE_NOT 0/* Some CPU is not idle. */ #define RCU_SYSIDLE_SHORT 1/* All CPUs idle for brief period. */
@@ -2813,7 +2803,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,* not the flavor of RCU that tracks sysidle state, or if this * is an offline or the timekeeping CPU, nothing to do. */ -if (!*isidle || rdp->rsp != rcu_sysidle_state || +if (!*isidle || rdp->rsp != rcu_state_p ||cpu_is_offline (rdp->cpu) || rdp->cpu == tick_do_timer_cpu)return ;if (rcu_gp_in_progress (rdp->rsp))
@@ -2839,7 +2829,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,*/ static bool is_sysidle_rcu_state (struct rcu_state *rsp) { -return rsp == rcu_sysidle_state; +return rsp == rcu_state_p; }/*
@@ -2917,7 +2907,7 @@ static void rcu_sysidle_cancel(void)static void rcu_sysidle_report (struct rcu_state *rsp,int isidle,unsigned long maxj,bool gpkt) { -if (rsp != rcu_sysidle_state) +if (rsp != rcu_state_p)return ;/* Wrong flavor, ignore. */ if (gpkt && nr_cpu_ids <=CONFIG_NO_HZ_FULL_SYSIDLE_SMALL )return ;/* Running state machine from timekeeping CPU. */
@@ -2986,13 +2976,12 @@ bool rcu_sys_is_idle(void)/* Scan all the CPUs looking for nonidle CPUs. */ for_each_possible_cpu (cpu) { - rdp =per_cpu_ptr (rcu_sysidle_state->rda, cpu); + rdp =per_cpu_ptr (rcu_state_p->rda, cpu);rcu_sysidle_check_cpu (rdp, &isidle, &maxj);if (!isidle)break ; } -rcu_sysidle_report (rcu_sysidle_state, - isidle, maxj, false); +rcu_sysidle_report (rcu_state_p, isidle, maxj, false); oldrss = rss; rss =ACCESS_ONCE (full_sysidle_state); }
@@ -3019,7 +3008,7 @@ bool rcu_sys_is_idle(void)* provided by the memory allocator. */ if (nr_cpu_ids >CONFIG_NO_HZ_FULL_SYSIDLE_SMALL && - !rcu_gp_in_progress (rcu_sysidle_state) && + !rcu_gp_in_progress (rcu_state_p) && !rsh.inuse &&xchg (&rsh.inuse,1 ) ==0 )call_rcu (&rsh.rh, rcu_sysidle_cb);return false;
RFC PATCH 2/2 Don't track sysidle state if no nohz_full= CPUs
If there are no nohz_full= CPUs, then there is currently no reason to track sysidle state. This commit therefore short-circuits this state tracking if !tick_nohz_full_enabled().
Note that these checks will need to be revisited if nohz_full= state can ever be changed at runtime.
kernel/rcu/tree_plugin.h +18 -1
@@ -2679,6 +2679,10 @@ static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq) {unsigned long j; +/* If there are no nohz_full= CPUs, no need to track this. */ +if (!tick_nohz_full_enabled ()) +return ; +/* Adjust nesting, check for fully idle. */ if (irq) { rdtp->dynticks_idle_nesting--;
@@ -2744,6 +2748,10 @@ void rcu_sysidle_force_exit(void)*/ static void rcu_sysidle_exit (struct rcu_dynticks *rdtp,int irq) { +/* If there are no nohz_full= CPUs, no need to track this. */ +if (!tick_nohz_full_enabled ()) +return ; +/* Adjust nesting, check for already non-idle. */ if (irq) { rdtp->dynticks_idle_nesting++;
@@ -2798,6 +2806,10 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,unsigned long j;struct rcu_dynticks *rdtp = rdp->dynticks; +/* If there are no nohz_full= CPUs, don't check system-wide idleness. */ +if (!tick_nohz_full_enabled ()) +return ; +/* * If some other CPU has already reported non-idle, if this is * not the flavor of RCU that tracks sysidle state, or if this
@@ -2924,6 +2936,10 @@ static void rcu_sysidle_report(struct rcu_state *rsp, int isidle,static void rcu_sysidle_report_gp (struct rcu_state *rsp,int isidle,unsigned long maxj) { +/* If there are no nohz_full= CPUs, no need to track this. */ +if (!tick_nohz_full_enabled ()) +return ; +rcu_sysidle_report (rsp, isidle, maxj, true); }
@@ -2950,7 +2966,8 @@ static void rcu_sysidle_cb(struct rcu_head *rhp)/* * Check to see if the system is fully idle, other than the timekeeping CPU. -* The caller must have disabled interrupts. +* The caller must have disabled interrupts. This is not intended to be +* called unless tick_nohz_full_enabled(). */ bool rcu_sys_is_idle (void ) {
Re: [PATCH RFC tip/core/rcu 2/2] Don't track sysidle state if no nohz_full= CPUs
Quoted 8 lines · Paul E. McKenney
If there are no nohz_full= CPUs, then there is currently no reason to track sysidle state. This commit therefore short-circuits this state tracking if !tick_nohz_full_enabled().
Note that these checks will need to be revisited if nohz_full= state can ever be changed at runtime.
Signed-off-by Paul E. McKenney <[email protected]>
Quoted 7 lines · Paul E. McKenney
Now that we have
rcu_state_p, which referencesrcu_preempt_stateforTREE_PREEMPT_RCUandrcu_sched_stateforTREE_RCU, we don't need a separatercu_sysidle_statevariable. This commit therefore eliminatesrcu_preempt_statein favor ofrcu_state_p.Signed-off-by Paul E. McKenney <[email protected]>
Quoted 74 lines
kernel/rcu/tree_plugin.h +6
-17@@ -2662,16 +2662,6 @@ static void __maybe_unused rcu_kick_nohz_cpu(int cpu)#ifdef CONFIG_NO_HZ_FULL_SYSIDLE -/* -* Define RCU flavor that holds sysidle state. This needs to be the -* most active flavor of RCU. -*/ -#ifdef CONFIG_PREEMPT_RCU -static struct rcu_state *rcu_sysidle_state = &rcu_preempt_state; -#else /* #ifdef CONFIG_PREEMPT_RCU */ -static struct rcu_state *rcu_sysidle_state = &rcu_sched_state; -#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ -static int full_sysidle_state;/* Current system-idle state. */ #define RCU_SYSIDLE_NOT 0/* Some CPU is not idle. */ #define RCU_SYSIDLE_SHORT 1/* All CPUs idle for brief period. */ @@ -2813,7 +2803,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,* not the flavor of RCU that tracks sysidle state, or if this * is an offline or the timekeeping CPU, nothing to do. */ -if (!*isidle || rdp->rsp != rcu_sysidle_state || +if (!*isidle || rdp->rsp != rcu_state_p ||cpu_is_offline (rdp->cpu) || rdp->cpu == tick_do_timer_cpu)return ;if (rcu_gp_in_progress (rdp->rsp))@@ -2839,7 +2829,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,*/ static bool is_sysidle_rcu_state (struct rcu_state *rsp) { -return rsp == rcu_sysidle_state; +return rsp == rcu_state_p; }/* @@ -2917,7 +2907,7 @@ static void rcu_sysidle_cancel(void)static void rcu_sysidle_report (struct rcu_state *rsp,int isidle,unsigned long maxj,bool gpkt) { -if (rsp != rcu_sysidle_state) +if (rsp != rcu_state_p)return ;/* Wrong flavor, ignore. */ if (gpkt && nr_cpu_ids <=CONFIG_NO_HZ_FULL_SYSIDLE_SMALL )return ;/* Running state machine from timekeeping CPU. */ @@ -2986,13 +2976,12 @@ bool rcu_sys_is_idle(void)/* Scan all the CPUs looking for nonidle CPUs. */ for_each_possible_cpu (cpu) { - rdp =per_cpu_ptr (rcu_sysidle_state->rda, cpu); + rdp =per_cpu_ptr (rcu_state_p->rda, cpu);rcu_sysidle_check_cpu (rdp, &isidle, &maxj);if (!isidle)break ; } -rcu_sysidle_report (rcu_sysidle_state, - isidle, maxj, false); +rcu_sysidle_report (rcu_state_p, isidle, maxj, false); oldrss = rss; rss =ACCESS_ONCE (full_sysidle_state); }@@ -3019,7 +3008,7 @@ bool rcu_sys_is_idle(void)* provided by the memory allocator. */ if (nr_cpu_ids >CONFIG_NO_HZ_FULL_SYSIDLE_SMALL && - !rcu_gp_in_progress (rcu_sysidle_state) && + !rcu_gp_in_progress (rcu_state_p) && !rsh.inuse &&xchg (&rsh.inuse,1 ) ==0 )call_rcu (&rsh.rh, rcu_sysidle_cb);return false;
Signature · 1 line
Pranith
Quoted 6 lines · Paul E. McKenney
Now that we have
rcu_state_p, which referencesrcu_preempt_stateforTREE_PREEMPT_RCUandrcu_sched_stateforTREE_RCU, we don't need a separatercu_sysidle_statevariable. This commit therefore eliminatesrcu_preempt_statein favor ofrcu_state_p.Signed-off-by Paul E. McKenney <[email protected]>
Quoted 75 lines
kernel/rcu/tree_plugin.h +6
-17@@ -2662,16 +2662,6 @@ static void __maybe_unused rcu_kick_nohz_cpu(int cpu)#ifdef CONFIG_NO_HZ_FULL_SYSIDLE -/* -* Define RCU flavor that holds sysidle state. This needs to be the -* most active flavor of RCU. -*/ -#ifdef CONFIG_PREEMPT_RCU -static struct rcu_state *rcu_sysidle_state = &rcu_preempt_state; -#else /* #ifdef CONFIG_PREEMPT_RCU */ -static struct rcu_state *rcu_sysidle_state = &rcu_sched_state; -#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ -static int full_sysidle_state;/* Current system-idle state. */ #define RCU_SYSIDLE_NOT 0/* Some CPU is not idle. */ #define RCU_SYSIDLE_SHORT 1/* All CPUs idle for brief period. */ @@ -2813,7 +2803,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,* not the flavor of RCU that tracks sysidle state, or if this * is an offline or the timekeeping CPU, nothing to do. */ -if (!*isidle || rdp->rsp != rcu_sysidle_state || +if (!*isidle || rdp->rsp != rcu_state_p ||cpu_is_offline (rdp->cpu) || rdp->cpu == tick_do_timer_cpu)return ;if (rcu_gp_in_progress (rdp->rsp))@@ -2839,7 +2829,7 @@ static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,*/ static bool is_sysidle_rcu_state (struct rcu_state *rsp) { -return rsp == rcu_sysidle_state; +return rsp == rcu_state_p; }/* @@ -2917,7 +2907,7 @@ static void rcu_sysidle_cancel(void)static void rcu_sysidle_report (struct rcu_state *rsp,int isidle,unsigned long maxj,bool gpkt) { -if (rsp != rcu_sysidle_state) +if (rsp != rcu_state_p)return ;/* Wrong flavor, ignore. */ if (gpkt && nr_cpu_ids <=CONFIG_NO_HZ_FULL_SYSIDLE_SMALL )return ;/* Running state machine from timekeeping CPU. */ @@ -2986,13 +2976,12 @@ bool rcu_sys_is_idle(void)/* Scan all the CPUs looking for nonidle CPUs. */ for_each_possible_cpu (cpu) { - rdp =per_cpu_ptr (rcu_sysidle_state->rda, cpu); + rdp =per_cpu_ptr (rcu_state_p->rda, cpu);rcu_sysidle_check_cpu (rdp, &isidle, &maxj);if (!isidle)break ; } -rcu_sysidle_report (rcu_sysidle_state, - isidle, maxj, false); +rcu_sysidle_report (rcu_state_p, isidle, maxj, false); oldrss = rss; rss =ACCESS_ONCE (full_sysidle_state); }@@ -3019,7 +3008,7 @@ bool rcu_sys_is_idle(void)* provided by the memory allocator. */ if (nr_cpu_ids >CONFIG_NO_HZ_FULL_SYSIDLE_SMALL && - !rcu_gp_in_progress (rcu_sysidle_state) && + !rcu_gp_in_progress (rcu_state_p) && !rsh.inuse &&xchg (&rsh.inuse,1 ) ==0 )call_rcu (&rsh.rh, rcu_sysidle_cb);return false;