On Fri, Apr 08, 2016 at 03:07:12AM +0200, Frederic Weisbecker wrote: > +void cpu_load_update_nohz_start(void) > { > struct rq *this_rq = this_rq(); > + > + /* > + * This is all lockless but should be fine. If weighted_cpuload changes > + * concurrently we'll exit nohz. And cpu_load write can race with > + * cpu_load_update_idle() but both updater would be writing the same. > + */ > + this_rq->cpu_load[0] = weighted_cpuload(cpu_of(this_rq)); > +}
There is more to this; this also updates ->cpu_load[0] at possibly much higher frequency than we've done before, while not updating the other ->cpu_load[] members. Now, I'm not sure we care, but it is a bit odd. > +/* > + * Account the tickless load in the end of a nohz frame. > + */ > +void cpu_load_update_nohz_stop(void) > +{ > unsigned long curr_jiffies = READ_ONCE(jiffies); > + struct rq *this_rq = this_rq(); > + unsigned long load; > > if (curr_jiffies == this_rq->last_load_update_tick) > return; > > + load = weighted_cpuload(cpu_of(this_rq)); > raw_spin_lock(&this_rq->lock); > + cpu_load_update_nohz(this_rq, curr_jiffies, load); > raw_spin_unlock(&this_rq->lock); > } And this makes us take rq->lock when waking from nohz; a bit unfortunate. Do we really need this though? Will not a tick be forthcoming real-soon-now?