diff options
author | Stefan Fritsch <sf@cvs.openbsd.org> | 2015-07-18 16:35:34 +0000 |
---|---|---|
committer | Stefan Fritsch <sf@cvs.openbsd.org> | 2015-07-18 16:35:34 +0000 |
commit | 3d29d879bd4176fd8e76911696388ce90c19dd05 (patch) | |
tree | 5829cb5a770cffde0ccf257920bc8154c1fa978b /sys/dev | |
parent | e3219bc596c12b643a4c84b2591002a4ec729c15 (diff) |
virtio_pci: Do the ISR read without kernel lock
The ISR read is relatively expensive because it causes a vmexit. Grab the
kernel lock only after it is done.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/virtio_pci.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/dev/pci/virtio_pci.c b/sys/dev/pci/virtio_pci.c index ffa1e0d9c97..2aa2fc9a407 100644 --- a/sys/dev/pci/virtio_pci.c +++ b/sys/dev/pci/virtio_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio_pci.c,v 1.10 2015/07/18 00:37:16 sf Exp $ */ +/* $OpenBSD: virtio_pci.c,v 1.11 2015/07/18 16:35:33 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -217,8 +217,15 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux) goto fail_2; } intrstr = pci_intr_string(pc, ih); - sc->sc_ih = pci_intr_establish(pc, ih, vsc->sc_ipl, virtio_pci_intr, - sc, vsc->sc_dev.dv_xname); + /* + * We always set the IPL_MPSAFE flag in order to do the relatively + * expensive ISR read without lock, and then grab the kernel lock in + * the interrupt handler. + * For now, we don't support IPL_MPSAFE vq_done functions. + */ + KASSERT((vsc->sc_ipl & IPL_MPSAFE) == 0); + sc->sc_ih = pci_intr_establish(pc, ih, vsc->sc_ipl | IPL_MPSAFE, + virtio_pci_intr, sc, vsc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf("%s: couldn't establish interrupt", vsc->sc_dev.dv_xname); if (intrstr != NULL) @@ -395,11 +402,13 @@ virtio_pci_intr(void *arg) VIRTIO_CONFIG_ISR_STATUS); if (isr == 0) return 0; + KERNEL_LOCK(); if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && (vsc->sc_config_change != NULL)) r = (vsc->sc_config_change)(vsc); if (vsc->sc_intrhand != NULL) r |= (vsc->sc_intrhand)(vsc); + KERNEL_UNLOCK(); return r; } |