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>
