Commit f62bc980e6fd26434012c0d5676ecb17179d9ee4
1 parent
2d62ece14f
Exists in
master
and in
4 other branches
dma-debug: add checking for map/unmap_page/single
Impact: add debug callbacks for dma_{un}map_[page|single] Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Showing 2 changed files with 76 additions and 0 deletions Side-by-side Diff
include/linux/dma-debug.h
... | ... | @@ -28,11 +28,34 @@ |
28 | 28 | |
29 | 29 | extern void dma_debug_init(u32 num_entries); |
30 | 30 | |
31 | +extern void debug_dma_map_page(struct device *dev, struct page *page, | |
32 | + size_t offset, size_t size, | |
33 | + int direction, dma_addr_t dma_addr, | |
34 | + bool map_single); | |
35 | + | |
36 | +extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | |
37 | + size_t size, int direction, bool map_single); | |
38 | + | |
39 | + | |
31 | 40 | #else /* CONFIG_DMA_API_DEBUG */ |
32 | 41 | |
33 | 42 | static inline void dma_debug_init(u32 num_entries) |
34 | 43 | { |
35 | 44 | } |
45 | + | |
46 | +static inline void debug_dma_map_page(struct device *dev, struct page *page, | |
47 | + size_t offset, size_t size, | |
48 | + int direction, dma_addr_t dma_addr, | |
49 | + bool map_single) | |
50 | +{ | |
51 | +} | |
52 | + | |
53 | +static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | |
54 | + size_t size, int direction, | |
55 | + bool map_single) | |
56 | +{ | |
57 | +} | |
58 | + | |
36 | 59 | |
37 | 60 | #endif /* CONFIG_DMA_API_DEBUG */ |
38 | 61 |
lib/dma-debug.c
... | ... | @@ -565,4 +565,57 @@ |
565 | 565 | put_hash_bucket(bucket, &flags); |
566 | 566 | |
567 | 567 | } |
568 | + | |
569 | +void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | |
570 | + size_t size, int direction, dma_addr_t dma_addr, | |
571 | + bool map_single) | |
572 | +{ | |
573 | + struct dma_debug_entry *entry; | |
574 | + | |
575 | + if (unlikely(global_disable)) | |
576 | + return; | |
577 | + | |
578 | + if (unlikely(dma_mapping_error(dev, dma_addr))) | |
579 | + return; | |
580 | + | |
581 | + entry = dma_entry_alloc(); | |
582 | + if (!entry) | |
583 | + return; | |
584 | + | |
585 | + entry->dev = dev; | |
586 | + entry->type = dma_debug_page; | |
587 | + entry->paddr = page_to_phys(page) + offset; | |
588 | + entry->dev_addr = dma_addr; | |
589 | + entry->size = size; | |
590 | + entry->direction = direction; | |
591 | + | |
592 | + if (map_single) { | |
593 | + entry->type = dma_debug_single; | |
594 | + check_for_stack(dev, page_address(page) + offset); | |
595 | + } | |
596 | + | |
597 | + add_dma_entry(entry); | |
598 | +} | |
599 | +EXPORT_SYMBOL(debug_dma_map_page); | |
600 | + | |
601 | +void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | |
602 | + size_t size, int direction, bool map_single) | |
603 | +{ | |
604 | + struct dma_debug_entry ref = { | |
605 | + .type = dma_debug_page, | |
606 | + .dev = dev, | |
607 | + .dev_addr = addr, | |
608 | + .size = size, | |
609 | + .direction = direction, | |
610 | + }; | |
611 | + | |
612 | + if (unlikely(global_disable)) | |
613 | + return; | |
614 | + | |
615 | + if (map_single) | |
616 | + ref.type = dma_debug_single; | |
617 | + | |
618 | + check_unmap(&ref); | |
619 | +} | |
620 | +EXPORT_SYMBOL(debug_dma_unmap_page); |