Skip to content

Commit 02e7656

Browse files
ZhangPengChristoph Hellwig
authored andcommitted
swiotlb: add debugfs to track swiotlb transient pool usage
Introduce a new debugfs interface io_tlb_transient_nslabs. The device driver can create a new swiotlb transient memory pool once default memory pool is full. To export the swiotlb transient memory pool usage via debugfs would help the user estimate the size of transient swiotlb memory pool or analyze device driver memory leak issue. Signed-off-by: ZhangPeng <zhangpeng362@huawei.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent cf11829 commit 02e7656

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
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/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)