Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb usb(4): Bus exploration is single-threaded -- as...
details: https://anonhg.NetBSD.org/src/rev/60e25230e590
branches: trunk
changeset: 983909:60e25230e590
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Jun 13 14:48:10 2021 +0000
description:
usb(4): Bus exploration is single-threaded -- assert it so.
New usb_in_event_thread(dev) returns true if dev is a USB device --
that is, a device with a usbN ancestor -- and the current thread is
the USB event thread.
(Kinda kludgey to pass around the device_t instead of, say, struct
usbd_bus, but I don't see a good way to get to the usbN device_t or
struct usb_softc from there.)
diffstat:
sys/dev/usb/uhub.c | 12 +++++++-----
sys/dev/usb/usb.c | 26 ++++++++++++++++++++++++--
sys/dev/usb/usb_subr.c | 15 ++++++++-------
sys/dev/usb/usbdi.h | 4 +++-
4 files changed, 42 insertions(+), 15 deletions(-)
diffs (186 lines):
diff -r 1f23520b1f33 -r 60e25230e590 sys/dev/usb/uhub.c
--- a/sys/dev/usb/uhub.c Sun Jun 13 14:46:07 2021 +0000
+++ b/sys/dev/usb/uhub.c Sun Jun 13 14:48:10 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uhub.c,v 1.152 2021/06/13 14:46:07 riastradh Exp $ */
+/* $NetBSD: uhub.c,v 1.153 2021/06/13 14:48:10 riastradh Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
/* $OpenBSD: uhub.c,v 1.86 2015/06/29 18:27:40 mpi Exp $ */
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.152 2021/06/13 14:46:07 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.153 2021/06/13 14:48:10 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -269,9 +269,11 @@
usb_endpoint_descriptor_t *ed;
struct usbd_tt *tts = NULL;
- config_pending_incr(self);
+ UHUBHIST_FUNC(); UHUBHIST_CALLED();
- UHUBHIST_FUNC(); UHUBHIST_CALLED();
+ KASSERT(usb_in_event_thread(parent));
+
+ config_pending_incr(self);
sc->sc_dev = self;
sc->sc_hub = dev;
@@ -498,7 +500,7 @@
device_unit(sc->sc_dev), (uintptr_t)dev, dev->ud_addr,
dev->ud_speed);
- KASSERT(KERNEL_LOCKED_P());
+ KASSERT(usb_in_event_thread(sc->sc_dev));
if (!sc->sc_running)
return USBD_NOT_STARTED;
diff -r 1f23520b1f33 -r 60e25230e590 sys/dev/usb/usb.c
--- a/sys/dev/usb/usb.c Sun Jun 13 14:46:07 2021 +0000
+++ b/sys/dev/usb/usb.c Sun Jun 13 14:48:10 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.c,v 1.195 2021/06/12 12:13:10 riastradh Exp $ */
+/* $NetBSD: usb.c,v 1.196 2021/06/13 14:48:10 riastradh Exp $ */
/*
* Copyright (c) 1998, 2002, 2008, 2012 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.195 2021/06/12 12:13:10 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.196 2021/06/13 14:48:10 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -142,6 +142,7 @@
struct usbd_port sc_port; /* dummy port for root hub */
struct lwp *sc_event_thread;
+ struct lwp *sc_attach_thread;
char sc_dying;
bool sc_pmf_registered;
@@ -483,8 +484,10 @@
ue->u.ue_ctrlr.ue_bus = device_unit(self);
usb_add_event(USB_EVENT_CTRLR_ATTACH, ue);
+ sc->sc_attach_thread = curlwp;
err = usbd_new_device(self, sc->sc_bus, 0, speed, 0,
&sc->sc_port);
+ sc->sc_attach_thread = NULL;
if (!err) {
dev = sc->sc_port.up_dev;
if (dev->ud_hub == NULL) {
@@ -529,6 +532,25 @@
}
}
+bool
+usb_in_event_thread(device_t dev)
+{
+ struct usb_softc *sc;
+
+ if (cold)
+ return true;
+
+ for (; dev; dev = device_parent(dev)) {
+ if (device_is_a(dev, "usb"))
+ break;
+ }
+ if (dev == NULL)
+ return false;
+ sc = device_private(dev);
+
+ return curlwp == sc->sc_event_thread || curlwp == sc->sc_attach_thread;
+}
+
/*
* Add a task to be performed by the task thread. This function can be
* called from any context and the task will be executed in a process
diff -r 1f23520b1f33 -r 60e25230e590 sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c Sun Jun 13 14:46:07 2021 +0000
+++ b/sys/dev/usb/usb_subr.c Sun Jun 13 14:48:10 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_subr.c,v 1.264 2021/06/13 09:12:24 mlelstv Exp $ */
+/* $NetBSD: usb_subr.c,v 1.265 2021/06/13 14:48:10 riastradh Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.264 2021/06/13 09:12:24 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.265 2021/06/13 14:48:10 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -1097,6 +1097,8 @@
device_t dv;
int dlocs[USBDEVIFCF_NLOCS];
+ KASSERT(usb_in_event_thread(parent));
+
uaa.uaa_device = dev;
uaa.uaa_usegeneric = usegeneric;
uaa.uaa_port = port;
@@ -1147,8 +1149,7 @@
int i, j, loc;
device_t dv;
- /* Needed for access to dev->ud_subdevs. */
- KASSERT(KERNEL_LOCKED_P());
+ KASSERT(usb_in_event_thread(parent));
nifaces = dev->ud_cdesc->bNumInterface;
ifaces = kmem_zalloc(nifaces * sizeof(*ifaces), KM_SLEEP);
@@ -1240,7 +1241,7 @@
int confi, nifaces;
usbd_status err;
- KASSERT(KERNEL_LOCKED_P());
+ KASSERT(usb_in_event_thread(parent));
/* First try with device specific drivers. */
err = usbd_attachwholedevice(parent, dev, port, 0);
@@ -1310,7 +1311,7 @@
USBHIST_CALLARGS(usbdebug, "uhub%jd port=%jd",
device_unit(parent), port, 0, 0);
- KASSERT(KERNEL_LOCKED_P());
+ KASSERT(usb_in_event_thread(parent));
if (locators != NULL) {
loc = locators[USBIFIFCF_PORT];
@@ -1370,7 +1371,7 @@
int i;
int p;
- KASSERT(KERNEL_LOCKED_P());
+ KASSERT(usb_in_event_thread(parent));
if (bus->ub_methods->ubm_newdev != NULL)
return (bus->ub_methods->ubm_newdev)(parent, bus, depth, speed,
diff -r 1f23520b1f33 -r 60e25230e590 sys/dev/usb/usbdi.h
--- a/sys/dev/usb/usbdi.h Sun Jun 13 14:46:07 2021 +0000
+++ b/sys/dev/usb/usbdi.h Sun Jun 13 14:48:10 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.h,v 1.102 2020/02/16 09:40:35 maxv Exp $ */
+/* $NetBSD: usbdi.h,v 1.103 2021/06/13 14:48:10 riastradh Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@@ -222,6 +222,8 @@
bool usb_task_pending(struct usbd_device *, struct usb_task *);
#define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl))
+bool usb_in_event_thread(device_t);
+
struct usb_devno {
uint16_t ud_vendor;
uint16_t ud_product;
Home |
Main Index |
Thread Index |
Old Index