From d23b8e7e68136e12dbffe1538e744b11b5b71355 Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 13 Oct 2017 22:40:57 +0000 Subject: [PATCH] MFC 324039: Don't defer wakeup()s for completed journal workitems. Normally wakeups() are performed for completed softupdates work items in workitem_free() before the underlying memory is free()'d. complete_jseg() was clearing the "wakeup needed" flag in work items to defer the wakeup until the end of each loop iteration. However, this resulted in the item being free'd before it's address was used with wakeup(). As a result, another part of the kernel could allocate this memory from malloc() and use it as a wait channel for a different "event" with a different lock. This triggered an assertion failure when the lock passed to sleepq_add() did not match the existing lock associated with the sleep queue. Fix this by removing the code to defer the wakeup in complete_jseg() allowing the wakeup to occur slightly earlier in workitem_free() before free() is called. git-svn-id: svn://svn.freebsd.org/base/stable/10@324612 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/ufs/ffs/ffs_softdep.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 18e609e38..58b82b889 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -3594,15 +3594,13 @@ complete_jseg(jseg) { struct worklist *wk; struct jmvref *jmvref; - int waiting; #ifdef INVARIANTS int i = 0; #endif while ((wk = LIST_FIRST(&jseg->js_entries)) != NULL) { WORKLIST_REMOVE(wk); - waiting = wk->wk_state & IOWAITING; - wk->wk_state &= ~(INPROGRESS | IOWAITING); + wk->wk_state &= ~INPROGRESS; wk->wk_state |= COMPLETE; KASSERT(i++ < jseg->js_cnt, ("handle_written_jseg: overflow %d >= %d", @@ -3643,8 +3641,6 @@ complete_jseg(jseg) TYPENAME(wk->wk_type)); /* NOTREACHED */ } - if (waiting) - wakeup(wk); } /* Release the self reference so the structure may be freed. */ rele_jseg(jseg); -- 2.45.0