diff options
author | tegge <tegge@FreeBSD.org> | 2006-04-03 22:23:23 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-04-03 22:23:23 +0000 |
commit | 8582a7eef54875ec23f28273f78836913636fa30 (patch) | |
tree | cccc7fd7e3c14c4f41b9898b17f1cf6a4bd4d566 | |
parent | 3a90816456153dee9750b79d683eddd9712f640f (diff) | |
download | FreeBSD-src-8582a7eef54875ec23f28273f78836913636fa30.zip FreeBSD-src-8582a7eef54875ec23f28273f78836913636fa30.tar.gz |
Eliminate softdep_flush() livelock by accounting for number of worklist items
marked as being in progress.
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 7 | ||||
-rw-r--r-- | sys/ufs/ufs/ufsmount.h | 1 |
2 files changed, 7 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index bb0b9e1..466230f 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -718,6 +718,7 @@ softdep_flush(void) { struct mount *nmp; struct mount *mp; + struct ufsmount *ump; struct thread *td; int remaining; int vfslocked; @@ -752,7 +753,9 @@ softdep_flush(void) 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); @@ -914,11 +917,13 @@ process_worklist_item(mp, flags) 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; } diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index 4703a9b..5057991 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -76,6 +76,7 @@ struct ufsmount { 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. */ |