Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Feb 2016 16:53:22 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Jov <zhao6014@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Fwd: [BUGS] BUG #13900: stop standby failed with writer process hang(happen 3 times in 2 days)
Message-ID:  <20160202145322.GA91220@kib.kiev.ua>
In-Reply-To: <CADyrUxMN3_=thr0LutMMkpzkVzFr_NtYOQPM2Dn2Ce_JtSKROg@mail.gmail.com>
References:  <20160130071346.31022.37189@wrigleys.postgresql.org> <CADyrUxM9jWVrUZYkUYP6vxgg_eWOuCqCQTqEERQ6iSq11DjUeA@mail.gmail.com> <20160131162929.GI91220@kib.kiev.ua> <CADyrUxOw%2Bn-ZB9f71v9PFjB_Mk=x8-DMZWqsD0GXK0DYEVw2fA@mail.gmail.com> <20160201190415.GO91220@kib.kiev.ua> <CADyrUxMN3_=thr0LutMMkpzkVzFr_NtYOQPM2Dn2Ce_JtSKROg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Feb 02, 2016 at 09:36:19AM +0800, Jov wrote:
> ???Thanks for your info,Belousov.
> Would you please point which PR or which commit I can exam???I can not move
> to 10 stable now,maybe I can avoid trigger this bug or add some monitor???.
stable/10 is not fixed as well.

I do not have a good suggestion rather then to sync kern_timeout.c with
head.  After that, you need one more patch.

diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 9c9d25f..e827665 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -1162,7 +1162,7 @@ _callout_stop_safe(struct callout *c, int safe, void (*drain)(void *))
 	int direct, sq_locked, use_lock;
 	int not_on_a_list;
 
-	if (safe)
+	if ((safe & CS_DRAIN) != 0)
 		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, c->c_lock,
 		    "calling %s", __func__);
 
@@ -1170,7 +1170,7 @@ _callout_stop_safe(struct callout *c, int safe, void (*drain)(void *))
 	 * Some old subsystems don't hold Giant while running a callout_stop(),
 	 * so just discard this check for the moment.
 	 */
-	if (!safe && c->c_lock != NULL) {
+	if ((safe & CS_DRAIN) == 0 && c->c_lock != NULL) {
 		if (c->c_lock == &Giant.lock_object)
 			use_lock = mtx_owned(&Giant);
 		else {
@@ -1253,7 +1253,7 @@ again:
 			return (-1);
 		}
 
-		if (safe) {
+		if ((safe & CS_DRAIN) != 0) {
 			/*
 			 * The current callout is running (or just
 			 * about to run) and blocking is allowed, so
@@ -1370,7 +1370,7 @@ again:
 				cc_exec_drain(cc, direct) = drain;
 			}
 			CC_UNLOCK(cc);
-			return (0);
+			return ((safe & CS_MIGRBLOCK) != 0);
 		}
 		CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
 		    c, c->c_func, c->c_arg);
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index bbbec92..12908f6 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -586,7 +586,8 @@ sleepq_check_timeout(void)
 	 * another CPU, so synchronize with it to avoid having it
 	 * accidentally wake up a subsequent sleep.
 	 */
-	else if (callout_stop(&td->td_slpcallout) == 0) {
+	else if (_callout_stop_safe(&td->td_slpcallout, CS_MIGRBLOCK, NULL)
+	    == 0) {
 		td->td_flags |= TDF_TIMEOUT;
 		TD_SET_SLEEPING(td);
 		mi_switch(SW_INVOL | SWT_SLEEPQTIMO, NULL);
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index 3e71c87..51dc137 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -62,6 +62,9 @@ struct callout_handle {
 	struct callout *callout;
 };
 
+#define	CS_DRAIN		0x0001
+#define	CS_MIGRBLOCK		0x0002
+
 #ifdef _KERNEL
 /* 
  * Note the flags field is actually *two* fields. The c_flags
@@ -81,7 +84,7 @@ struct callout_handle {
  */
 #define	callout_active(c)	((c)->c_flags & CALLOUT_ACTIVE)
 #define	callout_deactivate(c)	((c)->c_flags &= ~CALLOUT_ACTIVE)
-#define	callout_drain(c)	_callout_stop_safe(c, 1, NULL)
+#define	callout_drain(c)	_callout_stop_safe(c, CS_DRAIN, NULL)
 void	callout_init(struct callout *, int);
 void	_callout_init_lock(struct callout *, struct lock_object *, int);
 #define	callout_init_mtx(c, mtx, flags)					\



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