Commit 6bf078715c1998d4d10716251cc10ce45908594c
1 parent
3b1e79ed73
Exists in
master
and in
4 other branches
dma-debug: add initialization code
Impact: add code to initialize dma-debug core data structures Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Showing 2 changed files with 80 additions and 0 deletions Side-by-side Diff
include/linux/dma-debug.h
... | ... | @@ -20,7 +20,21 @@ |
20 | 20 | #ifndef __DMA_DEBUG_H |
21 | 21 | #define __DMA_DEBUG_H |
22 | 22 | |
23 | +#include <linux/types.h> | |
24 | + | |
23 | 25 | struct device; |
26 | + | |
27 | +#ifdef CONFIG_DMA_API_DEBUG | |
28 | + | |
29 | +extern void dma_debug_init(u32 num_entries); | |
30 | + | |
31 | +#else /* CONFIG_DMA_API_DEBUG */ | |
32 | + | |
33 | +static inline void dma_debug_init(u32 num_entries) | |
34 | +{ | |
35 | +} | |
36 | + | |
37 | +#endif /* CONFIG_DMA_API_DEBUG */ | |
24 | 38 | |
25 | 39 | #endif /* __DMA_DEBUG_H */ |
lib/dma-debug.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | #include <linux/spinlock.h> |
22 | 22 | #include <linux/types.h> |
23 | 23 | #include <linux/list.h> |
24 | +#include <linux/slab.h> | |
24 | 25 | |
25 | 26 | #define HASH_SIZE 1024ULL |
26 | 27 | #define HASH_FN_SHIFT 13 |
... | ... | @@ -196,5 +197,70 @@ |
196 | 197 | list_add(&entry->list, &free_entries); |
197 | 198 | num_free_entries += 1; |
198 | 199 | spin_unlock_irqrestore(&free_entries_lock, flags); |
200 | +} | |
201 | + | |
202 | +/* | |
203 | + * DMA-API debugging init code | |
204 | + * | |
205 | + * The init code does two things: | |
206 | + * 1. Initialize core data structures | |
207 | + * 2. Preallocate a given number of dma_debug_entry structs | |
208 | + */ | |
209 | + | |
210 | +static int prealloc_memory(u32 num_entries) | |
211 | +{ | |
212 | + struct dma_debug_entry *entry, *next_entry; | |
213 | + int i; | |
214 | + | |
215 | + for (i = 0; i < num_entries; ++i) { | |
216 | + entry = kzalloc(sizeof(*entry), GFP_KERNEL); | |
217 | + if (!entry) | |
218 | + goto out_err; | |
219 | + | |
220 | + list_add_tail(&entry->list, &free_entries); | |
221 | + } | |
222 | + | |
223 | + num_free_entries = num_entries; | |
224 | + min_free_entries = num_entries; | |
225 | + | |
226 | + printk(KERN_INFO "DMA-API: preallocated %d debug entries\n", | |
227 | + num_entries); | |
228 | + | |
229 | + return 0; | |
230 | + | |
231 | +out_err: | |
232 | + | |
233 | + list_for_each_entry_safe(entry, next_entry, &free_entries, list) { | |
234 | + list_del(&entry->list); | |
235 | + kfree(entry); | |
236 | + } | |
237 | + | |
238 | + return -ENOMEM; | |
239 | +} | |
240 | + | |
241 | +/* | |
242 | + * Let the architectures decide how many entries should be preallocated. | |
243 | + */ | |
244 | +void dma_debug_init(u32 num_entries) | |
245 | +{ | |
246 | + int i; | |
247 | + | |
248 | + if (global_disable) | |
249 | + return; | |
250 | + | |
251 | + for (i = 0; i < HASH_SIZE; ++i) { | |
252 | + INIT_LIST_HEAD(&dma_entry_hash[i].list); | |
253 | + dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED; | |
254 | + } | |
255 | + | |
256 | + if (prealloc_memory(num_entries) != 0) { | |
257 | + printk(KERN_ERR "DMA-API: debugging out of memory error " | |
258 | + "- disabled\n"); | |
259 | + global_disable = true; | |
260 | + | |
261 | + return; | |
262 | + } | |
263 | + | |
264 | + printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n"); | |
199 | 265 | } |