Module Name: src
Committed By: riastradh
Date: Sun Aug 16 02:33:17 UTC 2020
Modified Files:
src/sys/dev/usb: ugen.c
Log Message:
Remove UGEN_ASLP microoptimization.
cv_signal already has this microoptimization.
While here, make the lock cover the relevant things we're issuing
cv_signal about -- progress toward real MP-safety.
To generate a diff of this commit:
cvs rdiff -u -r1.151 -r1.152 src/sys/dev/usb/ugen.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/usb/ugen.c
diff -u src/sys/dev/usb/ugen.c:1.151 src/sys/dev/usb/ugen.c:1.152
--- src/sys/dev/usb/ugen.c:1.151 Sat Mar 21 06:54:56 2020
+++ src/sys/dev/usb/ugen.c Sun Aug 16 02:33:17 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ugen.c,v 1.151 2020/03/21 06:54:56 skrll Exp $ */
+/* $NetBSD: ugen.c,v 1.152 2020/08/16 02:33:17 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.151 2020/03/21 06:54:56 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.152 2020/08/16 02:33:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -97,7 +97,6 @@ struct ugen_endpoint {
usb_endpoint_descriptor_t *edesc;
struct usbd_interface *iface;
int state;
-#define UGEN_ASLP 0x02 /* waiting for data */
#define UGEN_SHORT_OK 0x04 /* short xfers are OK */
#define UGEN_BULK_RA 0x08 /* in bulk read-ahead mode */
#define UGEN_BULK_WB 0x10 /* in bulk write-behind mode */
@@ -649,7 +648,6 @@ ugen_do_read(struct ugen_softc *sc, int
mutex_exit(&sc->sc_lock);
return EWOULDBLOCK;
}
- sce->state |= UGEN_ASLP;
DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
/* "ugenri" */
error = cv_timedwait_sig(&sce->cv, &sc->sc_lock,
@@ -657,10 +655,8 @@ ugen_do_read(struct ugen_softc *sc, int
DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
if (sc->sc_dying)
error = EIO;
- if (error) {
- sce->state &= ~UGEN_ASLP;
+ if (error)
break;
- }
}
mutex_exit(&sc->sc_lock);
@@ -693,7 +689,6 @@ ugen_do_read(struct ugen_softc *sc, int
}
while (uio->uio_resid > 0 && !error) {
while (sce->ra_wb_used == 0) {
- sce->state |= UGEN_ASLP;
DPRINTFN(5,
("ugenread: sleep on %p\n",
sce));
@@ -705,10 +700,8 @@ ugen_do_read(struct ugen_softc *sc, int
error));
if (sc->sc_dying)
error = EIO;
- if (error) {
- sce->state &= ~UGEN_ASLP;
+ if (error)
break;
- }
}
/* Copy data to the process. */
@@ -786,7 +779,6 @@ ugen_do_read(struct ugen_softc *sc, int
mutex_exit(&sc->sc_lock);
return EWOULDBLOCK;
}
- sce->state |= UGEN_ASLP;
/* "ugenri" */
DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
error = cv_timedwait_sig(&sce->cv, &sc->sc_lock,
@@ -794,10 +786,8 @@ ugen_do_read(struct ugen_softc *sc, int
DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
if (sc->sc_dying)
error = EIO;
- if (error) {
- sce->state &= ~UGEN_ASLP;
+ if (error)
break;
- }
}
while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
@@ -895,7 +885,6 @@ ugen_do_write(struct ugen_softc *sc, int
while (uio->uio_resid > 0 && !error) {
while (sce->ra_wb_used ==
sce->limit - sce->ibuf) {
- sce->state |= UGEN_ASLP;
DPRINTFN(5,
("ugenwrite: sleep on %p\n",
sce));
@@ -907,10 +896,8 @@ ugen_do_write(struct ugen_softc *sc, int
error));
if (sc->sc_dying)
error = EIO;
- if (error) {
- sce->state &= ~UGEN_ASLP;
+ if (error)
break;
- }
}
/* Copy data from the process. */
@@ -1136,14 +1123,9 @@ ugenintr(struct usbd_xfer *xfer, void *a
DPRINTFN(5, (" data = %02x %02x %02x\n",
ibuf[0], ibuf[1], ibuf[2]));
- (void)b_to_q(ibuf, count, &sce->q);
-
mutex_enter(&sc->sc_lock);
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
- cv_signal(&sce->cv);
- }
+ (void)b_to_q(ibuf, count, &sce->q);
+ cv_signal(&sce->cv);
mutex_exit(&sc->sc_lock);
selnotify(&sce->rsel, 0, 0);
}
@@ -1166,10 +1148,12 @@ ugen_isoc_rintr(struct usbd_xfer *xfer,
DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n",
(long)(req - sce->isoreqs), count));
+ mutex_enter(&sc->sc_lock);
+
/* throw away oldest input if the buffer is full */
- if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
+ if (sce->fill < sce->cur && sce->cur <= sce->fill + count) {
sce->cur += count;
- if(sce->cur >= sce->limit)
+ if (sce->cur >= sce->limit)
sce->cur = sce->ibuf + (sce->limit - sce->cur);
DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
count));
@@ -1188,7 +1172,7 @@ ugen_isoc_rintr(struct usbd_xfer *xfer,
tbuf += n;
actlen -= n;
sce->fill += n;
- if(sce->fill == sce->limit)
+ if (sce->fill == sce->limit)
sce->fill = sce->ibuf;
}
@@ -1200,12 +1184,7 @@ ugen_isoc_rintr(struct usbd_xfer *xfer,
ugen_isoc_rintr);
(void)usbd_transfer(xfer);
- mutex_enter(&sc->sc_lock);
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
- cv_signal(&sce->cv);
- }
+ cv_signal(&sce->cv);
mutex_exit(&sc->sc_lock);
selnotify(&sce->rsel, 0, 0);
}
@@ -1234,6 +1213,8 @@ ugen_bulkra_intr(struct usbd_xfer *xfer,
usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
+ mutex_enter(&sc->sc_lock);
+
/* Keep track of how much is in the buffer. */
sce->ra_wb_used += count;
@@ -1269,12 +1250,7 @@ ugen_bulkra_intr(struct usbd_xfer *xfer,
else
sce->state |= UGEN_RA_WB_STOP;
- mutex_enter(&sc->sc_lock);
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_bulkra_intr: waking %p\n", sce));
- cv_signal(&sce->cv);
- }
+ cv_signal(&sce->cv);
mutex_exit(&sc->sc_lock);
selnotify(&sce->rsel, 0, 0);
}
@@ -1303,6 +1279,8 @@ ugen_bulkwb_intr(struct usbd_xfer *xfer,
usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
+ mutex_enter(&sc->sc_lock);
+
/* Keep track of how much is in the buffer. */
sce->ra_wb_used -= count;
@@ -1337,12 +1315,7 @@ ugen_bulkwb_intr(struct usbd_xfer *xfer,
else
sce->state |= UGEN_RA_WB_STOP;
- mutex_enter(&sc->sc_lock);
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_bulkwb_intr: waking %p\n", sce));
- cv_signal(&sce->cv);
- }
+ cv_signal(&sce->cv);
mutex_exit(&sc->sc_lock);
selnotify(&sce->rsel, 0, 0);
}