svn commit: r310531 - stable/11/sys/kern

Mark Johnston markj at FreeBSD.org
Sun Dec 25 00:35:01 UTC 2016


Author: markj
Date: Sun Dec 25 00:35:00 2016
New Revision: 310531
URL: https://svnweb.freebsd.org/changeset/base/310531

Log:
  MFC r310423, r310454:
  Revert part of r300109.

Modified:
  stable/11/sys/kern/subr_sleepqueue.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/subr_sleepqueue.c
==============================================================================
--- stable/11/sys/kern/subr_sleepqueue.c	Sat Dec 24 23:51:27 2016	(r310530)
+++ stable/11/sys/kern/subr_sleepqueue.c	Sun Dec 25 00:35:00 2016	(r310531)
@@ -880,7 +880,7 @@ int
 sleepq_broadcast(void *wchan, int flags, int pri, int queue)
 {
 	struct sleepqueue *sq;
-	struct thread *td;
+	struct thread *td, *tdn;
 	int wakeup_swapper;
 
 	CTR2(KTR_PROC, "sleepq_broadcast(%p, %d)", wchan, flags);
@@ -892,9 +892,14 @@ sleepq_broadcast(void *wchan, int flags,
 	KASSERT(sq->sq_type == (flags & SLEEPQ_TYPE),
 	    ("%s: mismatch between sleep/wakeup and cv_*", __func__));
 
-	/* Resume all blocked threads on the sleep queue. */
+	/*
+	 * Resume all blocked threads on the sleep queue.  The last thread will
+	 * be given ownership of sq and may re-enqueue itself before
+	 * sleepq_resume_thread() returns, so we must cache the "next" queue
+	 * item at the beginning of the final iteration.
+	 */
 	wakeup_swapper = 0;
-	while ((td = TAILQ_FIRST(&sq->sq_blocked[queue])) != NULL) {
+	TAILQ_FOREACH_SAFE(td, &sq->sq_blocked[queue], td_slpq, tdn) {
 		thread_lock(td);
 		wakeup_swapper |= sleepq_resume_thread(sq, td, pri);
 		thread_unlock(td);


More information about the svn-src-stable-11 mailing list