From owner-p4-projects@FreeBSD.ORG Tue Feb 21 21:51:27 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B935B16A424; Tue, 21 Feb 2006 21:51:26 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 775D716A420 for ; Tue, 21 Feb 2006 21:51:26 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id BA42C43D64 for ; Tue, 21 Feb 2006 21:51:18 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k1LLpI3P078273 for ; Tue, 21 Feb 2006 21:51:18 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k1LLpHPr078269 for perforce@freebsd.org; Tue, 21 Feb 2006 21:51:18 GMT (envelope-from jhb@freebsd.org) Date: Tue, 21 Feb 2006 21:51:18 GMT Message-Id: <200602212151.k1LLpHPr078269@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 92144 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Feb 2006 21:51:27 -0000 http://perforce.freebsd.org/chv.cgi?CH=92144 Change 92144 by jhb@jhb_slimer on 2006/02/21 21:51:15 Axe the callout_wait mutex and instead just use msleep_spin with the callout_lock spin lock directly. Affected files ... .. //depot/projects/smpng/sys/kern/kern_timeout.c#27 edit Differences ... ==== //depot/projects/smpng/sys/kern/kern_timeout.c#27 (text+ko) ==== @@ -85,31 +85,18 @@ * guarantees that the current callout will not run. * The softclock() function sets this to 0 before it * drops callout_lock to acquire c_mtx, and it calls - * the handler only if curr_cancelled still 0 when + * the handler only if curr_cancelled is still 0 after * c_mtx is successfully acquired. - * wakeup_ctr - Incremented every time a thread wants to wait - * for a callout to complete. Modified only when + * wakeup_needed - If a thread is waiting on callout_wait, then + * wakeup_needed is nonzero. Set only when * curr_callout is non-NULL. - * wakeup_needed - If a thread is waiting on callout_wait, then - * wakeup_needed is nonzero. Increased only when - * cutt_callout is non-NULL. + * callout_wait - Placeholder for a wait channel. */ static struct callout *curr_callout; static int curr_cancelled; -static int wakeup_ctr; static int wakeup_needed; +static int callout_wait; -/** - * Locked by callout_wait_lock: - * callout_wait - If wakeup_needed is set, callout_wait will be - * triggered after the current callout finishes. - * wakeup_done_ctr - Set to the current value of wakeup_ctr after - * callout_wait is triggered. - */ -static struct mtx callout_wait_lock; -static struct cv callout_wait; -static int wakeup_done_ctr; - /* * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization * @@ -157,8 +144,6 @@ TAILQ_INIT(&callwheel[i]); } mtx_init(&callout_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE); - mtx_init(&callout_wait_lock, "callout_wait_lock", NULL, MTX_DEF); - cv_init(&callout_wait, "callout_wait"); } /* @@ -188,7 +173,6 @@ int mpcalls; int mtxcalls; int gcalls; - int wakeup_cookie; #ifdef DIAGNOSTIC struct bintime bt1, bt2; struct timespec ts2; @@ -316,13 +300,7 @@ * There might be someone waiting * for the callout to complete. */ - wakeup_cookie = wakeup_ctr; - mtx_unlock_spin(&callout_lock); - mtx_lock(&callout_wait_lock); - cv_broadcast(&callout_wait); - wakeup_done_ctr = wakeup_cookie; - mtx_unlock(&callout_wait_lock); - mtx_lock_spin(&callout_lock); + wakeup(&callout_wait); wakeup_needed = 0; } steps = 0; @@ -497,7 +475,7 @@ struct callout *c; int safe; { - int use_mtx, wakeup_cookie; + int rval, use_mtx; if (!safe && c->c_mtx != NULL) { #ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */ @@ -520,30 +498,21 @@ mtx_unlock_spin(&callout_lock); return (0); } + rval = 0; if (safe) { /* We need to wait until the callout is finished. */ - wakeup_needed = 1; - wakeup_cookie = wakeup_ctr++; - mtx_unlock_spin(&callout_lock); - mtx_lock(&callout_wait_lock); - - /* - * Check to make sure that softclock() didn't - * do the wakeup in between our dropping - * callout_lock and picking up callout_wait_lock - */ - if (wakeup_cookie - wakeup_done_ctr > 0) - cv_wait(&callout_wait, &callout_wait_lock); - - mtx_unlock(&callout_wait_lock); + while (c == curr_callout) { + wakeup_needed = 1; + msleep_spin(&callout_wait, &callout_lock, + "costop", 0); + } } else if (use_mtx && !curr_cancelled) { /* We can stop the callout before it runs. */ curr_cancelled = 1; - mtx_unlock_spin(&callout_lock); - return (1); - } else - mtx_unlock_spin(&callout_lock); - return (0); + rval = 1; + } + mtx_unlock_spin(&callout_lock); + return (rval); } c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);