]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
blktap2: Fix event loop recursions in the I/O muxer.
authorDaniel Stodden <daniel.stodden@citrix.com>
Tue, 29 Jun 2010 20:03:09 +0000 (13:03 -0700)
committerDaniel Stodden <daniel.stodden@citrix.com>
Tue, 29 Jun 2010 20:03:09 +0000 (13:03 -0700)
Suffered from a one deadlock occasions and a potential crasher, due to
gc'ing event structs before unwinding.

Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
drivers/scheduler.c
drivers/tapdisk.h

index 7eacba7684f13327fd52843591dd98e0fb2bacb3..3274719ad22850edc4280e8a49dd1a7e8997aa18 100644 (file)
 #include <string.h>
 #include <sys/time.h>
 
+#include "tapdisk.h"
 #include "scheduler.h"
 #include "tapdisk-log.h"
 
 #define DBG(_f, _a...)               tlog_write(TLOG_DBG, _f, ##_a)
+#define BUG_ON(_cond)                if (_cond) td_panic()
 
 #define SCHEDULER_MAX_TIMEOUT        600
 #define SCHEDULER_POLL_FD           (SCHEDULER_POLL_READ_FD |  \
@@ -84,7 +86,7 @@ scheduler_prepare_events(scheduler_t *s)
        gettimeofday(&now, NULL);
 
        scheduler_for_each_event(s, event) {
-               if (event->masked)
+               if (event->masked || event->dead)
                        continue;
 
                if (event->mode & SCHEDULER_POLL_READ_FD) {
@@ -126,7 +128,7 @@ scheduler_check_events(scheduler_t *s, int nfds)
        gettimeofday(&now, NULL);
 
        scheduler_for_each_event(s, event) {
-               if (event->masked)
+               if (event->dead)
                        continue;
 
                if ((event->mode & SCHEDULER_POLL_READ_FD) &&
@@ -150,8 +152,10 @@ scheduler_check_events(scheduler_t *s, int nfds)
                        --nfds;
                }
 
-               if (event->pending)
+               if (event->pending) {
+                       BUG_ON(event->masked);
                        continue;
+               }
 
                if ((event->mode & SCHEDULER_POLL_TIMEOUT) &&
                    (event->deadline <= now.tv_sec))
@@ -314,12 +318,15 @@ scheduler_wait_for_events(scheduler_t *s)
                goto out;
 
        ret = scheduler_check_events(s, ret);
+       BUG_ON(ret);
 
        s->timeout     = SCHEDULER_MAX_TIMEOUT;
        s->max_timeout = SCHEDULER_MAX_TIMEOUT;
 
        scheduler_run_events(s);
-       scheduler_gc_events(s);
+
+       if (s->depth == 1)
+               scheduler_gc_events(s);
 
 out:
        s->depth--;
index bfcb6e66bc6ef560f502523ac9d0918a3981e79b..82b324d341595ef47561ca93a1fb23b951533f07 100644 (file)
@@ -152,4 +152,6 @@ struct tap_disk {
        void (*td_debug)             (td_driver_t *);
 };
 
+void td_panic(void);
+
 #endif