Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

locking/selftests: Add a selftest for check_irq_usage()

Johannes Berg reported a lockdep problem which could be reproduced by
the special test case introduced in this patch, so add it.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210618170110.3699115-5-boqun.feng@gmail.com

authored by

Boqun Feng and committed by
Peter Zijlstra
8946ccc2 7b1f8c61

+65
+65
lib/locking-selftest.c
··· 53 53 #define LOCKTYPE_WW 0x10 54 54 #define LOCKTYPE_RTMUTEX 0x20 55 55 #define LOCKTYPE_LL 0x40 56 + #define LOCKTYPE_SPECIAL 0x80 56 57 57 58 static struct ww_acquire_ctx t, t2; 58 59 static struct ww_mutex o, o2, o3; ··· 2745 2744 pr_cont("\n"); 2746 2745 } 2747 2746 2747 + static void hardirq_deadlock_softirq_not_deadlock(void) 2748 + { 2749 + /* mutex_A is hardirq-unsafe and softirq-unsafe */ 2750 + /* mutex_A -> lock_C */ 2751 + mutex_lock(&mutex_A); 2752 + HARDIRQ_DISABLE(); 2753 + spin_lock(&lock_C); 2754 + spin_unlock(&lock_C); 2755 + HARDIRQ_ENABLE(); 2756 + mutex_unlock(&mutex_A); 2757 + 2758 + /* lock_A is hardirq-safe */ 2759 + HARDIRQ_ENTER(); 2760 + spin_lock(&lock_A); 2761 + spin_unlock(&lock_A); 2762 + HARDIRQ_EXIT(); 2763 + 2764 + /* lock_A -> lock_B */ 2765 + HARDIRQ_DISABLE(); 2766 + spin_lock(&lock_A); 2767 + spin_lock(&lock_B); 2768 + spin_unlock(&lock_B); 2769 + spin_unlock(&lock_A); 2770 + HARDIRQ_ENABLE(); 2771 + 2772 + /* lock_B -> lock_C */ 2773 + HARDIRQ_DISABLE(); 2774 + spin_lock(&lock_B); 2775 + spin_lock(&lock_C); 2776 + spin_unlock(&lock_C); 2777 + spin_unlock(&lock_B); 2778 + HARDIRQ_ENABLE(); 2779 + 2780 + /* lock_D is softirq-safe */ 2781 + SOFTIRQ_ENTER(); 2782 + spin_lock(&lock_D); 2783 + spin_unlock(&lock_D); 2784 + SOFTIRQ_EXIT(); 2785 + 2786 + /* And lock_D is hardirq-unsafe */ 2787 + SOFTIRQ_DISABLE(); 2788 + spin_lock(&lock_D); 2789 + spin_unlock(&lock_D); 2790 + SOFTIRQ_ENABLE(); 2791 + 2792 + /* 2793 + * mutex_A -> lock_C -> lock_D is softirq-unsafe -> softirq-safe, not 2794 + * deadlock. 2795 + * 2796 + * lock_A -> lock_B -> lock_C -> lock_D is hardirq-safe -> 2797 + * hardirq-unsafe, deadlock. 2798 + */ 2799 + HARDIRQ_DISABLE(); 2800 + spin_lock(&lock_C); 2801 + spin_lock(&lock_D); 2802 + spin_unlock(&lock_D); 2803 + spin_unlock(&lock_C); 2804 + HARDIRQ_ENABLE(); 2805 + } 2806 + 2748 2807 void locking_selftest(void) 2749 2808 { 2750 2809 /* ··· 2932 2871 wait_context_tests(); 2933 2872 2934 2873 local_lock_tests(); 2874 + 2875 + print_testname("hardirq_unsafe_softirq_safe"); 2876 + dotest(hardirq_deadlock_softirq_not_deadlock, FAILURE, LOCKTYPE_SPECIAL); 2877 + pr_cont("\n"); 2935 2878 2936 2879 if (unexpected_testcase_failures) { 2937 2880 printk("-----------------------------------------------------------------\n");