Module Name:    src
Committed By:   jdolecek
Date:           Thu May 21 09:24:17 UTC 2020

Modified Files:
        src/sys/dev/ic: wdc.c

Log Message:
in wdctimeout(), do not schedule another timeout handler, as that only
creates race with eventual xfer resubmission - the c_intr()
method does all the necessary handling, including re-scheduling of the
timeout handler if appropriate

also make sure to clear ATACH_IRQ_WAIT before calling c_intr(), same
as real interrupt does; this is important so that eventual spurious timeout
would not interfere with xfer handling in the atabus thread

fixes another race in the atabus thread found by KASAN, reported by Paul Ripke


To generate a diff of this commit:
cvs rdiff -u -r1.300 -r1.301 src/sys/dev/ic/wdc.c

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/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.300 src/sys/dev/ic/wdc.c:1.301
--- src/sys/dev/ic/wdc.c:1.300	Tue May 19 08:21:29 2020
+++ src/sys/dev/ic/wdc.c	Thu May 21 09:24:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.300 2020/05/19 08:21:29 jdolecek Exp $ */
+/*	$NetBSD: wdc.c,v 1.301 2020/05/21 09:24:17 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.300 2020/05/19 08:21:29 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.301 2020/05/21 09:24:17 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -1375,12 +1375,9 @@ wdctimeout(void *arg)
 	 * Call the interrupt routine. If we just missed an interrupt,
 	 * it will do what's needed. Else, it will take the needed
 	 * action (reset the device).
-	 * Before that we need to reinstall the timeout callback,
-	 * in case it will miss another irq while in this transfer
-	 * We arbitray chose it to be 1s
 	 */
-	callout_reset(&chp->c_timo_callout, hz, wdctimeout, chp);
 	xfer->c_flags |= C_TIMEOU;
+	chp->ch_flags &= ~ATACH_IRQ_WAIT;
 	KASSERT(xfer->ops != NULL && xfer->ops->c_intr != NULL);
 	xfer->ops->c_intr(chp, xfer, 1);
 

Reply via email to