Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Apply patch in PR kern/44907 (crash due to race ...
details: https://anonhg.NetBSD.org/src/rev/00e7751d9f4c
branches: trunk
changeset: 765462:00e7751d9f4c
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Fri May 27 19:04:24 2011 +0000
description:
Apply patch in PR kern/44907 (crash due to race in ehci.c):
- make sure to remove abort_task in ehci_freex
- always initialize abort_task in ehci_allocx,
not in ehci_timeout just before adding the task
Also apply similar fixes to ohci and uhci.
XXX: should we also call abort_task handler before removing it from queue
if *hci_freex() is called for usbd_xfer_handle with queued abort_task?
diffstat:
sys/dev/usb/ehci.c | 18 +++++++++++-------
sys/dev/usb/ohci.c | 14 +++++++++-----
sys/dev/usb/ohcivar.h | 3 ++-
sys/dev/usb/uhci.c | 20 ++++++++++++--------
4 files changed, 34 insertions(+), 21 deletions(-)
diffs (230 lines):
diff -r 57e2ac7f3d2e -r 00e7751d9f4c sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c Fri May 27 18:00:21 2011 +0000
+++ b/sys/dev/usb/ehci.c Fri May 27 19:04:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.175 2011/05/27 17:19:18 drochner Exp $ */
+/* $NetBSD: ehci.c,v 1.176 2011/05/27 19:04:24 tsutsui Exp $ */
/*
* Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.175 2011/05/27 17:19:18 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.176 2011/05/27 19:04:24 tsutsui Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -1284,6 +1284,7 @@
{
struct ehci_softc *sc = bus->hci_private;
usbd_xfer_handle xfer;
+ struct ehci_xfer *exfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL) {
@@ -1295,12 +1296,14 @@
}
#endif
} else {
- xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
+ xfer = malloc(sizeof(*exfer), M_USB, M_NOWAIT);
}
if (xfer != NULL) {
- memset(xfer, 0, sizeof(struct ehci_xfer));
+ exfer = EXFER(xfer);
+ memset(exfer, 0, sizeof(*exfer));
+ usb_init_task(&exfer->abort_task, ehci_timeout_task, exfer);
#ifdef DIAGNOSTIC
- EXFER(xfer)->isdone = 1;
+ exfer->isdone = 1;
xfer->busy_free = XFER_BUSY;
#endif
}
@@ -1311,6 +1314,7 @@
ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
{
struct ehci_softc *sc = bus->hci_private;
+ struct ehci_xfer *exfer = EXFER(xfer);
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
@@ -1318,10 +1322,11 @@
xfer->busy_free);
}
xfer->busy_free = XFER_FREE;
- if (!EXFER(xfer)->isdone) {
+ if (!exfer->isdone) {
printf("ehci_freex: !isdone\n");
}
#endif
+ usb_rem_task(xfer->pipe->device, &exfer->abort_task);
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
@@ -3150,7 +3155,6 @@
}
/* Execute the abort in a process context. */
- usb_init_task(&exfer->abort_task, ehci_timeout_task, addr);
usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task,
USB_TASKQ_HC);
}
diff -r 57e2ac7f3d2e -r 00e7751d9f4c sys/dev/usb/ohci.c
--- a/sys/dev/usb/ohci.c Fri May 27 18:00:21 2011 +0000
+++ b/sys/dev/usb/ohci.c Fri May 27 19:04:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.212 2010/12/22 01:34:19 macallan Exp $ */
+/* $NetBSD: ohci.c,v 1.213 2011/05/27 19:04:24 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.212 2010/12/22 01:34:19 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.213 2011/05/27 19:04:24 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -945,6 +945,7 @@
{
struct ohci_softc *sc = bus->hci_private;
usbd_xfer_handle xfer;
+ struct ohci_xfer *oxfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL) {
@@ -956,10 +957,12 @@
}
#endif
} else {
- xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
+ xfer = malloc(sizeof(*oxfer), M_USB, M_NOWAIT);
}
if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct ohci_xfer));
+ oxfer = OXFER(xfer);
+ memset(oxfer, 0, sizeof(*oxfer));
+ usb_init_task(&oxfer->abort_task, ohci_timeout_task, oxfer);
#ifdef DIAGNOSTIC
xfer->busy_free = XFER_BUSY;
#endif
@@ -971,6 +974,7 @@
ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
{
struct ohci_softc *sc = bus->hci_private;
+ struct ohci_xfer *oxfer = OXFER(xfer);
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
@@ -979,6 +983,7 @@
}
xfer->busy_free = XFER_FREE;
#endif
+ usb_rem_task(xfer->pipe->device, &oxfer->abort_task);
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
@@ -1948,7 +1953,6 @@
}
/* Execute the abort in a process context. */
- usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr);
usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
USB_TASKQ_HC);
}
diff -r 57e2ac7f3d2e -r 00e7751d9f4c sys/dev/usb/ohcivar.h
--- a/sys/dev/usb/ohcivar.h Fri May 27 18:00:21 2011 +0000
+++ b/sys/dev/usb/ohcivar.h Fri May 27 19:04:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ohcivar.h,v 1.49 2010/11/03 22:34:23 dyoung Exp $ */
+/* $NetBSD: ohcivar.h,v 1.50 2011/05/27 19:04:24 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -140,6 +140,7 @@
struct usbd_xfer xfer;
struct usb_task abort_task;
};
+#define OXFER(xfer) ((struct ohci_xfer *)(xfer))
usbd_status ohci_init(ohci_softc_t *);
int ohci_intr(void *);
diff -r 57e2ac7f3d2e -r 00e7751d9f4c sys/dev/usb/uhci.c
--- a/sys/dev/usb/uhci.c Fri May 27 18:00:21 2011 +0000
+++ b/sys/dev/usb/uhci.c Fri May 27 19:04:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.236 2011/05/27 17:19:18 drochner Exp $ */
+/* $NetBSD: uhci.c,v 1.237 2011/05/27 19:04:24 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.236 2011/05/27 17:19:18 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.237 2011/05/27 19:04:24 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -640,6 +640,7 @@
{
struct uhci_softc *sc = bus->hci_private;
usbd_xfer_handle xfer;
+ struct uhci_xfer *uxfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL) {
@@ -651,13 +652,15 @@
}
#endif
} else {
- xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
+ xfer = malloc(sizeof(*uxfer), M_USB, M_NOWAIT);
}
if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct uhci_xfer));
- UXFER(xfer)->iinfo.sc = sc;
+ uxfer = UXFER(xfer);
+ memset(uxfer, 0, sizeof(*uxfer));
+ uxfer->iinfo.sc = sc;
+ usb_init_task(&uxfer->abort_task, uhci_timeout_task, uxfer);
#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
+ uxfer->iinfo.isdone = 1;
xfer->busy_free = XFER_BUSY;
#endif
}
@@ -668,6 +671,7 @@
uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
{
struct uhci_softc *sc = bus->hci_private;
+ struct uhci_xfer *uxfer = UXFER(xfer);
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
@@ -675,10 +679,11 @@
xfer->busy_free);
}
xfer->busy_free = XFER_FREE;
- if (!UXFER(xfer)->iinfo.isdone) {
+ if (!uxfer->iinfo.isdone) {
printf("uhci_freex: !isdone\n");
}
#endif
+ usb_rem_task(xfer->pipe->device, &uxfer->abort_task);
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
@@ -1619,7 +1624,6 @@
}
/* Execute the abort in a process context. */
- usb_init_task(&uxfer->abort_task, uhci_timeout_task, ii->xfer);
usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task,
USB_TASKQ_HC);
}
Home |
Main Index |
Thread Index |
Old Index