Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Feb 2002 17:27:45 -0500 (EST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        current@freebsd.org
Subject:   RE: Patch to improve mutex collision performance
Message-ID:  <XFMail.020220172745.jhb@FreeBSD.org>
In-Reply-To: <200202181912.g1IJCGK32122@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help

On 18-Feb-02 Matthew Dillon wrote:
>     While testing some Giant removal stuff I noticed that my current
>     system sometimes got into an extremely non-optimal flip-flop situation
>     between two processes contesting Giant on an SMP system which halved the
>     syscall performance in the test.
> 
>     In my getuid test, for example, with Giant in place I was getting
>     683Kcalls/sec with one process and 427Kcalls/sec with two.  Giant
>     was being obtained in two places: in userret and in getuid().
> 
>     When I turned off Giant in getuid() the syscall performance actually
>     went DOWN, to 250Kcalls/sec with two processes.  This was a totally
>     unexpected result.
> 
>     It turns out that the two processes got into an extremely non-optimal 
>     contested/sleep/wakeup situation, even though they do not actually have
>     to sleep on Giant in this situation.
> 
>     The solution is to allow _mtx_lock_sleep() to spin instead of sleep in
>     the situation where:  (1) there are no runnable processes other then
>     the ones already running on a cpu, (2) interrupts are enabled, and 
>     (3) the mutex in question is not contested (to avoid starving the thread
>     contesting the mutex).  In this case we can spin.
> 
>     This will go in tonight if no problems arise.

I would rather make the locks adaptive like so:  (untested)

--- //depot/projects/smpng/sys/conf/options     2002/02/08 13:19:07
+++ //depot/user/jhb/lock/conf/options  2002/02/08 13:50:54
@@ -56,6 +56,7 @@
                                        # mapped I/O
 
 # Miscellaneous options.
+ADAPTIVE_MUTEXES
 BLEED
 COMPAT_43      opt_compat.h
 COMPAT_SUNOS   opt_compat.h
--- //depot/projects/smpng/sys/i386/include/cpufunc.h   2001/12/18 13:07:32
+++ //depot/user/jhb/lock/i386/include/cpufunc.h        2001/12/20 15:54:32
@@ -550,6 +550,12 @@
        __asm __volatile("movl %0,%%dr7" : : "r" (sel));
 }
 
+static __inline void
+cpu_pause(void)
+{
+       __asm __volatile("pause");
+}
+
 static __inline critical_t
 cpu_critical_enter(void)
 {
--- //depot/projects/smpng/sys/kern/kern_mutex.c        2002/02/08 14:19:21
+++ //depot/user/jhb/lock/kern/kern_mutex.c     2002/02/08 13:50:54
@@ -34,6 +34,7 @@
  * Machine independent bits of mutex implementation.
  */
 
+#include "opt_adaptive_mutexes.h"
 #include "opt_ddb.h"
 
 #include <sys/param.h>
@@ -345,7 +354,22 @@
                        continue;
                }
 
+#if defined(SMP) && defined(ADAPTIVE_MUTEXES)
                /*
+                * If the current owner of the lock is executing on another
+                * CPU, spin instead of blocking.
+                */
+               if (((struct thread *)(v & MTX_FLAGMASK)->td_kse->kse_oncpu !=
+                   NOCPU) {
+                       mtx_unlock_spin(&sched_lock);
+#ifdef __i386__
+                       cpu_pause();
+#endif
+                       continue;
+               }
+#endif /* SMP && ADAPTIVE_MUTEXES */
+
+               /*
                 * We deffinately must sleep for this lock.
                 */
                mtx_assert(m, MA_NOTOWNED);
@@ -433,6 +457,9 @@
                /* Give interrupts a chance while we spin. */
                critical_exit();
                while (m->mtx_lock != MTX_UNOWNED) {
+#ifdef __i386__
+                       cpu_pause();
+#endif
                        if (i++ < 10000000)
                                continue;
                        if (i++ < 60000000)

This is more a specific problem with Giant and I don't think it will be a
problem with other mutexes, so I'd prefer a solution not quite so tailored to
this particular behavior of Giant.

-- 

John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.020220172745.jhb>