Lines Matching +full:class +full:- +full:d

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Module-based API test facility for ww_mutexes
23 (a)->deadlock_inject_countdown = ~0U; \
45 complete(&mtx->ready); in test_mutex_work()
46 wait_for_completion(&mtx->go); in test_mutex_work()
48 if (mtx->flags & TEST_MTX_TRY) { in test_mutex_work()
49 while (!ww_mutex_trylock(&mtx->mutex, NULL)) in test_mutex_work()
52 ww_mutex_lock(&mtx->mutex, NULL); in test_mutex_work()
54 complete(&mtx->done); in test_mutex_work()
55 ww_mutex_unlock(&mtx->mutex); in test_mutex_work()
58 static int __test_mutex(struct ww_class *class, unsigned int flags) in __test_mutex() argument
65 ww_mutex_init(&mtx.mutex, class); in __test_mutex()
67 ww_acquire_init(&ctx, class); in __test_mutex()
86 ret = -EINVAL; in __test_mutex()
101 ret = -EINVAL; in __test_mutex()
110 static int test_mutex(struct ww_class *class) in test_mutex() argument
116 ret = __test_mutex(class, i); in test_mutex()
124 static int test_aa(struct ww_class *class, bool trylock) in test_aa() argument
131 ww_mutex_init(&mutex, class); in test_aa()
132 ww_acquire_init(&ctx, class); in test_aa()
151 ret = -EINVAL; in test_aa()
158 ret = -EINVAL; in test_aa()
163 if (ret != -EALREADY) { in test_aa()
164 pr_err("%s: missed deadlock for recursing, ret=%d from %s\n", in test_aa()
168 ret = -EINVAL; in test_aa()
181 struct ww_class *class; member
196 ww_acquire_init_noinject(&ctx, abba->class); in test_abba_work()
197 if (!abba->trylock) in test_abba_work()
198 ww_mutex_lock(&abba->b_mutex, &ctx); in test_abba_work()
200 WARN_ON(!ww_mutex_trylock(&abba->b_mutex, &ctx)); in test_abba_work()
202 WARN_ON(READ_ONCE(abba->b_mutex.ctx) != &ctx); in test_abba_work()
204 complete(&abba->b_ready); in test_abba_work()
205 wait_for_completion(&abba->a_ready); in test_abba_work()
207 err = ww_mutex_lock(&abba->a_mutex, &ctx); in test_abba_work()
208 if (abba->resolve && err == -EDEADLK) { in test_abba_work()
209 ww_mutex_unlock(&abba->b_mutex); in test_abba_work()
210 ww_mutex_lock_slow(&abba->a_mutex, &ctx); in test_abba_work()
211 err = ww_mutex_lock(&abba->b_mutex, &ctx); in test_abba_work()
215 ww_mutex_unlock(&abba->a_mutex); in test_abba_work()
216 ww_mutex_unlock(&abba->b_mutex); in test_abba_work()
219 abba->result = err; in test_abba_work()
222 static int test_abba(struct ww_class *class, bool trylock, bool resolve) in test_abba() argument
228 ww_mutex_init(&abba.a_mutex, class); in test_abba()
229 ww_mutex_init(&abba.b_mutex, class); in test_abba()
233 abba.class = class; in test_abba()
239 ww_acquire_init_noinject(&ctx, class); in test_abba()
251 if (resolve && err == -EDEADLK) { in test_abba()
268 pr_err("%s: failed to resolve ABBA deadlock, A err=%d, B err=%d\n", in test_abba()
270 ret = -EINVAL; in test_abba()
273 if (err != -EDEADLK && abba.result != -EDEADLK) { in test_abba()
274 pr_err("%s: missed ABBA deadlock, A err=%d, B err=%d\n", in test_abba()
276 ret = -EINVAL; in test_abba()
284 struct ww_class *class; member
298 ww_acquire_init_noinject(&ctx, cycle->class); in test_cycle_work()
299 ww_mutex_lock(&cycle->a_mutex, &ctx); in test_cycle_work()
301 complete(cycle->a_signal); in test_cycle_work()
302 wait_for_completion(&cycle->b_signal); in test_cycle_work()
304 err = ww_mutex_lock(cycle->b_mutex, &ctx); in test_cycle_work()
305 if (err == -EDEADLK) { in test_cycle_work()
307 ww_mutex_unlock(&cycle->a_mutex); in test_cycle_work()
308 ww_mutex_lock_slow(cycle->b_mutex, &ctx); in test_cycle_work()
309 erra = ww_mutex_lock(&cycle->a_mutex, &ctx); in test_cycle_work()
313 ww_mutex_unlock(cycle->b_mutex); in test_cycle_work()
315 ww_mutex_unlock(&cycle->a_mutex); in test_cycle_work()
318 cycle->result = err ?: erra; in test_cycle_work()
321 static int __test_cycle(struct ww_class *class, unsigned int nthreads) in __test_cycle() argument
324 unsigned int n, last = nthreads - 1; in __test_cycle()
329 return -ENOMEM; in __test_cycle()
334 cycle->class = class; in __test_cycle()
335 ww_mutex_init(&cycle->a_mutex, class); in __test_cycle()
337 cycle->b_mutex = &cycles[0].a_mutex; in __test_cycle()
339 cycle->b_mutex = &cycles[n + 1].a_mutex; in __test_cycle()
342 cycle->a_signal = &cycles[last].b_signal; in __test_cycle()
344 cycle->a_signal = &cycles[n - 1].b_signal; in __test_cycle()
345 init_completion(&cycle->b_signal); in __test_cycle()
347 INIT_WORK(&cycle->work, test_cycle_work); in __test_cycle()
348 cycle->result = 0; in __test_cycle()
360 if (!cycle->result) in __test_cycle()
363 pr_err("cyclic deadlock not resolved, ret[%d/%d] = %d\n", in __test_cycle()
364 n, nthreads, cycle->result); in __test_cycle()
365 ret = -EINVAL; in __test_cycle()
375 static int test_cycle(struct ww_class *class, unsigned int ncpus) in test_cycle() argument
381 ret = __test_cycle(class, n); in test_cycle()
392 struct ww_class *class; member
422 for (n = count - 1; n > 1; n--) { in get_random_order()
439 const int nlocks = stress->nlocks; in stress_inorder_work()
440 struct ww_mutex *locks = stress->locks; in stress_inorder_work()
449 int contended = -1; in stress_inorder_work()
452 ww_acquire_init(&ctx, stress->class); in stress_inorder_work()
469 while (n--) in stress_inorder_work()
472 if (err == -EDEADLK) { in stress_inorder_work()
473 if (!time_after(jiffies, stress->timeout)) { in stress_inorder_work()
481 pr_err_once("stress (%s) failed with %d\n", in stress_inorder_work()
485 } while (!time_after(jiffies, stress->timeout)); in stress_inorder_work()
504 order = get_random_order(stress->nlocks); in stress_reorder_work()
508 for (n = 0; n < stress->nlocks; n++) { in stress_reorder_work()
513 ll->lock = &stress->locks[order[n]]; in stress_reorder_work()
514 list_add(&ll->link, &locks); in stress_reorder_work()
520 ww_acquire_init(&ctx, stress->class); in stress_reorder_work()
523 err = ww_mutex_lock(ll->lock, &ctx); in stress_reorder_work()
529 ww_mutex_unlock(ln->lock); in stress_reorder_work()
531 if (err != -EDEADLK) { in stress_reorder_work()
532 pr_err_once("stress (%s) failed with %d\n", in stress_reorder_work()
537 ww_mutex_lock_slow(ll->lock, &ctx); in stress_reorder_work()
538 list_move(&ll->link, &locks); /* restarts iteration */ in stress_reorder_work()
543 ww_mutex_unlock(ll->lock); in stress_reorder_work()
546 } while (!time_after(jiffies, stress->timeout)); in stress_reorder_work()
557 const int nlocks = stress->nlocks; in stress_one_work()
558 struct ww_mutex *lock = stress->locks + get_random_u32_below(nlocks); in stress_one_work()
567 pr_err_once("stress (%s) failed with %d\n", in stress_one_work()
571 } while (!time_after(jiffies, stress->timeout)); in stress_one_work()
579 static int stress(struct ww_class *class, int nlocks, int nthreads, unsigned int flags) in stress() argument
587 return -ENOMEM; in stress()
592 return -ENOMEM; in stress()
596 ww_mutex_init(&locks[n], class); in stress()
624 INIT_WORK(&stress->work, fn); in stress()
625 stress->class = class; in stress()
626 stress->locks = locks; in stress()
627 stress->nlocks = nlocks; in stress()
628 stress->timeout = jiffies + 2*HZ; in stress()
630 queue_work(wq, &stress->work); in stress()
631 nthreads--; in stress()
644 static int run_tests(struct ww_class *class) in run_tests() argument
649 ret = test_mutex(class); in run_tests()
653 ret = test_aa(class, false); in run_tests()
657 ret = test_aa(class, true); in run_tests()
662 ret = test_abba(class, i & 1, i & 2); in run_tests()
667 ret = test_cycle(class, ncpus); in run_tests()
671 ret = stress(class, 16, 2 * ncpus, STRESS_INORDER); in run_tests()
675 ret = stress(class, 16, 2 * ncpus, STRESS_REORDER); in run_tests()
679 ret = stress(class, 2046, hweight32(STRESS_ALL) * ncpus, STRESS_ALL); in run_tests()
741 wq = alloc_workqueue("test-ww_mutex", WQ_UNBOUND, 0); in test_ww_mutex_init()
743 return -ENOMEM; in test_ww_mutex_init()
748 return -ENOMEM; in test_ww_mutex_init()