Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/raidframe As part of the effort to get RAIDframe pla...



details:   https://anonhg.NetBSD.org/src/rev/f3c6f23a9a22
branches:  trunk
changeset: 537703:f3c6f23a9a22
user:      oster <oster%NetBSD.org@localhost>
date:      Fri Oct 04 20:05:14 2002 +0000

description:
As part of the effort to get RAIDframe playing nicely with LOCKDEBUG,
rework how completed requests are handled.  In particular, instead of
doing all sorts of work and locking in interrupt context, completed
requests are now queued.  A new kernel thread (rf_RaidIOThread) now
handles calling rf_DiskIOComplete() and (req->CompleteFunc)() for each
completed request.  There is still work to be done to make RAIDframe
LOCKDEBUG friendly, but this change is a huge step forward.

Reviewed by (and many thanks to): thorpej

diffstat:

 sys/dev/raidframe/rf_diskqueue.h   |  10 +++-
 sys/dev/raidframe/rf_driver.c      |   7 ++-
 sys/dev/raidframe/rf_engine.c      |  81 ++++++++++++++++++++++++++++++++++++-
 sys/dev/raidframe/rf_netbsdkintf.c |  19 +++++++-
 sys/dev/raidframe/rf_raid.h        |  13 +++++-
 5 files changed, 116 insertions(+), 14 deletions(-)

diffs (278 lines):

diff -r bb374f7131bf -r f3c6f23a9a22 sys/dev/raidframe/rf_diskqueue.h
--- a/sys/dev/raidframe/rf_diskqueue.h  Fri Oct 04 20:00:00 2002 +0000
+++ b/sys/dev/raidframe/rf_diskqueue.h  Fri Oct 04 20:05:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_diskqueue.h,v 1.10 2002/09/15 21:34:03 oster Exp $  */
+/*     $NetBSD: rf_diskqueue.h,v 1.11 2002/10/04 20:05:14 oster Exp $  */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -38,14 +38,14 @@
 #ifndef _RF__RF_DISKQUEUE_H_
 #define _RF__RF_DISKQUEUE_H_
 
+#include <sys/queue.h>
+
 #include <dev/raidframe/raidframevar.h>
 
 #include "rf_threadstuff.h"
 #include "rf_acctrace.h"
 #include "rf_alloclist.h"
 #include "rf_etimer.h"
-
-
 #include "rf_netbsd.h"
 
 
@@ -77,6 +77,10 @@
        struct proc *b_proc;    /* the b_proc from the original bp passed into
                                 * the driver for this I/O */
        struct buf *bp;         /* a bp to use to get this I/O done */
+       /* TAILQ bits for a queue for completed I/O requests */
+       TAILQ_ENTRY(RF_DiskQueueData_s) iodone_entries; 
+       int  error;             /* Indicate if an error occured 
+                                  on this I/O (1=yes, 0=no) */
 };
 #define RF_LOCK_DISK_QUEUE   0x01
 #define RF_UNLOCK_DISK_QUEUE 0x02
diff -r bb374f7131bf -r f3c6f23a9a22 sys/dev/raidframe/rf_driver.c
--- a/sys/dev/raidframe/rf_driver.c     Fri Oct 04 20:00:00 2002 +0000
+++ b/sys/dev/raidframe/rf_driver.c     Fri Oct 04 20:05:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_driver.c,v 1.63 2002/09/23 04:14:20 oster Exp $     */
+/*     $NetBSD: rf_driver.c,v 1.64 2002/10/04 20:05:14 oster Exp $     */
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -73,7 +73,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.63 2002/09/23 04:14:20 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.64 2002/10/04 20:05:14 oster Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -402,6 +402,9 @@
                raidPtr->reconControl[i] = NULL;
        }
 
+       TAILQ_INIT(&(raidPtr->iodone));
+       simple_lock_init(&(raidPtr->iodone_lock));
+
        DO_RAID_INIT_CONFIGURE(rf_ConfigureEngine);
        DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLocks);
 
diff -r bb374f7131bf -r f3c6f23a9a22 sys/dev/raidframe/rf_engine.c
--- a/sys/dev/raidframe/rf_engine.c     Fri Oct 04 20:00:00 2002 +0000
+++ b/sys/dev/raidframe/rf_engine.c     Fri Oct 04 20:05:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_engine.c,v 1.21 2002/10/02 21:48:00 oster Exp $     */
+/*     $NetBSD: rf_engine.c,v 1.22 2002/10/04 20:05:15 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.21 2002/10/02 21:48:00 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.22 2002/10/04 20:05:15 oster Exp $");
 
 #include "rf_threadstuff.h"
 
@@ -70,6 +70,7 @@
 #include "rf_raid.h"
 
 static void DAGExecutionThread(RF_ThreadArg_t arg);
+static void rf_RaidIOThread(RF_ThreadArg_t arg);
 
 #define DO_INIT(_l_,_r_) { \
   int _rc; \
@@ -110,10 +111,29 @@
        void   *arg;
 {
        RF_Raid_t *raidPtr;
+       int ks;
 
        raidPtr = (RF_Raid_t *) arg;
-       raidPtr->shutdown_engine = 1;
-       DO_SIGNAL(raidPtr);
+
+       /* Tell the rf_RaidIOThread to shutdown */
+       simple_lock(&(raidPtr->iodone_lock));
+
+       raidPtr->shutdown_raidio = 1;
+       wakeup(&(raidPtr->iodone));
+
+       /* ...and wait for it to tell us it has finished */
+       while (raidPtr->shutdown_raidio)
+               ltsleep(&(raidPtr->shutdown_raidio), PRIBIO, "raidshutdown", 0,
+                       &(raidPtr->iodone_lock));
+
+       simple_unlock(&(raidPtr->iodone_lock));
+
+       /* Now shut down the DAG execution engine. */
+       DO_LOCK(raidPtr);
+       raidPtr->shutdown_engine = 1;
+       DO_SIGNAL(raidPtr);
+       DO_UNLOCK(raidPtr);
+
 }
 
 int 
@@ -143,6 +163,13 @@
                RF_ERRORMSG("RAIDFRAME: Unable to create engine thread\n");
                return (ENOMEM);
        }
+       if (RF_CREATE_ENGINE_THREAD(raidPtr->engine_helper_thread,
+                                   rf_RaidIOThread, raidPtr, 
+                                   "raidio%d", raidPtr->raidid)) {
+               printf("raid%d: Unable to create raidio thread\n", 
+                      raidPtr->raidid);
+               return (ENOMEM);
+       }
        if (rf_engineDebug) {
                printf("raid%d: Created engine thread\n", raidPtr->raidid);
        }
@@ -811,3 +838,49 @@
        splx(s);
        kthread_exit(0);
 }
+
+/* 
+   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.
+*/
+
+static void
+rf_RaidIOThread(RF_ThreadArg_t arg)
+{
+       RF_Raid_t *raidPtr;
+       RF_DiskQueueData_t *req;
+       int s;
+
+       raidPtr = (RF_Raid_t *) arg;
+
+       s = splbio();
+       simple_lock(&(raidPtr->iodone_lock));
+
+       while (!raidPtr->shutdown_raidio) {
+               /* if there is nothing to do, then snooze. */
+               if (TAILQ_EMPTY(&(raidPtr->iodone))) {
+                       ltsleep(&(raidPtr->iodone), PRIBIO, "raidiow", 0,
+                               &(raidPtr->iodone_lock));
+               }
+
+               /* See what I/Os, if any, have arrived */
+               while ((req = TAILQ_FIRST(&(raidPtr->iodone))) != NULL) {
+                       TAILQ_REMOVE(&(raidPtr->iodone), req, iodone_entries);
+                       simple_unlock(&(raidPtr->iodone_lock));
+                       rf_DiskIOComplete(req->queue, req, req->error);
+                       (req->CompleteFunc) (req->argument, req->error);
+                       simple_lock(&(raidPtr->iodone_lock));
+               }
+       }
+
+       /* Let rf_ShutdownEngine know that we're done... */
+       raidPtr->shutdown_raidio = 0;
+       wakeup(&(raidPtr->shutdown_raidio));
+
+       simple_unlock(&(raidPtr->iodone_lock));
+       splx(s);
+
+       kthread_exit(0);
+}
diff -r bb374f7131bf -r f3c6f23a9a22 sys/dev/raidframe/rf_netbsdkintf.c
--- a/sys/dev/raidframe/rf_netbsdkintf.c        Fri Oct 04 20:00:00 2002 +0000
+++ b/sys/dev/raidframe/rf_netbsdkintf.c        Fri Oct 04 20:05:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_netbsdkintf.c,v 1.142 2002/10/01 18:11:57 thorpej Exp $     */
+/*     $NetBSD: rf_netbsdkintf.c,v 1.143 2002/10/04 20:05:14 oster Exp $       */
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -114,7 +114,7 @@
  ***********************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.142 2002/10/01 18:11:57 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.143 2002/10/04 20:05:14 oster Exp $");
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -1931,8 +1931,19 @@
 
        pool_put(&raidframe_cbufpool, raidbp);
 
-       rf_DiskIOComplete(queue, req, (bp->b_flags & B_ERROR) ? 1 : 0);
-       (req->CompleteFunc) (req->argument, (bp->b_flags & B_ERROR) ? 1 : 0);
+       /* Fill in the error value */
+
+       req->error = (bp->b_flags & B_ERROR) ? bp->b_error : 0;
+
+       simple_lock(&queue->raidPtr->iodone_lock);
+
+       /* Drop this one on the "finished" queue... */
+       TAILQ_INSERT_TAIL(&(queue->raidPtr->iodone), req, iodone_entries);
+
+       /* Let the raidio thread know there is work to be done. */
+       wakeup(&(queue->raidPtr->iodone));
+
+       simple_unlock(&queue->raidPtr->iodone_lock);
 
        splx(s);
 }
diff -r bb374f7131bf -r f3c6f23a9a22 sys/dev/raidframe/rf_raid.h
--- a/sys/dev/raidframe/rf_raid.h       Fri Oct 04 20:00:00 2002 +0000
+++ b/sys/dev/raidframe/rf_raid.h       Fri Oct 04 20:05:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_raid.h,v 1.14 2001/10/04 15:58:55 oster Exp $       */
+/*     $NetBSD: rf_raid.h,v 1.15 2002/10/04 20:05:14 oster Exp $       */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -42,6 +42,7 @@
 
 #include <sys/disklabel.h>
 #include <sys/types.h>
+#include <sys/queue.h>
 
 #include "rf_alloclist.h"
 #include "rf_stripelocks.h"
@@ -51,6 +52,7 @@
 #include "rf_diskqueue.h"
 #include "rf_reconstruct.h"
 #include "rf_acctrace.h"
+#include "rf_fifo.h"
 
 #if RF_INCLUDE_PARITYLOGGING > 0
 #include "rf_paritylog.h"
@@ -157,6 +159,13 @@
                                 This may be in conflict with last_unit!!?! */
                              /* Not currently used. */
 
+       /* queue to gather up requests from KernelWakeupFunc() and let
+          a kernel thread deal with calling rf_DiskIOComplete and any
+          callback functions. */
+       TAILQ_HEAD(iodone_q,RF_DiskQueueData_s) iodone; 
+       /* and a lock to protect it */
+       struct simplelock iodone_lock;
+
        /*
          * Cleanup stuff
          */
@@ -210,9 +219,11 @@
        RF_Thread_t parity_rewrite_thread;
        RF_Thread_t copyback_thread;
        RF_Thread_t engine_thread;
+       RF_Thread_t engine_helper_thread;
        RF_Thread_t recon_thread;
        RF_ThreadGroup_t engine_tg;
        int     shutdown_engine;
+       int     shutdown_raidio;
        int     dags_in_flight; /* debug */
 
        /*



Home | Main Index | Thread Index | Old Index