Re: [patch V2 28/38] posix-cpu-timers: Restructure expiry array

2019-08-26 Thread Thomas Gleixner
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

2019-08-26 Thread Frederic Weisbecker
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

2019-08-26 Thread Thomas Gleixner
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

2019-08-26 Thread Frederic Weisbecker
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);
>  }
> 
>