18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * lib/locking-selftest.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Testsuite for various locking APIs: spinlocks, rwlocks, 68c2ecf20Sopenharmony_ci * mutexes and rw-semaphores. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * It is checking both false positives and false negatives. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Started by Ingo Molnar: 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#include <linux/rwsem.h> 158c2ecf20Sopenharmony_ci#include <linux/mutex.h> 168c2ecf20Sopenharmony_ci#include <linux/ww_mutex.h> 178c2ecf20Sopenharmony_ci#include <linux/sched.h> 188c2ecf20Sopenharmony_ci#include <linux/delay.h> 198c2ecf20Sopenharmony_ci#include <linux/lockdep.h> 208c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 218c2ecf20Sopenharmony_ci#include <linux/kallsyms.h> 228c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 238c2ecf20Sopenharmony_ci#include <linux/debug_locks.h> 248c2ecf20Sopenharmony_ci#include <linux/irqflags.h> 258c2ecf20Sopenharmony_ci#include <linux/rtmutex.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* 288c2ecf20Sopenharmony_ci * Change this to 1 if you want to see the failure printouts: 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_cistatic unsigned int debug_locks_verbose; 318c2ecf20Sopenharmony_ciunsigned int force_read_lock_recursive; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic DEFINE_WD_CLASS(ww_lockdep); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int __init setup_debug_locks_verbose(char *str) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci get_option(&str, &debug_locks_verbose); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return 1; 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci__setup("debug_locks_verbose=", setup_debug_locks_verbose); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define FAILURE 0 458c2ecf20Sopenharmony_ci#define SUCCESS 1 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define LOCKTYPE_SPIN 0x1 488c2ecf20Sopenharmony_ci#define LOCKTYPE_RWLOCK 0x2 498c2ecf20Sopenharmony_ci#define LOCKTYPE_MUTEX 0x4 508c2ecf20Sopenharmony_ci#define LOCKTYPE_RWSEM 0x8 518c2ecf20Sopenharmony_ci#define LOCKTYPE_WW 0x10 528c2ecf20Sopenharmony_ci#define LOCKTYPE_RTMUTEX 0x20 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic struct ww_acquire_ctx t, t2; 558c2ecf20Sopenharmony_cistatic struct ww_mutex o, o2, o3; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * Normal standalone locks, for the circular and irq-context 598c2ecf20Sopenharmony_ci * dependency tests: 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_A); 628c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_B); 638c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_C); 648c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_D); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_A); 678c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_B); 688c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_C); 698c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_D); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_A); 728c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_B); 738c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_C); 748c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_D); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_A); 778c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_B); 788c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_C); 798c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_D); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_A); 848c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_B); 858c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_C); 868c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_D); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#endif 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* 918c2ecf20Sopenharmony_ci * Locks that we initialize dynamically as well so that 928c2ecf20Sopenharmony_ci * e.g. X1 and X2 becomes two instances of the same class, 938c2ecf20Sopenharmony_ci * but X* and Y* are different classes. We do this so that 948c2ecf20Sopenharmony_ci * we do not trigger a real lockup: 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_X1); 978c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_X2); 988c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_Y1); 998c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_Y2); 1008c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_Z1); 1018c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(lock_Z2); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_X1); 1048c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_X2); 1058c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_Y1); 1068c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_Y2); 1078c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_Z1); 1088c2ecf20Sopenharmony_cistatic DEFINE_RWLOCK(rwlock_Z2); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_X1); 1118c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_X2); 1128c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_Y1); 1138c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_Y2); 1148c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_Z1); 1158c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(mutex_Z2); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_X1); 1188c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_X2); 1198c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_Y1); 1208c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_Y2); 1218c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_Z1); 1228c2ecf20Sopenharmony_cistatic DECLARE_RWSEM(rwsem_Z2); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_X1); 1278c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_X2); 1288c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_Y1); 1298c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_Y2); 1308c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_Z1); 1318c2ecf20Sopenharmony_cistatic DEFINE_RT_MUTEX(rtmutex_Z2); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#endif 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* 1368c2ecf20Sopenharmony_ci * non-inlined runtime initializers, to let separate locks share 1378c2ecf20Sopenharmony_ci * the same lock-class: 1388c2ecf20Sopenharmony_ci */ 1398c2ecf20Sopenharmony_ci#define INIT_CLASS_FUNC(class) \ 1408c2ecf20Sopenharmony_cistatic noinline void \ 1418c2ecf20Sopenharmony_ciinit_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \ 1428c2ecf20Sopenharmony_ci struct mutex *mutex, struct rw_semaphore *rwsem)\ 1438c2ecf20Sopenharmony_ci{ \ 1448c2ecf20Sopenharmony_ci raw_spin_lock_init(lock); \ 1458c2ecf20Sopenharmony_ci rwlock_init(rwlock); \ 1468c2ecf20Sopenharmony_ci mutex_init(mutex); \ 1478c2ecf20Sopenharmony_ci init_rwsem(rwsem); \ 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ciINIT_CLASS_FUNC(X) 1518c2ecf20Sopenharmony_ciINIT_CLASS_FUNC(Y) 1528c2ecf20Sopenharmony_ciINIT_CLASS_FUNC(Z) 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic void init_shared_classes(void) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 1578c2ecf20Sopenharmony_ci static struct lock_class_key rt_X, rt_Y, rt_Z; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_X1, __func__, &rt_X); 1608c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_X2, __func__, &rt_X); 1618c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y); 1628c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y); 1638c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z); 1648c2ecf20Sopenharmony_ci __rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z); 1658c2ecf20Sopenharmony_ci#endif 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1); 1688c2ecf20Sopenharmony_ci init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1); 1718c2ecf20Sopenharmony_ci init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1); 1748c2ecf20Sopenharmony_ci init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci/* 1788c2ecf20Sopenharmony_ci * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests. 1798c2ecf20Sopenharmony_ci * The following functions use a lock from a simulated hardirq/softirq 1808c2ecf20Sopenharmony_ci * context, causing the locks to be marked as hardirq-safe/softirq-safe: 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#define HARDIRQ_DISABLE local_irq_disable 1848c2ecf20Sopenharmony_ci#define HARDIRQ_ENABLE local_irq_enable 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci#define HARDIRQ_ENTER() \ 1878c2ecf20Sopenharmony_ci local_irq_disable(); \ 1888c2ecf20Sopenharmony_ci __irq_enter(); \ 1898c2ecf20Sopenharmony_ci lockdep_hardirq_threaded(); \ 1908c2ecf20Sopenharmony_ci WARN_ON(!in_irq()); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#define HARDIRQ_EXIT() \ 1938c2ecf20Sopenharmony_ci __irq_exit(); \ 1948c2ecf20Sopenharmony_ci local_irq_enable(); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci#define SOFTIRQ_DISABLE local_bh_disable 1978c2ecf20Sopenharmony_ci#define SOFTIRQ_ENABLE local_bh_enable 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#define SOFTIRQ_ENTER() \ 2008c2ecf20Sopenharmony_ci local_bh_disable(); \ 2018c2ecf20Sopenharmony_ci local_irq_disable(); \ 2028c2ecf20Sopenharmony_ci lockdep_softirq_enter(); \ 2038c2ecf20Sopenharmony_ci WARN_ON(!in_softirq()); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#define SOFTIRQ_EXIT() \ 2068c2ecf20Sopenharmony_ci lockdep_softirq_exit(); \ 2078c2ecf20Sopenharmony_ci local_irq_enable(); \ 2088c2ecf20Sopenharmony_ci local_bh_enable(); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci/* 2118c2ecf20Sopenharmony_ci * Shortcuts for lock/unlock API variants, to keep 2128c2ecf20Sopenharmony_ci * the testcases compact: 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_ci#define L(x) raw_spin_lock(&lock_##x) 2158c2ecf20Sopenharmony_ci#define U(x) raw_spin_unlock(&lock_##x) 2168c2ecf20Sopenharmony_ci#define LU(x) L(x); U(x) 2178c2ecf20Sopenharmony_ci#define SI(x) raw_spin_lock_init(&lock_##x) 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci#define WL(x) write_lock(&rwlock_##x) 2208c2ecf20Sopenharmony_ci#define WU(x) write_unlock(&rwlock_##x) 2218c2ecf20Sopenharmony_ci#define WLU(x) WL(x); WU(x) 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci#define RL(x) read_lock(&rwlock_##x) 2248c2ecf20Sopenharmony_ci#define RU(x) read_unlock(&rwlock_##x) 2258c2ecf20Sopenharmony_ci#define RLU(x) RL(x); RU(x) 2268c2ecf20Sopenharmony_ci#define RWI(x) rwlock_init(&rwlock_##x) 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci#define ML(x) mutex_lock(&mutex_##x) 2298c2ecf20Sopenharmony_ci#define MU(x) mutex_unlock(&mutex_##x) 2308c2ecf20Sopenharmony_ci#define MI(x) mutex_init(&mutex_##x) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci#define RTL(x) rt_mutex_lock(&rtmutex_##x) 2338c2ecf20Sopenharmony_ci#define RTU(x) rt_mutex_unlock(&rtmutex_##x) 2348c2ecf20Sopenharmony_ci#define RTI(x) rt_mutex_init(&rtmutex_##x) 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci#define WSL(x) down_write(&rwsem_##x) 2378c2ecf20Sopenharmony_ci#define WSU(x) up_write(&rwsem_##x) 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci#define RSL(x) down_read(&rwsem_##x) 2408c2ecf20Sopenharmony_ci#define RSU(x) up_read(&rwsem_##x) 2418c2ecf20Sopenharmony_ci#define RWSI(x) init_rwsem(&rwsem_##x) 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH 2448c2ecf20Sopenharmony_ci#define WWAI(x) ww_acquire_init(x, &ww_lockdep) 2458c2ecf20Sopenharmony_ci#else 2468c2ecf20Sopenharmony_ci#define WWAI(x) do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0) 2478c2ecf20Sopenharmony_ci#endif 2488c2ecf20Sopenharmony_ci#define WWAD(x) ww_acquire_done(x) 2498c2ecf20Sopenharmony_ci#define WWAF(x) ww_acquire_fini(x) 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci#define WWL(x, c) ww_mutex_lock(x, c) 2528c2ecf20Sopenharmony_ci#define WWT(x) ww_mutex_trylock(x) 2538c2ecf20Sopenharmony_ci#define WWL1(x) ww_mutex_lock(x, NULL) 2548c2ecf20Sopenharmony_ci#define WWU(x) ww_mutex_unlock(x) 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci#define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x) 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci/* 2608c2ecf20Sopenharmony_ci * Generate different permutations of the same testcase, using 2618c2ecf20Sopenharmony_ci * the same basic lock-dependency/state events: 2628c2ecf20Sopenharmony_ci */ 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci#define GENERATE_TESTCASE(name) \ 2658c2ecf20Sopenharmony_ci \ 2668c2ecf20Sopenharmony_cistatic void name(void) { E(); } 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci#define GENERATE_PERMUTATIONS_2_EVENTS(name) \ 2698c2ecf20Sopenharmony_ci \ 2708c2ecf20Sopenharmony_cistatic void name##_12(void) { E1(); E2(); } \ 2718c2ecf20Sopenharmony_cistatic void name##_21(void) { E2(); E1(); } 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci#define GENERATE_PERMUTATIONS_3_EVENTS(name) \ 2748c2ecf20Sopenharmony_ci \ 2758c2ecf20Sopenharmony_cistatic void name##_123(void) { E1(); E2(); E3(); } \ 2768c2ecf20Sopenharmony_cistatic void name##_132(void) { E1(); E3(); E2(); } \ 2778c2ecf20Sopenharmony_cistatic void name##_213(void) { E2(); E1(); E3(); } \ 2788c2ecf20Sopenharmony_cistatic void name##_231(void) { E2(); E3(); E1(); } \ 2798c2ecf20Sopenharmony_cistatic void name##_312(void) { E3(); E1(); E2(); } \ 2808c2ecf20Sopenharmony_cistatic void name##_321(void) { E3(); E2(); E1(); } 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci/* 2838c2ecf20Sopenharmony_ci * AA deadlock: 2848c2ecf20Sopenharmony_ci */ 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci#define E() \ 2878c2ecf20Sopenharmony_ci \ 2888c2ecf20Sopenharmony_ci LOCK(X1); \ 2898c2ecf20Sopenharmony_ci LOCK(X2); /* this one should fail */ 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/* 2928c2ecf20Sopenharmony_ci * 6 testcases: 2938c2ecf20Sopenharmony_ci */ 2948c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 2958c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_spin) 2968c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 2978c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_wlock) 2988c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 2998c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_rlock) 3008c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 3018c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_mutex) 3028c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 3038c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_wsem) 3048c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 3058c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_rsem) 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 3088c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 3098c2ecf20Sopenharmony_ciGENERATE_TESTCASE(AA_rtmutex); 3108c2ecf20Sopenharmony_ci#endif 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci#undef E 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci/* 3158c2ecf20Sopenharmony_ci * Special-case for read-locking, they are 3168c2ecf20Sopenharmony_ci * allowed to recurse on the same lock class: 3178c2ecf20Sopenharmony_ci */ 3188c2ecf20Sopenharmony_cistatic void rlock_AA1(void) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci RL(X1); 3218c2ecf20Sopenharmony_ci RL(X1); // this one should NOT fail 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cistatic void rlock_AA1B(void) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci RL(X1); 3278c2ecf20Sopenharmony_ci RL(X2); // this one should NOT fail 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic void rsem_AA1(void) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci RSL(X1); 3338c2ecf20Sopenharmony_ci RSL(X1); // this one should fail 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic void rsem_AA1B(void) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci RSL(X1); 3398c2ecf20Sopenharmony_ci RSL(X2); // this one should fail 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci/* 3428c2ecf20Sopenharmony_ci * The mixing of read and write locks is not allowed: 3438c2ecf20Sopenharmony_ci */ 3448c2ecf20Sopenharmony_cistatic void rlock_AA2(void) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci RL(X1); 3478c2ecf20Sopenharmony_ci WL(X2); // this one should fail 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic void rsem_AA2(void) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci RSL(X1); 3538c2ecf20Sopenharmony_ci WSL(X2); // this one should fail 3548c2ecf20Sopenharmony_ci} 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistatic void rlock_AA3(void) 3578c2ecf20Sopenharmony_ci{ 3588c2ecf20Sopenharmony_ci WL(X1); 3598c2ecf20Sopenharmony_ci RL(X2); // this one should fail 3608c2ecf20Sopenharmony_ci} 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_cistatic void rsem_AA3(void) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci WSL(X1); 3658c2ecf20Sopenharmony_ci RSL(X2); // this one should fail 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci/* 3698c2ecf20Sopenharmony_ci * read_lock(A) 3708c2ecf20Sopenharmony_ci * spin_lock(B) 3718c2ecf20Sopenharmony_ci * spin_lock(B) 3728c2ecf20Sopenharmony_ci * write_lock(A) 3738c2ecf20Sopenharmony_ci */ 3748c2ecf20Sopenharmony_cistatic void rlock_ABBA1(void) 3758c2ecf20Sopenharmony_ci{ 3768c2ecf20Sopenharmony_ci RL(X1); 3778c2ecf20Sopenharmony_ci L(Y1); 3788c2ecf20Sopenharmony_ci U(Y1); 3798c2ecf20Sopenharmony_ci RU(X1); 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci L(Y1); 3828c2ecf20Sopenharmony_ci WL(X1); 3838c2ecf20Sopenharmony_ci WU(X1); 3848c2ecf20Sopenharmony_ci U(Y1); // should fail 3858c2ecf20Sopenharmony_ci} 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_cistatic void rwsem_ABBA1(void) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci RSL(X1); 3908c2ecf20Sopenharmony_ci ML(Y1); 3918c2ecf20Sopenharmony_ci MU(Y1); 3928c2ecf20Sopenharmony_ci RSU(X1); 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci ML(Y1); 3958c2ecf20Sopenharmony_ci WSL(X1); 3968c2ecf20Sopenharmony_ci WSU(X1); 3978c2ecf20Sopenharmony_ci MU(Y1); // should fail 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci/* 4018c2ecf20Sopenharmony_ci * read_lock(A) 4028c2ecf20Sopenharmony_ci * spin_lock(B) 4038c2ecf20Sopenharmony_ci * spin_lock(B) 4048c2ecf20Sopenharmony_ci * write_lock(A) 4058c2ecf20Sopenharmony_ci * 4068c2ecf20Sopenharmony_ci * This test case is aimed at poking whether the chain cache prevents us from 4078c2ecf20Sopenharmony_ci * detecting a read-lock/lock-write deadlock: if the chain cache doesn't differ 4088c2ecf20Sopenharmony_ci * read/write locks, the following case may happen 4098c2ecf20Sopenharmony_ci * 4108c2ecf20Sopenharmony_ci * { read_lock(A)->lock(B) dependency exists } 4118c2ecf20Sopenharmony_ci * 4128c2ecf20Sopenharmony_ci * P0: 4138c2ecf20Sopenharmony_ci * lock(B); 4148c2ecf20Sopenharmony_ci * read_lock(A); 4158c2ecf20Sopenharmony_ci * 4168c2ecf20Sopenharmony_ci * { Not a deadlock, B -> A is added in the chain cache } 4178c2ecf20Sopenharmony_ci * 4188c2ecf20Sopenharmony_ci * P1: 4198c2ecf20Sopenharmony_ci * lock(B); 4208c2ecf20Sopenharmony_ci * write_lock(A); 4218c2ecf20Sopenharmony_ci * 4228c2ecf20Sopenharmony_ci * { B->A found in chain cache, not reported as a deadlock } 4238c2ecf20Sopenharmony_ci * 4248c2ecf20Sopenharmony_ci */ 4258c2ecf20Sopenharmony_cistatic void rlock_chaincache_ABBA1(void) 4268c2ecf20Sopenharmony_ci{ 4278c2ecf20Sopenharmony_ci RL(X1); 4288c2ecf20Sopenharmony_ci L(Y1); 4298c2ecf20Sopenharmony_ci U(Y1); 4308c2ecf20Sopenharmony_ci RU(X1); 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci L(Y1); 4338c2ecf20Sopenharmony_ci RL(X1); 4348c2ecf20Sopenharmony_ci RU(X1); 4358c2ecf20Sopenharmony_ci U(Y1); 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci L(Y1); 4388c2ecf20Sopenharmony_ci WL(X1); 4398c2ecf20Sopenharmony_ci WU(X1); 4408c2ecf20Sopenharmony_ci U(Y1); // should fail 4418c2ecf20Sopenharmony_ci} 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci/* 4448c2ecf20Sopenharmony_ci * read_lock(A) 4458c2ecf20Sopenharmony_ci * spin_lock(B) 4468c2ecf20Sopenharmony_ci * spin_lock(B) 4478c2ecf20Sopenharmony_ci * read_lock(A) 4488c2ecf20Sopenharmony_ci */ 4498c2ecf20Sopenharmony_cistatic void rlock_ABBA2(void) 4508c2ecf20Sopenharmony_ci{ 4518c2ecf20Sopenharmony_ci RL(X1); 4528c2ecf20Sopenharmony_ci L(Y1); 4538c2ecf20Sopenharmony_ci U(Y1); 4548c2ecf20Sopenharmony_ci RU(X1); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci L(Y1); 4578c2ecf20Sopenharmony_ci RL(X1); 4588c2ecf20Sopenharmony_ci RU(X1); 4598c2ecf20Sopenharmony_ci U(Y1); // should NOT fail 4608c2ecf20Sopenharmony_ci} 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic void rwsem_ABBA2(void) 4638c2ecf20Sopenharmony_ci{ 4648c2ecf20Sopenharmony_ci RSL(X1); 4658c2ecf20Sopenharmony_ci ML(Y1); 4668c2ecf20Sopenharmony_ci MU(Y1); 4678c2ecf20Sopenharmony_ci RSU(X1); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci ML(Y1); 4708c2ecf20Sopenharmony_ci RSL(X1); 4718c2ecf20Sopenharmony_ci RSU(X1); 4728c2ecf20Sopenharmony_ci MU(Y1); // should fail 4738c2ecf20Sopenharmony_ci} 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci/* 4778c2ecf20Sopenharmony_ci * write_lock(A) 4788c2ecf20Sopenharmony_ci * spin_lock(B) 4798c2ecf20Sopenharmony_ci * spin_lock(B) 4808c2ecf20Sopenharmony_ci * write_lock(A) 4818c2ecf20Sopenharmony_ci */ 4828c2ecf20Sopenharmony_cistatic void rlock_ABBA3(void) 4838c2ecf20Sopenharmony_ci{ 4848c2ecf20Sopenharmony_ci WL(X1); 4858c2ecf20Sopenharmony_ci L(Y1); 4868c2ecf20Sopenharmony_ci U(Y1); 4878c2ecf20Sopenharmony_ci WU(X1); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci L(Y1); 4908c2ecf20Sopenharmony_ci WL(X1); 4918c2ecf20Sopenharmony_ci WU(X1); 4928c2ecf20Sopenharmony_ci U(Y1); // should fail 4938c2ecf20Sopenharmony_ci} 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_cistatic void rwsem_ABBA3(void) 4968c2ecf20Sopenharmony_ci{ 4978c2ecf20Sopenharmony_ci WSL(X1); 4988c2ecf20Sopenharmony_ci ML(Y1); 4998c2ecf20Sopenharmony_ci MU(Y1); 5008c2ecf20Sopenharmony_ci WSU(X1); 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci ML(Y1); 5038c2ecf20Sopenharmony_ci WSL(X1); 5048c2ecf20Sopenharmony_ci WSU(X1); 5058c2ecf20Sopenharmony_ci MU(Y1); // should fail 5068c2ecf20Sopenharmony_ci} 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci/* 5098c2ecf20Sopenharmony_ci * ABBA deadlock: 5108c2ecf20Sopenharmony_ci */ 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci#define E() \ 5138c2ecf20Sopenharmony_ci \ 5148c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 5158c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, A); /* fail */ 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci/* 5188c2ecf20Sopenharmony_ci * 6 testcases: 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 5218c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_spin) 5228c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 5238c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_wlock) 5248c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 5258c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_rlock) 5268c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 5278c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_mutex) 5288c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 5298c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_wsem) 5308c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 5318c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_rsem) 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 5348c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 5358c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBA_rtmutex); 5368c2ecf20Sopenharmony_ci#endif 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci#undef E 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci/* 5418c2ecf20Sopenharmony_ci * AB BC CA deadlock: 5428c2ecf20Sopenharmony_ci */ 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci#define E() \ 5458c2ecf20Sopenharmony_ci \ 5468c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 5478c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, C); \ 5488c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(C, A); /* fail */ 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci/* 5518c2ecf20Sopenharmony_ci * 6 testcases: 5528c2ecf20Sopenharmony_ci */ 5538c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 5548c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_spin) 5558c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 5568c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_wlock) 5578c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 5588c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_rlock) 5598c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 5608c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_mutex) 5618c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 5628c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_wsem) 5638c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 5648c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_rsem) 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 5678c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 5688c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCA_rtmutex); 5698c2ecf20Sopenharmony_ci#endif 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci#undef E 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci/* 5748c2ecf20Sopenharmony_ci * AB CA BC deadlock: 5758c2ecf20Sopenharmony_ci */ 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci#define E() \ 5788c2ecf20Sopenharmony_ci \ 5798c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 5808c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(C, A); \ 5818c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, C); /* fail */ 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci/* 5848c2ecf20Sopenharmony_ci * 6 testcases: 5858c2ecf20Sopenharmony_ci */ 5868c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 5878c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_spin) 5888c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 5898c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_wlock) 5908c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 5918c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_rlock) 5928c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 5938c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_mutex) 5948c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 5958c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_wsem) 5968c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 5978c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_rsem) 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 6008c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 6018c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCABC_rtmutex); 6028c2ecf20Sopenharmony_ci#endif 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci#undef E 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci/* 6078c2ecf20Sopenharmony_ci * AB BC CD DA deadlock: 6088c2ecf20Sopenharmony_ci */ 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ci#define E() \ 6118c2ecf20Sopenharmony_ci \ 6128c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 6138c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, C); \ 6148c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(C, D); \ 6158c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(D, A); /* fail */ 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci/* 6188c2ecf20Sopenharmony_ci * 6 testcases: 6198c2ecf20Sopenharmony_ci */ 6208c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 6218c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_spin) 6228c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 6238c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_wlock) 6248c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 6258c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_rlock) 6268c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 6278c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_mutex) 6288c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 6298c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_wsem) 6308c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 6318c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_rsem) 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 6348c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 6358c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABBCCDDA_rtmutex); 6368c2ecf20Sopenharmony_ci#endif 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci#undef E 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci/* 6418c2ecf20Sopenharmony_ci * AB CD BD DA deadlock: 6428c2ecf20Sopenharmony_ci */ 6438c2ecf20Sopenharmony_ci#define E() \ 6448c2ecf20Sopenharmony_ci \ 6458c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 6468c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(C, D); \ 6478c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, D); \ 6488c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(D, A); /* fail */ 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci/* 6518c2ecf20Sopenharmony_ci * 6 testcases: 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 6548c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_spin) 6558c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 6568c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_wlock) 6578c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 6588c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_rlock) 6598c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 6608c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_mutex) 6618c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 6628c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_wsem) 6638c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 6648c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_rsem) 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 6678c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 6688c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBDDA_rtmutex); 6698c2ecf20Sopenharmony_ci#endif 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci#undef E 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci/* 6748c2ecf20Sopenharmony_ci * AB CD BC DA deadlock: 6758c2ecf20Sopenharmony_ci */ 6768c2ecf20Sopenharmony_ci#define E() \ 6778c2ecf20Sopenharmony_ci \ 6788c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(A, B); \ 6798c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(C, D); \ 6808c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(B, C); \ 6818c2ecf20Sopenharmony_ci LOCK_UNLOCK_2(D, A); /* fail */ 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci/* 6848c2ecf20Sopenharmony_ci * 6 testcases: 6858c2ecf20Sopenharmony_ci */ 6868c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 6878c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_spin) 6888c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 6898c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_wlock) 6908c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 6918c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_rlock) 6928c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 6938c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_mutex) 6948c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 6958c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_wsem) 6968c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 6978c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_rsem) 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 7008c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 7018c2ecf20Sopenharmony_ciGENERATE_TESTCASE(ABCDBCDA_rtmutex); 7028c2ecf20Sopenharmony_ci#endif 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci#undef E 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci/* 7078c2ecf20Sopenharmony_ci * Double unlock: 7088c2ecf20Sopenharmony_ci */ 7098c2ecf20Sopenharmony_ci#define E() \ 7108c2ecf20Sopenharmony_ci \ 7118c2ecf20Sopenharmony_ci LOCK(A); \ 7128c2ecf20Sopenharmony_ci UNLOCK(A); \ 7138c2ecf20Sopenharmony_ci UNLOCK(A); /* fail */ 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci/* 7168c2ecf20Sopenharmony_ci * 6 testcases: 7178c2ecf20Sopenharmony_ci */ 7188c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 7198c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_spin) 7208c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 7218c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_wlock) 7228c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 7238c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_rlock) 7248c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 7258c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_mutex) 7268c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 7278c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_wsem) 7288c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 7298c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_rsem) 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 7328c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 7338c2ecf20Sopenharmony_ciGENERATE_TESTCASE(double_unlock_rtmutex); 7348c2ecf20Sopenharmony_ci#endif 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci#undef E 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci/* 7398c2ecf20Sopenharmony_ci * initializing a held lock: 7408c2ecf20Sopenharmony_ci */ 7418c2ecf20Sopenharmony_ci#define E() \ 7428c2ecf20Sopenharmony_ci \ 7438c2ecf20Sopenharmony_ci LOCK(A); \ 7448c2ecf20Sopenharmony_ci INIT(A); /* fail */ 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci/* 7478c2ecf20Sopenharmony_ci * 6 testcases: 7488c2ecf20Sopenharmony_ci */ 7498c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 7508c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_spin) 7518c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 7528c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_wlock) 7538c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 7548c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_rlock) 7558c2ecf20Sopenharmony_ci#include "locking-selftest-mutex.h" 7568c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_mutex) 7578c2ecf20Sopenharmony_ci#include "locking-selftest-wsem.h" 7588c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_wsem) 7598c2ecf20Sopenharmony_ci#include "locking-selftest-rsem.h" 7608c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_rsem) 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 7638c2ecf20Sopenharmony_ci#include "locking-selftest-rtmutex.h" 7648c2ecf20Sopenharmony_ciGENERATE_TESTCASE(init_held_rtmutex); 7658c2ecf20Sopenharmony_ci#endif 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci#undef E 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci/* 7708c2ecf20Sopenharmony_ci * locking an irq-safe lock with irqs enabled: 7718c2ecf20Sopenharmony_ci */ 7728c2ecf20Sopenharmony_ci#define E1() \ 7738c2ecf20Sopenharmony_ci \ 7748c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 7758c2ecf20Sopenharmony_ci LOCK(A); \ 7768c2ecf20Sopenharmony_ci UNLOCK(A); \ 7778c2ecf20Sopenharmony_ci IRQ_EXIT(); 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci#define E2() \ 7808c2ecf20Sopenharmony_ci \ 7818c2ecf20Sopenharmony_ci LOCK(A); \ 7828c2ecf20Sopenharmony_ci UNLOCK(A); 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci/* 7858c2ecf20Sopenharmony_ci * Generate 24 testcases: 7868c2ecf20Sopenharmony_ci */ 7878c2ecf20Sopenharmony_ci#include "locking-selftest-spin-hardirq.h" 7888c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin) 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-hardirq.h" 7918c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-hardirq.h" 7948c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock) 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci#include "locking-selftest-spin-softirq.h" 7978c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin) 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-softirq.h" 8008c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock) 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-softirq.h" 8038c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci#undef E1 8068c2ecf20Sopenharmony_ci#undef E2 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci/* 8098c2ecf20Sopenharmony_ci * Enabling hardirqs with a softirq-safe lock held: 8108c2ecf20Sopenharmony_ci */ 8118c2ecf20Sopenharmony_ci#define E1() \ 8128c2ecf20Sopenharmony_ci \ 8138c2ecf20Sopenharmony_ci SOFTIRQ_ENTER(); \ 8148c2ecf20Sopenharmony_ci LOCK(A); \ 8158c2ecf20Sopenharmony_ci UNLOCK(A); \ 8168c2ecf20Sopenharmony_ci SOFTIRQ_EXIT(); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci#define E2() \ 8198c2ecf20Sopenharmony_ci \ 8208c2ecf20Sopenharmony_ci HARDIRQ_DISABLE(); \ 8218c2ecf20Sopenharmony_ci LOCK(A); \ 8228c2ecf20Sopenharmony_ci HARDIRQ_ENABLE(); \ 8238c2ecf20Sopenharmony_ci UNLOCK(A); 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci/* 8268c2ecf20Sopenharmony_ci * Generate 12 testcases: 8278c2ecf20Sopenharmony_ci */ 8288c2ecf20Sopenharmony_ci#include "locking-selftest-spin.h" 8298c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin) 8308c2ecf20Sopenharmony_ci 8318c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 8328c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock) 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 8358c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci#undef E1 8388c2ecf20Sopenharmony_ci#undef E2 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci/* 8418c2ecf20Sopenharmony_ci * Enabling irqs with an irq-safe lock held: 8428c2ecf20Sopenharmony_ci */ 8438c2ecf20Sopenharmony_ci#define E1() \ 8448c2ecf20Sopenharmony_ci \ 8458c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 8468c2ecf20Sopenharmony_ci LOCK(A); \ 8478c2ecf20Sopenharmony_ci UNLOCK(A); \ 8488c2ecf20Sopenharmony_ci IRQ_EXIT(); 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ci#define E2() \ 8518c2ecf20Sopenharmony_ci \ 8528c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 8538c2ecf20Sopenharmony_ci LOCK(A); \ 8548c2ecf20Sopenharmony_ci IRQ_ENABLE(); \ 8558c2ecf20Sopenharmony_ci UNLOCK(A); 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci/* 8588c2ecf20Sopenharmony_ci * Generate 24 testcases: 8598c2ecf20Sopenharmony_ci */ 8608c2ecf20Sopenharmony_ci#include "locking-selftest-spin-hardirq.h" 8618c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin) 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-hardirq.h" 8648c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-hardirq.h" 8678c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock) 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci#include "locking-selftest-spin-softirq.h" 8708c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin) 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-softirq.h" 8738c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock) 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-softirq.h" 8768c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci#undef E1 8798c2ecf20Sopenharmony_ci#undef E2 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_ci/* 8828c2ecf20Sopenharmony_ci * Acquiring a irq-unsafe lock while holding an irq-safe-lock: 8838c2ecf20Sopenharmony_ci */ 8848c2ecf20Sopenharmony_ci#define E1() \ 8858c2ecf20Sopenharmony_ci \ 8868c2ecf20Sopenharmony_ci LOCK(A); \ 8878c2ecf20Sopenharmony_ci LOCK(B); \ 8888c2ecf20Sopenharmony_ci UNLOCK(B); \ 8898c2ecf20Sopenharmony_ci UNLOCK(A); \ 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci#define E2() \ 8928c2ecf20Sopenharmony_ci \ 8938c2ecf20Sopenharmony_ci LOCK(B); \ 8948c2ecf20Sopenharmony_ci UNLOCK(B); 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci#define E3() \ 8978c2ecf20Sopenharmony_ci \ 8988c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 8998c2ecf20Sopenharmony_ci LOCK(A); \ 9008c2ecf20Sopenharmony_ci UNLOCK(A); \ 9018c2ecf20Sopenharmony_ci IRQ_EXIT(); 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci/* 9048c2ecf20Sopenharmony_ci * Generate 36 testcases: 9058c2ecf20Sopenharmony_ci */ 9068c2ecf20Sopenharmony_ci#include "locking-selftest-spin-hardirq.h" 9078c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin) 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-hardirq.h" 9108c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-hardirq.h" 9138c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock) 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci#include "locking-selftest-spin-softirq.h" 9168c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin) 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-softirq.h" 9198c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock) 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-softirq.h" 9228c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci#undef E1 9258c2ecf20Sopenharmony_ci#undef E2 9268c2ecf20Sopenharmony_ci#undef E3 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_ci/* 9298c2ecf20Sopenharmony_ci * If a lock turns into softirq-safe, but earlier it took 9308c2ecf20Sopenharmony_ci * a softirq-unsafe lock: 9318c2ecf20Sopenharmony_ci */ 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci#define E1() \ 9348c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 9358c2ecf20Sopenharmony_ci LOCK(A); \ 9368c2ecf20Sopenharmony_ci LOCK(B); \ 9378c2ecf20Sopenharmony_ci UNLOCK(B); \ 9388c2ecf20Sopenharmony_ci UNLOCK(A); \ 9398c2ecf20Sopenharmony_ci IRQ_ENABLE(); 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci#define E2() \ 9428c2ecf20Sopenharmony_ci LOCK(B); \ 9438c2ecf20Sopenharmony_ci UNLOCK(B); 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci#define E3() \ 9468c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 9478c2ecf20Sopenharmony_ci LOCK(A); \ 9488c2ecf20Sopenharmony_ci UNLOCK(A); \ 9498c2ecf20Sopenharmony_ci IRQ_EXIT(); 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci/* 9528c2ecf20Sopenharmony_ci * Generate 36 testcases: 9538c2ecf20Sopenharmony_ci */ 9548c2ecf20Sopenharmony_ci#include "locking-selftest-spin-hardirq.h" 9558c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin) 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-hardirq.h" 9588c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-hardirq.h" 9618c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock) 9628c2ecf20Sopenharmony_ci 9638c2ecf20Sopenharmony_ci#include "locking-selftest-spin-softirq.h" 9648c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin) 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-softirq.h" 9678c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock) 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-softirq.h" 9708c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci#undef E1 9738c2ecf20Sopenharmony_ci#undef E2 9748c2ecf20Sopenharmony_ci#undef E3 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci/* 9778c2ecf20Sopenharmony_ci * read-lock / write-lock irq inversion. 9788c2ecf20Sopenharmony_ci * 9798c2ecf20Sopenharmony_ci * Deadlock scenario: 9808c2ecf20Sopenharmony_ci * 9818c2ecf20Sopenharmony_ci * CPU#1 is at #1, i.e. it has write-locked A, but has not 9828c2ecf20Sopenharmony_ci * taken B yet. 9838c2ecf20Sopenharmony_ci * 9848c2ecf20Sopenharmony_ci * CPU#2 is at #2, i.e. it has locked B. 9858c2ecf20Sopenharmony_ci * 9868c2ecf20Sopenharmony_ci * Hardirq hits CPU#2 at point #2 and is trying to read-lock A. 9878c2ecf20Sopenharmony_ci * 9888c2ecf20Sopenharmony_ci * The deadlock occurs because CPU#1 will spin on B, and CPU#2 9898c2ecf20Sopenharmony_ci * will spin on A. 9908c2ecf20Sopenharmony_ci */ 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci#define E1() \ 9938c2ecf20Sopenharmony_ci \ 9948c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 9958c2ecf20Sopenharmony_ci WL(A); \ 9968c2ecf20Sopenharmony_ci LOCK(B); \ 9978c2ecf20Sopenharmony_ci UNLOCK(B); \ 9988c2ecf20Sopenharmony_ci WU(A); \ 9998c2ecf20Sopenharmony_ci IRQ_ENABLE(); 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci#define E2() \ 10028c2ecf20Sopenharmony_ci \ 10038c2ecf20Sopenharmony_ci LOCK(B); \ 10048c2ecf20Sopenharmony_ci UNLOCK(B); 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci#define E3() \ 10078c2ecf20Sopenharmony_ci \ 10088c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 10098c2ecf20Sopenharmony_ci RL(A); \ 10108c2ecf20Sopenharmony_ci RU(A); \ 10118c2ecf20Sopenharmony_ci IRQ_EXIT(); 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci/* 10148c2ecf20Sopenharmony_ci * Generate 36 testcases: 10158c2ecf20Sopenharmony_ci */ 10168c2ecf20Sopenharmony_ci#include "locking-selftest-spin-hardirq.h" 10178c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin) 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-hardirq.h" 10208c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock) 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-hardirq.h" 10238c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock) 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci#include "locking-selftest-spin-softirq.h" 10268c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin) 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci#include "locking-selftest-rlock-softirq.h" 10298c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock) 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci#include "locking-selftest-wlock-softirq.h" 10328c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock) 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci#undef E1 10358c2ecf20Sopenharmony_ci#undef E2 10368c2ecf20Sopenharmony_ci#undef E3 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci/* 10398c2ecf20Sopenharmony_ci * write-read / write-read / write-read deadlock even if read is recursive 10408c2ecf20Sopenharmony_ci */ 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci#define E1() \ 10438c2ecf20Sopenharmony_ci \ 10448c2ecf20Sopenharmony_ci WL(X1); \ 10458c2ecf20Sopenharmony_ci RL(Y1); \ 10468c2ecf20Sopenharmony_ci RU(Y1); \ 10478c2ecf20Sopenharmony_ci WU(X1); 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci#define E2() \ 10508c2ecf20Sopenharmony_ci \ 10518c2ecf20Sopenharmony_ci WL(Y1); \ 10528c2ecf20Sopenharmony_ci RL(Z1); \ 10538c2ecf20Sopenharmony_ci RU(Z1); \ 10548c2ecf20Sopenharmony_ci WU(Y1); 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci#define E3() \ 10578c2ecf20Sopenharmony_ci \ 10588c2ecf20Sopenharmony_ci WL(Z1); \ 10598c2ecf20Sopenharmony_ci RL(X1); \ 10608c2ecf20Sopenharmony_ci RU(X1); \ 10618c2ecf20Sopenharmony_ci WU(Z1); 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 10648c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1) 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci#undef E1 10678c2ecf20Sopenharmony_ci#undef E2 10688c2ecf20Sopenharmony_ci#undef E3 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_ci/* 10718c2ecf20Sopenharmony_ci * write-write / read-read / write-read deadlock even if read is recursive 10728c2ecf20Sopenharmony_ci */ 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_ci#define E1() \ 10758c2ecf20Sopenharmony_ci \ 10768c2ecf20Sopenharmony_ci WL(X1); \ 10778c2ecf20Sopenharmony_ci WL(Y1); \ 10788c2ecf20Sopenharmony_ci WU(Y1); \ 10798c2ecf20Sopenharmony_ci WU(X1); 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci#define E2() \ 10828c2ecf20Sopenharmony_ci \ 10838c2ecf20Sopenharmony_ci RL(Y1); \ 10848c2ecf20Sopenharmony_ci RL(Z1); \ 10858c2ecf20Sopenharmony_ci RU(Z1); \ 10868c2ecf20Sopenharmony_ci RU(Y1); 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci#define E3() \ 10898c2ecf20Sopenharmony_ci \ 10908c2ecf20Sopenharmony_ci WL(Z1); \ 10918c2ecf20Sopenharmony_ci RL(X1); \ 10928c2ecf20Sopenharmony_ci RU(X1); \ 10938c2ecf20Sopenharmony_ci WU(Z1); 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 10968c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1) 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_ci#undef E1 10998c2ecf20Sopenharmony_ci#undef E2 11008c2ecf20Sopenharmony_ci#undef E3 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci/* 11038c2ecf20Sopenharmony_ci * write-write / read-read / read-write is not deadlock when read is recursive 11048c2ecf20Sopenharmony_ci */ 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_ci#define E1() \ 11078c2ecf20Sopenharmony_ci \ 11088c2ecf20Sopenharmony_ci WL(X1); \ 11098c2ecf20Sopenharmony_ci WL(Y1); \ 11108c2ecf20Sopenharmony_ci WU(Y1); \ 11118c2ecf20Sopenharmony_ci WU(X1); 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci#define E2() \ 11148c2ecf20Sopenharmony_ci \ 11158c2ecf20Sopenharmony_ci RL(Y1); \ 11168c2ecf20Sopenharmony_ci RL(Z1); \ 11178c2ecf20Sopenharmony_ci RU(Z1); \ 11188c2ecf20Sopenharmony_ci RU(Y1); 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ci#define E3() \ 11218c2ecf20Sopenharmony_ci \ 11228c2ecf20Sopenharmony_ci RL(Z1); \ 11238c2ecf20Sopenharmony_ci WL(X1); \ 11248c2ecf20Sopenharmony_ci WU(X1); \ 11258c2ecf20Sopenharmony_ci RU(Z1); 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 11288c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1) 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci#undef E1 11318c2ecf20Sopenharmony_ci#undef E2 11328c2ecf20Sopenharmony_ci#undef E3 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci/* 11358c2ecf20Sopenharmony_ci * write-read / read-read / write-write is not deadlock when read is recursive 11368c2ecf20Sopenharmony_ci */ 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci#define E1() \ 11398c2ecf20Sopenharmony_ci \ 11408c2ecf20Sopenharmony_ci WL(X1); \ 11418c2ecf20Sopenharmony_ci RL(Y1); \ 11428c2ecf20Sopenharmony_ci RU(Y1); \ 11438c2ecf20Sopenharmony_ci WU(X1); 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_ci#define E2() \ 11468c2ecf20Sopenharmony_ci \ 11478c2ecf20Sopenharmony_ci RL(Y1); \ 11488c2ecf20Sopenharmony_ci RL(Z1); \ 11498c2ecf20Sopenharmony_ci RU(Z1); \ 11508c2ecf20Sopenharmony_ci RU(Y1); 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_ci#define E3() \ 11538c2ecf20Sopenharmony_ci \ 11548c2ecf20Sopenharmony_ci WL(Z1); \ 11558c2ecf20Sopenharmony_ci WL(X1); \ 11568c2ecf20Sopenharmony_ci WU(X1); \ 11578c2ecf20Sopenharmony_ci WU(Z1); 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 11608c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1) 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci#undef E1 11638c2ecf20Sopenharmony_ci#undef E2 11648c2ecf20Sopenharmony_ci#undef E3 11658c2ecf20Sopenharmony_ci/* 11668c2ecf20Sopenharmony_ci * read-lock / write-lock recursion that is actually safe. 11678c2ecf20Sopenharmony_ci */ 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci#define E1() \ 11708c2ecf20Sopenharmony_ci \ 11718c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 11728c2ecf20Sopenharmony_ci WL(A); \ 11738c2ecf20Sopenharmony_ci WU(A); \ 11748c2ecf20Sopenharmony_ci IRQ_ENABLE(); 11758c2ecf20Sopenharmony_ci 11768c2ecf20Sopenharmony_ci#define E2() \ 11778c2ecf20Sopenharmony_ci \ 11788c2ecf20Sopenharmony_ci RL(A); \ 11798c2ecf20Sopenharmony_ci RU(A); \ 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci#define E3() \ 11828c2ecf20Sopenharmony_ci \ 11838c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 11848c2ecf20Sopenharmony_ci LOCK(A); \ 11858c2ecf20Sopenharmony_ci L(B); \ 11868c2ecf20Sopenharmony_ci U(B); \ 11878c2ecf20Sopenharmony_ci UNLOCK(A); \ 11888c2ecf20Sopenharmony_ci IRQ_EXIT(); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci/* 11918c2ecf20Sopenharmony_ci * Generate 24 testcases: 11928c2ecf20Sopenharmony_ci */ 11938c2ecf20Sopenharmony_ci#include "locking-selftest-hardirq.h" 11948c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 11958c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock) 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 11988c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock) 11998c2ecf20Sopenharmony_ci 12008c2ecf20Sopenharmony_ci#include "locking-selftest-softirq.h" 12018c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 12028c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock) 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 12058c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock) 12068c2ecf20Sopenharmony_ci 12078c2ecf20Sopenharmony_ci#undef E1 12088c2ecf20Sopenharmony_ci#undef E2 12098c2ecf20Sopenharmony_ci#undef E3 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci/* 12128c2ecf20Sopenharmony_ci * read-lock / write-lock recursion that is unsafe. 12138c2ecf20Sopenharmony_ci */ 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci#define E1() \ 12168c2ecf20Sopenharmony_ci \ 12178c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 12188c2ecf20Sopenharmony_ci L(B); \ 12198c2ecf20Sopenharmony_ci LOCK(A); \ 12208c2ecf20Sopenharmony_ci UNLOCK(A); \ 12218c2ecf20Sopenharmony_ci U(B); \ 12228c2ecf20Sopenharmony_ci IRQ_ENABLE(); 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci#define E2() \ 12258c2ecf20Sopenharmony_ci \ 12268c2ecf20Sopenharmony_ci RL(A); \ 12278c2ecf20Sopenharmony_ci RU(A); \ 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci#define E3() \ 12308c2ecf20Sopenharmony_ci \ 12318c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 12328c2ecf20Sopenharmony_ci L(B); \ 12338c2ecf20Sopenharmony_ci U(B); \ 12348c2ecf20Sopenharmony_ci IRQ_EXIT(); 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci/* 12378c2ecf20Sopenharmony_ci * Generate 24 testcases: 12388c2ecf20Sopenharmony_ci */ 12398c2ecf20Sopenharmony_ci#include "locking-selftest-hardirq.h" 12408c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 12418c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock) 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 12448c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock) 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci#include "locking-selftest-softirq.h" 12478c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 12488c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock) 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 12518c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock) 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci#undef E1 12548c2ecf20Sopenharmony_ci#undef E2 12558c2ecf20Sopenharmony_ci#undef E3 12568c2ecf20Sopenharmony_ci/* 12578c2ecf20Sopenharmony_ci * read-lock / write-lock recursion that is unsafe. 12588c2ecf20Sopenharmony_ci * 12598c2ecf20Sopenharmony_ci * A is a ENABLED_*_READ lock 12608c2ecf20Sopenharmony_ci * B is a USED_IN_*_READ lock 12618c2ecf20Sopenharmony_ci * 12628c2ecf20Sopenharmony_ci * read_lock(A); 12638c2ecf20Sopenharmony_ci * write_lock(B); 12648c2ecf20Sopenharmony_ci * <interrupt> 12658c2ecf20Sopenharmony_ci * read_lock(B); 12668c2ecf20Sopenharmony_ci * write_lock(A); // if this one is read_lock(), no deadlock 12678c2ecf20Sopenharmony_ci */ 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci#define E1() \ 12708c2ecf20Sopenharmony_ci \ 12718c2ecf20Sopenharmony_ci IRQ_DISABLE(); \ 12728c2ecf20Sopenharmony_ci WL(B); \ 12738c2ecf20Sopenharmony_ci LOCK(A); \ 12748c2ecf20Sopenharmony_ci UNLOCK(A); \ 12758c2ecf20Sopenharmony_ci WU(B); \ 12768c2ecf20Sopenharmony_ci IRQ_ENABLE(); 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci#define E2() \ 12798c2ecf20Sopenharmony_ci \ 12808c2ecf20Sopenharmony_ci RL(A); \ 12818c2ecf20Sopenharmony_ci RU(A); \ 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci#define E3() \ 12848c2ecf20Sopenharmony_ci \ 12858c2ecf20Sopenharmony_ci IRQ_ENTER(); \ 12868c2ecf20Sopenharmony_ci RL(B); \ 12878c2ecf20Sopenharmony_ci RU(B); \ 12888c2ecf20Sopenharmony_ci IRQ_EXIT(); 12898c2ecf20Sopenharmony_ci 12908c2ecf20Sopenharmony_ci/* 12918c2ecf20Sopenharmony_ci * Generate 24 testcases: 12928c2ecf20Sopenharmony_ci */ 12938c2ecf20Sopenharmony_ci#include "locking-selftest-hardirq.h" 12948c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 12958c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock) 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 12988c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock) 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci#include "locking-selftest-softirq.h" 13018c2ecf20Sopenharmony_ci#include "locking-selftest-rlock.h" 13028c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock) 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci#include "locking-selftest-wlock.h" 13058c2ecf20Sopenharmony_ciGENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock) 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_LOCK_ALLOC 13088c2ecf20Sopenharmony_ci# define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map) 13098c2ecf20Sopenharmony_ci# define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map) 13108c2ecf20Sopenharmony_ci# define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) 13118c2ecf20Sopenharmony_ci# define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) 13128c2ecf20Sopenharmony_ci# define I_WW(x) lockdep_reset_lock(&x.dep_map) 13138c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 13148c2ecf20Sopenharmony_ci# define I_RTMUTEX(x) lockdep_reset_lock(&rtmutex_##x.dep_map) 13158c2ecf20Sopenharmony_ci#endif 13168c2ecf20Sopenharmony_ci#else 13178c2ecf20Sopenharmony_ci# define I_SPINLOCK(x) 13188c2ecf20Sopenharmony_ci# define I_RWLOCK(x) 13198c2ecf20Sopenharmony_ci# define I_MUTEX(x) 13208c2ecf20Sopenharmony_ci# define I_RWSEM(x) 13218c2ecf20Sopenharmony_ci# define I_WW(x) 13228c2ecf20Sopenharmony_ci#endif 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_ci#ifndef I_RTMUTEX 13258c2ecf20Sopenharmony_ci# define I_RTMUTEX(x) 13268c2ecf20Sopenharmony_ci#endif 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 13298c2ecf20Sopenharmony_ci#define I2_RTMUTEX(x) rt_mutex_init(&rtmutex_##x) 13308c2ecf20Sopenharmony_ci#else 13318c2ecf20Sopenharmony_ci#define I2_RTMUTEX(x) 13328c2ecf20Sopenharmony_ci#endif 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci#define I1(x) \ 13358c2ecf20Sopenharmony_ci do { \ 13368c2ecf20Sopenharmony_ci I_SPINLOCK(x); \ 13378c2ecf20Sopenharmony_ci I_RWLOCK(x); \ 13388c2ecf20Sopenharmony_ci I_MUTEX(x); \ 13398c2ecf20Sopenharmony_ci I_RWSEM(x); \ 13408c2ecf20Sopenharmony_ci I_RTMUTEX(x); \ 13418c2ecf20Sopenharmony_ci } while (0) 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci#define I2(x) \ 13448c2ecf20Sopenharmony_ci do { \ 13458c2ecf20Sopenharmony_ci raw_spin_lock_init(&lock_##x); \ 13468c2ecf20Sopenharmony_ci rwlock_init(&rwlock_##x); \ 13478c2ecf20Sopenharmony_ci mutex_init(&mutex_##x); \ 13488c2ecf20Sopenharmony_ci init_rwsem(&rwsem_##x); \ 13498c2ecf20Sopenharmony_ci I2_RTMUTEX(x); \ 13508c2ecf20Sopenharmony_ci } while (0) 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_cistatic void reset_locks(void) 13538c2ecf20Sopenharmony_ci{ 13548c2ecf20Sopenharmony_ci local_irq_disable(); 13558c2ecf20Sopenharmony_ci lockdep_free_key_range(&ww_lockdep.acquire_key, 1); 13568c2ecf20Sopenharmony_ci lockdep_free_key_range(&ww_lockdep.mutex_key, 1); 13578c2ecf20Sopenharmony_ci 13588c2ecf20Sopenharmony_ci I1(A); I1(B); I1(C); I1(D); 13598c2ecf20Sopenharmony_ci I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); 13608c2ecf20Sopenharmony_ci I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base); 13618c2ecf20Sopenharmony_ci lockdep_reset(); 13628c2ecf20Sopenharmony_ci I2(A); I2(B); I2(C); I2(D); 13638c2ecf20Sopenharmony_ci init_shared_classes(); 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep); 13668c2ecf20Sopenharmony_ci memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); 13678c2ecf20Sopenharmony_ci memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key)); 13688c2ecf20Sopenharmony_ci memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key)); 13698c2ecf20Sopenharmony_ci local_irq_enable(); 13708c2ecf20Sopenharmony_ci} 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci#undef I 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_cistatic int testcase_total; 13758c2ecf20Sopenharmony_cistatic int testcase_successes; 13768c2ecf20Sopenharmony_cistatic int expected_testcase_failures; 13778c2ecf20Sopenharmony_cistatic int unexpected_testcase_failures; 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_cistatic void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) 13808c2ecf20Sopenharmony_ci{ 13818c2ecf20Sopenharmony_ci unsigned long saved_preempt_count = preempt_count(); 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci WARN_ON(irqs_disabled()); 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_ci testcase_fn(); 13868c2ecf20Sopenharmony_ci /* 13878c2ecf20Sopenharmony_ci * Filter out expected failures: 13888c2ecf20Sopenharmony_ci */ 13898c2ecf20Sopenharmony_ci#ifndef CONFIG_PROVE_LOCKING 13908c2ecf20Sopenharmony_ci if (expected == FAILURE && debug_locks) { 13918c2ecf20Sopenharmony_ci expected_testcase_failures++; 13928c2ecf20Sopenharmony_ci pr_cont("failed|"); 13938c2ecf20Sopenharmony_ci } 13948c2ecf20Sopenharmony_ci else 13958c2ecf20Sopenharmony_ci#endif 13968c2ecf20Sopenharmony_ci if (debug_locks != expected) { 13978c2ecf20Sopenharmony_ci unexpected_testcase_failures++; 13988c2ecf20Sopenharmony_ci pr_cont("FAILED|"); 13998c2ecf20Sopenharmony_ci } else { 14008c2ecf20Sopenharmony_ci testcase_successes++; 14018c2ecf20Sopenharmony_ci pr_cont(" ok |"); 14028c2ecf20Sopenharmony_ci } 14038c2ecf20Sopenharmony_ci testcase_total++; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci if (debug_locks_verbose) 14068c2ecf20Sopenharmony_ci pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n", 14078c2ecf20Sopenharmony_ci lockclass_mask, debug_locks, expected); 14088c2ecf20Sopenharmony_ci /* 14098c2ecf20Sopenharmony_ci * Some tests (e.g. double-unlock) might corrupt the preemption 14108c2ecf20Sopenharmony_ci * count, so restore it: 14118c2ecf20Sopenharmony_ci */ 14128c2ecf20Sopenharmony_ci preempt_count_set(saved_preempt_count); 14138c2ecf20Sopenharmony_ci#ifdef CONFIG_TRACE_IRQFLAGS 14148c2ecf20Sopenharmony_ci if (softirq_count()) 14158c2ecf20Sopenharmony_ci current->softirqs_enabled = 0; 14168c2ecf20Sopenharmony_ci else 14178c2ecf20Sopenharmony_ci current->softirqs_enabled = 1; 14188c2ecf20Sopenharmony_ci#endif 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci reset_locks(); 14218c2ecf20Sopenharmony_ci} 14228c2ecf20Sopenharmony_ci 14238c2ecf20Sopenharmony_ci#ifdef CONFIG_RT_MUTEXES 14248c2ecf20Sopenharmony_ci#define dotest_rt(fn, e, m) dotest((fn), (e), (m)) 14258c2ecf20Sopenharmony_ci#else 14268c2ecf20Sopenharmony_ci#define dotest_rt(fn, e, m) 14278c2ecf20Sopenharmony_ci#endif 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_cistatic inline void print_testname(const char *testname) 14308c2ecf20Sopenharmony_ci{ 14318c2ecf20Sopenharmony_ci printk("%33s:", testname); 14328c2ecf20Sopenharmony_ci} 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci#define DO_TESTCASE_1(desc, name, nr) \ 14358c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14368c2ecf20Sopenharmony_ci dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ 14378c2ecf20Sopenharmony_ci pr_cont("\n"); 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_ci#define DO_TESTCASE_1B(desc, name, nr) \ 14408c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14418c2ecf20Sopenharmony_ci dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \ 14428c2ecf20Sopenharmony_ci pr_cont("\n"); 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci#define DO_TESTCASE_1RR(desc, name, nr) \ 14458c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14468c2ecf20Sopenharmony_ci pr_cont(" |"); \ 14478c2ecf20Sopenharmony_ci dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ 14488c2ecf20Sopenharmony_ci pr_cont("\n"); 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci#define DO_TESTCASE_1RRB(desc, name, nr) \ 14518c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14528c2ecf20Sopenharmony_ci pr_cont(" |"); \ 14538c2ecf20Sopenharmony_ci dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \ 14548c2ecf20Sopenharmony_ci pr_cont("\n"); 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci 14578c2ecf20Sopenharmony_ci#define DO_TESTCASE_3(desc, name, nr) \ 14588c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14598c2ecf20Sopenharmony_ci dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \ 14608c2ecf20Sopenharmony_ci dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \ 14618c2ecf20Sopenharmony_ci dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ 14628c2ecf20Sopenharmony_ci pr_cont("\n"); 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_ci#define DO_TESTCASE_3RW(desc, name, nr) \ 14658c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14668c2ecf20Sopenharmony_ci dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\ 14678c2ecf20Sopenharmony_ci dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \ 14688c2ecf20Sopenharmony_ci dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ 14698c2ecf20Sopenharmony_ci pr_cont("\n"); 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_ci#define DO_TESTCASE_2RW(desc, name, nr) \ 14728c2ecf20Sopenharmony_ci print_testname(desc"/"#nr); \ 14738c2ecf20Sopenharmony_ci pr_cont(" |"); \ 14748c2ecf20Sopenharmony_ci dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \ 14758c2ecf20Sopenharmony_ci dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ 14768c2ecf20Sopenharmony_ci pr_cont("\n"); 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci#define DO_TESTCASE_2x2RW(desc, name, nr) \ 14798c2ecf20Sopenharmony_ci DO_TESTCASE_2RW("hard-"desc, name##_hard, nr) \ 14808c2ecf20Sopenharmony_ci DO_TESTCASE_2RW("soft-"desc, name##_soft, nr) \ 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x2x2RW(desc, name) \ 14838c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 123); \ 14848c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 132); \ 14858c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 213); \ 14868c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 231); \ 14878c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 312); \ 14888c2ecf20Sopenharmony_ci DO_TESTCASE_2x2RW(desc, name, 321); 14898c2ecf20Sopenharmony_ci 14908c2ecf20Sopenharmony_ci#define DO_TESTCASE_6(desc, name) \ 14918c2ecf20Sopenharmony_ci print_testname(desc); \ 14928c2ecf20Sopenharmony_ci dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \ 14938c2ecf20Sopenharmony_ci dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \ 14948c2ecf20Sopenharmony_ci dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \ 14958c2ecf20Sopenharmony_ci dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ 14968c2ecf20Sopenharmony_ci dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ 14978c2ecf20Sopenharmony_ci dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ 14988c2ecf20Sopenharmony_ci dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \ 14998c2ecf20Sopenharmony_ci pr_cont("\n"); 15008c2ecf20Sopenharmony_ci 15018c2ecf20Sopenharmony_ci#define DO_TESTCASE_6_SUCCESS(desc, name) \ 15028c2ecf20Sopenharmony_ci print_testname(desc); \ 15038c2ecf20Sopenharmony_ci dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN); \ 15048c2ecf20Sopenharmony_ci dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK); \ 15058c2ecf20Sopenharmony_ci dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \ 15068c2ecf20Sopenharmony_ci dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \ 15078c2ecf20Sopenharmony_ci dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \ 15088c2ecf20Sopenharmony_ci dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \ 15098c2ecf20Sopenharmony_ci dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX); \ 15108c2ecf20Sopenharmony_ci pr_cont("\n"); 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci/* 15138c2ecf20Sopenharmony_ci * 'read' variant: rlocks must not trigger. 15148c2ecf20Sopenharmony_ci */ 15158c2ecf20Sopenharmony_ci#define DO_TESTCASE_6R(desc, name) \ 15168c2ecf20Sopenharmony_ci print_testname(desc); \ 15178c2ecf20Sopenharmony_ci dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \ 15188c2ecf20Sopenharmony_ci dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \ 15198c2ecf20Sopenharmony_ci dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \ 15208c2ecf20Sopenharmony_ci dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ 15218c2ecf20Sopenharmony_ci dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ 15228c2ecf20Sopenharmony_ci dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ 15238c2ecf20Sopenharmony_ci dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \ 15248c2ecf20Sopenharmony_ci pr_cont("\n"); 15258c2ecf20Sopenharmony_ci 15268c2ecf20Sopenharmony_ci#define DO_TESTCASE_2I(desc, name, nr) \ 15278c2ecf20Sopenharmony_ci DO_TESTCASE_1("hard-"desc, name##_hard, nr); \ 15288c2ecf20Sopenharmony_ci DO_TESTCASE_1("soft-"desc, name##_soft, nr); 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci#define DO_TESTCASE_2IB(desc, name, nr) \ 15318c2ecf20Sopenharmony_ci DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \ 15328c2ecf20Sopenharmony_ci DO_TESTCASE_1B("soft-"desc, name##_soft, nr); 15338c2ecf20Sopenharmony_ci 15348c2ecf20Sopenharmony_ci#define DO_TESTCASE_6I(desc, name, nr) \ 15358c2ecf20Sopenharmony_ci DO_TESTCASE_3("hard-"desc, name##_hard, nr); \ 15368c2ecf20Sopenharmony_ci DO_TESTCASE_3("soft-"desc, name##_soft, nr); 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci#define DO_TESTCASE_6IRW(desc, name, nr) \ 15398c2ecf20Sopenharmony_ci DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \ 15408c2ecf20Sopenharmony_ci DO_TESTCASE_3RW("soft-"desc, name##_soft, nr); 15418c2ecf20Sopenharmony_ci 15428c2ecf20Sopenharmony_ci#define DO_TESTCASE_2x3(desc, name) \ 15438c2ecf20Sopenharmony_ci DO_TESTCASE_3(desc, name, 12); \ 15448c2ecf20Sopenharmony_ci DO_TESTCASE_3(desc, name, 21); 15458c2ecf20Sopenharmony_ci 15468c2ecf20Sopenharmony_ci#define DO_TESTCASE_2x6(desc, name) \ 15478c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 12); \ 15488c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 21); 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x2(desc, name) \ 15518c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 123); \ 15528c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 132); \ 15538c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 213); \ 15548c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 231); \ 15558c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 312); \ 15568c2ecf20Sopenharmony_ci DO_TESTCASE_2I(desc, name, 321); 15578c2ecf20Sopenharmony_ci 15588c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x2B(desc, name) \ 15598c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 123); \ 15608c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 132); \ 15618c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 213); \ 15628c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 231); \ 15638c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 312); \ 15648c2ecf20Sopenharmony_ci DO_TESTCASE_2IB(desc, name, 321); 15658c2ecf20Sopenharmony_ci 15668c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x1RR(desc, name) \ 15678c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 123); \ 15688c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 132); \ 15698c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 213); \ 15708c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 231); \ 15718c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 312); \ 15728c2ecf20Sopenharmony_ci DO_TESTCASE_1RR(desc, name, 321); 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x1RRB(desc, name) \ 15758c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 123); \ 15768c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 132); \ 15778c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 213); \ 15788c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 231); \ 15798c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 312); \ 15808c2ecf20Sopenharmony_ci DO_TESTCASE_1RRB(desc, name, 321); 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x6(desc, name) \ 15838c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 123); \ 15848c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 132); \ 15858c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 213); \ 15868c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 231); \ 15878c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 312); \ 15888c2ecf20Sopenharmony_ci DO_TESTCASE_6I(desc, name, 321); 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci#define DO_TESTCASE_6x6RW(desc, name) \ 15918c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 123); \ 15928c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 132); \ 15938c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 213); \ 15948c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 231); \ 15958c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 312); \ 15968c2ecf20Sopenharmony_ci DO_TESTCASE_6IRW(desc, name, 321); 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_cistatic void ww_test_fail_acquire(void) 15998c2ecf20Sopenharmony_ci{ 16008c2ecf20Sopenharmony_ci int ret; 16018c2ecf20Sopenharmony_ci 16028c2ecf20Sopenharmony_ci WWAI(&t); 16038c2ecf20Sopenharmony_ci t.stamp++; 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_ci if (WARN_ON(!o.ctx) || 16088c2ecf20Sopenharmony_ci WARN_ON(ret)) 16098c2ecf20Sopenharmony_ci return; 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci /* No lockdep test, pure API */ 16128c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 16138c2ecf20Sopenharmony_ci WARN_ON(ret != -EALREADY); 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci ret = WWT(&o); 16168c2ecf20Sopenharmony_ci WARN_ON(ret); 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci t2 = t; 16198c2ecf20Sopenharmony_ci t2.stamp++; 16208c2ecf20Sopenharmony_ci ret = WWL(&o, &t2); 16218c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 16228c2ecf20Sopenharmony_ci WWU(&o); 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_ci if (WWT(&o)) 16258c2ecf20Sopenharmony_ci WWU(&o); 16268c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_LOCK_ALLOC 16278c2ecf20Sopenharmony_ci else 16288c2ecf20Sopenharmony_ci DEBUG_LOCKS_WARN_ON(1); 16298c2ecf20Sopenharmony_ci#endif 16308c2ecf20Sopenharmony_ci} 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_cistatic void ww_test_normal(void) 16338c2ecf20Sopenharmony_ci{ 16348c2ecf20Sopenharmony_ci int ret; 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_ci WWAI(&t); 16378c2ecf20Sopenharmony_ci 16388c2ecf20Sopenharmony_ci /* 16398c2ecf20Sopenharmony_ci * None of the ww_mutex codepaths should be taken in the 'normal' 16408c2ecf20Sopenharmony_ci * mutex calls. The easiest way to verify this is by using the 16418c2ecf20Sopenharmony_ci * normal mutex calls, and making sure o.ctx is unmodified. 16428c2ecf20Sopenharmony_ci */ 16438c2ecf20Sopenharmony_ci 16448c2ecf20Sopenharmony_ci /* mutex_lock (and indirectly, mutex_lock_nested) */ 16458c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16468c2ecf20Sopenharmony_ci mutex_lock(&o.base); 16478c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16488c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci /* mutex_lock_interruptible (and *_nested) */ 16518c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16528c2ecf20Sopenharmony_ci ret = mutex_lock_interruptible(&o.base); 16538c2ecf20Sopenharmony_ci if (!ret) 16548c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16558c2ecf20Sopenharmony_ci else 16568c2ecf20Sopenharmony_ci WARN_ON(1); 16578c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16588c2ecf20Sopenharmony_ci 16598c2ecf20Sopenharmony_ci /* mutex_lock_killable (and *_nested) */ 16608c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16618c2ecf20Sopenharmony_ci ret = mutex_lock_killable(&o.base); 16628c2ecf20Sopenharmony_ci if (!ret) 16638c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16648c2ecf20Sopenharmony_ci else 16658c2ecf20Sopenharmony_ci WARN_ON(1); 16668c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci /* trylock, succeeding */ 16698c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16708c2ecf20Sopenharmony_ci ret = mutex_trylock(&o.base); 16718c2ecf20Sopenharmony_ci WARN_ON(!ret); 16728c2ecf20Sopenharmony_ci if (ret) 16738c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16748c2ecf20Sopenharmony_ci else 16758c2ecf20Sopenharmony_ci WARN_ON(1); 16768c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci /* trylock, failing */ 16798c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16808c2ecf20Sopenharmony_ci mutex_lock(&o.base); 16818c2ecf20Sopenharmony_ci ret = mutex_trylock(&o.base); 16828c2ecf20Sopenharmony_ci WARN_ON(ret); 16838c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16848c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16858c2ecf20Sopenharmony_ci 16868c2ecf20Sopenharmony_ci /* nest_lock */ 16878c2ecf20Sopenharmony_ci o.ctx = (void *)~0UL; 16888c2ecf20Sopenharmony_ci mutex_lock_nest_lock(&o.base, &t); 16898c2ecf20Sopenharmony_ci mutex_unlock(&o.base); 16908c2ecf20Sopenharmony_ci WARN_ON(o.ctx != (void *)~0UL); 16918c2ecf20Sopenharmony_ci} 16928c2ecf20Sopenharmony_ci 16938c2ecf20Sopenharmony_cistatic void ww_test_two_contexts(void) 16948c2ecf20Sopenharmony_ci{ 16958c2ecf20Sopenharmony_ci WWAI(&t); 16968c2ecf20Sopenharmony_ci WWAI(&t2); 16978c2ecf20Sopenharmony_ci} 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_cistatic void ww_test_diff_class(void) 17008c2ecf20Sopenharmony_ci{ 17018c2ecf20Sopenharmony_ci WWAI(&t); 17028c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_MUTEXES 17038c2ecf20Sopenharmony_ci t.ww_class = NULL; 17048c2ecf20Sopenharmony_ci#endif 17058c2ecf20Sopenharmony_ci WWL(&o, &t); 17068c2ecf20Sopenharmony_ci} 17078c2ecf20Sopenharmony_ci 17088c2ecf20Sopenharmony_cistatic void ww_test_context_done_twice(void) 17098c2ecf20Sopenharmony_ci{ 17108c2ecf20Sopenharmony_ci WWAI(&t); 17118c2ecf20Sopenharmony_ci WWAD(&t); 17128c2ecf20Sopenharmony_ci WWAD(&t); 17138c2ecf20Sopenharmony_ci WWAF(&t); 17148c2ecf20Sopenharmony_ci} 17158c2ecf20Sopenharmony_ci 17168c2ecf20Sopenharmony_cistatic void ww_test_context_unlock_twice(void) 17178c2ecf20Sopenharmony_ci{ 17188c2ecf20Sopenharmony_ci WWAI(&t); 17198c2ecf20Sopenharmony_ci WWAD(&t); 17208c2ecf20Sopenharmony_ci WWAF(&t); 17218c2ecf20Sopenharmony_ci WWAF(&t); 17228c2ecf20Sopenharmony_ci} 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_cistatic void ww_test_context_fini_early(void) 17258c2ecf20Sopenharmony_ci{ 17268c2ecf20Sopenharmony_ci WWAI(&t); 17278c2ecf20Sopenharmony_ci WWL(&o, &t); 17288c2ecf20Sopenharmony_ci WWAD(&t); 17298c2ecf20Sopenharmony_ci WWAF(&t); 17308c2ecf20Sopenharmony_ci} 17318c2ecf20Sopenharmony_ci 17328c2ecf20Sopenharmony_cistatic void ww_test_context_lock_after_done(void) 17338c2ecf20Sopenharmony_ci{ 17348c2ecf20Sopenharmony_ci WWAI(&t); 17358c2ecf20Sopenharmony_ci WWAD(&t); 17368c2ecf20Sopenharmony_ci WWL(&o, &t); 17378c2ecf20Sopenharmony_ci} 17388c2ecf20Sopenharmony_ci 17398c2ecf20Sopenharmony_cistatic void ww_test_object_unlock_twice(void) 17408c2ecf20Sopenharmony_ci{ 17418c2ecf20Sopenharmony_ci WWL1(&o); 17428c2ecf20Sopenharmony_ci WWU(&o); 17438c2ecf20Sopenharmony_ci WWU(&o); 17448c2ecf20Sopenharmony_ci} 17458c2ecf20Sopenharmony_ci 17468c2ecf20Sopenharmony_cistatic void ww_test_object_lock_unbalanced(void) 17478c2ecf20Sopenharmony_ci{ 17488c2ecf20Sopenharmony_ci WWAI(&t); 17498c2ecf20Sopenharmony_ci WWL(&o, &t); 17508c2ecf20Sopenharmony_ci t.acquired = 0; 17518c2ecf20Sopenharmony_ci WWU(&o); 17528c2ecf20Sopenharmony_ci WWAF(&t); 17538c2ecf20Sopenharmony_ci} 17548c2ecf20Sopenharmony_ci 17558c2ecf20Sopenharmony_cistatic void ww_test_object_lock_stale_context(void) 17568c2ecf20Sopenharmony_ci{ 17578c2ecf20Sopenharmony_ci WWAI(&t); 17588c2ecf20Sopenharmony_ci o.ctx = &t2; 17598c2ecf20Sopenharmony_ci WWL(&o, &t); 17608c2ecf20Sopenharmony_ci} 17618c2ecf20Sopenharmony_ci 17628c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_normal(void) 17638c2ecf20Sopenharmony_ci{ 17648c2ecf20Sopenharmony_ci int ret; 17658c2ecf20Sopenharmony_ci 17668c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 17678c2ecf20Sopenharmony_ci o2.ctx = &t2; 17688c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 17698c2ecf20Sopenharmony_ci 17708c2ecf20Sopenharmony_ci WWAI(&t); 17718c2ecf20Sopenharmony_ci t2 = t; 17728c2ecf20Sopenharmony_ci t2.stamp--; 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 17758c2ecf20Sopenharmony_ci WARN_ON(ret); 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 17788c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_ci o2.ctx = NULL; 17818c2ecf20Sopenharmony_ci mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); 17828c2ecf20Sopenharmony_ci mutex_unlock(&o2.base); 17838c2ecf20Sopenharmony_ci WWU(&o); 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_ci WWL(&o2, &t); 17868c2ecf20Sopenharmony_ci} 17878c2ecf20Sopenharmony_ci 17888c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_normal_slow(void) 17898c2ecf20Sopenharmony_ci{ 17908c2ecf20Sopenharmony_ci int ret; 17918c2ecf20Sopenharmony_ci 17928c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 17938c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 17948c2ecf20Sopenharmony_ci o2.ctx = &t2; 17958c2ecf20Sopenharmony_ci 17968c2ecf20Sopenharmony_ci WWAI(&t); 17978c2ecf20Sopenharmony_ci t2 = t; 17988c2ecf20Sopenharmony_ci t2.stamp--; 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 18018c2ecf20Sopenharmony_ci WARN_ON(ret); 18028c2ecf20Sopenharmony_ci 18038c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 18048c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 18058c2ecf20Sopenharmony_ci 18068c2ecf20Sopenharmony_ci o2.ctx = NULL; 18078c2ecf20Sopenharmony_ci mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); 18088c2ecf20Sopenharmony_ci mutex_unlock(&o2.base); 18098c2ecf20Sopenharmony_ci WWU(&o); 18108c2ecf20Sopenharmony_ci 18118c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o2, &t); 18128c2ecf20Sopenharmony_ci} 18138c2ecf20Sopenharmony_ci 18148c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_no_unlock(void) 18158c2ecf20Sopenharmony_ci{ 18168c2ecf20Sopenharmony_ci int ret; 18178c2ecf20Sopenharmony_ci 18188c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 18198c2ecf20Sopenharmony_ci o2.ctx = &t2; 18208c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 18218c2ecf20Sopenharmony_ci 18228c2ecf20Sopenharmony_ci WWAI(&t); 18238c2ecf20Sopenharmony_ci t2 = t; 18248c2ecf20Sopenharmony_ci t2.stamp--; 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 18278c2ecf20Sopenharmony_ci WARN_ON(ret); 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 18308c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci o2.ctx = NULL; 18338c2ecf20Sopenharmony_ci mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); 18348c2ecf20Sopenharmony_ci mutex_unlock(&o2.base); 18358c2ecf20Sopenharmony_ci 18368c2ecf20Sopenharmony_ci WWL(&o2, &t); 18378c2ecf20Sopenharmony_ci} 18388c2ecf20Sopenharmony_ci 18398c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_no_unlock_slow(void) 18408c2ecf20Sopenharmony_ci{ 18418c2ecf20Sopenharmony_ci int ret; 18428c2ecf20Sopenharmony_ci 18438c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 18448c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 18458c2ecf20Sopenharmony_ci o2.ctx = &t2; 18468c2ecf20Sopenharmony_ci 18478c2ecf20Sopenharmony_ci WWAI(&t); 18488c2ecf20Sopenharmony_ci t2 = t; 18498c2ecf20Sopenharmony_ci t2.stamp--; 18508c2ecf20Sopenharmony_ci 18518c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 18528c2ecf20Sopenharmony_ci WARN_ON(ret); 18538c2ecf20Sopenharmony_ci 18548c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 18558c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 18568c2ecf20Sopenharmony_ci 18578c2ecf20Sopenharmony_ci o2.ctx = NULL; 18588c2ecf20Sopenharmony_ci mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); 18598c2ecf20Sopenharmony_ci mutex_unlock(&o2.base); 18608c2ecf20Sopenharmony_ci 18618c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o2, &t); 18628c2ecf20Sopenharmony_ci} 18638c2ecf20Sopenharmony_ci 18648c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_more(void) 18658c2ecf20Sopenharmony_ci{ 18668c2ecf20Sopenharmony_ci int ret; 18678c2ecf20Sopenharmony_ci 18688c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 18698c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 18708c2ecf20Sopenharmony_ci o2.ctx = &t2; 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci WWAI(&t); 18738c2ecf20Sopenharmony_ci t2 = t; 18748c2ecf20Sopenharmony_ci t2.stamp--; 18758c2ecf20Sopenharmony_ci 18768c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 18778c2ecf20Sopenharmony_ci WARN_ON(ret); 18788c2ecf20Sopenharmony_ci 18798c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 18808c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 18818c2ecf20Sopenharmony_ci 18828c2ecf20Sopenharmony_ci ret = WWL(&o3, &t); 18838c2ecf20Sopenharmony_ci} 18848c2ecf20Sopenharmony_ci 18858c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_more_slow(void) 18868c2ecf20Sopenharmony_ci{ 18878c2ecf20Sopenharmony_ci int ret; 18888c2ecf20Sopenharmony_ci 18898c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 18908c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 18918c2ecf20Sopenharmony_ci o2.ctx = &t2; 18928c2ecf20Sopenharmony_ci 18938c2ecf20Sopenharmony_ci WWAI(&t); 18948c2ecf20Sopenharmony_ci t2 = t; 18958c2ecf20Sopenharmony_ci t2.stamp--; 18968c2ecf20Sopenharmony_ci 18978c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 18988c2ecf20Sopenharmony_ci WARN_ON(ret); 18998c2ecf20Sopenharmony_ci 19008c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 19018c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19028c2ecf20Sopenharmony_ci 19038c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o3, &t); 19048c2ecf20Sopenharmony_ci} 19058c2ecf20Sopenharmony_ci 19068c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_more_edeadlk(void) 19078c2ecf20Sopenharmony_ci{ 19088c2ecf20Sopenharmony_ci int ret; 19098c2ecf20Sopenharmony_ci 19108c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 19118c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 19128c2ecf20Sopenharmony_ci o2.ctx = &t2; 19138c2ecf20Sopenharmony_ci 19148c2ecf20Sopenharmony_ci mutex_lock(&o3.base); 19158c2ecf20Sopenharmony_ci mutex_release(&o3.base.dep_map, _THIS_IP_); 19168c2ecf20Sopenharmony_ci o3.ctx = &t2; 19178c2ecf20Sopenharmony_ci 19188c2ecf20Sopenharmony_ci WWAI(&t); 19198c2ecf20Sopenharmony_ci t2 = t; 19208c2ecf20Sopenharmony_ci t2.stamp--; 19218c2ecf20Sopenharmony_ci 19228c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 19238c2ecf20Sopenharmony_ci WARN_ON(ret); 19248c2ecf20Sopenharmony_ci 19258c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 19268c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19278c2ecf20Sopenharmony_ci 19288c2ecf20Sopenharmony_ci ret = WWL(&o3, &t); 19298c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19308c2ecf20Sopenharmony_ci} 19318c2ecf20Sopenharmony_ci 19328c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_more_edeadlk_slow(void) 19338c2ecf20Sopenharmony_ci{ 19348c2ecf20Sopenharmony_ci int ret; 19358c2ecf20Sopenharmony_ci 19368c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 19378c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 19388c2ecf20Sopenharmony_ci o2.ctx = &t2; 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci mutex_lock(&o3.base); 19418c2ecf20Sopenharmony_ci mutex_release(&o3.base.dep_map, _THIS_IP_); 19428c2ecf20Sopenharmony_ci o3.ctx = &t2; 19438c2ecf20Sopenharmony_ci 19448c2ecf20Sopenharmony_ci WWAI(&t); 19458c2ecf20Sopenharmony_ci t2 = t; 19468c2ecf20Sopenharmony_ci t2.stamp--; 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 19498c2ecf20Sopenharmony_ci WARN_ON(ret); 19508c2ecf20Sopenharmony_ci 19518c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 19528c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19538c2ecf20Sopenharmony_ci 19548c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o3, &t); 19558c2ecf20Sopenharmony_ci} 19568c2ecf20Sopenharmony_ci 19578c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_wrong(void) 19588c2ecf20Sopenharmony_ci{ 19598c2ecf20Sopenharmony_ci int ret; 19608c2ecf20Sopenharmony_ci 19618c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 19628c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 19638c2ecf20Sopenharmony_ci o2.ctx = &t2; 19648c2ecf20Sopenharmony_ci 19658c2ecf20Sopenharmony_ci WWAI(&t); 19668c2ecf20Sopenharmony_ci t2 = t; 19678c2ecf20Sopenharmony_ci t2.stamp--; 19688c2ecf20Sopenharmony_ci 19698c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 19708c2ecf20Sopenharmony_ci WARN_ON(ret); 19718c2ecf20Sopenharmony_ci 19728c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 19738c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19748c2ecf20Sopenharmony_ci if (!ret) 19758c2ecf20Sopenharmony_ci WWU(&o2); 19768c2ecf20Sopenharmony_ci 19778c2ecf20Sopenharmony_ci WWU(&o); 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci ret = WWL(&o3, &t); 19808c2ecf20Sopenharmony_ci} 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_cistatic void ww_test_edeadlk_acquire_wrong_slow(void) 19838c2ecf20Sopenharmony_ci{ 19848c2ecf20Sopenharmony_ci int ret; 19858c2ecf20Sopenharmony_ci 19868c2ecf20Sopenharmony_ci mutex_lock(&o2.base); 19878c2ecf20Sopenharmony_ci mutex_release(&o2.base.dep_map, _THIS_IP_); 19888c2ecf20Sopenharmony_ci o2.ctx = &t2; 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_ci WWAI(&t); 19918c2ecf20Sopenharmony_ci t2 = t; 19928c2ecf20Sopenharmony_ci t2.stamp--; 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 19958c2ecf20Sopenharmony_ci WARN_ON(ret); 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 19988c2ecf20Sopenharmony_ci WARN_ON(ret != -EDEADLK); 19998c2ecf20Sopenharmony_ci if (!ret) 20008c2ecf20Sopenharmony_ci WWU(&o2); 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci WWU(&o); 20038c2ecf20Sopenharmony_ci 20048c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o3, &t); 20058c2ecf20Sopenharmony_ci} 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_cistatic void ww_test_spin_nest_unlocked(void) 20088c2ecf20Sopenharmony_ci{ 20098c2ecf20Sopenharmony_ci raw_spin_lock_nest_lock(&lock_A, &o.base); 20108c2ecf20Sopenharmony_ci U(A); 20118c2ecf20Sopenharmony_ci} 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_cistatic void ww_test_unneeded_slow(void) 20148c2ecf20Sopenharmony_ci{ 20158c2ecf20Sopenharmony_ci WWAI(&t); 20168c2ecf20Sopenharmony_ci 20178c2ecf20Sopenharmony_ci ww_mutex_lock_slow(&o, &t); 20188c2ecf20Sopenharmony_ci} 20198c2ecf20Sopenharmony_ci 20208c2ecf20Sopenharmony_cistatic void ww_test_context_block(void) 20218c2ecf20Sopenharmony_ci{ 20228c2ecf20Sopenharmony_ci int ret; 20238c2ecf20Sopenharmony_ci 20248c2ecf20Sopenharmony_ci WWAI(&t); 20258c2ecf20Sopenharmony_ci 20268c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 20278c2ecf20Sopenharmony_ci WARN_ON(ret); 20288c2ecf20Sopenharmony_ci WWL1(&o2); 20298c2ecf20Sopenharmony_ci} 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_cistatic void ww_test_context_try(void) 20328c2ecf20Sopenharmony_ci{ 20338c2ecf20Sopenharmony_ci int ret; 20348c2ecf20Sopenharmony_ci 20358c2ecf20Sopenharmony_ci WWAI(&t); 20368c2ecf20Sopenharmony_ci 20378c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 20388c2ecf20Sopenharmony_ci WARN_ON(ret); 20398c2ecf20Sopenharmony_ci 20408c2ecf20Sopenharmony_ci ret = WWT(&o2); 20418c2ecf20Sopenharmony_ci WARN_ON(!ret); 20428c2ecf20Sopenharmony_ci WWU(&o2); 20438c2ecf20Sopenharmony_ci WWU(&o); 20448c2ecf20Sopenharmony_ci} 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_cistatic void ww_test_context_context(void) 20478c2ecf20Sopenharmony_ci{ 20488c2ecf20Sopenharmony_ci int ret; 20498c2ecf20Sopenharmony_ci 20508c2ecf20Sopenharmony_ci WWAI(&t); 20518c2ecf20Sopenharmony_ci 20528c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 20538c2ecf20Sopenharmony_ci WARN_ON(ret); 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 20568c2ecf20Sopenharmony_ci WARN_ON(ret); 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci WWU(&o2); 20598c2ecf20Sopenharmony_ci WWU(&o); 20608c2ecf20Sopenharmony_ci} 20618c2ecf20Sopenharmony_ci 20628c2ecf20Sopenharmony_cistatic void ww_test_try_block(void) 20638c2ecf20Sopenharmony_ci{ 20648c2ecf20Sopenharmony_ci bool ret; 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci ret = WWT(&o); 20678c2ecf20Sopenharmony_ci WARN_ON(!ret); 20688c2ecf20Sopenharmony_ci 20698c2ecf20Sopenharmony_ci WWL1(&o2); 20708c2ecf20Sopenharmony_ci WWU(&o2); 20718c2ecf20Sopenharmony_ci WWU(&o); 20728c2ecf20Sopenharmony_ci} 20738c2ecf20Sopenharmony_ci 20748c2ecf20Sopenharmony_cistatic void ww_test_try_try(void) 20758c2ecf20Sopenharmony_ci{ 20768c2ecf20Sopenharmony_ci bool ret; 20778c2ecf20Sopenharmony_ci 20788c2ecf20Sopenharmony_ci ret = WWT(&o); 20798c2ecf20Sopenharmony_ci WARN_ON(!ret); 20808c2ecf20Sopenharmony_ci ret = WWT(&o2); 20818c2ecf20Sopenharmony_ci WARN_ON(!ret); 20828c2ecf20Sopenharmony_ci WWU(&o2); 20838c2ecf20Sopenharmony_ci WWU(&o); 20848c2ecf20Sopenharmony_ci} 20858c2ecf20Sopenharmony_ci 20868c2ecf20Sopenharmony_cistatic void ww_test_try_context(void) 20878c2ecf20Sopenharmony_ci{ 20888c2ecf20Sopenharmony_ci int ret; 20898c2ecf20Sopenharmony_ci 20908c2ecf20Sopenharmony_ci ret = WWT(&o); 20918c2ecf20Sopenharmony_ci WARN_ON(!ret); 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci WWAI(&t); 20948c2ecf20Sopenharmony_ci 20958c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 20968c2ecf20Sopenharmony_ci WARN_ON(ret); 20978c2ecf20Sopenharmony_ci} 20988c2ecf20Sopenharmony_ci 20998c2ecf20Sopenharmony_cistatic void ww_test_block_block(void) 21008c2ecf20Sopenharmony_ci{ 21018c2ecf20Sopenharmony_ci WWL1(&o); 21028c2ecf20Sopenharmony_ci WWL1(&o2); 21038c2ecf20Sopenharmony_ci} 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_cistatic void ww_test_block_try(void) 21068c2ecf20Sopenharmony_ci{ 21078c2ecf20Sopenharmony_ci bool ret; 21088c2ecf20Sopenharmony_ci 21098c2ecf20Sopenharmony_ci WWL1(&o); 21108c2ecf20Sopenharmony_ci ret = WWT(&o2); 21118c2ecf20Sopenharmony_ci WARN_ON(!ret); 21128c2ecf20Sopenharmony_ci} 21138c2ecf20Sopenharmony_ci 21148c2ecf20Sopenharmony_cistatic void ww_test_block_context(void) 21158c2ecf20Sopenharmony_ci{ 21168c2ecf20Sopenharmony_ci int ret; 21178c2ecf20Sopenharmony_ci 21188c2ecf20Sopenharmony_ci WWL1(&o); 21198c2ecf20Sopenharmony_ci WWAI(&t); 21208c2ecf20Sopenharmony_ci 21218c2ecf20Sopenharmony_ci ret = WWL(&o2, &t); 21228c2ecf20Sopenharmony_ci WARN_ON(ret); 21238c2ecf20Sopenharmony_ci} 21248c2ecf20Sopenharmony_ci 21258c2ecf20Sopenharmony_cistatic void ww_test_spin_block(void) 21268c2ecf20Sopenharmony_ci{ 21278c2ecf20Sopenharmony_ci L(A); 21288c2ecf20Sopenharmony_ci U(A); 21298c2ecf20Sopenharmony_ci 21308c2ecf20Sopenharmony_ci WWL1(&o); 21318c2ecf20Sopenharmony_ci L(A); 21328c2ecf20Sopenharmony_ci U(A); 21338c2ecf20Sopenharmony_ci WWU(&o); 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_ci L(A); 21368c2ecf20Sopenharmony_ci WWL1(&o); 21378c2ecf20Sopenharmony_ci WWU(&o); 21388c2ecf20Sopenharmony_ci U(A); 21398c2ecf20Sopenharmony_ci} 21408c2ecf20Sopenharmony_ci 21418c2ecf20Sopenharmony_cistatic void ww_test_spin_try(void) 21428c2ecf20Sopenharmony_ci{ 21438c2ecf20Sopenharmony_ci bool ret; 21448c2ecf20Sopenharmony_ci 21458c2ecf20Sopenharmony_ci L(A); 21468c2ecf20Sopenharmony_ci U(A); 21478c2ecf20Sopenharmony_ci 21488c2ecf20Sopenharmony_ci ret = WWT(&o); 21498c2ecf20Sopenharmony_ci WARN_ON(!ret); 21508c2ecf20Sopenharmony_ci L(A); 21518c2ecf20Sopenharmony_ci U(A); 21528c2ecf20Sopenharmony_ci WWU(&o); 21538c2ecf20Sopenharmony_ci 21548c2ecf20Sopenharmony_ci L(A); 21558c2ecf20Sopenharmony_ci ret = WWT(&o); 21568c2ecf20Sopenharmony_ci WARN_ON(!ret); 21578c2ecf20Sopenharmony_ci WWU(&o); 21588c2ecf20Sopenharmony_ci U(A); 21598c2ecf20Sopenharmony_ci} 21608c2ecf20Sopenharmony_ci 21618c2ecf20Sopenharmony_cistatic void ww_test_spin_context(void) 21628c2ecf20Sopenharmony_ci{ 21638c2ecf20Sopenharmony_ci int ret; 21648c2ecf20Sopenharmony_ci 21658c2ecf20Sopenharmony_ci L(A); 21668c2ecf20Sopenharmony_ci U(A); 21678c2ecf20Sopenharmony_ci 21688c2ecf20Sopenharmony_ci WWAI(&t); 21698c2ecf20Sopenharmony_ci 21708c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 21718c2ecf20Sopenharmony_ci WARN_ON(ret); 21728c2ecf20Sopenharmony_ci L(A); 21738c2ecf20Sopenharmony_ci U(A); 21748c2ecf20Sopenharmony_ci WWU(&o); 21758c2ecf20Sopenharmony_ci 21768c2ecf20Sopenharmony_ci L(A); 21778c2ecf20Sopenharmony_ci ret = WWL(&o, &t); 21788c2ecf20Sopenharmony_ci WARN_ON(ret); 21798c2ecf20Sopenharmony_ci WWU(&o); 21808c2ecf20Sopenharmony_ci U(A); 21818c2ecf20Sopenharmony_ci} 21828c2ecf20Sopenharmony_ci 21838c2ecf20Sopenharmony_cistatic void ww_tests(void) 21848c2ecf20Sopenharmony_ci{ 21858c2ecf20Sopenharmony_ci printk(" --------------------------------------------------------------------------\n"); 21868c2ecf20Sopenharmony_ci printk(" | Wound/wait tests |\n"); 21878c2ecf20Sopenharmony_ci printk(" ---------------------\n"); 21888c2ecf20Sopenharmony_ci 21898c2ecf20Sopenharmony_ci print_testname("ww api failures"); 21908c2ecf20Sopenharmony_ci dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW); 21918c2ecf20Sopenharmony_ci dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW); 21928c2ecf20Sopenharmony_ci dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW); 21938c2ecf20Sopenharmony_ci pr_cont("\n"); 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci print_testname("ww contexts mixing"); 21968c2ecf20Sopenharmony_ci dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW); 21978c2ecf20Sopenharmony_ci dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW); 21988c2ecf20Sopenharmony_ci pr_cont("\n"); 21998c2ecf20Sopenharmony_ci 22008c2ecf20Sopenharmony_ci print_testname("finishing ww context"); 22018c2ecf20Sopenharmony_ci dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW); 22028c2ecf20Sopenharmony_ci dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW); 22038c2ecf20Sopenharmony_ci dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW); 22048c2ecf20Sopenharmony_ci dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW); 22058c2ecf20Sopenharmony_ci pr_cont("\n"); 22068c2ecf20Sopenharmony_ci 22078c2ecf20Sopenharmony_ci print_testname("locking mismatches"); 22088c2ecf20Sopenharmony_ci dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW); 22098c2ecf20Sopenharmony_ci dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW); 22108c2ecf20Sopenharmony_ci dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW); 22118c2ecf20Sopenharmony_ci pr_cont("\n"); 22128c2ecf20Sopenharmony_ci 22138c2ecf20Sopenharmony_ci print_testname("EDEADLK handling"); 22148c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW); 22158c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW); 22168c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW); 22178c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW); 22188c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW); 22198c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW); 22208c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW); 22218c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW); 22228c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW); 22238c2ecf20Sopenharmony_ci dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW); 22248c2ecf20Sopenharmony_ci pr_cont("\n"); 22258c2ecf20Sopenharmony_ci 22268c2ecf20Sopenharmony_ci print_testname("spinlock nest unlocked"); 22278c2ecf20Sopenharmony_ci dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW); 22288c2ecf20Sopenharmony_ci pr_cont("\n"); 22298c2ecf20Sopenharmony_ci 22308c2ecf20Sopenharmony_ci printk(" -----------------------------------------------------\n"); 22318c2ecf20Sopenharmony_ci printk(" |block | try |context|\n"); 22328c2ecf20Sopenharmony_ci printk(" -----------------------------------------------------\n"); 22338c2ecf20Sopenharmony_ci 22348c2ecf20Sopenharmony_ci print_testname("context"); 22358c2ecf20Sopenharmony_ci dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW); 22368c2ecf20Sopenharmony_ci dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW); 22378c2ecf20Sopenharmony_ci dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW); 22388c2ecf20Sopenharmony_ci pr_cont("\n"); 22398c2ecf20Sopenharmony_ci 22408c2ecf20Sopenharmony_ci print_testname("try"); 22418c2ecf20Sopenharmony_ci dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW); 22428c2ecf20Sopenharmony_ci dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW); 22438c2ecf20Sopenharmony_ci dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW); 22448c2ecf20Sopenharmony_ci pr_cont("\n"); 22458c2ecf20Sopenharmony_ci 22468c2ecf20Sopenharmony_ci print_testname("block"); 22478c2ecf20Sopenharmony_ci dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW); 22488c2ecf20Sopenharmony_ci dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW); 22498c2ecf20Sopenharmony_ci dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW); 22508c2ecf20Sopenharmony_ci pr_cont("\n"); 22518c2ecf20Sopenharmony_ci 22528c2ecf20Sopenharmony_ci print_testname("spinlock"); 22538c2ecf20Sopenharmony_ci dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW); 22548c2ecf20Sopenharmony_ci dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW); 22558c2ecf20Sopenharmony_ci dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW); 22568c2ecf20Sopenharmony_ci pr_cont("\n"); 22578c2ecf20Sopenharmony_ci} 22588c2ecf20Sopenharmony_ci 22598c2ecf20Sopenharmony_ci 22608c2ecf20Sopenharmony_ci/* 22618c2ecf20Sopenharmony_ci * <in hardirq handler> 22628c2ecf20Sopenharmony_ci * read_lock(&A); 22638c2ecf20Sopenharmony_ci * <hardirq disable> 22648c2ecf20Sopenharmony_ci * spin_lock(&B); 22658c2ecf20Sopenharmony_ci * spin_lock(&B); 22668c2ecf20Sopenharmony_ci * read_lock(&A); 22678c2ecf20Sopenharmony_ci * 22688c2ecf20Sopenharmony_ci * is a deadlock. 22698c2ecf20Sopenharmony_ci */ 22708c2ecf20Sopenharmony_cistatic void queued_read_lock_hardirq_RE_Er(void) 22718c2ecf20Sopenharmony_ci{ 22728c2ecf20Sopenharmony_ci HARDIRQ_ENTER(); 22738c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 22748c2ecf20Sopenharmony_ci LOCK(B); 22758c2ecf20Sopenharmony_ci UNLOCK(B); 22768c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 22778c2ecf20Sopenharmony_ci HARDIRQ_EXIT(); 22788c2ecf20Sopenharmony_ci 22798c2ecf20Sopenharmony_ci HARDIRQ_DISABLE(); 22808c2ecf20Sopenharmony_ci LOCK(B); 22818c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 22828c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 22838c2ecf20Sopenharmony_ci UNLOCK(B); 22848c2ecf20Sopenharmony_ci HARDIRQ_ENABLE(); 22858c2ecf20Sopenharmony_ci} 22868c2ecf20Sopenharmony_ci 22878c2ecf20Sopenharmony_ci/* 22888c2ecf20Sopenharmony_ci * <in hardirq handler> 22898c2ecf20Sopenharmony_ci * spin_lock(&B); 22908c2ecf20Sopenharmony_ci * <hardirq disable> 22918c2ecf20Sopenharmony_ci * read_lock(&A); 22928c2ecf20Sopenharmony_ci * read_lock(&A); 22938c2ecf20Sopenharmony_ci * spin_lock(&B); 22948c2ecf20Sopenharmony_ci * 22958c2ecf20Sopenharmony_ci * is not a deadlock. 22968c2ecf20Sopenharmony_ci */ 22978c2ecf20Sopenharmony_cistatic void queued_read_lock_hardirq_ER_rE(void) 22988c2ecf20Sopenharmony_ci{ 22998c2ecf20Sopenharmony_ci HARDIRQ_ENTER(); 23008c2ecf20Sopenharmony_ci LOCK(B); 23018c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 23028c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 23038c2ecf20Sopenharmony_ci UNLOCK(B); 23048c2ecf20Sopenharmony_ci HARDIRQ_EXIT(); 23058c2ecf20Sopenharmony_ci 23068c2ecf20Sopenharmony_ci HARDIRQ_DISABLE(); 23078c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 23088c2ecf20Sopenharmony_ci LOCK(B); 23098c2ecf20Sopenharmony_ci UNLOCK(B); 23108c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 23118c2ecf20Sopenharmony_ci HARDIRQ_ENABLE(); 23128c2ecf20Sopenharmony_ci} 23138c2ecf20Sopenharmony_ci 23148c2ecf20Sopenharmony_ci/* 23158c2ecf20Sopenharmony_ci * <hardirq disable> 23168c2ecf20Sopenharmony_ci * spin_lock(&B); 23178c2ecf20Sopenharmony_ci * read_lock(&A); 23188c2ecf20Sopenharmony_ci * <in hardirq handler> 23198c2ecf20Sopenharmony_ci * spin_lock(&B); 23208c2ecf20Sopenharmony_ci * read_lock(&A); 23218c2ecf20Sopenharmony_ci * 23228c2ecf20Sopenharmony_ci * is a deadlock. Because the two read_lock()s are both non-recursive readers. 23238c2ecf20Sopenharmony_ci */ 23248c2ecf20Sopenharmony_cistatic void queued_read_lock_hardirq_inversion(void) 23258c2ecf20Sopenharmony_ci{ 23268c2ecf20Sopenharmony_ci 23278c2ecf20Sopenharmony_ci HARDIRQ_ENTER(); 23288c2ecf20Sopenharmony_ci LOCK(B); 23298c2ecf20Sopenharmony_ci UNLOCK(B); 23308c2ecf20Sopenharmony_ci HARDIRQ_EXIT(); 23318c2ecf20Sopenharmony_ci 23328c2ecf20Sopenharmony_ci HARDIRQ_DISABLE(); 23338c2ecf20Sopenharmony_ci LOCK(B); 23348c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 23358c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 23368c2ecf20Sopenharmony_ci UNLOCK(B); 23378c2ecf20Sopenharmony_ci HARDIRQ_ENABLE(); 23388c2ecf20Sopenharmony_ci 23398c2ecf20Sopenharmony_ci read_lock(&rwlock_A); 23408c2ecf20Sopenharmony_ci read_unlock(&rwlock_A); 23418c2ecf20Sopenharmony_ci} 23428c2ecf20Sopenharmony_ci 23438c2ecf20Sopenharmony_cistatic void queued_read_lock_tests(void) 23448c2ecf20Sopenharmony_ci{ 23458c2ecf20Sopenharmony_ci printk(" --------------------------------------------------------------------------\n"); 23468c2ecf20Sopenharmony_ci printk(" | queued read lock tests |\n"); 23478c2ecf20Sopenharmony_ci printk(" ---------------------------\n"); 23488c2ecf20Sopenharmony_ci print_testname("hardirq read-lock/lock-read"); 23498c2ecf20Sopenharmony_ci dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK); 23508c2ecf20Sopenharmony_ci pr_cont("\n"); 23518c2ecf20Sopenharmony_ci 23528c2ecf20Sopenharmony_ci print_testname("hardirq lock-read/read-lock"); 23538c2ecf20Sopenharmony_ci dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK); 23548c2ecf20Sopenharmony_ci pr_cont("\n"); 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci print_testname("hardirq inversion"); 23578c2ecf20Sopenharmony_ci dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK); 23588c2ecf20Sopenharmony_ci pr_cont("\n"); 23598c2ecf20Sopenharmony_ci} 23608c2ecf20Sopenharmony_ci 23618c2ecf20Sopenharmony_civoid locking_selftest(void) 23628c2ecf20Sopenharmony_ci{ 23638c2ecf20Sopenharmony_ci /* 23648c2ecf20Sopenharmony_ci * Got a locking failure before the selftest ran? 23658c2ecf20Sopenharmony_ci */ 23668c2ecf20Sopenharmony_ci if (!debug_locks) { 23678c2ecf20Sopenharmony_ci printk("----------------------------------\n"); 23688c2ecf20Sopenharmony_ci printk("| Locking API testsuite disabled |\n"); 23698c2ecf20Sopenharmony_ci printk("----------------------------------\n"); 23708c2ecf20Sopenharmony_ci return; 23718c2ecf20Sopenharmony_ci } 23728c2ecf20Sopenharmony_ci 23738c2ecf20Sopenharmony_ci /* 23748c2ecf20Sopenharmony_ci * treats read_lock() as recursive read locks for testing purpose 23758c2ecf20Sopenharmony_ci */ 23768c2ecf20Sopenharmony_ci force_read_lock_recursive = 1; 23778c2ecf20Sopenharmony_ci 23788c2ecf20Sopenharmony_ci /* 23798c2ecf20Sopenharmony_ci * Run the testsuite: 23808c2ecf20Sopenharmony_ci */ 23818c2ecf20Sopenharmony_ci printk("------------------------\n"); 23828c2ecf20Sopenharmony_ci printk("| Locking API testsuite:\n"); 23838c2ecf20Sopenharmony_ci printk("----------------------------------------------------------------------------\n"); 23848c2ecf20Sopenharmony_ci printk(" | spin |wlock |rlock |mutex | wsem | rsem |\n"); 23858c2ecf20Sopenharmony_ci printk(" --------------------------------------------------------------------------\n"); 23868c2ecf20Sopenharmony_ci 23878c2ecf20Sopenharmony_ci init_shared_classes(); 23888c2ecf20Sopenharmony_ci debug_locks_silent = !debug_locks_verbose; 23898c2ecf20Sopenharmony_ci lockdep_set_selftest_task(current); 23908c2ecf20Sopenharmony_ci 23918c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-A deadlock", AA); 23928c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-B-A deadlock", ABBA); 23938c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA); 23948c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC); 23958c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA); 23968c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA); 23978c2ecf20Sopenharmony_ci DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA); 23988c2ecf20Sopenharmony_ci DO_TESTCASE_6("double unlock", double_unlock); 23998c2ecf20Sopenharmony_ci DO_TESTCASE_6("initialize held", init_held); 24008c2ecf20Sopenharmony_ci 24018c2ecf20Sopenharmony_ci printk(" --------------------------------------------------------------------------\n"); 24028c2ecf20Sopenharmony_ci print_testname("recursive read-lock"); 24038c2ecf20Sopenharmony_ci pr_cont(" |"); 24048c2ecf20Sopenharmony_ci dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK); 24058c2ecf20Sopenharmony_ci pr_cont(" |"); 24068c2ecf20Sopenharmony_ci dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM); 24078c2ecf20Sopenharmony_ci pr_cont("\n"); 24088c2ecf20Sopenharmony_ci 24098c2ecf20Sopenharmony_ci print_testname("recursive read-lock #2"); 24108c2ecf20Sopenharmony_ci pr_cont(" |"); 24118c2ecf20Sopenharmony_ci dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK); 24128c2ecf20Sopenharmony_ci pr_cont(" |"); 24138c2ecf20Sopenharmony_ci dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM); 24148c2ecf20Sopenharmony_ci pr_cont("\n"); 24158c2ecf20Sopenharmony_ci 24168c2ecf20Sopenharmony_ci print_testname("mixed read-write-lock"); 24178c2ecf20Sopenharmony_ci pr_cont(" |"); 24188c2ecf20Sopenharmony_ci dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK); 24198c2ecf20Sopenharmony_ci pr_cont(" |"); 24208c2ecf20Sopenharmony_ci dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM); 24218c2ecf20Sopenharmony_ci pr_cont("\n"); 24228c2ecf20Sopenharmony_ci 24238c2ecf20Sopenharmony_ci print_testname("mixed write-read-lock"); 24248c2ecf20Sopenharmony_ci pr_cont(" |"); 24258c2ecf20Sopenharmony_ci dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK); 24268c2ecf20Sopenharmony_ci pr_cont(" |"); 24278c2ecf20Sopenharmony_ci dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); 24288c2ecf20Sopenharmony_ci pr_cont("\n"); 24298c2ecf20Sopenharmony_ci 24308c2ecf20Sopenharmony_ci print_testname("mixed read-lock/lock-write ABBA"); 24318c2ecf20Sopenharmony_ci pr_cont(" |"); 24328c2ecf20Sopenharmony_ci dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK); 24338c2ecf20Sopenharmony_ci pr_cont(" |"); 24348c2ecf20Sopenharmony_ci dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM); 24358c2ecf20Sopenharmony_ci 24368c2ecf20Sopenharmony_ci print_testname("mixed read-lock/lock-read ABBA"); 24378c2ecf20Sopenharmony_ci pr_cont(" |"); 24388c2ecf20Sopenharmony_ci dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK); 24398c2ecf20Sopenharmony_ci pr_cont(" |"); 24408c2ecf20Sopenharmony_ci dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM); 24418c2ecf20Sopenharmony_ci 24428c2ecf20Sopenharmony_ci print_testname("mixed write-lock/lock-write ABBA"); 24438c2ecf20Sopenharmony_ci pr_cont(" |"); 24448c2ecf20Sopenharmony_ci dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK); 24458c2ecf20Sopenharmony_ci pr_cont(" |"); 24468c2ecf20Sopenharmony_ci dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM); 24478c2ecf20Sopenharmony_ci 24488c2ecf20Sopenharmony_ci print_testname("chain cached mixed R-L/L-W ABBA"); 24498c2ecf20Sopenharmony_ci pr_cont(" |"); 24508c2ecf20Sopenharmony_ci dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK); 24518c2ecf20Sopenharmony_ci 24528c2ecf20Sopenharmony_ci DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1); 24538c2ecf20Sopenharmony_ci DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1); 24548c2ecf20Sopenharmony_ci DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1); 24558c2ecf20Sopenharmony_ci DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1); 24568c2ecf20Sopenharmony_ci 24578c2ecf20Sopenharmony_ci printk(" --------------------------------------------------------------------------\n"); 24588c2ecf20Sopenharmony_ci 24598c2ecf20Sopenharmony_ci /* 24608c2ecf20Sopenharmony_ci * irq-context testcases: 24618c2ecf20Sopenharmony_ci */ 24628c2ecf20Sopenharmony_ci DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1); 24638c2ecf20Sopenharmony_ci DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A); 24648c2ecf20Sopenharmony_ci DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B); 24658c2ecf20Sopenharmony_ci DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3); 24668c2ecf20Sopenharmony_ci DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4); 24678c2ecf20Sopenharmony_ci DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion); 24688c2ecf20Sopenharmony_ci 24698c2ecf20Sopenharmony_ci DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion); 24708c2ecf20Sopenharmony_ci DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2); 24718c2ecf20Sopenharmony_ci DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3); 24728c2ecf20Sopenharmony_ci 24738c2ecf20Sopenharmony_ci ww_tests(); 24748c2ecf20Sopenharmony_ci 24758c2ecf20Sopenharmony_ci force_read_lock_recursive = 0; 24768c2ecf20Sopenharmony_ci /* 24778c2ecf20Sopenharmony_ci * queued_read_lock() specific test cases can be put here 24788c2ecf20Sopenharmony_ci */ 24798c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS)) 24808c2ecf20Sopenharmony_ci queued_read_lock_tests(); 24818c2ecf20Sopenharmony_ci 24828c2ecf20Sopenharmony_ci if (unexpected_testcase_failures) { 24838c2ecf20Sopenharmony_ci printk("-----------------------------------------------------------------\n"); 24848c2ecf20Sopenharmony_ci debug_locks = 0; 24858c2ecf20Sopenharmony_ci printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n", 24868c2ecf20Sopenharmony_ci unexpected_testcase_failures, testcase_total); 24878c2ecf20Sopenharmony_ci printk("-----------------------------------------------------------------\n"); 24888c2ecf20Sopenharmony_ci } else if (expected_testcase_failures && testcase_successes) { 24898c2ecf20Sopenharmony_ci printk("--------------------------------------------------------\n"); 24908c2ecf20Sopenharmony_ci printk("%3d out of %3d testcases failed, as expected. |\n", 24918c2ecf20Sopenharmony_ci expected_testcase_failures, testcase_total); 24928c2ecf20Sopenharmony_ci printk("----------------------------------------------------\n"); 24938c2ecf20Sopenharmony_ci debug_locks = 1; 24948c2ecf20Sopenharmony_ci } else if (expected_testcase_failures && !testcase_successes) { 24958c2ecf20Sopenharmony_ci printk("--------------------------------------------------------\n"); 24968c2ecf20Sopenharmony_ci printk("All %3d testcases failed, as expected. |\n", 24978c2ecf20Sopenharmony_ci expected_testcase_failures); 24988c2ecf20Sopenharmony_ci printk("----------------------------------------\n"); 24998c2ecf20Sopenharmony_ci debug_locks = 1; 25008c2ecf20Sopenharmony_ci } else { 25018c2ecf20Sopenharmony_ci printk("-------------------------------------------------------\n"); 25028c2ecf20Sopenharmony_ci printk("Good, all %3d testcases passed! |\n", 25038c2ecf20Sopenharmony_ci testcase_successes); 25048c2ecf20Sopenharmony_ci printk("---------------------------------\n"); 25058c2ecf20Sopenharmony_ci debug_locks = 1; 25068c2ecf20Sopenharmony_ci } 25078c2ecf20Sopenharmony_ci lockdep_set_selftest_task(NULL); 25088c2ecf20Sopenharmony_ci debug_locks_silent = 0; 25098c2ecf20Sopenharmony_ci} 2510