From: jacob Date: Thu, 18 Nov 2004 19:17:18 +0000 (+0000) Subject: b=5246 X-Git-Tag: v1_8_0_110~486^5~105 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=68e715be735b5d8b0126d38334e3b05ce2c48b8a;p=fs%2Flustre-release.git b=5246 r=phil We can't use wait_for_completion() in the watchdog, because it sets TASK_UNINTERRUPTIBLE. We need to use wait_event_interruptible() or l_wait_event() instead. --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 2bd1182..04449b8 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -6,6 +6,7 @@ tbd Cluster File Systems, Inc. - return async write errors to application if possible (2248) - return last_committed value from OST to avoid OOM (4966) - memory shortage at startup could cause assertion (5176) + - the watchdog thread now runs as interruptible (5246) * miscellania - reorganization of lov code - single portals codebase diff --git a/lustre/portals/libcfs/watchdog.c b/lustre/portals/libcfs/watchdog.c index 6faebfb..91a077c 100644 --- a/lustre/portals/libcfs/watchdog.c +++ b/lustre/portals/libcfs/watchdog.c @@ -52,14 +52,14 @@ struct lc_watchdog { /* * The dispatcher will complete lcw_start_completion when it starts, * and lcw_stop_completion when it exits. - * Complete lcw_event_completion to signal timer callback dispatches. + * Wake lcw_event_waitq to signal timer callback dispatches. */ -struct completion lcw_start_completion; -struct completion lcw_event_completion; -struct completion lcw_stop_completion; +static struct completion lcw_start_completion; +static struct completion lcw_stop_completion; +static wait_queue_head_t lcw_event_waitq; /* - * Set this and complete lcw_event_completion to stop the dispatcher. + * Set this and wake lcw_event_waitq to stop the dispatcher. */ enum { LCW_FLAG_STOP = 0 @@ -128,13 +128,24 @@ static void lcw_cb(unsigned long data) spin_lock_irqsave(&lcw_pending_timers_lock, flags); if (list_empty(&lcw->lcw_list)) { list_add(&lcw->lcw_list, &lcw_pending_timers); - complete(&lcw_event_completion); + wake_up(&lcw_event_waitq); } spin_unlock_irqrestore(&lcw_pending_timers_lock, flags); EXIT; } +static int is_watchdog_fired(void) +{ + unsigned long flags; + + if (test_bit(LCW_FLAG_STOP, &lcw_flags)) + return 1; + + spin_lock_irqsave(&lcw_pending_timers_lock, flags); + return !list_empty(&lcw_pending_timers); +} + static int lcw_dispatch_main(void *data) { int rc = 0; @@ -154,7 +165,7 @@ static int lcw_dispatch_main(void *data) complete(&lcw_start_completion); while (1) { - wait_for_completion(&lcw_event_completion); + wait_event_interruptible(lcw_event_waitq, is_watchdog_fired()); CDEBUG(D_INFO, "Watchdog got woken up...\n"); if (test_bit(LCW_FLAG_STOP, &lcw_flags)) { CDEBUG(D_INFO, "LCW_FLAG_STOP was set, shutting down...\n"); @@ -208,7 +219,7 @@ static void lcw_dispatch_start(void) init_completion(&lcw_stop_completion); init_completion(&lcw_start_completion); - init_completion(&lcw_event_completion); + init_waitqueue_head(&lcw_event_waitq); CDEBUG(D_INFO, "starting dispatch thread\n"); rc = kernel_thread(lcw_dispatch_main, NULL, 0); @@ -231,7 +242,7 @@ static void lcw_dispatch_stop(void) CDEBUG(D_INFO, "trying to stop watchdog dispatcher.\n"); set_bit(LCW_FLAG_STOP, &lcw_flags); - complete(&lcw_event_completion); + wake_up(&lcw_event_waitq); wait_for_completion(&lcw_stop_completion);