Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Feb 2002 11:50:09 -0800 (PST)
From:      Julian Elischer <julian@elischer.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        current@freebsd.org
Subject:   Re: Patch to improve mutex collision performance
Message-ID:  <Pine.BSF.4.21.0202181140100.52663-100000@InterJet.elischer.org>
In-Reply-To: <200202181912.g1IJCGK32122@apollo.backplane.com>

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


On Mon, 18 Feb 2002, Matthew Dillon wrote:

[...]
> 
>     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.

it's possible John's preemption code may also handle this..

> 
> 							-Matt
> 
> Index: kern/kern_mutex.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/kern/kern_mutex.c,v
> retrieving revision 1.80
> diff -u -r1.80 kern_mutex.c
> --- kern/kern_mutex.c	18 Feb 2002 17:51:47 -0000	1.80
> +++ kern/kern_mutex.c	18 Feb 2002 19:11:17 -0000
> @@ -287,7 +287,9 @@
>  _mtx_lock_sleep(struct mtx *m, int opts, const char *file, int line)
>  {
>  	struct thread *td = curthread;
> +#if 0
>  	struct ksegrp *kg = td->td_ksegrp;
> +#endif
>  
>  	if ((m->mtx_lock & MTX_FLAGMASK) == (uintptr_t)td) {
>  		m->mtx_recurse++;
> @@ -312,6 +314,22 @@
>  		 * the sched_lock.
>  		 */
>  		if ((v = m->mtx_lock) == MTX_UNOWNED) {
> 			mtx_unlock_spin(&sched_lock);
> 			continue;
> 		}
> +
> +		/*
> +		 * Check to see if there are any runnable processes.  If
> +		 * there aren't and nobody is contesting the mutex (to avoid
> +		 * starving a contester) and interrupts are enabled, then
> +		 * we can safely spin.
> +		 *
> +		 * This prevents a silly-sleep-flip-flop situation on SMP
> +		 * systems where two running processes need Giant (or any
> +		 * other sleep mutex).
> +		 */
> +		if (td->td_critnest == 0 && (v & MTX_CONTESTED) == 0 &&
> +		    procrunnable() == 0) {
> + 			mtx_unlock_spin(&sched_lock);
> + 			continue;
> + 		}

I can't see any major problem with this but I can't help thinking that
there must be one.. on UP the question is: "who is going to 
release the lock if no-one is runnable?"




can you detail in more clarity the flip-flopping you were seeing?





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


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?Pine.BSF.4.21.0202181140100.52663-100000>