summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gerdts <mike.gerdts@joyent.com>2018-05-03 19:33:18 +0000
committerMike Gerdts <mike.gerdts@joyent.com>2018-05-09 01:00:54 +0000
commitdb9746572d6692af88b9f55827fcb63f1bcb3c46 (patch)
tree9f635eb38aa8a04edfa58964379167fdc3f780c4
parentcd2e7e66ffa1c4b5f8d136fb0913699fbac5c6d8 (diff)
downloadillumos-joyent-db9746572d6692af88b9f55827fcb63f1bcb3c46.tar.gz
OS-6928 recursive mutex in pci_xhci
Reviewed by: John Levon <john.levon@joyent.com> Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Patrick Mooney <patrick.mooney@joyent.com>
-rw-r--r--usr/src/cmd/bhyve/pci_xhci.c19
-rw-r--r--usr/src/cmd/bhyve/usb_emul.h8
2 files changed, 25 insertions, 2 deletions
diff --git a/usr/src/cmd/bhyve/pci_xhci.c b/usr/src/cmd/bhyve/pci_xhci.c
index f178468108..1cb2246486 100644
--- a/usr/src/cmd/bhyve/pci_xhci.c
+++ b/usr/src/cmd/bhyve/pci_xhci.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2014 Leon Dang <ldang@nahannisys.com>
+ * Copyright 2018 Joyent, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1661,7 +1662,16 @@ pci_xhci_try_usb_xfer(struct pci_xhci_softc *sc,
do_intr = 0;
xfer = devep->ep_xfer;
+#ifdef __FreeBSD__
USB_DATA_XFER_LOCK(xfer);
+#else
+ /*
+ * At least one caller needs to hold this lock across the call to this
+ * function and other code. To avoid deadlock from a recursive mutex
+ * enter, we ensure that all callers hold this lock.
+ */
+ assert(USB_DATA_XFER_LOCK_HELD(xfer));
+#endif
/* outstanding requests queued up */
if (dev->dev_ue->ue_data != NULL) {
@@ -1684,8 +1694,9 @@ pci_xhci_try_usb_xfer(struct pci_xhci_softc *sc,
}
}
+#ifdef __FreeBSD__
USB_DATA_XFER_UNLOCK(xfer);
-
+#endif
return (err);
}
@@ -1917,7 +1928,13 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot,
/* handle pending transfers */
if (devep->ep_xfer->ndata > 0) {
+#ifndef __FreeBSD__
+ USB_DATA_XFER_LOCK(devep->ep_xfer);
+#endif
pci_xhci_try_usb_xfer(sc, dev, devep, ep_ctx, slot, epid);
+#ifndef __FreeBSD__
+ USB_DATA_XFER_UNLOCK(devep->ep_xfer);
+#endif
return;
}
diff --git a/usr/src/cmd/bhyve/usb_emul.h b/usr/src/cmd/bhyve/usb_emul.h
index 69df135466..083557f64f 100644
--- a/usr/src/cmd/bhyve/usb_emul.h
+++ b/usr/src/cmd/bhyve/usb_emul.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2014 Leon Dang <ldang@nahannisys.com>
+ * Copyright 2018 Joyent, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +33,9 @@
#include <stdlib.h>
#include <sys/linker_set.h>
#include <pthread.h>
+#ifndef __FreeBSD__
+#include <synch.h>
+#endif
#define USB_MAX_XFER_BLOCKS 8
@@ -145,7 +149,9 @@ enum USB_ERRCODE {
#define USB_DATA_XFER_UNLOCK(x) do { \
pthread_mutex_unlock(&((x)->mtx)); \
} while (0)
-
+#ifndef __FreeBSD__
+#define USB_DATA_XFER_LOCK_HELD(x) MUTEX_HELD(&((x)->mtx))
+#endif
struct usb_devemu *usb_emu_finddev(char *name);