Skip to content

Commit 51ae62a

Browse files
committed
Merge tag 'dma-mapping-6.13-2024-11-19' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - improve the DMA API tracing code (Sean Anderson) - misc cleanups (Christoph Hellwig, Sui Jingfeng) - fix pointer abuse when finding the shared DMA pool (Geert Uytterhoeven) - fix a deadlock in dma-debug (Levi Yun) * tag 'dma-mapping-6.13-2024-11-19' of git://git.infradead.org/users/hch/dma-mapping: dma-mapping: save base/size instead of pointer to shared DMA pool dma-mapping: fix swapped dir/flags arguments to trace_dma_alloc_sgt_err dma-mapping: drop unneeded includes from dma-mapping.h dma-mapping: trace more error paths dma-mapping: use trace_dma_alloc for dma_alloc* instead of using trace_dma_map dma-mapping: trace dma_alloc/free direction dma-mapping: use macros to define events in a class dma-mapping: remove an outdated comment from dma-map-ops.h dma-debug: remove DMA_API_DEBUG_SG dma-debug: store a phys_addr_t in struct dma_debug_entry dma-debug: fix a possible deadlock on radix_lock
2 parents 40f48f8 + 22293c3 commit 51ae62a

File tree

8 files changed

+242
-135
lines changed

8 files changed

+242
-135
lines changed

arch/powerpc/platforms/pseries/svm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <linux/mm.h>
1010
#include <linux/memblock.h>
11+
#include <linux/mem_encrypt.h>
1112
#include <linux/cc_platform.h>
1213
#include <asm/machdep.h>
1314
#include <asm/svm.h>

include/linux/dma-map-ops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static inline bool dev_is_dma_coherent(struct device *dev)
242242
{
243243
return true;
244244
}
245-
#endif /* CONFIG_ARCH_HAS_DMA_COHERENCE_H */
245+
#endif
246246

247247
static inline void dma_reset_need_sync(struct device *dev)
248248
{

include/linux/dma-mapping.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22
#ifndef _LINUX_DMA_MAPPING_H
33
#define _LINUX_DMA_MAPPING_H
44

5-
#include <linux/cache.h>
6-
#include <linux/sizes.h>
7-
#include <linux/string.h>
85
#include <linux/device.h>
96
#include <linux/err.h>
107
#include <linux/dma-direction.h>
118
#include <linux/scatterlist.h>
129
#include <linux/bug.h>
13-
#include <linux/mem_encrypt.h>
1410

1511
/**
1612
* List of possible attributes associated with a DMA mapping. The semantics

include/trace/events/dma.h

Lines changed: 173 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,14 @@ DECLARE_EVENT_CLASS(dma_map,
6565
decode_dma_attrs(__entry->attrs))
6666
);
6767

68-
DEFINE_EVENT(dma_map, dma_map_page,
69-
TP_PROTO(struct device *dev, phys_addr_t phys_addr, dma_addr_t dma_addr,
70-
size_t size, enum dma_data_direction dir, unsigned long attrs),
71-
TP_ARGS(dev, phys_addr, dma_addr, size, dir, attrs));
68+
#define DEFINE_MAP_EVENT(name) \
69+
DEFINE_EVENT(dma_map, name, \
70+
TP_PROTO(struct device *dev, phys_addr_t phys_addr, dma_addr_t dma_addr, \
71+
size_t size, enum dma_data_direction dir, unsigned long attrs), \
72+
TP_ARGS(dev, phys_addr, dma_addr, size, dir, attrs))
7273

73-
DEFINE_EVENT(dma_map, dma_map_resource,
74-
TP_PROTO(struct device *dev, phys_addr_t phys_addr, dma_addr_t dma_addr,
75-
size_t size, enum dma_data_direction dir, unsigned long attrs),
76-
TP_ARGS(dev, phys_addr, dma_addr, size, dir, attrs));
74+
DEFINE_MAP_EVENT(dma_map_page);
75+
DEFINE_MAP_EVENT(dma_map_resource);
7776

7877
DECLARE_EVENT_CLASS(dma_unmap,
7978
TP_PROTO(struct device *dev, dma_addr_t addr, size_t size,
@@ -104,27 +103,28 @@ DECLARE_EVENT_CLASS(dma_unmap,
104103
decode_dma_attrs(__entry->attrs))
105104
);
106105

107-
DEFINE_EVENT(dma_unmap, dma_unmap_page,
108-
TP_PROTO(struct device *dev, dma_addr_t addr, size_t size,
109-
enum dma_data_direction dir, unsigned long attrs),
110-
TP_ARGS(dev, addr, size, dir, attrs));
106+
#define DEFINE_UNMAP_EVENT(name) \
107+
DEFINE_EVENT(dma_unmap, name, \
108+
TP_PROTO(struct device *dev, dma_addr_t addr, size_t size, \
109+
enum dma_data_direction dir, unsigned long attrs), \
110+
TP_ARGS(dev, addr, size, dir, attrs))
111111

112-
DEFINE_EVENT(dma_unmap, dma_unmap_resource,
113-
TP_PROTO(struct device *dev, dma_addr_t addr, size_t size,
114-
enum dma_data_direction dir, unsigned long attrs),
115-
TP_ARGS(dev, addr, size, dir, attrs));
112+
DEFINE_UNMAP_EVENT(dma_unmap_page);
113+
DEFINE_UNMAP_EVENT(dma_unmap_resource);
116114

117-
TRACE_EVENT(dma_alloc,
115+
DECLARE_EVENT_CLASS(dma_alloc_class,
118116
TP_PROTO(struct device *dev, void *virt_addr, dma_addr_t dma_addr,
119-
size_t size, gfp_t flags, unsigned long attrs),
120-
TP_ARGS(dev, virt_addr, dma_addr, size, flags, attrs),
117+
size_t size, enum dma_data_direction dir, gfp_t flags,
118+
unsigned long attrs),
119+
TP_ARGS(dev, virt_addr, dma_addr, size, dir, flags, attrs),
121120

122121
TP_STRUCT__entry(
123122
__string(device, dev_name(dev))
124123
__field(void *, virt_addr)
125124
__field(u64, dma_addr)
126125
__field(size_t, size)
127126
__field(gfp_t, flags)
127+
__field(enum dma_data_direction, dir)
128128
__field(unsigned long, attrs)
129129
),
130130

@@ -137,25 +137,79 @@ TRACE_EVENT(dma_alloc,
137137
__entry->attrs = attrs;
138138
),
139139

140-
TP_printk("%s dma_addr=%llx size=%zu virt_addr=%p flags=%s attrs=%s",
140+
TP_printk("%s dir=%s dma_addr=%llx size=%zu virt_addr=%p flags=%s attrs=%s",
141141
__get_str(device),
142+
decode_dma_data_direction(__entry->dir),
142143
__entry->dma_addr,
143144
__entry->size,
144145
__entry->virt_addr,
145146
show_gfp_flags(__entry->flags),
146147
decode_dma_attrs(__entry->attrs))
147148
);
148149

149-
TRACE_EVENT(dma_free,
150+
#define DEFINE_ALLOC_EVENT(name) \
151+
DEFINE_EVENT(dma_alloc_class, name, \
152+
TP_PROTO(struct device *dev, void *virt_addr, dma_addr_t dma_addr, \
153+
size_t size, enum dma_data_direction dir, gfp_t flags, \
154+
unsigned long attrs), \
155+
TP_ARGS(dev, virt_addr, dma_addr, size, dir, flags, attrs))
156+
157+
DEFINE_ALLOC_EVENT(dma_alloc);
158+
DEFINE_ALLOC_EVENT(dma_alloc_pages);
159+
DEFINE_ALLOC_EVENT(dma_alloc_sgt_err);
160+
161+
TRACE_EVENT(dma_alloc_sgt,
162+
TP_PROTO(struct device *dev, struct sg_table *sgt, size_t size,
163+
enum dma_data_direction dir, gfp_t flags, unsigned long attrs),
164+
TP_ARGS(dev, sgt, size, dir, flags, attrs),
165+
166+
TP_STRUCT__entry(
167+
__string(device, dev_name(dev))
168+
__dynamic_array(u64, phys_addrs, sgt->orig_nents)
169+
__field(u64, dma_addr)
170+
__field(size_t, size)
171+
__field(enum dma_data_direction, dir)
172+
__field(gfp_t, flags)
173+
__field(unsigned long, attrs)
174+
),
175+
176+
TP_fast_assign(
177+
struct scatterlist *sg;
178+
int i;
179+
180+
__assign_str(device);
181+
for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
182+
((u64 *)__get_dynamic_array(phys_addrs))[i] = sg_phys(sg);
183+
__entry->dma_addr = sg_dma_address(sgt->sgl);
184+
__entry->size = size;
185+
__entry->dir = dir;
186+
__entry->flags = flags;
187+
__entry->attrs = attrs;
188+
),
189+
190+
TP_printk("%s dir=%s dma_addr=%llx size=%zu phys_addrs=%s flags=%s attrs=%s",
191+
__get_str(device),
192+
decode_dma_data_direction(__entry->dir),
193+
__entry->dma_addr,
194+
__entry->size,
195+
__print_array(__get_dynamic_array(phys_addrs),
196+
__get_dynamic_array_len(phys_addrs) /
197+
sizeof(u64), sizeof(u64)),
198+
show_gfp_flags(__entry->flags),
199+
decode_dma_attrs(__entry->attrs))
200+
);
201+
202+
DECLARE_EVENT_CLASS(dma_free_class,
150203
TP_PROTO(struct device *dev, void *virt_addr, dma_addr_t dma_addr,
151-
size_t size, unsigned long attrs),
152-
TP_ARGS(dev, virt_addr, dma_addr, size, attrs),
204+
size_t size, enum dma_data_direction dir, unsigned long attrs),
205+
TP_ARGS(dev, virt_addr, dma_addr, size, dir, attrs),
153206

154207
TP_STRUCT__entry(
155208
__string(device, dev_name(dev))
156209
__field(void *, virt_addr)
157210
__field(u64, dma_addr)
158211
__field(size_t, size)
212+
__field(enum dma_data_direction, dir)
159213
__field(unsigned long, attrs)
160214
),
161215

@@ -164,17 +218,63 @@ TRACE_EVENT(dma_free,
164218
__entry->virt_addr = virt_addr;
165219
__entry->dma_addr = dma_addr;
166220
__entry->size = size;
221+
__entry->dir = dir;
167222
__entry->attrs = attrs;
168223
),
169224

170-
TP_printk("%s dma_addr=%llx size=%zu virt_addr=%p attrs=%s",
225+
TP_printk("%s dir=%s dma_addr=%llx size=%zu virt_addr=%p attrs=%s",
171226
__get_str(device),
227+
decode_dma_data_direction(__entry->dir),
172228
__entry->dma_addr,
173229
__entry->size,
174230
__entry->virt_addr,
175231
decode_dma_attrs(__entry->attrs))
176232
);
177233

234+
#define DEFINE_FREE_EVENT(name) \
235+
DEFINE_EVENT(dma_free_class, name, \
236+
TP_PROTO(struct device *dev, void *virt_addr, dma_addr_t dma_addr, \
237+
size_t size, enum dma_data_direction dir, unsigned long attrs), \
238+
TP_ARGS(dev, virt_addr, dma_addr, size, dir, attrs))
239+
240+
DEFINE_FREE_EVENT(dma_free);
241+
DEFINE_FREE_EVENT(dma_free_pages);
242+
243+
TRACE_EVENT(dma_free_sgt,
244+
TP_PROTO(struct device *dev, struct sg_table *sgt, size_t size,
245+
enum dma_data_direction dir),
246+
TP_ARGS(dev, sgt, size, dir),
247+
248+
TP_STRUCT__entry(
249+
__string(device, dev_name(dev))
250+
__dynamic_array(u64, phys_addrs, sgt->orig_nents)
251+
__field(u64, dma_addr)
252+
__field(size_t, size)
253+
__field(enum dma_data_direction, dir)
254+
),
255+
256+
TP_fast_assign(
257+
struct scatterlist *sg;
258+
int i;
259+
260+
__assign_str(device);
261+
for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
262+
((u64 *)__get_dynamic_array(phys_addrs))[i] = sg_phys(sg);
263+
__entry->dma_addr = sg_dma_address(sgt->sgl);
264+
__entry->size = size;
265+
__entry->dir = dir;
266+
),
267+
268+
TP_printk("%s dir=%s dma_addr=%llx size=%zu phys_addrs=%s",
269+
__get_str(device),
270+
decode_dma_data_direction(__entry->dir),
271+
__entry->dma_addr,
272+
__entry->size,
273+
__print_array(__get_dynamic_array(phys_addrs),
274+
__get_dynamic_array_len(phys_addrs) /
275+
sizeof(u64), sizeof(u64)))
276+
);
277+
178278
TRACE_EVENT(dma_map_sg,
179279
TP_PROTO(struct device *dev, struct scatterlist *sgl, int nents,
180280
int ents, enum dma_data_direction dir, unsigned long attrs),
@@ -221,6 +321,41 @@ TRACE_EVENT(dma_map_sg,
221321
decode_dma_attrs(__entry->attrs))
222322
);
223323

324+
TRACE_EVENT(dma_map_sg_err,
325+
TP_PROTO(struct device *dev, struct scatterlist *sgl, int nents,
326+
int err, enum dma_data_direction dir, unsigned long attrs),
327+
TP_ARGS(dev, sgl, nents, err, dir, attrs),
328+
329+
TP_STRUCT__entry(
330+
__string(device, dev_name(dev))
331+
__dynamic_array(u64, phys_addrs, nents)
332+
__field(int, err)
333+
__field(enum dma_data_direction, dir)
334+
__field(unsigned long, attrs)
335+
),
336+
337+
TP_fast_assign(
338+
struct scatterlist *sg;
339+
int i;
340+
341+
__assign_str(device);
342+
for_each_sg(sgl, sg, nents, i)
343+
((u64 *)__get_dynamic_array(phys_addrs))[i] = sg_phys(sg);
344+
__entry->err = err;
345+
__entry->dir = dir;
346+
__entry->attrs = attrs;
347+
),
348+
349+
TP_printk("%s dir=%s dma_addrs=%s err=%d attrs=%s",
350+
__get_str(device),
351+
decode_dma_data_direction(__entry->dir),
352+
__print_array(__get_dynamic_array(phys_addrs),
353+
__get_dynamic_array_len(phys_addrs) /
354+
sizeof(u64), sizeof(u64)),
355+
__entry->err,
356+
decode_dma_attrs(__entry->attrs))
357+
);
358+
224359
TRACE_EVENT(dma_unmap_sg,
225360
TP_PROTO(struct device *dev, struct scatterlist *sgl, int nents,
226361
enum dma_data_direction dir, unsigned long attrs),
@@ -279,15 +414,14 @@ DECLARE_EVENT_CLASS(dma_sync_single,
279414
__entry->size)
280415
);
281416

282-
DEFINE_EVENT(dma_sync_single, dma_sync_single_for_cpu,
283-
TP_PROTO(struct device *dev, dma_addr_t dma_addr, size_t size,
284-
enum dma_data_direction dir),
285-
TP_ARGS(dev, dma_addr, size, dir));
417+
#define DEFINE_SYNC_SINGLE_EVENT(name) \
418+
DEFINE_EVENT(dma_sync_single, name, \
419+
TP_PROTO(struct device *dev, dma_addr_t dma_addr, size_t size, \
420+
enum dma_data_direction dir), \
421+
TP_ARGS(dev, dma_addr, size, dir))
286422

287-
DEFINE_EVENT(dma_sync_single, dma_sync_single_for_device,
288-
TP_PROTO(struct device *dev, dma_addr_t dma_addr, size_t size,
289-
enum dma_data_direction dir),
290-
TP_ARGS(dev, dma_addr, size, dir));
423+
DEFINE_SYNC_SINGLE_EVENT(dma_sync_single_for_cpu);
424+
DEFINE_SYNC_SINGLE_EVENT(dma_sync_single_for_device);
291425

292426
DECLARE_EVENT_CLASS(dma_sync_sg,
293427
TP_PROTO(struct device *dev, struct scatterlist *sgl, int nents,
@@ -326,15 +460,14 @@ DECLARE_EVENT_CLASS(dma_sync_sg,
326460
sizeof(unsigned int), sizeof(unsigned int)))
327461
);
328462

329-
DEFINE_EVENT(dma_sync_sg, dma_sync_sg_for_cpu,
330-
TP_PROTO(struct device *dev, struct scatterlist *sg, int nents,
331-
enum dma_data_direction dir),
332-
TP_ARGS(dev, sg, nents, dir));
463+
#define DEFINE_SYNC_SG_EVENT(name) \
464+
DEFINE_EVENT(dma_sync_sg, name, \
465+
TP_PROTO(struct device *dev, struct scatterlist *sg, int nents, \
466+
enum dma_data_direction dir), \
467+
TP_ARGS(dev, sg, nents, dir))
333468

334-
DEFINE_EVENT(dma_sync_sg, dma_sync_sg_for_device,
335-
TP_PROTO(struct device *dev, struct scatterlist *sg, int nents,
336-
enum dma_data_direction dir),
337-
TP_ARGS(dev, sg, nents, dir));
469+
DEFINE_SYNC_SG_EVENT(dma_sync_sg_for_cpu);
470+
DEFINE_SYNC_SG_EVENT(dma_sync_sg_for_device);
338471

339472
#endif /* _TRACE_DMA_H */
340473

kernel/dma/Kconfig

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,23 +260,6 @@ config DMA_API_DEBUG
260260

261261
If unsure, say N.
262262

263-
config DMA_API_DEBUG_SG
264-
bool "Debug DMA scatter-gather usage"
265-
default y
266-
depends on DMA_API_DEBUG
267-
help
268-
Perform extra checking that callers of dma_map_sg() have respected the
269-
appropriate segment length/boundary limits for the given device when
270-
preparing DMA scatterlists.
271-
272-
This is particularly likely to have been overlooked in cases where the
273-
dma_map_sg() API is used for general bulk mapping of pages rather than
274-
preparing literal scatter-gather descriptors, where there is a risk of
275-
unexpected behaviour from DMA API implementations if the scatterlist
276-
is technically out-of-spec.
277-
278-
If unsure, say N.
279-
280263
config DMA_MAP_BENCHMARK
281264
bool "Enable benchmarking of streaming DMA mapping"
282265
depends on DEBUG_FS

kernel/dma/coherent.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ int dma_init_global_coherent(phys_addr_t phys_addr, size_t size)
330330
#include <linux/of_reserved_mem.h>
331331

332332
#ifdef CONFIG_DMA_GLOBAL_POOL
333-
static struct reserved_mem *dma_reserved_default_memory __initdata;
333+
static phys_addr_t dma_reserved_default_memory_base __initdata;
334+
static phys_addr_t dma_reserved_default_memory_size __initdata;
334335
#endif
335336

336337
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
@@ -376,9 +377,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
376377

377378
#ifdef CONFIG_DMA_GLOBAL_POOL
378379
if (of_get_flat_dt_prop(node, "linux,dma-default", NULL)) {
379-
WARN(dma_reserved_default_memory,
380+
WARN(dma_reserved_default_memory_size,
380381
"Reserved memory: region for default DMA coherent area is redefined\n");
381-
dma_reserved_default_memory = rmem;
382+
dma_reserved_default_memory_base = rmem->base;
383+
dma_reserved_default_memory_size = rmem->size;
382384
}
383385
#endif
384386

@@ -391,10 +393,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
391393
#ifdef CONFIG_DMA_GLOBAL_POOL
392394
static int __init dma_init_reserved_memory(void)
393395
{
394-
if (!dma_reserved_default_memory)
396+
if (!dma_reserved_default_memory_size)
395397
return -ENOMEM;
396-
return dma_init_global_coherent(dma_reserved_default_memory->base,
397-
dma_reserved_default_memory->size);
398+
return dma_init_global_coherent(dma_reserved_default_memory_base,
399+
dma_reserved_default_memory_size);
398400
}
399401
core_initcall(dma_init_reserved_memory);
400402
#endif /* CONFIG_DMA_GLOBAL_POOL */

0 commit comments

Comments
 (0)