svn commit: r295518 - head/sys/arm64/arm64

Zbigniew Bodek zbb at FreeBSD.org
Thu Feb 11 12:03:13 UTC 2016


Author: zbb
Date: Thu Feb 11 12:03:11 2016
New Revision: 295518
URL: https://svnweb.freebsd.org/changeset/base/295518

Log:
  Implement finer locking in ITS
  
  - Change locks' names to be more suitable
  - Don't use blocking mutex. Lock only basic operations such
    as lists or bitmaps modifications.
  
  Reviewed by:   wma
  Obtained from: Semihalf
  Sponsored by:  Cavium
  Differential Revision: https://reviews.freebsd.org/D5230

Modified:
  head/sys/arm64/arm64/gic_v3_its.c
  head/sys/arm64/arm64/gic_v3_var.h

Modified: head/sys/arm64/arm64/gic_v3_its.c
==============================================================================
--- head/sys/arm64/arm64/gic_v3_its.c	Thu Feb 11 12:01:33 2016	(r295517)
+++ head/sys/arm64/arm64/gic_v3_its.c	Thu Feb 11 12:03:11 2016	(r295518)
@@ -197,9 +197,9 @@ gic_v3_its_attach(device_t dev)
 	 * Initialize sleep & spin mutex for ITS
 	 */
 	/* Protects ITS device list and assigned LPIs bitmaps. */
-	mtx_init(&sc->its_mtx, "ITS sleep lock", NULL, MTX_DEF);
+	mtx_init(&sc->its_dev_lock, "ITS dev lock", NULL, MTX_SPIN);
 	/* Protects access to ITS command circular buffer. */
-	mtx_init(&sc->its_spin_mtx, "ITS spin lock", NULL, MTX_SPIN);
+	mtx_init(&sc->its_cmd_lock, "ITS cmd lock", NULL, MTX_SPIN);
 
 	rid = 0;
 	sc->its_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
@@ -1181,7 +1181,7 @@ its_cmd_alloc_locked(struct gic_v3_its_s
 	 */
 	us_left = 1000000;
 
-	mtx_assert(&sc->its_spin_mtx, MA_OWNED);
+	mtx_assert(&sc->its_cmd_lock, MA_OWNED);
 	while (its_cmd_queue_full(sc)) {
 		if (us_left-- == 0) {
 			/* Timeout while waiting for free command */
@@ -1334,11 +1334,11 @@ its_cmd_send(struct gic_v3_its_softc *sc
 	struct its_cmd_desc desc_sync;
 	uint64_t target, cwriter;
 
-	mtx_lock_spin(&sc->its_spin_mtx);
+	mtx_lock_spin(&sc->its_cmd_lock);
 	cmd = its_cmd_alloc_locked(sc);
 	if (cmd == NULL) {
 		device_printf(sc->dev, "could not allocate ITS command\n");
-		mtx_unlock_spin(&sc->its_spin_mtx);
+		mtx_unlock_spin(&sc->its_cmd_lock);
 		return (EBUSY);
 	}
 
@@ -1360,7 +1360,7 @@ end:
 	cwriter = its_cmd_cwriter_offset(sc, sc->its_cmdq_write);
 	gic_its_write(sc, 8, GITS_CWRITER, cwriter);
 	cmd_write = sc->its_cmdq_write;
-	mtx_unlock_spin(&sc->its_spin_mtx);
+	mtx_unlock_spin(&sc->its_cmd_lock);
 
 	its_cmd_wait_completion(sc, cmd, cmd_write);
 
@@ -1372,7 +1372,7 @@ its_device_find_locked(struct gic_v3_its
 {
 	struct its_dev *its_dev;
 
-	mtx_assert(&sc->its_mtx, MA_OWNED);
+	mtx_assert(&sc->its_dev_lock, MA_OWNED);
 	/* Find existing device if any */
 	TAILQ_FOREACH(its_dev, &sc->its_dev_list, entry) {
 		if (its_dev->pci_dev == pci_dev)
@@ -1383,7 +1383,7 @@ its_device_find_locked(struct gic_v3_its
 }
 
 static struct its_dev *
-its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev,
+its_device_alloc(struct gic_v3_its_softc *sc, device_t pci_dev,
     u_int nvecs)
 {
 	struct its_dev *newdev;
@@ -1391,10 +1391,12 @@ its_device_alloc_locked(struct gic_v3_it
 	uint32_t devid;
 	u_int cpuid;
 	size_t esize;
+	int err;
 
-	mtx_assert(&sc->its_mtx, MA_OWNED);
+	mtx_lock_spin(&sc->its_dev_lock);
 	/* Find existing device if any */
 	newdev = its_device_find_locked(sc, pci_dev);
+	mtx_unlock_spin(&sc->its_dev_lock);
 	if (newdev != NULL)
 		return (newdev);
 
@@ -1408,7 +1410,10 @@ its_device_alloc_locked(struct gic_v3_it
 	newdev->pci_dev = pci_dev;
 	newdev->devid = devid;
 
-	if (lpi_alloc_chunk(sc, &newdev->lpis, nvecs) != 0) {
+	mtx_lock_spin(&sc->its_dev_lock);
+	err = lpi_alloc_chunk(sc, &newdev->lpis, nvecs);
+	mtx_unlock_spin(&sc->its_dev_lock);
+	if (err != 0) {
 		free(newdev, M_GIC_V3_ITS);
 		return (NULL);
 	}
@@ -1424,7 +1429,9 @@ its_device_alloc_locked(struct gic_v3_it
 	    roundup2(roundup2(nvecs, 2) * esize, 0x100), M_GIC_V3_ITS,
 	    (M_NOWAIT | M_ZERO), 0, ~0UL, 0x100, 0);
 	if (newdev->itt == 0) {
+		mtx_lock_spin(&sc->its_dev_lock);
 		lpi_free_chunk(sc, &newdev->lpis);
+		mtx_unlock_spin(&sc->its_dev_lock);
 		free(newdev, M_GIC_V3_ITS);
 		return (NULL);
 	}
@@ -1436,7 +1443,9 @@ its_device_alloc_locked(struct gic_v3_it
 	cpuid = 0;
 	newdev->col = sc->its_cols[cpuid];
 
+	mtx_lock_spin(&sc->its_dev_lock);
 	TAILQ_INSERT_TAIL(&sc->its_dev_list, newdev, entry);
+	mtx_unlock_spin(&sc->its_dev_lock);
 
 	/* Map device to its ITT */
 	its_cmd_mapd(sc, newdev, 1);
@@ -1449,7 +1458,7 @@ its_device_asign_lpi_locked(struct gic_v
     struct its_dev *its_dev, u_int *irq)
 {
 
-	mtx_assert(&sc->its_mtx, MA_OWNED);
+	mtx_assert(&sc->its_dev_lock, MA_OWNED);
 	if (its_dev->lpis.lpi_free == 0) {
 		panic("Requesting more LPIs than allocated for this device. "
 		    "LPI num: %u, free %u", its_dev->lpis.lpi_num,
@@ -1612,21 +1621,19 @@ gic_v3_its_alloc_msix(device_t dev, devi
 
 	sc = device_get_softc(dev);
 
-	mtx_lock(&sc->its_mtx);
 	nvecs = PCI_MSIX_NUM(pci_dev);
 
 	/*
 	 * Allocate device as seen by ITS if not already available.
 	 * Notice that MSI-X interrupts are allocated on one-by-one basis.
 	 */
-	its_dev = its_device_alloc_locked(sc, pci_dev, nvecs);
-	if (its_dev == NULL) {
-		mtx_unlock(&sc->its_mtx);
+	its_dev = its_device_alloc(sc, pci_dev, nvecs);
+	if (its_dev == NULL)
 		return (ENOMEM);
-	}
 
+	mtx_lock_spin(&sc->its_dev_lock);
 	its_device_asign_lpi_locked(sc, its_dev, irq);
-	mtx_unlock(&sc->its_mtx);
+	mtx_unlock_spin(&sc->its_dev_lock);
 
 	return (0);
 }
@@ -1640,18 +1647,16 @@ gic_v3_its_alloc_msi(device_t dev, devic
 	sc = device_get_softc(dev);
 
 	/* Allocate device as seen by ITS if not already available. */
-	mtx_lock(&sc->its_mtx);
-	its_dev = its_device_alloc_locked(sc, pci_dev, count);
-	if (its_dev == NULL) {
-		mtx_unlock(&sc->its_mtx);
+	its_dev = its_device_alloc(sc, pci_dev, count);
+	if (its_dev == NULL)
 		return (ENOMEM);
-	}
 
+	mtx_lock_spin(&sc->its_dev_lock);
 	for (; count > 0; count--) {
 		its_device_asign_lpi_locked(sc, its_dev, irqs);
 		irqs++;
 	}
-	mtx_unlock(&sc->its_mtx);
+	mtx_unlock_spin(&sc->its_dev_lock);
 
 	return (0);
 }
@@ -1668,9 +1673,9 @@ gic_v3_its_map_msi(device_t dev, device_
 
 	sc = device_get_softc(dev);
 	/* Verify that this device is allocated and owns this LPI */
-	mtx_lock(&sc->its_mtx);
-	its_dev = its_device_find_locked(sc, pci_dev);
-	mtx_unlock(&sc->its_mtx);
+	mtx_lock_spin(&sc->its_dev_lock);
+	its_dev = its_device_find_locked(sc, pci_dev, 0);
+	mtx_unlock_spin(&sc->its_dev_lock);
 	if (its_dev == NULL)
 		return (EINVAL);
 

Modified: head/sys/arm64/arm64/gic_v3_var.h
==============================================================================
--- head/sys/arm64/arm64/gic_v3_var.h	Thu Feb 11 12:01:33 2016	(r295517)
+++ head/sys/arm64/arm64/gic_v3_var.h	Thu Feb 11 12:03:11 2016	(r295518)
@@ -230,8 +230,8 @@ struct gic_v3_its_softc {
 	unsigned long *		its_lpi_bitmap;
 	uint32_t		its_lpi_maxid;
 
-	struct mtx		its_mtx;
-	struct mtx		its_spin_mtx;
+	struct mtx		its_dev_lock;
+	struct mtx		its_cmd_lock;
 
 	uint32_t		its_socket;	/* Socket number ITS is attached to */
 };


More information about the svn-src-head mailing list