Module Name: src
Committed By: oster
Date: Mon Mar 23 18:38:54 UTC 2009
Modified Files:
src/sys/dev/raidframe: rf_dagfuncs.c rf_diskqueue.c rf_diskqueue.h
Log Message:
Rework/simplify the disk queuing code. A bunch of this was still
holdovers from the simulator and would never be seen/used in-kernel.
To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/raidframe/rf_dagfuncs.c
cvs rdiff -u -r1.51 -r1.52 src/sys/dev/raidframe/rf_diskqueue.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/raidframe/rf_diskqueue.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/raidframe/rf_dagfuncs.c
diff -u src/sys/dev/raidframe/rf_dagfuncs.c:1.29 src/sys/dev/raidframe/rf_dagfuncs.c:1.30
--- src/sys/dev/raidframe/rf_dagfuncs.c:1.29 Sun Mar 4 06:02:36 2007
+++ src/sys/dev/raidframe/rf_dagfuncs.c Mon Mar 23 18:38:54 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dagfuncs.c,v 1.29 2007/03/04 06:02:36 christos Exp $ */
+/* $NetBSD: rf_dagfuncs.c,v 1.30 2009/03/23 18:38:54 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_dagfuncs.c,v 1.29 2007/03/04 06:02:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagfuncs.c,v 1.30 2009/03/23 18:38:54 oster Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -366,7 +366,7 @@
NULL,
#endif
(void *) (node->dagHdr->raidPtr),
- RF_UNLOCK_DISK_QUEUE, NULL, PR_NOWAIT);
+ 0, NULL, PR_NOWAIT);
if (!req)
(node->wakeFunc) (node, ENOMEM);
else {
Index: src/sys/dev/raidframe/rf_diskqueue.c
diff -u src/sys/dev/raidframe/rf_diskqueue.c:1.51 src/sys/dev/raidframe/rf_diskqueue.c:1.52
--- src/sys/dev/raidframe/rf_diskqueue.c:1.51 Tue Jun 17 14:53:11 2008
+++ src/sys/dev/raidframe/rf_diskqueue.c Mon Mar 23 18:38:54 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_diskqueue.c,v 1.51 2008/06/17 14:53:11 reinoud Exp $ */
+/* $NetBSD: rf_diskqueue.c,v 1.52 2009/03/23 18:38:54 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -66,7 +66,7 @@
****************************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_diskqueue.c,v 1.51 2008/06/17 14:53:11 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_diskqueue.c,v 1.52 2009/03/23 18:38:54 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -169,7 +169,6 @@
diskqueue->queueLength = 0;
diskqueue->maxOutstanding = maxOutstanding;
diskqueue->curPriority = RF_IO_NORMAL_PRIORITY;
- diskqueue->nextLockingOp = NULL;
diskqueue->flags = 0;
diskqueue->raidPtr = raidPtr;
diskqueue->rf_cinfo = &raidPtr->raid_cinfo[c];
@@ -252,10 +251,6 @@
}
/* Enqueue a disk I/O
*
- * Unfortunately, we have to do things differently in the different
- * environments (simulator, user-level, kernel).
- * At user level, all I/O is blocking, so we have 1 or more threads/disk
- * and the thread that enqueues is different from the thread that dequeues.
* In the kernel, I/O is non-blocking and so we'd like to have multiple
* I/Os outstanding on the physical disks when possible.
*
@@ -264,20 +259,10 @@
* queue it up
*
* kernel rules for when to do what:
- * locking request: queue empty => dispatch and lock queue,
- * else queue it
* unlocking req : always dispatch it
* normal req : queue empty => dispatch it & set priority
* queue not full & priority is ok => dispatch it
* else queue it
- *
- * user-level rules:
- * always enqueue. In the special case of an unlocking op, enqueue
- * in a special way that will cause the unlocking op to be the next
- * thing dequeued.
- *
- * simulator rules:
- * Do the same as at user level, with the sleeps and wakeups suppressed.
*/
void
rf_DiskIOEnqueue(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req, int pri)
@@ -291,65 +276,27 @@
printf("Warning: Enqueueing zero-sector access\n");
}
#endif
- /*
- * kernel
- */
RF_LOCK_QUEUE_MUTEX(queue, "DiskIOEnqueue");
- /* locking request */
- if (RF_LOCKING_REQ(req)) {
- if (RF_QUEUE_EMPTY(queue)) {
- Dprintf2("Dispatching pri %d locking op to c %d (queue empty)\n", pri, queue->col);
- RF_LOCK_QUEUE(queue);
- rf_DispatchKernelIO(queue, req);
- } else {
- queue->queueLength++; /* increment count of number
- * of requests waiting in this
- * queue */
- Dprintf2("Enqueueing pri %d locking op to c %d (queue not empty)\n", pri, queue->col);
- req->queue = (void *) queue;
- (queue->qPtr->Enqueue) (queue->qHdr, req, pri);
- }
+ if (RF_OK_TO_DISPATCH(queue, req)) {
+ Dprintf2("Dispatching pri %d regular op to c %d (ok to dispatch)\n", pri, queue->col);
+ rf_DispatchKernelIO(queue, req);
+ } else {
+ queue->queueLength++; /* increment count of number of requests waiting in this queue */
+ Dprintf2("Enqueueing pri %d regular op to c %d (not ok to dispatch)\n", pri, queue->col);
+ req->queue = (void *) queue;
+ (queue->qPtr->Enqueue) (queue->qHdr, req, pri);
}
- /* unlocking request */
- else
- if (RF_UNLOCKING_REQ(req)) { /* we'll do the actual unlock
- * when this I/O completes */
- Dprintf2("Dispatching pri %d unlocking op to c %d\n", pri, queue->col);
- RF_ASSERT(RF_QUEUE_LOCKED(queue));
- rf_DispatchKernelIO(queue, req);
- }
- /* normal request */
- else
- if (RF_OK_TO_DISPATCH(queue, req)) {
- Dprintf2("Dispatching pri %d regular op to c %d (ok to dispatch)\n", pri, queue->col);
- rf_DispatchKernelIO(queue, req);
- } else {
- queue->queueLength++; /* increment count of
- * number of requests
- * waiting in this queue */
- Dprintf2("Enqueueing pri %d regular op to c %d (not ok to dispatch)\n", pri, queue->col);
- req->queue = (void *) queue;
- (queue->qPtr->Enqueue) (queue->qHdr, req, pri);
- }
RF_UNLOCK_QUEUE_MUTEX(queue, "DiskIOEnqueue");
}
-/* get the next set of I/Os started, kernel version only */
+/* get the next set of I/Os started */
void
rf_DiskIOComplete(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req, int status)
{
int done = 0;
RF_LOCK_QUEUE_MUTEX(queue, "DiskIOComplete");
-
- /* unlock the queue: (1) after an unlocking req completes (2) after a
- * locking req fails */
- if (RF_UNLOCKING_REQ(req) || (RF_LOCKING_REQ(req) && status)) {
- Dprintf1("DiskIOComplete: unlocking queue at c %d\n", queue->col);
- RF_ASSERT(RF_QUEUE_LOCKED(queue));
- RF_UNLOCK_QUEUE(queue);
- }
queue->numOutstanding--;
RF_ASSERT(queue->numOutstanding >= 0);
@@ -357,64 +304,27 @@
/* no reason to continue once we've filled up the queue */
/* no reason to even start if the queue is locked */
- while (!done && !RF_QUEUE_FULL(queue) && !RF_QUEUE_LOCKED(queue)) {
- if (queue->nextLockingOp) {
- req = queue->nextLockingOp;
- queue->nextLockingOp = NULL;
- Dprintf2("DiskIOComplete: a pri %d locking req was pending at c %d\n", req->priority, queue->col);
- } else {
- req = (queue->qPtr->Dequeue) (queue->qHdr);
- if (req != NULL) {
- Dprintf2("DiskIOComplete: extracting pri %d req from queue at c %d\n", req->priority, queue->col);
- } else {
- Dprintf1("DiskIOComplete: no more requests to extract.\n", "");
- }
- }
+ while (!done && !RF_QUEUE_FULL(queue)) {
+ req = (queue->qPtr->Dequeue) (queue->qHdr);
if (req) {
- queue->queueLength--; /* decrement count of number
- * of requests waiting in this
- * queue */
+ Dprintf2("DiskIOComplete: extracting pri %d req from queue at c %d\n", req->priority, queue->col);
+ queue->queueLength--; /* decrement count of number of requests waiting in this queue */
RF_ASSERT(queue->queueLength >= 0);
- }
- if (!req)
+ if (RF_OK_TO_DISPATCH(queue, req)) {
+ Dprintf2("DiskIOComplete: dispatching pri %d regular req to c %d (ok to dispatch)\n", req->priority, queue->col);
+ rf_DispatchKernelIO(queue, req);
+ } else {
+ /* we can't dispatch it, so just re-enqueue it.
+ potential trouble here if disk queues batch reqs */
+ Dprintf2("DiskIOComplete: re-enqueueing pri %d regular req to c %d\n", req->priority, queue->col);
+ queue->queueLength++;
+ (queue->qPtr->Enqueue) (queue->qHdr, req, req->priority);
+ done = 1;
+ }
+ } else {
+ Dprintf1("DiskIOComplete: no more requests to extract.\n", "");
done = 1;
- else
- if (RF_LOCKING_REQ(req)) {
- if (RF_QUEUE_EMPTY(queue)) { /* dispatch it */
- Dprintf2("DiskIOComplete: dispatching pri %d locking req to c %d (queue empty)\n", req->priority, queue->col);
- RF_LOCK_QUEUE(queue);
- rf_DispatchKernelIO(queue, req);
- done = 1;
- } else { /* put it aside to wait for
- * the queue to drain */
- Dprintf2("DiskIOComplete: postponing pri %d locking req to c %d\n", req->priority, queue->col);
- RF_ASSERT(queue->nextLockingOp == NULL);
- queue->nextLockingOp = req;
- done = 1;
- }
- } else
- if (RF_UNLOCKING_REQ(req)) { /* should not happen:
- * unlocking ops should
- * not get queued */
- RF_ASSERT(RF_QUEUE_LOCKED(queue)); /* support it anyway for
- * the future */
- Dprintf2("DiskIOComplete: dispatching pri %d unl req to c %d (SHOULD NOT SEE THIS)\n", req->priority, queue->col);
- rf_DispatchKernelIO(queue, req);
- done = 1;
- } else
- if (RF_OK_TO_DISPATCH(queue, req)) {
- Dprintf2("DiskIOComplete: dispatching pri %d regular req to c %d (ok to dispatch)\n", req->priority, queue->col);
- rf_DispatchKernelIO(queue, req);
- } else { /* we can't dispatch it,
- * so just re-enqueue
- * it. */
- /* potential trouble here if
- * disk queues batch reqs */
- Dprintf2("DiskIOComplete: re-enqueueing pri %d regular req to c %d\n", req->priority, queue->col);
- queue->queueLength++;
- (queue->qPtr->Enqueue) (queue->qHdr, req, req->priority);
- done = 1;
- }
+ }
}
RF_UNLOCK_QUEUE_MUTEX(queue, "DiskIOComplete");
Index: src/sys/dev/raidframe/rf_diskqueue.h
diff -u src/sys/dev/raidframe/rf_diskqueue.h:1.22 src/sys/dev/raidframe/rf_diskqueue.h:1.23
--- src/sys/dev/raidframe/rf_diskqueue.h:1.22 Sun Mar 4 06:02:37 2007
+++ src/sys/dev/raidframe/rf_diskqueue.h Mon Mar 23 18:38:54 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_diskqueue.h,v 1.22 2007/03/04 06:02:37 christos Exp $ */
+/* $NetBSD: rf_diskqueue.h,v 1.23 2009/03/23 18:38:54 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -82,8 +82,6 @@
int error; /* Indicate if an error occurred
on this I/O (1=yes, 0=no) */
};
-#define RF_LOCK_DISK_QUEUE 0x01
-#define RF_UNLOCK_DISK_QUEUE 0x02
/* note: "Create" returns type-specific queue header pointer cast to (void *) */
struct RF_DiskQueueSW_s {
@@ -114,10 +112,6 @@
int curPriority; /* the priority of accs all that are currently
* outstanding */
long queueLength; /* number of requests in queue */
- RF_DiskQueueData_t *nextLockingOp; /* a locking op that has
- * arrived at the head of the
- * queue & is waiting for
- * drainage */
RF_DiskQueueFlags_t flags; /* terminate, locked */
RF_Raid_t *raidPtr; /* associated array */
dev_t dev; /* device number for kernel version */
@@ -130,19 +124,12 @@
* explicitly unlocked */
/* macros setting & returning information about queues and requests */
-#define RF_QUEUE_LOCKED(_q) ((_q)->flags & RF_DQ_LOCKED)
-#define RF_QUEUE_EMPTY(_q) (((_q)->numOutstanding == 0) && ((_q)->nextLockingOp == NULL) && !RF_QUEUE_LOCKED(_q))
+#define RF_QUEUE_EMPTY(_q) ((_q)->numOutstanding == 0)
#define RF_QUEUE_FULL(_q) ((_q)->numOutstanding == (_q)->maxOutstanding)
-#define RF_LOCK_QUEUE(_q) (_q)->flags |= RF_DQ_LOCKED
-#define RF_UNLOCK_QUEUE(_q) (_q)->flags &= ~RF_DQ_LOCKED
-
#define RF_LOCK_QUEUE_MUTEX(_q_,_wh_) RF_LOCK_MUTEX((_q_)->mutex)
#define RF_UNLOCK_QUEUE_MUTEX(_q_,_wh_) RF_UNLOCK_MUTEX((_q_)->mutex)
-#define RF_LOCKING_REQ(_r) ((_r)->flags & RF_LOCK_DISK_QUEUE)
-#define RF_UNLOCKING_REQ(_r) ((_r)->flags & RF_UNLOCK_DISK_QUEUE)
-
/* whether it is ok to dispatch a regular request */
#define RF_OK_TO_DISPATCH(_q_,_r_) \
(RF_QUEUE_EMPTY(_q_) || \