Re: [patch V2 28/38] posix-cpu-timers: Restructure expiry array
On Mon, 26 Aug 2019, Frederic Weisbecker wrote: > On Wed, Aug 21, 2019 at 09:09:15PM +0200, Thomas Gleixner wrote: > > @@ -884,7 +888,7 @@ static void check_process_timers(struct > > struct list_head *firing) > > { > > struct signal_struct *const sig = tsk->signal; > > - struct list_head *timers = sig->posix_cputimers.cpu_timers; > > + struct posix_cputimer_base *base = sig->posix_cputimers.bases; > > u64 utime, ptime, virt_expires, prof_expires; > > u64 sum_sched_runtime, sched_expires; > > struct task_cputime cputime; > > @@ -912,9 +916,12 @@ static void check_process_timers(struct > > ptime = utime + cputime.stime; > > sum_sched_runtime = cputime.sum_exec_runtime; > > > > - prof_expires = check_timers_list(timers, firing, ptime); > > - virt_expires = check_timers_list(++timers, firing, utime); > > - sched_expires = check_timers_list(++timers, firing, sum_sched_runtime); > > + prof_expires = check_timers_list([CPUCLOCK_PROF].cpu_timers, > > +firing, ptime); > > + virt_expires = check_timers_list([CPUCLOCK_VIRT].cpu_timers, > > +firing, utime); > > + sched_expires = check_timers_list([CLPCLOCK_SCHED].cpu_timers, > > ^^ > 0-day bot should have warned by now. It didn't but my own testing found it and I fixed it locally already
Re: [patch V2 28/38] posix-cpu-timers: Restructure expiry array
On Wed, Aug 21, 2019 at 09:09:15PM +0200, Thomas Gleixner wrote: > @@ -884,7 +888,7 @@ static void check_process_timers(struct >struct list_head *firing) > { > struct signal_struct *const sig = tsk->signal; > - struct list_head *timers = sig->posix_cputimers.cpu_timers; > + struct posix_cputimer_base *base = sig->posix_cputimers.bases; > u64 utime, ptime, virt_expires, prof_expires; > u64 sum_sched_runtime, sched_expires; > struct task_cputime cputime; > @@ -912,9 +916,12 @@ static void check_process_timers(struct > ptime = utime + cputime.stime; > sum_sched_runtime = cputime.sum_exec_runtime; > > - prof_expires = check_timers_list(timers, firing, ptime); > - virt_expires = check_timers_list(++timers, firing, utime); > - sched_expires = check_timers_list(++timers, firing, sum_sched_runtime); > + prof_expires = check_timers_list([CPUCLOCK_PROF].cpu_timers, > + firing, ptime); > + virt_expires = check_timers_list([CPUCLOCK_VIRT].cpu_timers, > + firing, utime); > + sched_expires = check_timers_list([CLPCLOCK_SCHED].cpu_timers, ^^ 0-day bot should have warned by now.
Re: [patch V2 28/38] posix-cpu-timers: Restructure expiry array
On Mon, 26 Aug 2019, Frederic Weisbecker wrote: > On Wed, Aug 21, 2019 at 09:09:15PM +0200, Thomas Gleixner wrote: > > /** > > - * task_cputimers_expired - Compare two task_cputime entities. > > + * task_cputimers_expired - Check whether posix CPU timers are expired > > * > > * @samples: Array of current samples for the CPUCLOCK clocks > > - * @expiries: Array of expiry values for the CPUCLOCK clocks > > + * @pct: Pointer to a posix_cputimers container > > * > > - * Returns true if any mmember of @samples is greater than the > > corresponding > > - * member of @expiries if that member is non zero. False otherwise > > + * Returns true if any member of @samples is greater than the corresponding > > + * member of @pct->bases[CLK].nextevt. False otherwise > > */ > > -static inline bool task_cputimers_expired(const u64 *sample, const u64 > > *expiries) > > +static inline bool > > +task_cputimers_expired(const u64 *sample, struct posix_cputimers *pct) > > { > > int i; > > > > for (i = 0; i < CPUCLOCK_MAX; i++) { > > - if (expiries[i] && sample[i] >= expiries[i]) > > + if (sample[i] >= pct->bases[i].nextevt) > > You may have false positive here if you don't check if pct->bases[i].nextevt > is 0. Probably no big deal by the end of the series since you change that 0 > for KTIME_MAX later but right now it might hurt bisection with performance > issues (locking sighand at every tick...). Hrm. That should have stayed until the patch which removes that 0 state > [...] > > > @@ -1176,7 +1182,7 @@ void run_posix_cpu_timers(void) > > void set_process_cpu_timer(struct task_struct *tsk, unsigned int clkid, > >u64 *newval, u64 *oldval) > > { > > - u64 now, *expiry = tsk->signal->posix_cputimers.expiries + clkid; > > + u64 now, *nextevt = >signal->posix_cputimers.bases[clkid].nextevt; > > You're dereferencing the pointer before checking clkid sanity below. Urgh. Yes. Thanks, tglx
Re: [patch V2 28/38] posix-cpu-timers: Restructure expiry array
On Wed, Aug 21, 2019 at 09:09:15PM +0200, Thomas Gleixner wrote: > /** > - * task_cputimers_expired - Compare two task_cputime entities. > + * task_cputimers_expired - Check whether posix CPU timers are expired > * > * @samples: Array of current samples for the CPUCLOCK clocks > - * @expiries:Array of expiry values for the CPUCLOCK clocks > + * @pct: Pointer to a posix_cputimers container > * > - * Returns true if any mmember of @samples is greater than the corresponding > - * member of @expiries if that member is non zero. False otherwise > + * Returns true if any member of @samples is greater than the corresponding > + * member of @pct->bases[CLK].nextevt. False otherwise > */ > -static inline bool task_cputimers_expired(const u64 *sample, const u64 > *expiries) > +static inline bool > +task_cputimers_expired(const u64 *sample, struct posix_cputimers *pct) > { > int i; > > for (i = 0; i < CPUCLOCK_MAX; i++) { > - if (expiries[i] && sample[i] >= expiries[i]) > + if (sample[i] >= pct->bases[i].nextevt) You may have false positive here if you don't check if pct->bases[i].nextevt is 0. Probably no big deal by the end of the series since you change that 0 for KTIME_MAX later but right now it might hurt bisection with performance issues (locking sighand at every tick...). [...] > @@ -1176,7 +1182,7 @@ void run_posix_cpu_timers(void) > void set_process_cpu_timer(struct task_struct *tsk, unsigned int clkid, > u64 *newval, u64 *oldval) > { > - u64 now, *expiry = tsk->signal->posix_cputimers.expiries + clkid; > + u64 now, *nextevt = >signal->posix_cputimers.bases[clkid].nextevt; You're dereferencing the pointer before checking clkid sanity below. > > if (WARN_ON_ONCE(clkid >= CPUCLOCK_SCHED)) > return; > @@ -1207,8 +1213,8 @@ void set_process_cpu_timer(struct task_s >* Update expiration cache if this is the earliest timer. CPUCLOCK_PROF >* expiry cache is also used by RLIMIT_CPU!. >*/ > - if (expires_gt(*expiry, *newval)) > - *expiry = *newval; > + if (expires_gt(*nextevt, *newval)) > + *nextevt = *newval; > > tick_dep_set_signal(tsk->signal, TICK_DEP_BIT_POSIX_TIMER); > } > >