From ea3e5a38b860e515307b6210d6004e5215f7f859 Mon Sep 17 00:00:00 2001 From: fvdl Date: Wed, 12 Apr 2000 11:33:43 +0000 Subject: [PATCH] Fix from Ethan Solomita to avoid a livelock problem where the buffer cache code would be recycling B_AGE buffers with dependencies. --- sys/kern/vfs_bio.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 1edf20fb169f..293958f37181 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_bio.c,v 1.66 2000/03/30 09:27:14 augustss Exp $ */ +/* $NetBSD: vfs_bio.c,v 1.67 2000/04/12 11:33:43 fvdl Exp $ */ /*- * Copyright (c) 1994 Christopher G. Demetriou @@ -573,16 +573,29 @@ brelse(bp) /* * It has valid data. Put it on the end of the appropriate * queue, so that it'll stick around for as long as possible. + * If buf is AGE, but has dependencies, must put it on last + * bufqueue to be scanned, ie LRU. This protects against the + * livelock where BQ_AGE only has buffers with dependencies, + * and we thus never get to the dependent buffers in BQ_LRU. */ if (ISSET(bp->b_flags, B_LOCKED)) /* locked in core */ bufq = &bufqueues[BQ_LOCKED]; - else if (ISSET(bp->b_flags, B_AGE)) - /* stale but valid data */ - bufq = &bufqueues[BQ_AGE]; - else + else if (!ISSET(bp->b_flags, B_AGE)) /* valid data */ bufq = &bufqueues[BQ_LRU]; + else { + /* stale but valid data */ + int has_deps; + + if (LIST_FIRST(&bp->b_dep) != NULL && + bioops.io_countdeps) + has_deps = (*bioops.io_countdeps)(bp, 0); + else + has_deps = 0; + bufq = has_deps ? &bufqueues[BQ_LRU] : + &bufqueues[BQ_AGE]; + } binstailfree(bp, bufq); }