Re: Livelock / softdep_flush "loop"

From: Tor Egge <Tor.Egge_at_cvsup.no.freebsd.org>
Date: Sun, 02 Apr 2006 18:01:53 +0000 (UTC)
> I managed to zoom in on the livelocks I've been seeing lately.

According to the console log, process 708 has marked one dependency as being in
progress, locked a vnode and then slept waiting for the softdep lock.

softdep_flush() doesn't take into account that some of the remaining
dependencies cannot be processed at once.

Process 45 ended up looping inside softdep_flush(), never sleeping, always
believing that more work could be done.

The enclosed patch might help.

- Tor Egge

Index: sys/ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.193
diff -u -r1.193 ffs_softdep.c
--- sys/ufs/ffs/ffs_softdep.c	12 Mar 2006 05:25:16 -0000	1.193
+++ sys/ufs/ffs/ffs_softdep.c	2 Apr 2006 17:21:13 -0000
_at__at_ -718,6 +718,7 _at__at_
 {
 	struct mount *nmp;
 	struct mount *mp;
+	struct ufsmount *ump;
 	struct thread *td;
 	int remaining;
 	int vfslocked;
_at__at_ -752,7 +753,9 _at__at_
 				continue;
 			vfslocked = VFS_LOCK_GIANT(mp);
 			softdep_process_worklist(mp, 0);
-			remaining += VFSTOUFS(mp)->softdep_on_worklist;
+			ump = VFSTOUFS(mp);
+			remaining += ump->softdep_on_worklist -
+				ump->softdep_on_worklist_inprogress;
 			VFS_UNLOCK_GIANT(vfslocked);
 			mtx_lock(&mountlist_mtx);
 			nmp = TAILQ_NEXT(mp, mnt_list);
_at__at_ -914,11 +917,13 _at__at_
 		if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
 			break;
 		wk->wk_state |= INPROGRESS;
+		ump->softdep_on_worklist_inprogress++;
 		FREE_LOCK(&lk);
 		ffs_vget(mp, WK_DIRREM(wk)->dm_oldinum,
 		    LK_NOWAIT | LK_EXCLUSIVE, &vp);
 		ACQUIRE_LOCK(&lk);
 		wk->wk_state &= ~INPROGRESS;
+		ump->softdep_on_worklist_inprogress--;
 		if (vp != NULL)
 			break;
 	}
Index: sys/ufs/ufs/ufsmount.h
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufsmount.h,v
retrieving revision 1.36
diff -u -r1.36 ufsmount.h
--- sys/ufs/ufs/ufsmount.h	8 Mar 2006 23:43:39 -0000	1.36
+++ sys/ufs/ufs/ufsmount.h	2 Apr 2006 17:21:13 -0000
_at__at_ -76,6 +76,7 _at__at_
 	struct workhead softdep_workitem_pending; /* softdep work queue */
 	struct worklist *softdep_worklist_tail;	/* Tail pointer for above */
 	int	softdep_on_worklist;		/* Items on the worklist */
+	int	softdep_on_worklist_inprogress;	/* Busy items on worklist */
 	int	softdep_deps;			/* Total dependency count */
 	int	softdep_accdeps;		/* accumulated dep count */
 	int	softdep_req;			/* Wakeup when deps hits 0. */
Received on Sun Apr 02 2006 - 16:01:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:54 UTC