Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+54 -4
+3
include/linux/swiotlb.h
··· 120 120 * debugfs. 121 121 * @used_hiwater: The high water mark for total_used. Used only for reporting 122 122 * in debugfs. 123 + * @transient_nslabs: The total number of slots in all transient pools that 124 + * are currently used across all areas. 123 125 */ 124 126 struct io_tlb_mem { 125 127 struct io_tlb_pool defpool; ··· 139 137 #ifdef CONFIG_DEBUG_FS 140 138 atomic_long_t total_used; 141 139 atomic_long_t used_hiwater; 140 + atomic_long_t transient_nslabs; 142 141 #endif 143 142 }; 144 143
+5 -4
kernel/dma/direct.c
··· 286 286 } else { 287 287 ret = page_address(page); 288 288 if (dma_set_decrypted(dev, ret, size)) 289 - goto out_free_pages; 289 + goto out_leak_pages; 290 290 } 291 291 292 292 memset(ret, 0, size); ··· 306 306 return NULL; 307 307 out_free_pages: 308 308 __dma_direct_free_pages(dev, page, size); 309 + return NULL; 310 + out_leak_pages: 309 311 return NULL; 310 312 } 311 313 ··· 369 367 370 368 ret = page_address(page); 371 369 if (dma_set_decrypted(dev, ret, size)) 372 - goto out_free_pages; 370 + goto out_leak_pages; 373 371 memset(ret, 0, size); 374 372 *dma_handle = phys_to_dma_direct(dev, page_to_phys(page)); 375 373 return page; 376 - out_free_pages: 377 - __dma_direct_free_pages(dev, page, size); 374 + out_leak_pages: 378 375 return NULL; 379 376 } 380 377
+46
kernel/dma/swiotlb.c
··· 956 956 } 957 957 #endif /* CONFIG_DEBUG_FS */ 958 958 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 + 959 981 /** 960 982 * swiotlb_search_pool_area() - search one memory area in one pool 961 983 * @dev: Device which maps the buffer. ··· 1192 1170 spin_lock_irqsave(&dev->dma_io_tlb_lock, flags); 1193 1171 list_add_rcu(&pool->node, &dev->dma_io_tlb_pools); 1194 1172 spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags); 1173 + inc_transient_used(mem, pool->nslabs); 1195 1174 1196 1175 found: 1197 1176 WRITE_ONCE(dev->dma_uses_io_tlb, true); ··· 1438 1415 1439 1416 dec_used(dev->dma_io_tlb_mem, pool->nslabs); 1440 1417 swiotlb_del_pool(dev, pool); 1418 + dec_transient_used(dev->dma_io_tlb_mem, pool->nslabs); 1441 1419 return true; 1442 1420 } 1443 1421 ··· 1581 1557 } 1582 1558 1583 1559 #ifdef CONFIG_DEBUG_FS 1560 + #ifdef CONFIG_SWIOTLB_DYNAMIC 1561 + static unsigned long mem_transient_used(struct io_tlb_mem *mem) 1562 + { 1563 + return atomic_long_read(&mem->transient_nslabs); 1564 + } 1565 + 1566 + static int io_tlb_transient_used_get(void *data, u64 *val) 1567 + { 1568 + struct io_tlb_mem *mem = data; 1569 + 1570 + *val = mem_transient_used(mem); 1571 + return 0; 1572 + } 1573 + 1574 + DEFINE_DEBUGFS_ATTRIBUTE(fops_io_tlb_transient_used, io_tlb_transient_used_get, 1575 + NULL, "%llu\n"); 1576 + #endif /* CONFIG_SWIOTLB_DYNAMIC */ 1584 1577 1585 1578 static int io_tlb_used_get(void *data, u64 *val) 1586 1579 { ··· 1646 1605 &fops_io_tlb_used); 1647 1606 debugfs_create_file("io_tlb_used_hiwater", 0600, mem->debugfs, mem, 1648 1607 &fops_io_tlb_hiwater); 1608 + #ifdef CONFIG_SWIOTLB_DYNAMIC 1609 + atomic_long_set(&mem->transient_nslabs, 0); 1610 + debugfs_create_file("io_tlb_transient_nslabs", 0400, mem->debugfs, 1611 + mem, &fops_io_tlb_transient_used); 1612 + #endif 1649 1613 } 1650 1614 1651 1615 static int __init swiotlb_create_default_debugfs(void)