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

Configure Feed

Select the types of activity you want to include in your feed.

dma-debug: remove debug_dma_assert_idle() function

This remoes the code from the COW path to call debug_dma_assert_idle(),
which was added many years ago.

Google shows that it hasn't caught anything in the 6+ years we've had it
apart from a false positive, and Hugh just noticed how it had a very
unfortunate spinlock serialization in the COW path.

He fixed that issue the previous commit (a85ffd59bd36: "dma-debug: fix
debug_dma_assert_idle(), use rcu_read_lock()"), but let's see if anybody
even notices when we remove this function entirely.

NOTE! We keep the dma tracking infrastructure that was added by the
commit that introduced it. Partly to make it easier to resurrect this
debug code if we ever deside to, and partly because that tracking by pfn
and offset looks quite reasonable.

The problem with this debug code was simply that it was expensive and
didn't seem worth it, not that it was wrong per se.

Acked-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+1 -58
-6
include/linux/dma-debug.h
··· 67 67 68 68 extern void debug_dma_dump_mappings(struct device *dev); 69 69 70 - extern void debug_dma_assert_idle(struct page *page); 71 - 72 70 #else /* CONFIG_DMA_API_DEBUG */ 73 71 74 72 static inline void dma_debug_add_bus(struct bus_type *bus) ··· 152 154 } 153 155 154 156 static inline void debug_dma_dump_mappings(struct device *dev) 155 - { 156 - } 157 - 158 - static inline void debug_dma_assert_idle(struct page *page) 159 157 { 160 158 } 161 159
-5
kernel/dma/Kconfig
··· 186 186 drivers like double-freeing of DMA mappings or freeing mappings that 187 187 were never allocated. 188 188 189 - This also attempts to catch cases where a page owned by DMA is 190 - accessed by the cpu in a way that could cause data corruption. For 191 - example, this enables cow_user_page() to check that the source page is 192 - not undergoing DMA. 193 - 194 189 This option causes a performance degradation. Use only if you want to 195 190 debug device drivers and dma interactions. 196 191
+1 -45
kernel/dma/debug.c
··· 448 448 * dma_active_cacheline entry to track per event. dma_map_sg(), on the 449 449 * other hand, consumes a single dma_debug_entry, but inserts 'nents' 450 450 * entries into the tree. 451 - * 452 - * At any time debug_dma_assert_idle() can be called to trigger a 453 - * warning if any cachelines in the given page are in the active set. 454 451 */ 455 452 static RADIX_TREE(dma_active_cacheline, GFP_NOWAIT); 456 453 static DEFINE_SPINLOCK(radix_lock); ··· 494 497 overlap = active_cacheline_set_overlap(cln, ++overlap); 495 498 496 499 /* If we overflowed the overlap counter then we're potentially 497 - * leaking dma-mappings. Otherwise, if maps and unmaps are 498 - * balanced then this overflow may cause false negatives in 499 - * debug_dma_assert_idle() as the cacheline may be marked idle 500 - * prematurely. 500 + * leaking dma-mappings. 501 501 */ 502 502 WARN_ONCE(overlap > ACTIVE_CACHELINE_MAX_OVERLAP, 503 503 pr_fmt("exceeded %d overlapping mappings of cacheline %pa\n"), ··· 547 553 if (active_cacheline_dec_overlap(cln) < 0) 548 554 radix_tree_delete(&dma_active_cacheline, cln); 549 555 spin_unlock_irqrestore(&radix_lock, flags); 550 - } 551 - 552 - /** 553 - * debug_dma_assert_idle() - assert that a page is not undergoing dma 554 - * @page: page to lookup in the dma_active_cacheline tree 555 - * 556 - * Place a call to this routine in cases where the cpu touching the page 557 - * before the dma completes (page is dma_unmapped) will lead to data 558 - * corruption. 559 - */ 560 - void debug_dma_assert_idle(struct page *page) 561 - { 562 - struct dma_debug_entry *entry; 563 - unsigned long pfn; 564 - phys_addr_t cln; 565 - 566 - if (dma_debug_disabled()) 567 - return; 568 - 569 - if (!page) 570 - return; 571 - 572 - pfn = page_to_pfn(page); 573 - cln = (phys_addr_t) pfn << CACHELINE_PER_PAGE_SHIFT; 574 - 575 - rcu_read_lock(); 576 - if (!radix_tree_gang_lookup(&dma_active_cacheline, (void **) &entry, 577 - cln, 1) || entry->pfn != pfn) 578 - entry = NULL; 579 - rcu_read_unlock(); 580 - 581 - if (!entry) 582 - return; 583 - 584 - cln = to_cacheline_number(entry); 585 - err_printk(entry->dev, entry, 586 - "cpu touching an active dma mapped cacheline [cln=%pa]\n", 587 - &cln); 588 556 } 589 557 590 558 /*
-2
mm/memory.c
··· 2411 2411 struct mm_struct *mm = vma->vm_mm; 2412 2412 unsigned long addr = vmf->address; 2413 2413 2414 - debug_dma_assert_idle(src); 2415 - 2416 2414 if (likely(src)) { 2417 2415 copy_user_highpage(dst, src, addr, vma); 2418 2416 return true;