dma-debug: add function to dump dma mappings
This adds a function to dump the DMA mappings that the debugging code is aware of -- either for a single device, or for _all_ devices. This can be useful for debugging -- sticking a call to it in the DMA page fault handler, for example, to see if the faulting address _should_ be mapped or not, and hence work out whether it's IOMMU bugs we're seeing, or driver bugs. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
Родитель
a31fba5d68
Коммит
ac26c18bd3
|
@ -76,6 +76,8 @@ extern void debug_dma_sync_sg_for_device(struct device *dev,
|
||||||
struct scatterlist *sg,
|
struct scatterlist *sg,
|
||||||
int nelems, int direction);
|
int nelems, int direction);
|
||||||
|
|
||||||
|
extern void debug_dma_dump_mappings(struct device *dev);
|
||||||
|
|
||||||
#else /* CONFIG_DMA_API_DEBUG */
|
#else /* CONFIG_DMA_API_DEBUG */
|
||||||
|
|
||||||
static inline void dma_debug_init(u32 num_entries)
|
static inline void dma_debug_init(u32 num_entries)
|
||||||
|
@ -156,6 +158,10 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void debug_dma_dump_mappings(struct device *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DMA_API_DEBUG */
|
#endif /* CONFIG_DMA_API_DEBUG */
|
||||||
|
|
||||||
#endif /* __DMA_DEBUG_H */
|
#endif /* __DMA_DEBUG_H */
|
||||||
|
|
|
@ -193,6 +193,36 @@ static void hash_bucket_del(struct dma_debug_entry *entry)
|
||||||
list_del(&entry->list);
|
list_del(&entry->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump mapping entries for debugging purposes
|
||||||
|
*/
|
||||||
|
void debug_dma_dump_mappings(struct device *dev)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < HASH_SIZE; idx++) {
|
||||||
|
struct hash_bucket *bucket = &dma_entry_hash[idx];
|
||||||
|
struct dma_debug_entry *entry;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&bucket->lock, flags);
|
||||||
|
|
||||||
|
list_for_each_entry(entry, &bucket->list, list) {
|
||||||
|
if (!dev || dev == entry->dev) {
|
||||||
|
dev_info(entry->dev,
|
||||||
|
"%s idx %d P=%Lx D=%Lx L=%Lx %s\n",
|
||||||
|
type2name[entry->type], idx,
|
||||||
|
(unsigned long long)entry->paddr,
|
||||||
|
entry->dev_addr, entry->size,
|
||||||
|
dir2name[entry->direction]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&bucket->lock, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(debug_dma_dump_mappings);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper function for adding an entry to the hash.
|
* Wrapper function for adding an entry to the hash.
|
||||||
* This function takes care of locking itself.
|
* This function takes care of locking itself.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче