From 96ba5552faacd92218f0b82b6b17c5e0a0dd811f Mon Sep 17 00:00:00 2001 From: oster Date: Sun, 25 Sep 2005 19:47:17 +0000 Subject: [PATCH] Re-work the handling of incoming I/O in RAIDframe: - introduce rf_buf_queue_check() which checks to see if there is work to do in the incoming buffer queue - rf_RaidIOThread() is now responsible for calling raidstart(), and is also now the only place that calls raidstart() - raidstrategy() now just queues requests in buf_queue and signals rf_RaidIOThread() that work has arrived Hopefully addresses PR#30233 --- sys/dev/raidframe/rf_engine.c | 26 ++++++++++++++++++-------- sys/dev/raidframe/rf_netbsd.h | 3 ++- sys/dev/raidframe/rf_netbsdkintf.c | 27 ++++++++++++++++++++++++--- sys/dev/raidframe/rf_states.c | 7 +++---- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/sys/dev/raidframe/rf_engine.c b/sys/dev/raidframe/rf_engine.c index de2f879922fa..d850f90f5499 100644 --- a/sys/dev/raidframe/rf_engine.c +++ b/sys/dev/raidframe/rf_engine.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_engine.c,v 1.35 2005/02/27 00:27:44 perry Exp $ */ +/* $NetBSD: rf_engine.c,v 1.36 2005/09/25 19:47:17 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -55,7 +55,7 @@ ****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.35 2005/02/27 00:27:44 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.36 2005/09/25 19:47:17 oster Exp $"); #include @@ -67,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.35 2005/02/27 00:27:44 perry Exp $") #include "rf_dagutils.h" #include "rf_shutdown.h" #include "rf_raid.h" +#include "rf_kintf.h" static void rf_ShutdownEngine(void *); static void DAGExecutionThread(RF_ThreadArg_t arg); @@ -825,11 +826,13 @@ DAGExecutionThread(RF_ThreadArg_t arg) } /* - * rf_RaidIOThread() -- When I/O to a component completes, - * KernelWakeupFunc() puts the completed request onto raidPtr->iodone - * TAILQ. This function looks after requests on that queue by calling - * rf_DiskIOComplete() for the request, and by calling any required - * CompleteFunc for the request. + * rf_RaidIOThread() -- When I/O to a component begins, raidstrategy() + * puts the I/O on a buf_queue, and then signals raidPtr->iodone. If + * necessary, this function calls raidstart() to initiate the I/O. + * When I/O to a component completes, KernelWakeupFunc() puts the + * completed request onto raidPtr->iodone TAILQ. This function looks + * after requests on that queue by calling rf_DiskIOComplete() for the + * request, and by calling any required CompleteFunc for the request. */ static void @@ -846,7 +849,8 @@ rf_RaidIOThread(RF_ThreadArg_t arg) while (!raidPtr->shutdown_raidio) { /* if there is nothing to do, then snooze. */ - if (TAILQ_EMPTY(&(raidPtr->iodone))) { + if (TAILQ_EMPTY(&(raidPtr->iodone)) && + rf_buf_queue_check(raidPtr->raidid)) { ltsleep(&(raidPtr->iodone), PRIBIO, "raidiow", 0, &(raidPtr->iodone_lock)); } @@ -859,6 +863,12 @@ rf_RaidIOThread(RF_ThreadArg_t arg) (req->CompleteFunc) (req->argument, req->error); simple_lock(&(raidPtr->iodone_lock)); } + + /* process any pending outgoing IO */ + simple_unlock(&(raidPtr->iodone_lock)); + raidstart(raidPtr); + simple_lock(&(raidPtr->iodone_lock)); + } /* Let rf_ShutdownEngine know that we're done... */ diff --git a/sys/dev/raidframe/rf_netbsd.h b/sys/dev/raidframe/rf_netbsd.h index 8a282507ff90..bf58444669f0 100644 --- a/sys/dev/raidframe/rf_netbsd.h +++ b/sys/dev/raidframe/rf_netbsd.h @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsd.h,v 1.23 2005/05/29 22:03:09 christos Exp $ */ +/* $NetBSD: rf_netbsd.h,v 1.24 2005/09/25 19:47:17 oster Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -90,6 +90,7 @@ struct RF_Pools_s { extern struct RF_Pools_s rf_pools; void rf_pool_init(struct pool *, size_t, const char *, size_t, size_t); +int rf_buf_queue_check(int); /* XXX probably belongs in a different .h file. */ typedef struct RF_AutoConfig_s { diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index 28b5256c14ce..b16d3b1032c1 100644 --- a/sys/dev/raidframe/rf_netbsdkintf.c +++ b/sys/dev/raidframe/rf_netbsdkintf.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsdkintf.c,v 1.189 2005/09/24 22:51:55 oster Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.190 2005/09/25 19:47:17 oster Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. @@ -146,7 +146,7 @@ ***********************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.189 2005/09/24 22:51:55 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.190 2005/09/25 19:47:17 oster Exp $"); #include #include @@ -735,7 +735,8 @@ raidstrategy(struct buf *bp) /* stuff it onto our queue */ BUFQ_PUT(&rs->buf_queue, bp); - raidstart(raidPtrs[raidID]); + /* scheduled the IO to happen at the next convenient time */ + wakeup(&(raidPtrs[raidID]->iodone)); splx(s); } @@ -3330,3 +3331,23 @@ rf_pool_init(struct pool *p, size_t size, const char *w_chan, pool_prime(p, xmin); pool_setlowat(p, xmin); } + +/* + * rf_buf_queue_check(int raidid) -- looks into the buf_queue to see + * if there is IO pending and if that IO could possibly be done for a + * given RAID set. Returns 0 if IO is waiting and can be done, 1 + * otherwise. + * + */ + +int +rf_buf_queue_check(int raidid) +{ + if ((BUFQ_PEEK(&(raid_softc[raidid].buf_queue)) != NULL) && + raidPtrs[raidid]->openings > 0) { + /* there is work to do */ + return 0; + } + /* default is nothing to do */ + return 1; +} diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c index a08763ecbe1e..06c9c816f364 100644 --- a/sys/dev/raidframe/rf_states.c +++ b/sys/dev/raidframe/rf_states.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_states.c,v 1.38 2005/02/27 00:27:45 perry Exp $ */ +/* $NetBSD: rf_states.c,v 1.39 2005/09/25 19:47:17 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.38 2005/02/27 00:27:45 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.39 2005/09/25 19:47:17 oster Exp $"); #include @@ -235,8 +235,7 @@ rf_State_LastState(RF_RaidAccessDesc_t *desc) ((RF_Raid_t *) desc->raidPtr)->openings++; RF_UNLOCK_MUTEX(((RF_Raid_t *) desc->raidPtr)->mutex); - /* wake up any pending IO */ - raidstart(((RF_Raid_t *) desc->raidPtr)); + wakeup(&(desc->raidPtr->iodone)); /* printf("Calling biodone on 0x%x\n",desc->bp); */ biodone(desc->bp); /* access came through ioctl */