.. | .. |
---|
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), |
---|