Module Name: src Committed By: thorpej Date: Fri Dec 1 06:47:59 UTC 2023
Modified Files: src/sys/arch/sparc64/dev: iommu.c iommuvar.h sbus.c Log Message: Use vmem(9) rather than extent(9) to manage DVMA mappings. To generate a diff of this commit: cvs rdiff -u -r1.116 -r1.117 src/sys/arch/sparc64/dev/iommu.c cvs rdiff -u -r1.25 -r1.26 src/sys/arch/sparc64/dev/iommuvar.h cvs rdiff -u -r1.104 -r1.105 src/sys/arch/sparc64/dev/sbus.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/dev/iommu.c diff -u src/sys/arch/sparc64/dev/iommu.c:1.116 src/sys/arch/sparc64/dev/iommu.c:1.117 --- src/sys/arch/sparc64/dev/iommu.c:1.116 Mon Apr 26 07:18:01 2021 +++ src/sys/arch/sparc64/dev/iommu.c Fri Dec 1 06:47:59 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: iommu.c,v 1.116 2021/04/26 07:18:01 mrg Exp $ */ +/* $NetBSD: iommu.c,v 1.117 2023/12/01 06:47:59 thorpej Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.116 2021/04/26 07:18:01 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.117 2023/12/01 06:47:59 thorpej Exp $"); #include "opt_ddb.h" @@ -212,13 +212,17 @@ iommu_init(char *name, struct iommu_stat aprint_debug("IOTSB: %llx to %llx\n", (unsigned long long)is->is_ptsb, (unsigned long long)(is->is_ptsb + size - 1)); - is->is_dvmamap = extent_create(name, - is->is_dvmabase, is->is_dvmaend, - 0, 0, EX_NOWAIT); - if (!is->is_dvmamap) - panic("iommu_init: extent_create() failed"); - - mutex_init(&is->is_lock, MUTEX_DEFAULT, IPL_HIGH); + is->is_dvmamap = vmem_create(name, + is->is_dvmabase, + (is->is_dvmaend + 1) - is->is_dvmabase, + PAGE_SIZE, /* quantum */ + NULL, /* importfn */ + NULL, /* releasefn */ + NULL, /* source */ + 0, /* qcache_max */ + VM_SLEEP, + IPL_VM); + KASSERT(is->is_dvmamap != NULL); /* * Set the TSB size. The relevant bits were moved to the TSB @@ -554,7 +558,8 @@ iommu_dvmamap_load(bus_dma_tag_t t, bus_ int err, needsflush; bus_size_t sgsize; paddr_t curaddr; - u_long dvmaddr, sgstart, sgend, bmask; + u_long sgstart, sgend, bmask; + vmem_addr_t dvmaddr; bus_size_t align, boundary, len; vaddr_t vaddr = (vaddr_t)buf; int seg; @@ -596,12 +601,15 @@ iommu_dvmamap_load(bus_dma_tag_t t, bus_ * If our segment size is larger than the boundary we need to * split the transfer up int little pieces ourselves. */ - KASSERT(is->is_dvmamap); - mutex_enter(&is->is_lock); - err = extent_alloc(is->is_dvmamap, sgsize, align, - (sgsize > boundary) ? 0 : boundary, - EX_NOWAIT|EX_BOUNDZERO, &dvmaddr); - mutex_exit(&is->is_lock); + KASSERT(is->is_dvmamap != NULL); + err = vmem_xalloc(is->is_dvmamap, sgsize, + align, /* alignment */ + 0, /* phase */ + (sgsize > boundary) ? 0 : boundary, + VMEM_ADDR_MIN, /* minaddr */ + VMEM_ADDR_MAX, /* maxaddr */ + VM_NOSLEEP | VM_BESTFIT, + &dvmaddr); #ifdef DEBUG if (err || (dvmaddr == (u_long)-1)) { @@ -649,15 +657,9 @@ iommu_dvmamap_load(bus_dma_tag_t t, bus_ /* Too many segments. Fail the operation. */ DPRINTF(IDB_INFO, ("iommu_dvmamap_load: " "too many segments %d\n", seg)); - mutex_enter(&is->is_lock); - err = extent_free(is->is_dvmamap, - dvmaddr, sgsize, EX_NOWAIT); + vmem_xfree(is->is_dvmamap, dvmaddr, sgsize); map->_dm_dvmastart = 0; map->_dm_dvmasize = 0; - mutex_exit(&is->is_lock); - if (err != 0) - printf("warning: %s: %" PRId64 - " of DVMA space lost\n", __func__, sgsize); return (EFBIG); } sgstart += len; @@ -741,8 +743,6 @@ iommu_dvmamap_unload(bus_dma_tag_t t, bu { struct strbuf_ctl *sb = (struct strbuf_ctl *)map->_dm_cookie; struct iommu_state *is = sb->sb_is; - int error; - bus_size_t sgsize = map->_dm_dvmasize; /* Flush the iommu */ if (!map->_dm_dvmastart) @@ -763,15 +763,9 @@ iommu_dvmamap_unload(bus_dma_tag_t t, bu bus_dmamap_unload(t->_parent, map); } - mutex_enter(&is->is_lock); - error = extent_free(is->is_dvmamap, map->_dm_dvmastart, - map->_dm_dvmasize, EX_NOWAIT); + vmem_xfree(is->is_dvmamap, map->_dm_dvmastart, map->_dm_dvmasize); map->_dm_dvmastart = 0; map->_dm_dvmasize = 0; - mutex_exit(&is->is_lock); - if (error != 0) - printf("warning: %s: %" PRId64 " of DVMA space lost\n", - __func__, sgsize); /* Clear the map */ } @@ -833,17 +827,21 @@ iommu_dvmamap_load_raw(bus_dma_tag_t t, } sgsize = round_page(sgsize); - mutex_enter(&is->is_lock); /* * If our segment size is larger than the boundary we need to * split the transfer up into little pieces ourselves. */ - err = extent_alloc(is->is_dvmamap, sgsize, align, - (sgsize > boundary) ? 0 : boundary, - ((flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT) | - EX_BOUNDZERO, &dvmaddr); - mutex_exit(&is->is_lock); + const vm_flag_t vmflags = VM_BESTFIT | + ((flags & BUS_DMA_NOWAIT) ? VM_NOSLEEP : VM_SLEEP); + err = vmem_xalloc(is->is_dvmamap, sgsize, + align, /* alignment */ + 0, /* phase */ + (sgsize > boundary) ? 0 : boundary, + VMEM_ADDR_MIN, /* minaddr */ + VMEM_ADDR_MAX, /* maxaddr */ + vmflags, + &dvmaddr); if (err != 0) return (err); @@ -1075,15 +1073,9 @@ iommu_dvmamap_load_raw(bus_dma_tag_t t, return (0); fail: - mutex_enter(&is->is_lock); - err = extent_free(is->is_dvmamap, map->_dm_dvmastart, sgsize, - EX_NOWAIT); + vmem_free(is->is_dvmamap, map->_dm_dvmastart, sgsize); map->_dm_dvmastart = 0; map->_dm_dvmasize = 0; - mutex_exit(&is->is_lock); - if (err != 0) - printf("warning: %s: %" PRId64 " of DVMA space lost\n", - __func__, sgsize); return (EFBIG); } Index: src/sys/arch/sparc64/dev/iommuvar.h diff -u src/sys/arch/sparc64/dev/iommuvar.h:1.25 src/sys/arch/sparc64/dev/iommuvar.h:1.26 --- src/sys/arch/sparc64/dev/iommuvar.h:1.25 Sat Jul 24 21:31:36 2021 +++ src/sys/arch/sparc64/dev/iommuvar.h Fri Dec 1 06:47:59 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: iommuvar.h,v 1.25 2021/07/24 21:31:36 andvar Exp $ */ +/* $NetBSD: iommuvar.h,v 1.26 2023/12/01 06:47:59 thorpej Exp $ */ /* * Copyright (c) 1999 Matthew R. Green @@ -29,6 +29,8 @@ #ifndef _SPARC64_DEV_IOMMUVAR_H_ #define _SPARC64_DEV_IOMMUVAR_H_ +#include <sys/vmem.h> + /* * Streaming buffer control * @@ -54,8 +56,7 @@ struct iommu_state { u_int is_dvmabase; u_int is_dvmaend; int64_t is_cr; /* IOMMU control register value */ - struct extent *is_dvmamap; /* DVMA map for this instance */ - kmutex_t is_lock; /* lock for DVMA map */ + vmem_t *is_dvmamap; /* DVMA map for this instance */ int is_flags; #define IOMMU_FLUSH_CACHE 0x00000001 #define IOMMU_TSBSIZE_IN_PTSB 0x00000002 /* PCIe */ Index: src/sys/arch/sparc64/dev/sbus.c diff -u src/sys/arch/sparc64/dev/sbus.c:1.104 src/sys/arch/sparc64/dev/sbus.c:1.105 --- src/sys/arch/sparc64/dev/sbus.c:1.104 Sat Jan 22 11:49:17 2022 +++ src/sys/arch/sparc64/dev/sbus.c Fri Dec 1 06:47:59 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: sbus.c,v 1.104 2022/01/22 11:49:17 thorpej Exp $ */ +/* $NetBSD: sbus.c,v 1.105 2023/12/01 06:47:59 thorpej Exp $ */ /* * Copyright (c) 1999-2002 Eduardo Horvath @@ -34,17 +34,17 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.104 2022/01/22 11:49:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.105 2023/12/01 06:47:59 thorpej Exp $"); #include "opt_ddb.h" #include <sys/param.h> -#include <sys/extent.h> #include <sys/malloc.h> #include <sys/kmem.h> #include <sys/systm.h> #include <sys/device.h> #include <sys/reboot.h> +#include <sys/vmem.h> #include <sys/bus.h> #include <machine/openfirm.h> @@ -269,13 +269,18 @@ sbus_attach(device_t parent, device_t se * To avoid bugs we'll alloc and ignore the first entry in the IOTSB. */ { - u_long dummy; + vmem_addr_t dummy; - if (extent_alloc_subregion(sc->sc_is.is_dvmamap, - sc->sc_is.is_dvmabase, sc->sc_is.is_dvmabase + PAGE_SIZE, - PAGE_SIZE, PAGE_SIZE, 0, EX_WAITOK|EX_BOUNDZERO, - (u_long *)&dummy) != 0) + if (vmem_xalloc(sc->sc_is.is_dvmamap, PAGE_SIZE, + 0, /* alignment */ + 0, /* phase */ + 0, /* nocross */ + sc->sc_is.is_dvmabase, + sc->sc_is.is_dvmabase + PAGE_SIZE - 1, + VM_BESTFIT | VM_NOSLEEP, + &dummy) != 0) { panic("sbus iommu: can't toss first dvma page"); + } } /*