Skip to content

Commit 7d62cb2

Browse files
committed
Merge tag 'dma-mapping-6.9-2024-03-11' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - fix leaked pages on dma_set_decrypted() failure (Rick Edgecombe) - add a new swiotlb debugfs file (ZhangPeng) * tag 'dma-mapping-6.9-2024-03-11' of git://git.infradead.org/users/hch/dma-mapping: dma-direct: Leak pages on dma_set_decrypted() failure swiotlb: add debugfs to track swiotlb transient pool usage
2 parents 8c9c2f8 + b9fa169 commit 7d62cb2

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

include/linux/swiotlb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct io_tlb_pool {
120120
* debugfs.
121121
* @used_hiwater: The high water mark for total_used. Used only for reporting
122122
* in debugfs.
123+
* @transient_nslabs: The total number of slots in all transient pools that
124+
* are currently used across all areas.
123125
*/
124126
struct io_tlb_mem {
125127
struct io_tlb_pool defpool;
@@ -137,6 +139,7 @@ struct io_tlb_mem {
137139
#ifdef CONFIG_DEBUG_FS
138140
atomic_long_t total_used;
139141
atomic_long_t used_hiwater;
142+
atomic_long_t transient_nslabs;
140143
#endif
141144
};
142145

kernel/dma/direct.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
286286
} else {
287287
ret = page_address(page);
288288
if (dma_set_decrypted(dev, ret, size))
289-
goto out_free_pages;
289+
goto out_leak_pages;
290290
}
291291

292292
memset(ret, 0, size);
@@ -307,6 +307,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
307307
out_free_pages:
308308
__dma_direct_free_pages(dev, page, size);
309309
return NULL;
310+
out_leak_pages:
311+
return NULL;
310312
}
311313

312314
void dma_direct_free(struct device *dev, size_t size,
@@ -367,12 +369,11 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
367369

368370
ret = page_address(page);
369371
if (dma_set_decrypted(dev, ret, size))
370-
goto out_free_pages;
372+
goto out_leak_pages;
371373
memset(ret, 0, size);
372374
*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
373375
return page;
374-
out_free_pages:
375-
__dma_direct_free_pages(dev, page, size);
376+
out_leak_pages:
376377
return NULL;
377378
}
378379

kernel/dma/swiotlb.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,28 @@ static void dec_used(struct io_tlb_mem *mem, unsigned int nslots)
956956
}
957957
#endif /* CONFIG_DEBUG_FS */
958958

959+
#ifdef CONFIG_SWIOTLB_DYNAMIC
960+
#ifdef CONFIG_DEBUG_FS
961+
static void inc_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
962+
{
963+
atomic_long_add(nslots, &mem->transient_nslabs);
964+
}
965+
966+
static void dec_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
967+
{
968+
atomic_long_sub(nslots, &mem->transient_nslabs);
969+
}
970+
971+
#else /* !CONFIG_DEBUG_FS */
972+
static void inc_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
973+
{
974+
}
975+
static void dec_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
976+
{
977+
}
978+
#endif /* CONFIG_DEBUG_FS */
979+
#endif /* CONFIG_SWIOTLB_DYNAMIC */
980+
959981
/**
960982
* swiotlb_search_pool_area() - search one memory area in one pool
961983
* @dev: Device which maps the buffer.
@@ -1170,6 +1192,7 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr,
11701192
spin_lock_irqsave(&dev->dma_io_tlb_lock, flags);
11711193
list_add_rcu(&pool->node, &dev->dma_io_tlb_pools);
11721194
spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags);
1195+
inc_transient_used(mem, pool->nslabs);
11731196

11741197
found:
11751198
WRITE_ONCE(dev->dma_uses_io_tlb, true);
@@ -1415,6 +1438,7 @@ static bool swiotlb_del_transient(struct device *dev, phys_addr_t tlb_addr)
14151438

14161439
dec_used(dev->dma_io_tlb_mem, pool->nslabs);
14171440
swiotlb_del_pool(dev, pool);
1441+
dec_transient_used(dev->dma_io_tlb_mem, pool->nslabs);
14181442
return true;
14191443
}
14201444

@@ -1557,6 +1581,23 @@ phys_addr_t default_swiotlb_limit(void)
15571581
}
15581582

15591583
#ifdef CONFIG_DEBUG_FS
1584+
#ifdef CONFIG_SWIOTLB_DYNAMIC
1585+
static unsigned long mem_transient_used(struct io_tlb_mem *mem)
1586+
{
1587+
return atomic_long_read(&mem->transient_nslabs);
1588+
}
1589+
1590+
static int io_tlb_transient_used_get(void *data, u64 *val)
1591+
{
1592+
struct io_tlb_mem *mem = data;
1593+
1594+
*val = mem_transient_used(mem);
1595+
return 0;
1596+
}
1597+
1598+
DEFINE_DEBUGFS_ATTRIBUTE(fops_io_tlb_transient_used, io_tlb_transient_used_get,
1599+
NULL, "%llu\n");
1600+
#endif /* CONFIG_SWIOTLB_DYNAMIC */
15601601

15611602
static int io_tlb_used_get(void *data, u64 *val)
15621603
{
@@ -1605,6 +1646,11 @@ static void swiotlb_create_debugfs_files(struct io_tlb_mem *mem,
16051646
&fops_io_tlb_used);
16061647
debugfs_create_file("io_tlb_used_hiwater", 0600, mem->debugfs, mem,
16071648
&fops_io_tlb_hiwater);
1649+
#ifdef CONFIG_SWIOTLB_DYNAMIC
1650+
atomic_long_set(&mem->transient_nslabs, 0);
1651+
debugfs_create_file("io_tlb_transient_nslabs", 0400, mem->debugfs,
1652+
mem, &fops_io_tlb_transient_used);
1653+
#endif
16081654
}
16091655

16101656
static int __init swiotlb_create_default_debugfs(void)

0 commit comments

Comments
 (0)