Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic in wdctimeout(), do not schedule another timeout ...



details:   https://anonhg.NetBSD.org/src/rev/4b0e72a5e7eb
branches:  trunk
changeset: 933188:4b0e72a5e7eb
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Thu May 21 09:24:17 2020 +0000

description:
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

diffstat:

 sys/dev/ic/wdc.c |  9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diffs (32 lines):

diff -r 6442769548a2 -r 4b0e72a5e7eb sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c  Thu May 21 09:11:33 2020 +0000
+++ b/sys/dev/ic/wdc.c  Thu May 21 09:24:17 2020 +0000
@@ -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 @@
         * 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);
 



Home | Main Index | Thread Index | Old Index