Re: process: annotate locking for setitimer(2) state

2020-08-11 Thread Anton Lindqvist
On Sun, Aug 09, 2020 at 05:33:58PM +0200, Mark Kettenis wrote:
> > Date: Sun, 9 Aug 2020 10:02:38 -0500
> > From: Scott Cheloha 
> > 
> > On Sun, Aug 09, 2020 at 04:43:24PM +0200, Mark Kettenis wrote:
> > > > Date: Sat, 8 Aug 2020 19:46:14 -0500
> > > > From: Scott Cheloha 
> > > > 
> > > > Hi,
> > > > 
> > > > I want to annotate the locking for the per-process interval timers.
> > > > 
> > > > In the process struct, the ITIMER_REAL itimerspec and the ps_itimer_to
> > > > timeout are protected by the kernel lock.  These should be annotated
> > > > with "K", right?
> > > > 
> > > > Also in the process struct, the ITIMER_VIRTUAL and ITIMER_PROF
> > > > itimerspecs are protected by the global itimer_mtx.
> > > > 
> > > > However, I don't think "itimer_mtx" isn't the best name for it, as it
> > > > doesn't protect state for *all* per-process interval timers.  Just the
> > > > virtual ones.
> > > > 
> > > > Could I rename the mutex to "virtual_itimer_mtx"?  Then I can annotate
> > > > the state protected by it with "V", as shown here in this patch.
> > > 
> > > That's quite a long variable name though.  And it also protects
> > > ITIMER_PROF.  So I'd say the name would be at least as misleading as
> > > the current one and perhaps even more so.  You can just use "I" as the
> > > annotation perhaps?
> > 
> > The convention is to use "I" for immutable variables.  We do it
> > everywhere.  I don't think we should buck convention here.
> > 
> > I also proposed using "i" in a prior patch to annotate these
> > variables, but mpi@ said it was too close to "I".  Also, it's a global
> > lock, and we have settled on only annotate global locks with capital
> > letters.
> > 
> > If you don't want to rename the mutex I guess we could use "T" for
> > "timer".  We use "T" for other global locks (tc_lock, timeout_mutex)
> > but not in this context.
> > 
> > However, there are only so many letters.  Eventually this scheme will
> > run afoul of that limitation.  An idea I had re. the letter shortage
> > was to use two letters where necessary.  So instead of "I" you could
> > use "It" for "itimer".  We annotate locking hierarchies with commas so
> > there isn't an ambiguity when reading it.
> > 
> > For example, if the code for writing a hypothetical "ps_foo" process
> > struct member was:
> > 
> > KERNEL_LOCK();
> > mtx_enter(_mtx);
> > ps.ps_foo = 10;
> > mtx_leave(_mtx);
> > KERNEL_UNLOCK();
> > 
> > You could annotate it like this:
> > 
> > /*
> >  * Locks used to protect process struct members:
> >  *
> >  *  It  itimer_mtx
> >  *  K   kernel lock
> >  */
> > struct process {
> > /* [...] */
> > int ps_foo; /* [K,It] per-process foobar */
> > /* [...] */
> > };
> > 
> > anton@, mpi@: is that too radical or easily misread?
> > 
> > Sorry if this all seems fussy, but I'd like to get this right the
> > first time.
> 
> 'T' is fine with me.  But I'm clearly not an authority here.  Anyway,
> renaming variables because you don't have a matching letter to
> annotate the lock doesn't feel right.

I'm also fine with T.



Re: process: annotate locking for setitimer(2) state

2020-08-09 Thread Mark Kettenis
> Date: Sun, 9 Aug 2020 10:02:38 -0500
> From: Scott Cheloha 
> 
> On Sun, Aug 09, 2020 at 04:43:24PM +0200, Mark Kettenis wrote:
> > > Date: Sat, 8 Aug 2020 19:46:14 -0500
> > > From: Scott Cheloha 
> > > 
> > > Hi,
> > > 
> > > I want to annotate the locking for the per-process interval timers.
> > > 
> > > In the process struct, the ITIMER_REAL itimerspec and the ps_itimer_to
> > > timeout are protected by the kernel lock.  These should be annotated
> > > with "K", right?
> > > 
> > > Also in the process struct, the ITIMER_VIRTUAL and ITIMER_PROF
> > > itimerspecs are protected by the global itimer_mtx.
> > > 
> > > However, I don't think "itimer_mtx" isn't the best name for it, as it
> > > doesn't protect state for *all* per-process interval timers.  Just the
> > > virtual ones.
> > > 
> > > Could I rename the mutex to "virtual_itimer_mtx"?  Then I can annotate
> > > the state protected by it with "V", as shown here in this patch.
> > 
> > That's quite a long variable name though.  And it also protects
> > ITIMER_PROF.  So I'd say the name would be at least as misleading as
> > the current one and perhaps even more so.  You can just use "I" as the
> > annotation perhaps?
> 
> The convention is to use "I" for immutable variables.  We do it
> everywhere.  I don't think we should buck convention here.
> 
> I also proposed using "i" in a prior patch to annotate these
> variables, but mpi@ said it was too close to "I".  Also, it's a global
> lock, and we have settled on only annotate global locks with capital
> letters.
> 
> If you don't want to rename the mutex I guess we could use "T" for
> "timer".  We use "T" for other global locks (tc_lock, timeout_mutex)
> but not in this context.
> 
> However, there are only so many letters.  Eventually this scheme will
> run afoul of that limitation.  An idea I had re. the letter shortage
> was to use two letters where necessary.  So instead of "I" you could
> use "It" for "itimer".  We annotate locking hierarchies with commas so
> there isn't an ambiguity when reading it.
> 
> For example, if the code for writing a hypothetical "ps_foo" process
> struct member was:
> 
>   KERNEL_LOCK();
>   mtx_enter(_mtx);
>   ps.ps_foo = 10;
>   mtx_leave(_mtx);
>   KERNEL_UNLOCK();
> 
> You could annotate it like this:
> 
> /*
>  * Locks used to protect process struct members:
>  *
>  *It  itimer_mtx
>  *K   kernel lock
>  */
> struct process {
>   /* [...] */
>   int ps_foo; /* [K,It] per-process foobar */
>   /* [...] */
> };
> 
> anton@, mpi@: is that too radical or easily misread?
> 
> Sorry if this all seems fussy, but I'd like to get this right the
> first time.

'T' is fine with me.  But I'm clearly not an authority here.  Anyway,
renaming variables because you don't have a matching letter to
annotate the lock doesn't feel right.



Re: process: annotate locking for setitimer(2) state

2020-08-09 Thread Scott Cheloha
On Sun, Aug 09, 2020 at 04:43:24PM +0200, Mark Kettenis wrote:
> > Date: Sat, 8 Aug 2020 19:46:14 -0500
> > From: Scott Cheloha 
> > 
> > Hi,
> > 
> > I want to annotate the locking for the per-process interval timers.
> > 
> > In the process struct, the ITIMER_REAL itimerspec and the ps_itimer_to
> > timeout are protected by the kernel lock.  These should be annotated
> > with "K", right?
> > 
> > Also in the process struct, the ITIMER_VIRTUAL and ITIMER_PROF
> > itimerspecs are protected by the global itimer_mtx.
> > 
> > However, I don't think "itimer_mtx" isn't the best name for it, as it
> > doesn't protect state for *all* per-process interval timers.  Just the
> > virtual ones.
> > 
> > Could I rename the mutex to "virtual_itimer_mtx"?  Then I can annotate
> > the state protected by it with "V", as shown here in this patch.
> 
> That's quite a long variable name though.  And it also protects
> ITIMER_PROF.  So I'd say the name would be at least as misleading as
> the current one and perhaps even more so.  You can just use "I" as the
> annotation perhaps?

The convention is to use "I" for immutable variables.  We do it
everywhere.  I don't think we should buck convention here.

I also proposed using "i" in a prior patch to annotate these
variables, but mpi@ said it was too close to "I".  Also, it's a global
lock, and we have settled on only annotate global locks with capital
letters.

If you don't want to rename the mutex I guess we could use "T" for
"timer".  We use "T" for other global locks (tc_lock, timeout_mutex)
but not in this context.

However, there are only so many letters.  Eventually this scheme will
run afoul of that limitation.  An idea I had re. the letter shortage
was to use two letters where necessary.  So instead of "I" you could
use "It" for "itimer".  We annotate locking hierarchies with commas so
there isn't an ambiguity when reading it.

For example, if the code for writing a hypothetical "ps_foo" process
struct member was:

KERNEL_LOCK();
mtx_enter(_mtx);
ps.ps_foo = 10;
mtx_leave(_mtx);
KERNEL_UNLOCK();

You could annotate it like this:

/*
 * Locks used to protect process struct members:
 *
 *  It  itimer_mtx
 *  K   kernel lock
 */
struct process {
/* [...] */
int ps_foo; /* [K,It] per-process foobar */
/* [...] */
};

anton@, mpi@: is that too radical or easily misread?

Sorry if this all seems fussy, but I'd like to get this right the
first time.

-Scott



Re: process: annotate locking for setitimer(2) state

2020-08-09 Thread Mark Kettenis
> Date: Sat, 8 Aug 2020 19:46:14 -0500
> From: Scott Cheloha 
> 
> Hi,
> 
> I want to annotate the locking for the per-process interval timers.
> 
> In the process struct, the ITIMER_REAL itimerspec and the ps_itimer_to
> timeout are protected by the kernel lock.  These should be annotated
> with "K", right?
> 
> Also in the process struct, the ITIMER_VIRTUAL and ITIMER_PROF
> itimerspecs are protected by the global itimer_mtx.
> 
> However, I don't think "itimer_mtx" isn't the best name for it, as it
> doesn't protect state for *all* per-process interval timers.  Just the
> virtual ones.
> 
> Could I rename the mutex to "virtual_itimer_mtx"?  Then I can annotate
> the state protected by it with "V", as shown here in this patch.

That's quite a long variable name though.  And it also protects
ITIMER_PROF.  So I'd say the name would be at least as misleading as
the current one and perhaps even more so.  You can just use "I" as the
annotation perhaps?

> Preferences?  ok?
> 
> Index: kern/kern_time.c
> ===
> RCS file: /cvs/src/sys/kern/kern_time.c,v
> retrieving revision 1.134
> diff -u -p -r1.134 kern_time.c
> --- kern/kern_time.c  8 Aug 2020 01:01:26 -   1.134
> +++ kern/kern_time.c  9 Aug 2020 00:41:10 -
> @@ -488,7 +488,13 @@ out:
>  }
>  
>  
> -struct mutex itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
> +/*
> + * Global virtual interval timer mutex.
> + *
> + * Protects state for the per-process ITIMER_VIRTUAL and ITIMER_PROF
> + * interval timers.
> + */
> +struct mutex virtual_itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
>  
>  /*
>   * Get value of an interval timer.  The process virtual and
> @@ -526,10 +532,10 @@ sys_getitimer(struct proc *p, void *v, r
>   return (EINVAL);
>   itimer = >p_p->ps_timer[which];
>   memset(, 0, sizeof(aitv));
> - mtx_enter(_mtx);
> + mtx_enter(_itimer_mtx);
>   TIMESPEC_TO_TIMEVAL(_interval, >it_interval);
>   TIMESPEC_TO_TIMEVAL(_value, >it_value);
> - mtx_leave(_mtx);
> + mtx_leave(_itimer_mtx);
>  
>   if (which == ITIMER_REAL) {
>   struct timeval now;
> @@ -604,9 +610,9 @@ sys_setitimer(struct proc *p, void *v, r
>   }
>   pr->ps_timer[ITIMER_REAL] = aits;
>   } else {
> - mtx_enter(_mtx);
> + mtx_enter(_itimer_mtx);
>   pr->ps_timer[which] = aits;
> - mtx_leave(_mtx);
> + mtx_leave(_itimer_mtx);
>   }
>  
>   return (0);
> @@ -681,20 +687,20 @@ itimerdecr(struct itimerspec *itp, long 
>  
>   NSEC_TO_TIMESPEC(nsec, );
>  
> - mtx_enter(_mtx);
> + mtx_enter(_itimer_mtx);
>   timespecsub(>it_value, , >it_value);
>   if (itp->it_value.tv_sec >= 0 && timespecisset(>it_value)) {
> - mtx_leave(_mtx);
> + mtx_leave(_itimer_mtx);
>   return (1);
>   }
>   if (!timespecisset(>it_interval)) {
>   timespecclear(>it_value);
> - mtx_leave(_mtx);
> + mtx_leave(_itimer_mtx);
>   return (0);
>   }
>   while (itp->it_value.tv_sec < 0 || !timespecisset(>it_value))
>   timespecadd(>it_value, >it_interval, >it_value);
> - mtx_leave(_mtx);
> + mtx_leave(_itimer_mtx);
>   return (0);
>  }
>  
> Index: sys/proc.h
> ===
> RCS file: /cvs/src/sys/sys/proc.h,v
> retrieving revision 1.297
> diff -u -p -r1.297 proc.h
> --- sys/proc.h6 Jul 2020 13:33:09 -   1.297
> +++ sys/proc.h9 Aug 2020 00:41:11 -
> @@ -150,9 +150,11 @@ struct unveil;
>  /*
>   * Locks used to protect struct members in this file:
>   *   a   atomic operations
> + *   K   kernel lock
>   *   m   this process' `ps_mtx'
>   *   p   this process' `ps_lock'
>   *   R   rlimit_lock
> + *   V   virtual_itimer_mtx
>   */
>  struct process {
>   /*
> @@ -216,7 +218,8 @@ struct process {
>   struct  rusage *ps_ru;  /* sum of stats for dead threads. */
>   struct  tusage ps_tu;   /* accumulated times. */
>   struct  rusage ps_cru;  /* sum of stats for reaped children */
> - struct  itimerspec ps_timer[3]; /* timers, indexed by ITIMER_* */
> + struct  itimerspec ps_timer[3]; /* [K] ITIMER_REAL timer */
> + /* [V] ITIMER_{PROF,VIRTUAL} timers */
>   struct  timeout ps_rucheck_to;  /* [] resource limit check timer */
>   time_t  ps_nextxcpu;/* when to send next SIGXCPU, */
>   /* in seconds of process runtime */
> @@ -269,7 +272,7 @@ struct process {
>   int ps_refcnt;  /* Number of references. */
>  
>   struct  timespec ps_start;  /* starting uptime. */
> - struct  timeout ps_realit_to;   /* real-time itimer trampoline. */
> + struct  timeout ps_realit_to;   /* [K] ITIMER_REAL 

process: annotate locking for setitimer(2) state

2020-08-08 Thread Scott Cheloha
Hi,

I want to annotate the locking for the per-process interval timers.

In the process struct, the ITIMER_REAL itimerspec and the ps_itimer_to
timeout are protected by the kernel lock.  These should be annotated
with "K", right?

Also in the process struct, the ITIMER_VIRTUAL and ITIMER_PROF
itimerspecs are protected by the global itimer_mtx.

However, I don't think "itimer_mtx" isn't the best name for it, as it
doesn't protect state for *all* per-process interval timers.  Just the
virtual ones.

Could I rename the mutex to "virtual_itimer_mtx"?  Then I can annotate
the state protected by it with "V", as shown here in this patch.

Preferences?  ok?

Index: kern/kern_time.c
===
RCS file: /cvs/src/sys/kern/kern_time.c,v
retrieving revision 1.134
diff -u -p -r1.134 kern_time.c
--- kern/kern_time.c8 Aug 2020 01:01:26 -   1.134
+++ kern/kern_time.c9 Aug 2020 00:41:10 -
@@ -488,7 +488,13 @@ out:
 }
 
 
-struct mutex itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
+/*
+ * Global virtual interval timer mutex.
+ *
+ * Protects state for the per-process ITIMER_VIRTUAL and ITIMER_PROF
+ * interval timers.
+ */
+struct mutex virtual_itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
 
 /*
  * Get value of an interval timer.  The process virtual and
@@ -526,10 +532,10 @@ sys_getitimer(struct proc *p, void *v, r
return (EINVAL);
itimer = >p_p->ps_timer[which];
memset(, 0, sizeof(aitv));
-   mtx_enter(_mtx);
+   mtx_enter(_itimer_mtx);
TIMESPEC_TO_TIMEVAL(_interval, >it_interval);
TIMESPEC_TO_TIMEVAL(_value, >it_value);
-   mtx_leave(_mtx);
+   mtx_leave(_itimer_mtx);
 
if (which == ITIMER_REAL) {
struct timeval now;
@@ -604,9 +610,9 @@ sys_setitimer(struct proc *p, void *v, r
}
pr->ps_timer[ITIMER_REAL] = aits;
} else {
-   mtx_enter(_mtx);
+   mtx_enter(_itimer_mtx);
pr->ps_timer[which] = aits;
-   mtx_leave(_mtx);
+   mtx_leave(_itimer_mtx);
}
 
return (0);
@@ -681,20 +687,20 @@ itimerdecr(struct itimerspec *itp, long 
 
NSEC_TO_TIMESPEC(nsec, );
 
-   mtx_enter(_mtx);
+   mtx_enter(_itimer_mtx);
timespecsub(>it_value, , >it_value);
if (itp->it_value.tv_sec >= 0 && timespecisset(>it_value)) {
-   mtx_leave(_mtx);
+   mtx_leave(_itimer_mtx);
return (1);
}
if (!timespecisset(>it_interval)) {
timespecclear(>it_value);
-   mtx_leave(_mtx);
+   mtx_leave(_itimer_mtx);
return (0);
}
while (itp->it_value.tv_sec < 0 || !timespecisset(>it_value))
timespecadd(>it_value, >it_interval, >it_value);
-   mtx_leave(_mtx);
+   mtx_leave(_itimer_mtx);
return (0);
 }
 
Index: sys/proc.h
===
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.297
diff -u -p -r1.297 proc.h
--- sys/proc.h  6 Jul 2020 13:33:09 -   1.297
+++ sys/proc.h  9 Aug 2020 00:41:11 -
@@ -150,9 +150,11 @@ struct unveil;
 /*
  * Locks used to protect struct members in this file:
  * a   atomic operations
+ * K   kernel lock
  * m   this process' `ps_mtx'
  * p   this process' `ps_lock'
  * R   rlimit_lock
+ * V   virtual_itimer_mtx
  */
 struct process {
/*
@@ -216,7 +218,8 @@ struct process {
struct  rusage *ps_ru;  /* sum of stats for dead threads. */
struct  tusage ps_tu;   /* accumulated times. */
struct  rusage ps_cru;  /* sum of stats for reaped children */
-   struct  itimerspec ps_timer[3]; /* timers, indexed by ITIMER_* */
+   struct  itimerspec ps_timer[3]; /* [K] ITIMER_REAL timer */
+   /* [V] ITIMER_{PROF,VIRTUAL} timers */
struct  timeout ps_rucheck_to;  /* [] resource limit check timer */
time_t  ps_nextxcpu;/* when to send next SIGXCPU, */
/* in seconds of process runtime */
@@ -269,7 +272,7 @@ struct process {
int ps_refcnt;  /* Number of references. */
 
struct  timespec ps_start;  /* starting uptime. */
-   struct  timeout ps_realit_to;   /* real-time itimer trampoline. */
+   struct  timeout ps_realit_to;   /* [K] ITIMER_REAL timeout */
 };
 
 #defineps_session  ps_pgrp->pg_session