Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/dev Pull up following revision(s) (requested by tsuts...
details: https://anonhg.NetBSD.org/src/rev/9176a3ffafe0
branches: netbsd-9
changeset: 372848:9176a3ffafe0
user: martin <martin%NetBSD.org@localhost>
date: Fri Dec 30 14:39:09 2022 +0000
description:
Pull up following revision(s) (requested by tsutsui in ticket #1557):
sys/dev/ic/ahcisata_core.c: revision 1.83
sys/dev/ic/ahcisata_core.c: revision 1.102
sys/dev/ata/ata.c: revision 1.164
sys/dev/ata/ata_wdc.c: revision 1.115
sys/dev/ata/ata_recovery.c: revision 1.4
sys/dev/ic/siisata.c: revision 1.42
sys/dev/ic/wdc.c: revision 1.308
sys/dev/ic/mvsata.c: revision 1.56
sys/dev/scsipi/atapi_wdc.c: revision 1.138
sys/dev/ic/siisata.c: revision 1.49
sys/dev/ata/atavar.h: revision 1.105
sys/dev/ata/wd.c: revision 1.460
sys/dev/ata/ata.c: revision 1.155
sys/dev/ata/wd.c: revision 1.462
sys/dev/ata/atavar.h: revision 1.109
sys/dev/ata/satapmp_subr.c: revision 1.16
sys/dev/ic/wdc.c: revision 1.299
sys/dev/ic/ahcisata_core.c: revision 1.93
sys/dev/ata/ata_wdc.c: revision 1.120
sys/dev/ic/wdcvar.h: revision 1.100
sys/dev/scsipi/atapi_wdc.c: revision 1.141
sys/dev/ic/mvsata.c: revision 1.61
sys/dev/usb/umass_isdata.c (apply patch)
drop wd lock in wdstart1() before calling the ata_bio hook; when called
from ata thread context, that can still need to sleep for wdc attachments
in wdcwait()
fix use-after-free for ata xfer on bio submission found by KASAN
driver ata_bio hooks read parts of the xfer after ata_exec_xfer()
call in order to determine return value, change so that the hook
doesn't return any value - callers do not care already,
as all I/O requests are asynchronous
this problem was uncovered by recent change for wd(4) to not hold
wd mutex during ata_bio call, the interrupt for the xfer might
thus actually fire immediately
adjust also ata_exec_command driver hooks similarily - remove all
completion and waiting logic from drivers, upper layer ata code
using AT_WAIT/AT_POLL changed to call ata_wait_cmd() itself
PR kern/55169 by Nick Hudson
Function declaration formating whitespace consistency. NFCI.
PR kern/56403
Fix kernel freeze for wdc(4) variants with ATAC_CAP_NOIRQ:
(1) Change ata_xfer_ops:c_poll from void to int function. When it returns
ATAPOLL_AGAIN, let ata_xfer_start() iterate itself again.
(2) Let wdc_ata_bio_poll() return ATAPOLL_AGAIN until ATA_ITSDONE is
achieved.
A similar change has been made for mvsata(4) (see mvsata_bio_poll()),
and no functional changes for other devices.
This is how the drivers worked before jdolecek-ncq branch was merged.
Note that this changes are less likely to cause infinite recursion:
(1) wdc_ata_bio_intr() called from wdc_ata_bio_poll() asserts ATA_ITSDONE
in its error handling paths via wdc_ata_bio_done().
(2) Return value from c_start (= wdc_ata_bio_start()) is checked in
ata_xfer_start().
Therefore, errors encountered in ata_xfer_ops:c_poll and c_start routines
terminate the recursion for wdc(4). The situation is similar for mvsata(4).
Still, there is a possibility where ata_xfer_start() takes long time to
finish a normal operation. This can result in a delayed response for lower
priority interrupts. But, I've never observed such a situation, even when
heavy thrashing takes place for swap partition in wd(4).
"Go ahead" by jdolecek@.
diffstat:
sys/dev/ata/ata.c | 27 +++++-------
sys/dev/ata/ata_recovery.c | 12 ++---
sys/dev/ata/ata_wdc.c | 22 +++++----
sys/dev/ata/atavar.h | 10 ++-
sys/dev/ata/satapmp_subr.c | 26 ++++-------
sys/dev/ata/wd.c | 97 +++++++++++++++++----------------------------
sys/dev/ic/ahcisata_core.c | 58 +++++++++-----------------
sys/dev/ic/mvsata.c | 61 +++++++++++-----------------
sys/dev/ic/siisata.c | 56 +++++++++-----------------
sys/dev/ic/wdc.c | 30 ++-----------
sys/dev/ic/wdcvar.h | 4 +-
sys/dev/scsipi/atapi_wdc.c | 22 +++++-----
sys/dev/usb/umass_isdata.c | 40 +++++++-----------
13 files changed, 179 insertions(+), 286 deletions(-)
diffs (truncated from 1351 to 300 lines):
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/ata.c
--- a/sys/dev/ata/ata.c Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/ata.c Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata.c,v 1.149.2.2 2022/08/30 18:28:42 martin Exp $ */
+/* $NetBSD: ata.c,v 1.149.2.3 2022/12/30 14:39:10 martin Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.149.2.2 2022/08/30 18:28:42 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.149.2.3 2022/12/30 14:39:10 martin Exp $");
#include "opt_ata.h"
@@ -842,13 +842,8 @@
xfer->c_ata_c.flags = AT_READ | flags;
xfer->c_ata_c.data = tb;
xfer->c_ata_c.bcount = ATA_BSIZE;
- if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
- xfer) != ATACMD_COMPLETE) {
- ATADEBUG_PRINT(("ata_get_parms: wdc_exec_command failed\n"),
- DEBUG_FUNCS|DEBUG_PROBE);
- rv = CMD_AGAIN;
- goto out;
- }
+ (*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer);
+ ata_wait_cmd(chp, xfer);
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
ATADEBUG_PRINT(("ata_get_parms: ata_c.flags=0x%x\n",
xfer->c_ata_c.flags), DEBUG_FUNCS|DEBUG_PROBE);
@@ -932,11 +927,8 @@
xfer->c_ata_c.r_count = mode;
xfer->c_ata_c.flags = flags;
xfer->c_ata_c.timeout = 1000; /* 1s */
- if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
- xfer) != ATACMD_COMPLETE) {
- rv = CMD_AGAIN;
- goto out;
- }
+ (*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer);
+ ata_wait_cmd(chp, xfer);
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
rv = CMD_ERR;
goto out;
@@ -1218,10 +1210,11 @@
ata_xfer_start(struct ata_xfer *xfer)
{
struct ata_channel *chp = xfer->c_chp;
- int rv;
+ int rv, status;
KASSERT(mutex_owned(&chp->ch_lock));
+again:
rv = xfer->ops->c_start(chp, xfer);
switch (rv) {
case ATASTART_STARTED:
@@ -1235,8 +1228,10 @@
/* can happen even in thread context for some ATAPI devices */
ata_channel_unlock(chp);
KASSERT(xfer->ops != NULL && xfer->ops->c_poll != NULL);
- xfer->ops->c_poll(chp, xfer);
+ status = xfer->ops->c_poll(chp, xfer);
ata_channel_lock(chp);
+ if (status == ATAPOLL_AGAIN)
+ goto again;
break;
case ATASTART_ABORT:
ata_channel_unlock(chp);
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/ata_recovery.c
--- a/sys/dev/ata/ata_recovery.c Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/ata_recovery.c Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_recovery.c,v 1.2.8.1 2022/02/08 14:45:00 martin Exp $ */
+/* $NetBSD: ata_recovery.c,v 1.2.8.2 2022/12/30 14:39:10 martin Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_recovery.c,v 1.2.8.1 2022/02/08 14:45:00 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_recovery.c,v 1.2.8.2 2022/12/30 14:39:10 martin Exp $");
#include "opt_ata.h"
@@ -103,11 +103,9 @@
xfer->c_ata_c.data = tb;
xfer->c_ata_c.bcount = sizeof(chp->recovery_blk);
- if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
- xfer) != ATACMD_COMPLETE) {
- rv = EAGAIN;
- goto out;
- }
+ (*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer);
+ ata_wait_cmd(chp, xfer);
+
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
rv = EINVAL;
goto out;
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/ata_wdc.c Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_wdc.c,v 1.113 2018/11/12 18:51:01 jdolecek Exp $ */
+/* $NetBSD: ata_wdc.c,v 1.113.4.1 2022/12/30 14:39:10 martin Exp $ */
/*
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.113 2018/11/12 18:51:01 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.113.4.1 2022/12/30 14:39:10 martin Exp $");
#include "opt_ata.h"
#include "opt_wdc.h"
@@ -102,10 +102,10 @@
#define ATA_DELAY 10000 /* 10s for a drive I/O */
-static int wdc_ata_bio(struct ata_drive_datas*, struct ata_xfer *);
+static void wdc_ata_bio(struct ata_drive_datas*, struct ata_xfer *);
static int wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
static int _wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
-static void wdc_ata_bio_poll(struct ata_channel *,struct ata_xfer *);
+static int wdc_ata_bio_poll(struct ata_channel *,struct ata_xfer *);
static int wdc_ata_bio_intr(struct ata_channel *, struct ata_xfer *,
int);
static void wdc_ata_bio_kill_xfer(struct ata_channel *,
@@ -140,10 +140,9 @@
};
/*
- * Handle block I/O operation. Return ATACMD_COMPLETE, ATACMD_QUEUED, or
- * ATACMD_TRY_AGAIN. Must be called at splbio().
+ * Handle block I/O operation.
*/
-static int
+static void
wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
{
struct ata_channel *chp = drvp->chnl_softc;
@@ -171,7 +170,6 @@
xfer->c_bcount = ata_bio->bcount;
xfer->ops = &wdc_bio_xfer_ops;
ata_exec_xfer(chp, xfer);
- return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED;
}
static int
@@ -617,7 +615,7 @@
return ATASTART_ABORT;
}
-static void
+static int
wdc_ata_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
{
/* Wait for at last 400ns for status bit to be valid */
@@ -629,6 +627,7 @@
}
#endif
wdc_ata_bio_intr(chp, xfer, 0);
+ return (xfer->c_bio.flags & ATA_ITSDONE) ? ATAPOLL_DONE : ATAPOLL_AGAIN;
}
static int
@@ -779,7 +778,10 @@
/* Start the next operation */
ata_xfer_start(xfer);
} else {
- /* Let _wdc_ata_bio_start do the loop */
+ /*
+ * Let ata_xfer_start() do the loop;
+ * see wdc_ata_bio_poll().
+ */
}
ata_channel_unlock(chp);
return 1;
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/atavar.h Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.103 2019/04/05 21:31:44 bouyer Exp $ */
+/* $NetBSD: atavar.h,v 1.103.4.1 2022/12/30 14:39:10 martin Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -178,7 +178,9 @@
#define ATASTART_TH 1 /* xfer needs to be run in thread */
#define ATASTART_POLL 2 /* xfer needs to be polled */
#define ATASTART_ABORT 3 /* error occurred, abort xfer */
- void (*c_poll)(struct ata_channel *, struct ata_xfer *);
+ int (*c_poll)(struct ata_channel *, struct ata_xfer *);
+#define ATAPOLL_DONE 0
+#define ATAPOLL_AGAIN 1
void (*c_abort)(struct ata_channel *, struct ata_xfer *);
int (*c_intr)(struct ata_channel *, struct ata_xfer *, int);
void (*c_kill_xfer)(struct ata_channel *, struct ata_xfer *, int);
@@ -358,10 +360,10 @@
*/
struct ata_bustype {
int bustype_type; /* symbolic name of type */
- int (*ata_bio)(struct ata_drive_datas *, struct ata_xfer *);
+ void (*ata_bio)(struct ata_drive_datas *, struct ata_xfer *);
void (*ata_reset_drive)(struct ata_drive_datas *, int, uint32_t *);
void (*ata_reset_channel)(struct ata_channel *, int);
- int (*ata_exec_command)(struct ata_drive_datas *,
+ void (*ata_exec_command)(struct ata_drive_datas *,
struct ata_xfer *);
#define ATACMD_COMPLETE 0x01
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/satapmp_subr.c
--- a/sys/dev/ata/satapmp_subr.c Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/satapmp_subr.c Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: satapmp_subr.c,v 1.15 2018/10/22 20:13:47 jdolecek Exp $ */
+/* $NetBSD: satapmp_subr.c,v 1.15.4.1 2022/12/30 14:39:10 martin Exp $ */
/*
* Copyright (c) 2012 Manuel Bouyer. All rights reserved.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.15 2018/10/22 20:13:47 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.15.4.1 2022/12/30 14:39:10 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,13 +72,10 @@
xfer->c_ata_c.flags = AT_LBA48 | AT_READREG | AT_WAIT;
ata_channel_unlock(chp);
- if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
- xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(chp->atabus,
- "PMP port %d register %d read failed\n", port, reg);
- error = EIO;
- goto out;
- }
+
+ (*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer);
+ ata_wait_cmd(chp, xfer);
+
if (xfer->c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
aprint_error_dev(chp->atabus,
"PMP port %d register %d read failed, flags 0x%x\n",
@@ -148,13 +145,10 @@
xfer->c_ata_c.flags = AT_LBA48 | AT_WAIT;
ata_channel_unlock(chp);
- if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
- xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(chp->atabus,
- "PMP port %d register %d write failed\n", port, reg);
- error = EIO;
- goto out;
- }
+
+ (*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer);
+ ata_wait_cmd(chp, xfer);
+
if (xfer->c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
aprint_error_dev(chp->atabus,
"PMP port %d register %d write failed, flags 0x%x\n",
diff -r 5409c64da327 -r 9176a3ffafe0 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c Wed Dec 28 17:59:01 2022 +0000
+++ b/sys/dev/ata/wd.c Fri Dec 30 14:39:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.452.2.2 2020/03/21 15:52:09 martin Exp $ */
+/* $NetBSD: wd.c,v 1.452.2.3 2022/12/30 14:39:10 martin Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.452.2.2 2020/03/21 15:52:09 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.452.2.3 2022/12/30 14:39:10 martin Exp $");
#include "opt_ata.h"
#include "opt_wd.h"
@@ -201,7 +201,7 @@
static void wdbioretry(void *);
static void wdbiorequeue(void *);
static void wddone(device_t, struct ata_xfer *);
-static int wd_get_params(struct wd_softc *, uint8_t, struct ataparams *);
+static int wd_get_params(struct wd_softc *, struct ataparams *);
static void wd_set_geometry(struct wd_softc *);
static int wd_flushcache(struct wd_softc *, int, bool);
Home |
Main Index |
Thread Index |
Old Index