git: 3a1802fef4b5 - main - busdma: Add an internal BUS_DMA_FORCE_MAP flag to x86 bounce_busdma
Mark Johnston
markj at FreeBSD.org
Wed Aug 11 01:31:11 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=3a1802fef4b535d22b7f0d3fa6e0bc2de5003922
commit 3a1802fef4b535d22b7f0d3fa6e0bc2de5003922
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-08-10 21:11:43 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-08-11 01:27:54 +0000
busdma: Add an internal BUS_DMA_FORCE_MAP flag to x86 bounce_busdma
Use this flag to indicate that busdma should allocate a map structure
even no bouncing is required to satisfy the tag's constraints. This
will be used for KMSAN.
Also fix a memory leak that can occur if the kernel fails to allocate
bounce pages in bounce_bus_dmamap_create().
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D31338
---
sys/x86/x86/busdma_bounce.c | 43 +++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
index 75fdf4143b9b..d89d4d5a17ff 100644
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -66,6 +66,7 @@ enum {
BUS_DMA_COULD_BOUNCE = 0x01,
BUS_DMA_MIN_ALLOC_COMP = 0x02,
BUS_DMA_KMEM_ALLOC = 0x04,
+ BUS_DMA_FORCE_MAP = 0x08,
};
struct bounce_zone;
@@ -301,7 +302,7 @@ bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
error = 0;
if (dmat->segments == NULL) {
- dmat->segments = (bus_dma_segment_t *)malloc_domainset(
+ dmat->segments = malloc_domainset(
sizeof(bus_dma_segment_t) * dmat->common.nsegments,
M_DEVBUF, DOMAINSET_PREF(dmat->common.domain), M_NOWAIT);
if (dmat->segments == NULL) {
@@ -311,6 +312,19 @@ bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
}
}
+ if (dmat->bounce_flags & (BUS_DMA_COULD_BOUNCE | BUS_DMA_FORCE_MAP)) {
+ *mapp = malloc_domainset(sizeof(**mapp), M_DEVBUF,
+ DOMAINSET_PREF(dmat->common.domain), M_NOWAIT | M_ZERO);
+ if (*mapp == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
+ }
+ STAILQ_INIT(&(*mapp)->bpages);
+ } else {
+ *mapp = NULL;
+ }
+
/*
* Bouncing might be required if the driver asks for an active
* exclusion region, a data alignment that is stricter than 1, and/or
@@ -318,23 +332,11 @@ bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
*/
if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) {
/* Must bounce */
- if (dmat->bounce_zone == NULL) {
- if ((error = alloc_bounce_zone(dmat)) != 0)
- return (error);
- }
+ if (dmat->bounce_zone == NULL &&
+ (error = alloc_bounce_zone(dmat)) != 0)
+ goto out;
bz = dmat->bounce_zone;
- *mapp = (bus_dmamap_t)malloc_domainset(sizeof(**mapp), M_DEVBUF,
- DOMAINSET_PREF(dmat->common.domain), M_NOWAIT | M_ZERO);
- if (*mapp == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
- }
-
- /* Initialize the new map */
- STAILQ_INIT(&((*mapp)->bpages));
-
/*
* Attempt to add pages to our pool on a per-instance
* basis up to a sane limit.
@@ -361,11 +363,16 @@ bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
error = 0;
}
bz->map_count++;
+ }
+
+out:
+ if (error == 0) {
+ dmat->map_count++;
} else {
+ free(*mapp, M_DEVBUF);
*mapp = NULL;
}
- if (error == 0)
- dmat->map_count++;
+
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->common.flags, error);
return (error);
More information about the dev-commits-src-main
mailing list