| .. | .. |
|---|
| 606 | 606 | return entry; |
|---|
| 607 | 607 | } |
|---|
| 608 | 608 | |
|---|
| 609 | | -static void __dma_entry_alloc_check_leak(void) |
|---|
| 609 | +/* |
|---|
| 610 | + * This should be called outside of free_entries_lock scope to avoid potential |
|---|
| 611 | + * deadlocks with serial consoles that use DMA. |
|---|
| 612 | + */ |
|---|
| 613 | +static void __dma_entry_alloc_check_leak(u32 nr_entries) |
|---|
| 610 | 614 | { |
|---|
| 611 | | - u32 tmp = nr_total_entries % nr_prealloc_entries; |
|---|
| 615 | + u32 tmp = nr_entries % nr_prealloc_entries; |
|---|
| 612 | 616 | |
|---|
| 613 | 617 | /* Shout each time we tick over some multiple of the initial pool */ |
|---|
| 614 | 618 | if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) { |
|---|
| 615 | 619 | pr_info("dma_debug_entry pool grown to %u (%u00%%)\n", |
|---|
| 616 | | - nr_total_entries, |
|---|
| 617 | | - (nr_total_entries / nr_prealloc_entries)); |
|---|
| 620 | + nr_entries, |
|---|
| 621 | + (nr_entries / nr_prealloc_entries)); |
|---|
| 618 | 622 | } |
|---|
| 619 | 623 | } |
|---|
| 620 | 624 | |
|---|
| .. | .. |
|---|
| 625 | 629 | */ |
|---|
| 626 | 630 | static struct dma_debug_entry *dma_entry_alloc(void) |
|---|
| 627 | 631 | { |
|---|
| 632 | + bool alloc_check_leak = false; |
|---|
| 628 | 633 | struct dma_debug_entry *entry; |
|---|
| 629 | 634 | unsigned long flags; |
|---|
| 635 | + u32 nr_entries; |
|---|
| 630 | 636 | |
|---|
| 631 | 637 | spin_lock_irqsave(&free_entries_lock, flags); |
|---|
| 632 | 638 | if (num_free_entries == 0) { |
|---|
| .. | .. |
|---|
| 636 | 642 | pr_err("debugging out of memory - disabling\n"); |
|---|
| 637 | 643 | return NULL; |
|---|
| 638 | 644 | } |
|---|
| 639 | | - __dma_entry_alloc_check_leak(); |
|---|
| 645 | + alloc_check_leak = true; |
|---|
| 646 | + nr_entries = nr_total_entries; |
|---|
| 640 | 647 | } |
|---|
| 641 | 648 | |
|---|
| 642 | 649 | entry = __dma_entry_alloc(); |
|---|
| 643 | 650 | |
|---|
| 644 | 651 | spin_unlock_irqrestore(&free_entries_lock, flags); |
|---|
| 645 | 652 | |
|---|
| 653 | + if (alloc_check_leak) |
|---|
| 654 | + __dma_entry_alloc_check_leak(nr_entries); |
|---|
| 655 | + |
|---|
| 646 | 656 | #ifdef CONFIG_STACKTRACE |
|---|
| 647 | 657 | entry->stack_len = stack_trace_save(entry->stack_entries, |
|---|
| 648 | 658 | ARRAY_SIZE(entry->stack_entries), |
|---|