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;

Reply via email to