Date: Thu, 11 Feb 2016 12:03:11 +0000 (UTC) From: Zbigniew Bodek <zbb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295518 - head/sys/arm64/arm64 Message-ID: <201602111203.u1BC3Bps053182@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */ };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602111203.u1BC3Bps053182>