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");
+		}
 	}
 
 	/*

Reply via email to