From a65a0da2f93d5c227afd0f64f15a16adfa1a8ba1 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Fri, 28 Oct 2005 20:25:02 +0000 Subject: [PATCH] Fix possible live-lock under heavy load where we can't allocate more memory for request. I was sure graid3 should handle such situations well, but green@ reported it is not and we want to fix it before 6.0. Submitted by: green --- sys/geom/raid3/g_raid3.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index e60bf9b75f44..65f4c0f03dc7 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -966,7 +966,7 @@ g_raid3_clone_bio(struct g_raid3_softc *sc, struct bio *pbp) if (cbp->bio_data == NULL) { if (size > 16384) g_raid3_64k_failed++; - if (size > 4096) + else if (size > 4096) g_raid3_16k_failed++; else g_raid3_4k_failed++; @@ -1560,6 +1560,17 @@ g_raid3_register_request(struct bio *pbp) if (cbp == NULL) { while ((cbp = G_RAID3_HEAD_BIO(pbp)) != NULL) g_raid3_destroy_bio(sc, cbp); + /* + * To prevent deadlock, we must run back up + * with the ENOMEM for failed requests of any + * of our consumers. Our own sync requests + * can stick around, as they are finite. + */ + if ((pbp->bio_cflags & + G_RAID3_BIO_CFLAG_REGULAR) != 0) { + g_io_deliver(pbp, ENOMEM); + return (0); + } return (ENOMEM); } cbp->bio_offset = offset;