Messages in this thread | | | Date | Wed, 10 May 2023 16:32:44 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH v2 2/2] sched/core: Avoid double calling update_rq_clock() |
| |
On Wed, May 10, 2023 at 04:34:50PM +0800, Hao Jia wrote: > There are some double rq clock update warnings are triggered. > ------------[ cut here ]------------ > rq->clock_update_flags & RQCF_UPDATED > WARNING: CPU: 17 PID: 138 at kernel/sched/core.c:741 > update_rq_clock+0xaf/0x180 > Call Trace: > <TASK> > __balance_push_cpu_stop+0x146/0x180 > ? migration_cpu_stop+0x2a0/0x2a0 > cpu_stopper_thread+0xa3/0x140 > smpboot_thread_fn+0x14f/0x210 > ? sort_range+0x20/0x20 > kthread+0xe6/0x110 > ? kthread_complete_and_exit+0x20/0x20 > ret_from_fork+0x1f/0x30 > > ------------[ cut here ]------------ > rq->clock_update_flags & RQCF_UPDATED > WARNING: CPU: 54 PID: 0 at kernel/sched/core.c:741 > update_rq_clock+0xaf/0x180 > Call Trace: > <TASK> > unthrottle_cfs_rq+0x4b/0x300 > __cfsb_csd_unthrottle+0xe0/0x100 > __flush_smp_call_function_queue+0xaf/0x1d0 > flush_smp_call_function_queue+0x49/0x90 > do_idle+0x17c/0x270 > cpu_startup_entry+0x19/0x20 > start_secondary+0xfa/0x120 > secondary_startup_64_no_verify+0xce/0xdb > > ------------[ cut here ]------------ > rq->clock_update_flags & RQCF_UPDATED > WARNING: CPU: 0 PID: 3323 at kernel/sched/core.c:741 > update_rq_clock+0xaf/0x180 > Call Trace: > <TASK> > unthrottle_cfs_rq+0x4b/0x300 > rq_offline_fair+0x89/0x90 > set_rq_offline.part.118+0x28/0x60 > rq_attach_root+0xc4/0xd0 > cpu_attach_domain+0x3dc/0x7f0 > partition_sched_domains_locked+0x2a5/0x3c0 > rebuild_sched_domains_locked+0x477/0x830 > rebuild_sched_domains+0x1b/0x30 > cpuset_hotplug_workfn+0x2ca/0xc90 > ? balance_push+0x56/0xf0 > ? _raw_spin_unlock+0x15/0x30 > ? finish_task_switch+0x98/0x2f0 > ? __switch_to+0x291/0x410 > ? __schedule+0x65e/0x1310 > process_one_work+0x1bc/0x3d0 > worker_thread+0x4c/0x380 > ? preempt_count_add+0x92/0xa0 > ? rescuer_thread+0x310/0x310 > kthread+0xe6/0x110 > ? kthread_complete_and_exit+0x20/0x20 > ret_from_fork+0x1f/0x30 > > For the __balance_push_cpu_stop() case, we remove update_rq_clock() from > the __migrate_task() function to avoid double updating the rq clock. > And in order to avoid missing rq clock update, add update_rq_clock() > call before migration_cpu_stop() calls __migrate_task(). > > For the unthrottle_cfs_rq() case, we use rq_clock_start_loop_update() to > prevent multiple calls to update_rq_clock() in unthrottle_cfs_rq(). > > Note that the rq clock has been updated before the set_rq_offline() > function runs, so we don't need to call update_rq_clock() in > unthrottle_offline_cfs_rqs().
This reads like 3 separate issues -- in which case this ought to be 3 separate patches.
> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index ec7b3e0a2b20..9c712f29e5a4 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -1536,6 +1536,27 @@ static inline void rq_clock_skip_update(struct rq *rq) > rq->clock_update_flags |= RQCF_REQ_SKIP; > } > > +/* > + * During cpu offlining and rq wide unthrottling, we can trigger > + * an update_rq_clock() for several cfs and rt runqueues (Typically > + * when using list_for_each_entry_*) > + * rq_clock_start_loop_update() can be called after updating the clock > + * once and before iterating over the list to prevent multiple update. > + * After the iterative traversal, we need to call rq_clock_stop_loop_update() > + * to restore rq->clock_update_flags. ^^^^^^^ > + */ > +static inline void rq_clock_start_loop_update(struct rq *rq) > +{ > + lockdep_assert_rq_held(rq); > + rq->clock_update_flags |= RQCF_ACT_SKIP; > +} > + > +static inline void rq_clock_stop_loop_update(struct rq *rq) > +{ > + lockdep_assert_rq_held(rq); > + rq->clock_update_flags &= ~RQCF_ACT_SKIP; > +}
This does not restore the flag, it clears the flag.
| |