Please people, test this diff, we need reports from all architectures if possible.
We always hear how much users want to help and so on, so please, test this diff. On Mon, Jul 23, 2012 at 08:45:17PM +0400, Alexander Polakov wrote: > This diff reduces IPI traffic for a case when process A is sending > a lot of signals to process B running on a different CPU. userret() > delivers all process signals at once, so there is no need to send > an interrupt for every signal. > > The problem was noticed by rtorrent 0.9.2 users, which does exactly > this, which led to process/system hangs and slowness. > > Tested and known to help on amd64 by me and dcoppa@. > > Index: amd64/amd64/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v > retrieving revision 1.155 > diff -u -r1.155 machdep.c > --- amd64/amd64/machdep.c 4 Jun 2012 15:19:47 -0000 1.155 > +++ amd64/amd64/machdep.c 23 Jul 2012 13:49:40 -0000 > @@ -690,8 +690,10 @@ > void > signotify(struct proc *p) > { > - aston(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > } > > #ifdef MULTIPROCESSOR > Index: amd64/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v > retrieving revision 1.73 > diff -u -r1.73 cpu.h > --- amd64/include/cpu.h 17 Apr 2012 16:02:33 -0000 1.73 > +++ amd64/include/cpu.h 23 Jul 2012 13:49:40 -0000 > @@ -213,6 +213,7 @@ > #endif > > #define aston(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > #define curpcb curcpu()->ci_curpcb > > Index: hppa/hppa/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/hppa/hppa/machdep.c,v > retrieving revision 1.206 > diff -u -r1.206 machdep.c > --- hppa/hppa/machdep.c 21 Jun 2012 00:56:59 -0000 1.206 > +++ hppa/hppa/machdep.c 23 Jul 2012 13:49:40 -0000 > @@ -1399,8 +1399,10 @@ > void > signotify(struct proc *p) > { > - setsoftast(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + setsoftast(p); > + cpu_unidle(p->p_cpu); > + } > } > > /* > Index: hppa/include/intr.h > =================================================================== > RCS file: /cvs/src/sys/arch/hppa/include/intr.h,v > retrieving revision 1.37 > diff -u -r1.37 intr.h > --- hppa/include/intr.h 14 Jan 2011 13:20:06 -0000 1.37 > +++ hppa/include/intr.h 23 Jul 2012 13:49:40 -0000 > @@ -157,7 +157,8 @@ > int hppa_ipi_broadcast(u_long); > #endif > > -#define setsoftast(p) (p->p_md.md_astpending = 1) > +#define setsoftast(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > void *softintr_establish(int, void (*)(void *), void *); > void softintr_disestablish(void *); > Index: i386/i386/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v > retrieving revision 1.510 > diff -u -r1.510 machdep.c > --- i386/i386/machdep.c 23 May 2012 08:23:43 -0000 1.510 > +++ i386/i386/machdep.c 23 Jul 2012 13:49:40 -0000 > @@ -2420,8 +2420,10 @@ > void > signotify(struct proc *p) > { > - aston(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > } > > #ifdef MULTIPROCESSOR > Index: i386/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v > retrieving revision 1.122 > diff -u -r1.122 cpu.h > --- i386/include/cpu.h 27 Mar 2012 06:44:01 -0000 1.122 > +++ i386/include/cpu.h 23 Jul 2012 13:49:41 -0000 > @@ -226,6 +226,7 @@ > #endif > > #define aston(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > #define curpcb curcpu()->ci_curpcb > > Index: m88k/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/m88k/include/cpu.h,v > retrieving revision 1.54 > diff -u -r1.54 cpu.h > --- m88k/include/cpu.h 25 Oct 2011 18:38:06 -0000 1.54 > +++ m88k/include/cpu.h 23 Jul 2012 13:49:41 -0000 > @@ -256,6 +256,7 @@ > (((struct cpu_info *)(framep)->tf.tf_cpu)->ci_intrdepth > 1) > > #define aston(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > /* > * This is used during profiling to integrate system time. > Index: m88k/m88k/m88k_machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/m88k/m88k/m88k_machdep.c,v > retrieving revision 1.52 > diff -u -r1.52 m88k_machdep.c > --- m88k/m88k/m88k_machdep.c 23 Mar 2012 15:51:26 -0000 1.52 > +++ m88k/m88k/m88k_machdep.c 23 Jul 2012 13:49:41 -0000 > @@ -314,8 +314,10 @@ > void > signotify(struct proc *p) > { > - aston(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > } > > #ifdef MULTIPROCESSOR > Index: macppc/macppc/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v > retrieving revision 1.131 > diff -u -r1.131 machdep.c > --- macppc/macppc/machdep.c 29 Aug 2011 20:21:44 -0000 1.131 > +++ macppc/macppc/machdep.c 23 Jul 2012 13:49:41 -0000 > @@ -935,8 +935,10 @@ > void > signotify(struct proc *p) > { > - aston(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > } > > #ifdef MULTIPROCESSOR > Index: mips64/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v > retrieving revision 1.83 > diff -u -r1.83 cpu.h > --- mips64/include/cpu.h 14 Jul 2012 19:50:11 -0000 1.83 > +++ mips64/include/cpu.h 23 Jul 2012 13:49:41 -0000 > @@ -511,12 +511,20 @@ > * process as soon as possible. > */ > #ifdef MULTIPROCESSOR > -#define signotify(p) (aston(p), cpu_unidle(p->p_cpu)) > +static __inline void > +signotify(struct proc *p) > +{ > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > +} > #else > #define signotify(p) aston(p) > #endif > > -#define aston(p) p->p_md.md_astpending = 1 > +#define aston(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > #endif /* _KERNEL && !_LOCORE */ > > Index: powerpc/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v > retrieving revision 1.46 > diff -u -r1.46 cpu.h > --- powerpc/include/cpu.h 28 Sep 2010 20:27:55 -0000 1.46 > +++ powerpc/include/cpu.h 23 Jul 2012 13:49:41 -0000 > @@ -155,6 +155,7 @@ > #define DELAY(n) delay(n) > > #define aston(p) ((p)->p_md.md_astpending = 1) > +#define isastset(p) ((p)->p_md.md_astpending == 1) > > /* > * Preempt the current process if in interrupt from user mode, > Index: sparc64/include/cpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/sparc64/include/cpu.h,v > retrieving revision 1.78 > diff -u -r1.78 cpu.h > --- sparc64/include/cpu.h 6 Jul 2011 22:26:44 -0000 1.78 > +++ sparc64/include/cpu.h 23 Jul 2012 13:49:41 -0000 > @@ -226,7 +226,7 @@ > extern void (*cpu_start_clock)(void); > > #define aston(p) ((p)->p_md.md_astpending = 1) > - > +#define isastset(p) ((p)->p_md.md_astpending == 1) > /* > * Preempt the current process if in interrupt from user mode, > * or after the current trap/syscall if in system mode. > Index: sparc64/sparc64/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/sparc64/sparc64/machdep.c,v > retrieving revision 1.138 > diff -u -r1.138 machdep.c > --- sparc64/sparc64/machdep.c 9 May 2012 18:34:21 -0000 1.138 > +++ sparc64/sparc64/machdep.c 23 Jul 2012 13:49:42 -0000 > @@ -613,8 +613,10 @@ > void > signotify(struct proc *p) > { > - aston(p); > - cpu_unidle(p->p_cpu); > + if (!isastset(p)) { > + aston(p); > + cpu_unidle(p->p_cpu); > + } > } > > int waittime = -1;