uhid(4): Omit needless softint indirection.
USB xfer callbacks already run in softint context at IPL_SOFTSERIAL, and I see no reason why the call to psignal must happen instead at the lower priority of IPL_SOFTCLOCK, so let's avoid using up the scarce resource of softints for something that doesn't need 'em. While here, use atomic_store_relaxed to update sc->sc_async and atomic_load_relaxed to optimisitcally test it without acquiring proc_lock.
This commit is contained in:
parent
3766bfcd77
commit
92f37f2423
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: uhid.c,v 1.115 2020/11/29 22:54:51 riastradh Exp $ */
|
/* $NetBSD: uhid.c,v 1.116 2020/11/30 00:48:35 riastradh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.115 2020/11/29 22:54:51 riastradh Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.116 2020/11/30 00:48:35 riastradh Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_compat_netbsd.h"
|
#include "opt_compat_netbsd.h"
|
||||||
|
@ -138,7 +138,6 @@ const struct cdevsw uhid_cdevsw = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Static void uhid_intr(struct uhidev *, void *, u_int);
|
Static void uhid_intr(struct uhidev *, void *, u_int);
|
||||||
Static void uhid_softintr(void *);
|
|
||||||
|
|
||||||
Static int uhid_do_read(struct uhid_softc *, struct uio *, int);
|
Static int uhid_do_read(struct uhid_softc *, struct uio *, int);
|
||||||
Static int uhid_do_write(struct uhid_softc *, struct uio *, int);
|
Static int uhid_do_write(struct uhid_softc *, struct uio *, int);
|
||||||
|
@ -180,7 +179,6 @@ uhid_attach(device_t parent, device_t self, void *aux)
|
||||||
sc->sc_hdev.sc_intr = uhid_intr;
|
sc->sc_hdev.sc_intr = uhid_intr;
|
||||||
sc->sc_hdev.sc_parent = uha->parent;
|
sc->sc_hdev.sc_parent = uha->parent;
|
||||||
sc->sc_hdev.sc_report_id = uha->reportid;
|
sc->sc_hdev.sc_report_id = uha->reportid;
|
||||||
sc->sc_sih = softint_establish(SOFTINT_CLOCK, uhid_softintr, sc);
|
|
||||||
|
|
||||||
uhidev_get_report_desc(uha->parent, &desc, &size);
|
uhidev_get_report_desc(uha->parent, &desc, &size);
|
||||||
repid = uha->reportid;
|
repid = uha->reportid;
|
||||||
|
@ -277,7 +275,6 @@ uhid_detach(device_t self, int flags)
|
||||||
cv_destroy(&sc->sc_detach_cv);
|
cv_destroy(&sc->sc_detach_cv);
|
||||||
mutex_destroy(&sc->sc_lock);
|
mutex_destroy(&sc->sc_lock);
|
||||||
seldestroy(&sc->sc_rsel);
|
seldestroy(&sc->sc_rsel);
|
||||||
softint_disestablish(sc->sc_sih);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -304,26 +301,18 @@ uhid_intr(struct uhidev *addr, void *data, u_int len)
|
||||||
DPRINTFN(5, ("uhid_intr: waking %p\n", &sc->sc_q));
|
DPRINTFN(5, ("uhid_intr: waking %p\n", &sc->sc_q));
|
||||||
cv_broadcast(&sc->sc_cv);
|
cv_broadcast(&sc->sc_cv);
|
||||||
selnotify(&sc->sc_rsel, 0, NOTE_SUBMIT);
|
selnotify(&sc->sc_rsel, 0, NOTE_SUBMIT);
|
||||||
if (sc->sc_async != NULL) {
|
if (atomic_load_relaxed(&sc->sc_async) != NULL) {
|
||||||
DPRINTFN(3, ("uhid_intr: sending SIGIO %p\n", sc->sc_async));
|
mutex_enter(&proc_lock);
|
||||||
softint_schedule(sc->sc_sih);
|
if (sc->sc_async != NULL) {
|
||||||
|
DPRINTFN(3, ("uhid_intr: sending SIGIO to %jd\n",
|
||||||
|
(intmax_t)sc->sc_async->p_pid));
|
||||||
|
psignal(sc->sc_async, SIGIO);
|
||||||
|
}
|
||||||
|
mutex_exit(&proc_lock);
|
||||||
}
|
}
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uhid_softintr(void *cookie)
|
|
||||||
{
|
|
||||||
struct uhid_softc *sc;
|
|
||||||
|
|
||||||
sc = cookie;
|
|
||||||
|
|
||||||
mutex_enter(&proc_lock);
|
|
||||||
if (sc->sc_async != NULL)
|
|
||||||
psignal(sc->sc_async, SIGIO);
|
|
||||||
mutex_exit(&proc_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
|
uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
|
||||||
{
|
{
|
||||||
|
@ -367,7 +356,7 @@ uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
|
||||||
|
|
||||||
/* Paranoia: reset SIGIO before enabling interrputs. */
|
/* Paranoia: reset SIGIO before enabling interrputs. */
|
||||||
mutex_enter(&proc_lock);
|
mutex_enter(&proc_lock);
|
||||||
sc->sc_async = NULL;
|
atomic_store_relaxed(&sc->sc_async, NULL);
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
|
|
||||||
/* Open the uhidev -- after this point we can get interrupts. */
|
/* Open the uhidev -- after this point we can get interrupts. */
|
||||||
|
@ -390,7 +379,7 @@ fail2: __unused
|
||||||
uhidev_close(&sc->sc_hdev);
|
uhidev_close(&sc->sc_hdev);
|
||||||
fail1: selnotify(&sc->sc_rsel, POLLHUP, 0);
|
fail1: selnotify(&sc->sc_rsel, POLLHUP, 0);
|
||||||
mutex_enter(&proc_lock);
|
mutex_enter(&proc_lock);
|
||||||
sc->sc_async = NULL;
|
atomic_store_relaxed(&sc->sc_async, NULL);
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
if (sc->sc_osize > 0) {
|
if (sc->sc_osize > 0) {
|
||||||
kmem_free(sc->sc_obuf, sc->sc_osize);
|
kmem_free(sc->sc_obuf, sc->sc_osize);
|
||||||
|
@ -429,7 +418,7 @@ uhidclose(dev_t dev, int flag, int mode, struct lwp *l)
|
||||||
|
|
||||||
/* Reset SIGIO. */
|
/* Reset SIGIO. */
|
||||||
mutex_enter(&proc_lock);
|
mutex_enter(&proc_lock);
|
||||||
sc->sc_async = NULL;
|
atomic_store_relaxed(&sc->sc_async, NULL);
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
|
|
||||||
/* Free the buffer and queue. */
|
/* Free the buffer and queue. */
|
||||||
|
@ -644,10 +633,10 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
}
|
}
|
||||||
sc->sc_async = l->l_proc;
|
atomic_store_relaxed(&sc->sc_async, l->l_proc);
|
||||||
DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", l->l_proc));
|
DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", l->l_proc));
|
||||||
} else
|
} else
|
||||||
sc->sc_async = NULL;
|
atomic_store_relaxed(&sc->sc_async, NULL);
|
||||||
mutex_exit(&proc_lock);
|
mutex_exit(&proc_lock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue