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