···42244224 printk("\n%srcu_scheduler_active = %d, debug_locks = %d\n",42254225 !rcu_lockdep_current_cpu_online()42264226 ? "RCU used illegally from offline CPU!\n"42274227- : rcu_is_cpu_idle()42274227+ : !rcu_is_watching()42284228 ? "RCU used illegally from idle CPU!\n"42294229 : "",42304230 rcu_scheduler_active, debug_locks);···42474247 * So complain bitterly if someone does call rcu_read_lock(),42484248 * rcu_read_lock_bh() and so on from extended quiescent states.42494249 */42504250- if (rcu_is_cpu_idle())42504250+ if (!rcu_is_watching())42514251 printk("RCU used illegally from extended quiescent state!\n");4252425242534253 lockdep_print_held_locks(curr);
+1-1
kernel/rcupdate.c
···148148{149149 if (!debug_lockdep_rcu_enabled())150150 return 1;151151- if (rcu_is_cpu_idle())151151+ if (!rcu_is_watching())152152 return 0;153153 if (!rcu_lockdep_current_cpu_online())154154 return 0;
+5-5
kernel/rcutiny.c
···176176}177177EXPORT_SYMBOL_GPL(rcu_irq_enter);178178179179-#ifdef CONFIG_DEBUG_LOCK_ALLOC179179+#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)180180181181/*182182 * Test whether RCU thinks that the current CPU is idle.183183 */184184-int rcu_is_cpu_idle(void)184184+bool __rcu_is_watching(void)185185{186186- return !rcu_dynticks_nesting;186186+ return rcu_dynticks_nesting;187187}188188-EXPORT_SYMBOL(rcu_is_cpu_idle);188188+EXPORT_SYMBOL(__rcu_is_watching);189189190190-#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */190190+#endif /* defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */191191192192/*193193 * Test whether the current CPU was interrupted from idle. Nested
+18-5
kernel/rcutree.c
···650650}651651652652/**653653- * rcu_is_cpu_idle - see if RCU thinks that the current CPU is idle653653+ * __rcu_is_watching - are RCU read-side critical sections safe?654654+ *655655+ * Return true if RCU is watching the running CPU, which means that656656+ * this CPU can safely enter RCU read-side critical sections. Unlike657657+ * rcu_is_watching(), the caller of __rcu_is_watching() must have at658658+ * least disabled preemption.659659+ */660660+bool __rcu_is_watching(void)661661+{662662+ return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1;663663+}664664+665665+/**666666+ * rcu_is_watching - see if RCU thinks that the current CPU is idle654667 *655668 * If the current CPU is in its idle loop and is neither in an interrupt656669 * or NMI handler, return true.657670 */658658-int rcu_is_cpu_idle(void)671671+bool rcu_is_watching(void)659672{660673 int ret;661674662675 preempt_disable();663663- ret = (atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1) == 0;676676+ ret = __rcu_is_watching();664677 preempt_enable();665678 return ret;666679}667667-EXPORT_SYMBOL(rcu_is_cpu_idle);680680+EXPORT_SYMBOL_GPL(rcu_is_watching);668681669682#if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU)670683···23342321 * If called from an extended quiescent state, invoke the RCU23352322 * core in order to force a re-evaluation of RCU's idleness.23362323 */23372337- if (rcu_is_cpu_idle() && cpu_online(smp_processor_id()))23242324+ if (!rcu_is_watching() && cpu_online(smp_processor_id()))23382325 invoke_rcu_core();2339232623402327 /* If interrupts were disabled or CPU offline, don't invoke RCU core. */
+2
kernel/rcutree.h
···104104 /* idle-period nonlazy_posted snapshot. */105105 unsigned long last_accelerate;106106 /* Last jiffy CBs were accelerated. */107107+ unsigned long last_advance_all;108108+ /* Last jiffy CBs were all advanced. */107109 int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */108110#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */109111};
+13-11
kernel/rcutree_plugin.h
···16351635extern int tick_nohz_enabled;1636163616371637/*16381638- * Try to advance callbacks for all flavors of RCU on the current CPU.16391639- * Afterwards, if there are any callbacks ready for immediate invocation,16401640- * return true.16381638+ * Try to advance callbacks for all flavors of RCU on the current CPU, but16391639+ * only if it has been awhile since the last time we did so. Afterwards,16401640+ * if there are any callbacks ready for immediate invocation, return true.16411641 */16421642static bool rcu_try_advance_all_cbs(void)16431643{16441644 bool cbs_ready = false;16451645 struct rcu_data *rdp;16461646+ struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);16461647 struct rcu_node *rnp;16471648 struct rcu_state *rsp;16491649+16501650+ /* Exit early if we advanced recently. */16511651+ if (jiffies == rdtp->last_advance_all)16521652+ return 0;16531653+ rdtp->last_advance_all = jiffies;1648165416491655 for_each_rcu_flavor(rsp) {16501656 rdp = this_cpu_ptr(rsp->rda);···17501744 */17511745 if (rdtp->all_lazy &&17521746 rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) {17471747+ rdtp->all_lazy = false;17481748+ rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted;17531749 invoke_rcu_core();17541750 return;17551751 }···17811773 */17821774static void rcu_cleanup_after_idle(int cpu)17831775{17841784- struct rcu_data *rdp;17851785- struct rcu_state *rsp;1786177617871777 if (rcu_is_nocb_cpu(cpu))17881778 return;17891789- rcu_try_advance_all_cbs();17901790- for_each_rcu_flavor(rsp) {17911791- rdp = per_cpu_ptr(rsp->rda, cpu);17921792- if (cpu_has_callbacks_ready_to_invoke(rdp))17931793- invoke_rcu_core();17941794- }17791779+ if (rcu_try_advance_all_cbs())17801780+ invoke_rcu_core();17951781}1796178217971783/*