From 6442ca2abf882d9d838fb844d852ba6acd1db7f4 Mon Sep 17 00:00:00 2001 From: Dongli Zhang Date: Fri, 18 Jan 2019 15:10:26 +0800 Subject: swiotlb: fix comment on swiotlb_bounce() Fix the comment as swiotlb_bounce() is used to copy from original dma location to swiotlb buffer during swiotlb_tbl_map_single(), while to copy from swiotlb buffer to original dma location during swiotlb_tbl_unmap_single(). Signed-off-by: Dongli Zhang Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 1fb6fd68b9c7..1d8b37747bf0 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -385,7 +385,7 @@ void __init swiotlb_exit(void) } /* - * Bounce: copy the swiotlb buffer back to the original dma location + * Bounce: copy the swiotlb buffer from or back to the original dma location */ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr, size_t size, enum dma_data_direction dir) -- cgit v1.2.3-59-g8ed1b From 71602fe6d4e9291af105adfef8e893b57c735906 Mon Sep 17 00:00:00 2001 From: Dongli Zhang Date: Fri, 18 Jan 2019 15:10:27 +0800 Subject: swiotlb: add debugfs to track swiotlb buffer usage The device driver will not be able to do dma operations once swiotlb buffer is full, either because the driver is using so many IO TLB blocks inflight, or because there is memory leak issue in device driver. To export the swiotlb buffer usage via debugfs would help the user estimate the size of swiotlb buffer to pre-allocate or analyze device driver memory leak issue. Signed-off-by: Dongli Zhang Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 1d8b37747bf0..bedc9f945836 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -34,6 +34,9 @@ #include #include #include +#ifdef CONFIG_DEBUG_FS +#include +#endif #include #include @@ -72,6 +75,11 @@ phys_addr_t io_tlb_start, io_tlb_end; */ static unsigned long io_tlb_nslabs; +/* + * The number of used IO TLB block + */ +static unsigned long io_tlb_used; + /* * This is a free list describing the number of free entries available from * each index @@ -524,6 +532,7 @@ not_found: dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes)\n", size); return DMA_MAPPING_ERROR; found: + io_tlb_used += nslots; spin_unlock_irqrestore(&io_tlb_lock, flags); /* @@ -584,6 +593,8 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, */ for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--) io_tlb_list[i] = ++count; + + io_tlb_used -= nslots; } spin_unlock_irqrestore(&io_tlb_lock, flags); } @@ -662,3 +673,36 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask) { return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask; } + +#ifdef CONFIG_DEBUG_FS + +static int __init swiotlb_create_debugfs(void) +{ + static struct dentry *d_swiotlb_usage; + struct dentry *ent; + + d_swiotlb_usage = debugfs_create_dir("swiotlb", NULL); + + if (!d_swiotlb_usage) + return -ENOMEM; + + ent = debugfs_create_ulong("io_tlb_nslabs", 0400, + d_swiotlb_usage, &io_tlb_nslabs); + if (!ent) + goto fail; + + ent = debugfs_create_ulong("io_tlb_used", 0400, + d_swiotlb_usage, &io_tlb_used); + if (!ent) + goto fail; + + return 0; + +fail: + debugfs_remove_recursive(d_swiotlb_usage); + return -ENOMEM; +} + +late_initcall(swiotlb_create_debugfs); + +#endif -- cgit v1.2.3-59-g8ed1b From 60513ed06a41049768a6875229b025b6e726e148 Mon Sep 17 00:00:00 2001 From: Dongli Zhang Date: Fri, 18 Jan 2019 15:10:28 +0800 Subject: swiotlb: checking whether swiotlb buffer is full with io_tlb_used This patch uses io_tlb_used to help check whether swiotlb buffer is full. io_tlb_used is no longer used for only debugfs. It is also used to help optimize swiotlb_tbl_map_single(). Suggested-by: Joe Jin Signed-off-by: Dongli Zhang Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index bedc9f945836..a01b83e95a2a 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -483,6 +483,10 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, * request and allocate a buffer from that IO TLB pool. */ spin_lock_irqsave(&io_tlb_lock, flags); + + if (unlikely(nslots > io_tlb_nslabs - io_tlb_used)) + goto not_found; + index = ALIGN(io_tlb_index, stride); if (index >= io_tlb_nslabs) index = 0; -- cgit v1.2.3-59-g8ed1b From 22cb45d7692ab502dd47dc5a607b3af240ee1e37 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 14 Feb 2019 09:04:08 +0000 Subject: swiotlb: drop pointless static qualifier in swiotlb_create_debugfs() There is no need to have the 'struct dentry *d_swiotlb_usage' variable static since new value always be assigned before use it. Signed-off-by: YueHaibing Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index a01b83e95a2a..2b0c8fd9658e 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -682,7 +682,7 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask) static int __init swiotlb_create_debugfs(void) { - static struct dentry *d_swiotlb_usage; + struct dentry *d_swiotlb_usage; struct dentry *ent; d_swiotlb_usage = debugfs_create_dir("swiotlb", NULL); -- cgit v1.2.3-59-g8ed1b