Commit ceb51173 authored by Robin Murphy's avatar Robin Murphy Committed by Christoph Hellwig

dma-debug: Make leak-like behaviour apparent

Now that we can dynamically allocate DMA debug entries to cope with
drivers maintaining excessively large numbers of live mappings, a driver
which *does* actually have a bug leaking mappings (and is not unloaded)
will no longer trigger the "DMA-API: debugging out of memory - disabling"
message until it gets to actual kernel OOM conditions, which means it
could go unnoticed for a while. To that end, let's inform the user each
time the pool has grown to a multiple of its initial size, which should
make it apparent that they either have a leak or might want to increase
the preallocation size.
Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
Tested-by: default avatarQian Cai <cai@lca.pw>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 2b9d9ac0
...@@ -747,7 +747,11 @@ driver afterwards. This filter can be disabled or changed later using debugfs. ...@@ -747,7 +747,11 @@ driver afterwards. This filter can be disabled or changed later using debugfs.
When the code disables itself at runtime this is most likely because it ran When the code disables itself at runtime this is most likely because it ran
out of dma_debug_entries and was unable to allocate more on-demand. 65536 out of dma_debug_entries and was unable to allocate more on-demand. 65536
entries are preallocated at boot - if this is too low for you boot with entries are preallocated at boot - if this is too low for you boot with
'dma_debug_entries=<your_desired_number>' to overwrite the default. 'dma_debug_entries=<your_desired_number>' to overwrite the default. The
code will print to the kernel log each time it has dynamically allocated
as many entries as were initially preallocated. This is to indicate that a
larger preallocation size may be appropriate, or if it happens continually
that a driver may be leaking mappings.
:: ::
......
...@@ -691,6 +691,18 @@ static struct dma_debug_entry *__dma_entry_alloc(void) ...@@ -691,6 +691,18 @@ static struct dma_debug_entry *__dma_entry_alloc(void)
return entry; return entry;
} }
void __dma_entry_alloc_check_leak(void)
{
u32 tmp = nr_total_entries % nr_prealloc_entries;
/* Shout each time we tick over some multiple of the initial pool */
if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) {
pr_info("dma_debug_entry pool grown to %u (%u00%%)\n",
nr_total_entries,
(nr_total_entries / nr_prealloc_entries));
}
}
/* struct dma_entry allocator /* struct dma_entry allocator
* *
* The next two functions implement the allocator for * The next two functions implement the allocator for
...@@ -710,6 +722,7 @@ static struct dma_debug_entry *dma_entry_alloc(void) ...@@ -710,6 +722,7 @@ static struct dma_debug_entry *dma_entry_alloc(void)
pr_err("debugging out of memory - disabling\n"); pr_err("debugging out of memory - disabling\n");
return NULL; return NULL;
} }
__dma_entry_alloc_check_leak();
} }
entry = __dma_entry_alloc(); entry = __dma_entry_alloc();
......
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