Commit 0a3b192c authored by Corentin Labbe's avatar Corentin Labbe Committed by Christoph Hellwig

dma-debug: add dumping facility via debugfs

While debugging a DMA mapping leak, I needed to access
debug_dma_dump_mappings() but easily from user space.

This patch adds a /sys/kernel/debug/dma-api/dump file which contain all
current DMA mapping.
Signed-off-by: default avatarCorentin Labbe <clabbe@baylibre.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 8e4d81b9
...@@ -696,6 +696,9 @@ dma-api/disabled This read-only file contains the character 'Y' ...@@ -696,6 +696,9 @@ dma-api/disabled This read-only file contains the character 'Y'
happen when it runs out of memory or if it was happen when it runs out of memory or if it was
disabled at boot time disabled at boot time
dma-api/dump This read-only file contains current DMA
mappings.
dma-api/error_count This file is read-only and shows the total dma-api/error_count This file is read-only and shows the total
numbers of errors found. numbers of errors found.
......
...@@ -829,6 +829,33 @@ static const struct file_operations filter_fops = { ...@@ -829,6 +829,33 @@ static const struct file_operations filter_fops = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static int dump_show(struct seq_file *seq, void *v)
{
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) {
seq_printf(seq,
"%s %s %s idx %d P=%llx N=%lx D=%llx L=%llx %s %s\n",
dev_name(entry->dev),
dev_driver_string(entry->dev),
type2name[entry->type], idx,
phys_addr(entry), entry->pfn,
entry->dev_addr, entry->size,
dir2name[entry->direction],
maperr2str[entry->map_err_type]);
}
spin_unlock_irqrestore(&bucket->lock, flags);
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(dump);
static void dma_debug_fs_init(void) static void dma_debug_fs_init(void)
{ {
struct dentry *dentry = debugfs_create_dir("dma-api", NULL); struct dentry *dentry = debugfs_create_dir("dma-api", NULL);
...@@ -841,6 +868,7 @@ static void dma_debug_fs_init(void) ...@@ -841,6 +868,7 @@ static void dma_debug_fs_init(void)
debugfs_create_u32("min_free_entries", 0444, dentry, &min_free_entries); debugfs_create_u32("min_free_entries", 0444, dentry, &min_free_entries);
debugfs_create_u32("nr_total_entries", 0444, dentry, &nr_total_entries); debugfs_create_u32("nr_total_entries", 0444, dentry, &nr_total_entries);
debugfs_create_file("driver_filter", 0644, dentry, NULL, &filter_fops); debugfs_create_file("driver_filter", 0644, dentry, NULL, &filter_fops);
debugfs_create_file("dump", 0444, dentry, NULL, &dump_fops);
} }
static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry) static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment