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
This commit is contained in:
oster 2005-09-25 19:47:17 +00:00
parent dee202322b
commit 96ba5552fa
4 changed files with 47 additions and 16 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/errno.h>
@ -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... */

View File

@ -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 {

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/errno.h>
@ -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;
}

View File

@ -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 <sys/cdefs.h>
__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 <sys/errno.h>
@ -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 */