From patchwork Thu Feb 28 10:25:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 15149 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A0C4823E2E for ; Thu, 28 Feb 2013 10:25:33 +0000 (UTC) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by fiordland.canonical.com (Postfix) with ESMTP id 1B3A2A18851 for ; Thu, 28 Feb 2013 10:25:33 +0000 (UTC) Received: by mail-vc0-f171.google.com with SMTP id fy7so1105367vcb.30 for ; Thu, 28 Feb 2013 02:25:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:to:from:date:message-id:in-reply-to:references :user-agent:mime-version:cc:subject:x-beenthere:x-mailman-version :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:content-type:content-transfer-encoding :sender:errors-to:x-gm-message-state; bh=zOSra3MMB4zpSZvFYJ7EKTqdjg4xE26Z/7lcaFkpu/A=; b=QVj3ZCUQ+wZ3jy1i8BFVUtQdnN1DQbaIpHNfLBjnf0MGnWgyvSl6ROMHcbyWUKml0H bqK6CLQDTrqrf/LU8c5InY0t9XFTbeqyaOHXYGy6BH0zt5l9t5UGUnuOfBSH8N9S7+OJ YmWLKkYxkKswWp516XvOwbrTX88Lf/Djzx66udJSkiOPlJ/KpKJvmH8ZxewnxiOyPmIE mCuxUBqHCDX8WegcMQUoWD9AYLWmR0DUa4HqI2PyA5SE42+M6QG9vw077W7GnJb14AUy 5PzDyFX15noEPG8OKlsRZbm3latjc2w0KkvoCVGVvq1eCC9c2IWlqiNEWcZRvJspH24q aV9A== X-Received: by 10.58.84.164 with SMTP id a4mr2401685vez.9.1362047132524; Thu, 28 Feb 2013 02:25:32 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp217641veb; Thu, 28 Feb 2013 02:25:31 -0800 (PST) X-Received: by 10.204.154.151 with SMTP id o23mr2127860bkw.17.1362047131014; Thu, 28 Feb 2013 02:25:31 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id gu18si1663501bkc.7.2013.02.28.02.25.30; Thu, 28 Feb 2013 02:25:30 -0800 (PST) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1UB0g3-0003hb-VE; Thu, 28 Feb 2013 10:25:28 +0000 Received: from adelie.canonical.com ([91.189.90.139]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1UB0g2-0003hU-7V for linaro-mm-sig@lists.linaro.org; Thu, 28 Feb 2013 10:25:26 +0000 Received: from lillypilly.canonical.com ([91.189.89.62]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1UB0fr-0001nm-QV; Thu, 28 Feb 2013 10:25:16 +0000 Received: by lillypilly.canonical.com (Postfix, from userid 3489) id C82C626C2174; Thu, 28 Feb 2013 10:25:15 +0000 (UTC) To: linux-kernel@vger.kernel.org From: Maarten Lankhorst Date: Thu, 28 Feb 2013 11:25:12 +0100 Message-ID: <20130228102512.15191.3060.stgit@patser> In-Reply-To: <20130228102452.15191.22673.stgit@patser> References: <20130228102452.15191.22673.stgit@patser> User-Agent: StGit/0.15 MIME-Version: 1.0 Cc: linux-arch@vger.kernel.org, a.p.zijlstra@chello.nl, x86@kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, robclark@gmail.com, tglx@linutronix.de, mingo@elte.hu, linux-media@vger.kernel.org Subject: [Linaro-mm-sig] [PATCH v2 3/3] reservation: Add tests to lib/locking-selftest.c. v2 X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQlO2DimCZgN22/jNjvbDO4iKOH62XXAnbCoDSGqguqyHKCgVEtdVIo3PcMyC8Wl+Ob8t5Zb This stresses the lockdep code in some ways specifically useful to reservations. It adds checks for most of the common locking errors. Since the lockdep tests were originally written to stress the reservation code, I duplicated some of the definitions into lib/locking-selftest.c for now. This will be cleaned up later when the api for reservations is accepted. I don't expect the tests to change, since the discussion is mostly about the fence aspect of reservations. Changes since v1: - Add tests to verify reservation_id is untouched. - Use L() and U() macros where possible. Signed-off-by: Maarten Lankhorst --- lib/locking-selftest.c | 588 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 569 insertions(+), 19 deletions(-) diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index c3eb261..2c52c0e 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -26,6 +26,67 @@ */ static unsigned int debug_locks_verbose; +/* + * These definitions are from the reservation objects patch series. + * For now we have to define it ourselves here. These definitions will + * be removed upon acceptance of that patch series. + */ +static const char reservation_object_name[] = "reservation_object"; +static struct lock_class_key reservation_object_class; +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static const char reservation_ticket_name[] = "reservation_ticket"; +static struct lock_class_key reservation_ticket_class; +#endif + +struct reservation_object { + struct ticket_mutex lock; +}; + +struct reservation_ticket { + unsigned long seqno; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif +}; + +static inline void +reservation_object_init(struct reservation_object *obj) +{ + __ticket_mutex_init(&obj->lock, reservation_object_name, + &reservation_object_class); +} + +static inline void +reservation_object_fini(struct reservation_object *obj) +{ + mutex_destroy(&obj->lock.base); +} + +static inline void +reservation_ticket_init(struct reservation_ticket *t) +{ +#ifdef CONFIG_DEBUG_LOCK_ALLOC + /* + * Make sure we are not reinitializing a held ticket: + */ + + debug_check_no_locks_freed((void *)t, sizeof(*t)); + lockdep_init_map(&t->dep_map, reservation_ticket_name, + &reservation_ticket_class, 0); +#endif + mutex_acquire(&t->dep_map, 0, 0, _THIS_IP_); + t->seqno = 5; +} + +static inline void +reservation_ticket_fini(struct reservation_ticket *t) +{ +#ifdef CONFIG_DEBUG_LOCK_ALLOC + mutex_release(&t->dep_map, 0, _THIS_IP_); + t->seqno = 0; +#endif +} + static int __init setup_debug_locks_verbose(char *str) { get_option(&str, &debug_locks_verbose); @@ -42,6 +103,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); #define LOCKTYPE_RWLOCK 0x2 #define LOCKTYPE_MUTEX 0x4 #define LOCKTYPE_RWSEM 0x8 +#define LOCKTYPE_RESERVATION 0x10 /* * Normal standalone locks, for the circular and irq-context @@ -920,11 +982,17 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) static void reset_locks(void) { local_irq_disable(); + lockdep_free_key_range(&reservation_object_class, 1); + lockdep_free_key_range(&reservation_ticket_class, 1); + I1(A); I1(B); I1(C); I1(D); I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); lockdep_reset(); I2(A); I2(B); I2(C); I2(D); init_shared_classes(); + + memset(&reservation_object_class, 0, sizeof(reservation_object_class)); + memset(&reservation_ticket_class, 0, sizeof(reservation_ticket_class)); local_irq_enable(); } @@ -938,7 +1006,6 @@ static int unexpected_testcase_failures; static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) { unsigned long saved_preempt_count = preempt_count(); - int expected_failure = 0; WARN_ON(irqs_disabled()); @@ -946,26 +1013,16 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) /* * Filter out expected failures: */ + if (debug_locks != expected) { #ifndef CONFIG_PROVE_LOCKING - if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected) - expected_failure = 1; - if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected) - expected_failure = 1; - if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected) - expected_failure = 1; - if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected) - expected_failure = 1; + expected_testcase_failures++; + printk("failed|"); +#else + unexpected_testcase_failures++; + printk("FAILED|"); + + dump_stack(); #endif - if (debug_locks != expected) { - if (expected_failure) { - expected_testcase_failures++; - printk("failed|"); - } else { - unexpected_testcase_failures++; - - printk("FAILED|"); - dump_stack(); - } } else { testcase_successes++; printk(" ok |"); @@ -1108,6 +1165,497 @@ static inline void print_testname(const char *testname) DO_TESTCASE_6IRW(desc, name, 312); \ DO_TESTCASE_6IRW(desc, name, 321); +static void reservation_test_fail_reserve(void) +{ + struct reservation_ticket t; + struct reservation_object o; + int ret; + + reservation_object_init(&o); + reservation_ticket_init(&t); + t.seqno++; + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + + BUG_ON(!atomic_long_read(&o.lock.reservation_id)); + + /* No lockdep test, pure API */ + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret != -EDEADLK); + + t.seqno++; + ret = mutex_trylock(&o.lock.base); + WARN_ON(ret); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret != -EAGAIN); + mutex_unlock(&o.lock.base); + + if (mutex_trylock(&o.lock.base)) + mutex_unlock(&o.lock.base); +#ifdef CONFIG_DEBUG_LOCK_ALLOC + else + DEBUG_LOCKS_WARN_ON(1); +#endif + + reservation_ticket_fini(&t); +} + +static void reservation_test_normal(void) +{ + struct reservation_object o; + struct reservation_ticket t; + int ret; + + reservation_object_init(&o); + reservation_ticket_init(&t); + + /* + * test if reservation_id is kept identical if not + * called with any of the reserve_* locking calls + */ + + /* mutex_lock (and indirectly, mutex_lock_nested) */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + mutex_lock(&o.lock.base); + mutex_unlock(&o.lock.base); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + /* mutex_lock_interruptible (and *_nested) */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + ret = mutex_lock_interruptible(&o.lock.base); + if (!ret) + mutex_unlock(&o.lock.base); + else + WARN_ON(1); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + /* mutex_lock_killable (and *_nested) */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + ret = mutex_lock_killable(&o.lock.base); + if (!ret) + mutex_unlock(&o.lock.base); + else + WARN_ON(1); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + /* trylock, succeeding */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + if (ret) + mutex_unlock(&o.lock.base); + else + WARN_ON(1); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + /* trylock, failing */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + mutex_lock(&o.lock.base); + ret = mutex_trylock(&o.lock.base); + WARN_ON(ret); + mutex_unlock(&o.lock.base); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + /* nest_lock */ + atomic_long_set(&o.lock.reservation_id, ~0UL); + mutex_lock_nest_lock(&o.lock.base, &t); + mutex_unlock(&o.lock.base); + WARN_ON(atomic_long_read(&o.lock.reservation_id) != ~0UL); + + reservation_ticket_fini(&t); +} + +static void reservation_test_two_tickets(void) +{ + struct reservation_ticket t, t2; + + reservation_ticket_init(&t); + reservation_ticket_init(&t2); + + reservation_ticket_fini(&t2); + reservation_ticket_fini(&t); +} + +static void reservation_test_ticket_unreserve_twice(void) +{ + struct reservation_ticket t; + + reservation_ticket_init(&t); + reservation_ticket_fini(&t); + reservation_ticket_fini(&t); +} + +static void reservation_test_object_unreserve_twice(void) +{ + struct reservation_object o; + + reservation_object_init(&o); + mutex_lock(&o.lock.base); + mutex_unlock(&o.lock.base); + mutex_unlock(&o.lock.base); +} + +static void reservation_test_fence_nest_unreserved(void) +{ + struct reservation_object o; + + reservation_object_init(&o); + + raw_spin_lock_nest_lock(&lock_A, &o.lock.base); + U(A); +} + +static void reservation_test_mismatch_normal_reserve(void) +{ + struct reservation_object o; + + reservation_object_init(&o); + + mutex_lock(&o.lock.base); + mutex_unreserve_unlock(&o.lock); +} + +static void reservation_test_mismatch_reserve_normal(void) +{ + struct reservation_ticket t; + struct reservation_object o; + int ret; + + reservation_ticket_init(&t); + reservation_object_init(&o); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + mutex_unlock(&o.lock.base); + + /* + * the second mutex_reserve_lock will detect the + * mismatch of the first one + */ + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + mutex_unreserve_unlock(&o.lock); + + reservation_ticket_fini(&t); +} + +static void reservation_test_mismatch_reserve_normal_slow(void) +{ + struct reservation_ticket t; + struct reservation_object o; + int ret; + + reservation_ticket_init(&t); + reservation_object_init(&o); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + mutex_unlock(&o.lock.base); + + /* + * the second mutex_reserve_lock will detect the + * mismatch of the first one + */ + mutex_reserve_lock_slow(&o.lock, &t, t.seqno); + mutex_unreserve_unlock(&o.lock); + + reservation_ticket_fini(&t); +} + +static void reservation_test_ticket_block(void) +{ + struct reservation_ticket t; + struct reservation_object o, o2; + int ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + mutex_lock(&o2.lock.base); + mutex_unlock(&o2.lock.base); + mutex_unreserve_unlock(&o.lock); + + reservation_ticket_fini(&t); +} + +static void reservation_test_ticket_try(void) +{ + struct reservation_ticket t; + struct reservation_object o, o2; + int ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + + ret = mutex_trylock(&o2.lock.base); + WARN_ON(!ret); + mutex_unlock(&o2.lock.base); + mutex_unreserve_unlock(&o.lock); + + reservation_ticket_fini(&t); +} + +static void reservation_test_ticket_ticket(void) +{ + struct reservation_ticket t; + struct reservation_object o, o2; + int ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + + ret = mutex_reserve_lock(&o2.lock, &t, t.seqno); + WARN_ON(ret); + + mutex_unreserve_unlock(&o2.lock); + mutex_unreserve_unlock(&o.lock); + + reservation_ticket_fini(&t); +} + +static void reservation_test_try_block(void) +{ + struct reservation_object o, o2; + bool ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + + mutex_lock(&o2.lock.base); + mutex_unlock(&o2.lock.base); + mutex_unlock(&o.lock.base); +} + +static void reservation_test_try_try(void) +{ + struct reservation_object o, o2; + bool ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + ret = mutex_trylock(&o2.lock.base); + WARN_ON(!ret); + mutex_unlock(&o2.lock.base); + mutex_unlock(&o.lock.base); +} + +static void reservation_test_try_ticket(void) +{ + struct reservation_ticket t; + struct reservation_object o, o2; + int ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o2.lock, &t, t.seqno); + WARN_ON(ret); + + mutex_unreserve_unlock(&o2.lock); + mutex_unlock(&o.lock.base); + + reservation_ticket_fini(&t); +} + +static void reservation_test_block_block(void) +{ + struct reservation_object o, o2; + + reservation_object_init(&o); + reservation_object_init(&o2); + + mutex_lock(&o.lock.base); + mutex_lock(&o2.lock.base); + mutex_unlock(&o2.lock.base); + mutex_unlock(&o.lock.base); +} + +static void reservation_test_block_try(void) +{ + struct reservation_object o, o2; + bool ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + + mutex_lock(&o.lock.base); + ret = mutex_trylock(&o2.lock.base); + WARN_ON(!ret); + mutex_unlock(&o2.lock.base); + mutex_unlock(&o.lock.base); +} + +static void reservation_test_block_ticket(void) +{ + struct reservation_ticket t; + struct reservation_object o, o2; + int ret; + + reservation_object_init(&o); + reservation_object_init(&o2); + + mutex_lock(&o.lock.base); + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o2.lock, &t, t.seqno); + WARN_ON(ret); + mutex_unreserve_unlock(&o2.lock); + mutex_unlock(&o.lock.base); + + reservation_ticket_fini(&t); +} + +static void reservation_test_fence_block(void) +{ + struct reservation_object o; + + reservation_object_init(&o); + L(A); + U(A); + + mutex_lock(&o.lock.base); + L(A); + U(A); + mutex_unlock(&o.lock.base); + + L(A); + mutex_lock(&o.lock.base); + mutex_unlock(&o.lock.base); + U(A); +} + +static void reservation_test_fence_try(void) +{ + struct reservation_object o; + bool ret; + + reservation_object_init(&o); + L(A); + U(A); + + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + L(A); + U(A); + mutex_unlock(&o.lock.base); + + L(A); + ret = mutex_trylock(&o.lock.base); + WARN_ON(!ret); + mutex_unlock(&o.lock.base); + U(A); +} + +static void reservation_test_fence_ticket(void) +{ + struct reservation_ticket t; + struct reservation_object o; + int ret; + + reservation_object_init(&o); + L(A); + U(A); + + reservation_ticket_init(&t); + + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + L(A); + U(A); + mutex_unreserve_unlock(&o.lock); + + L(A); + ret = mutex_reserve_lock(&o.lock, &t, t.seqno); + WARN_ON(ret); + mutex_unreserve_unlock(&o.lock); + U(A); + + reservation_ticket_fini(&t); +} + +static void reservation_tests(void) +{ + printk(" --------------------------------------------------------------------------\n"); + printk(" | Reservation tests |\n"); + printk(" ---------------------\n"); + + print_testname("reservation api failures"); + dotest(reservation_test_fail_reserve, SUCCESS, LOCKTYPE_RESERVATION); + dotest(reservation_test_normal, SUCCESS, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("reserving two tickets"); + dotest(reservation_test_two_tickets, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("unreserve ticket twice"); + dotest(reservation_test_ticket_unreserve_twice, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("unreserve object twice"); + dotest(reservation_test_object_unreserve_twice, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("spinlock nest unreserved"); + dotest(reservation_test_fence_nest_unreserved, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("mutex reserve (un)lock mismatch"); + dotest(reservation_test_mismatch_normal_reserve, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_mismatch_reserve_normal, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_mismatch_reserve_normal_slow, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + printk(" -----------------------------------------------------\n"); + printk(" |block | try |ticket|\n"); + printk(" -----------------------------------------------------\n"); + + print_testname("ticket"); + dotest(reservation_test_ticket_block, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_ticket_try, SUCCESS, LOCKTYPE_RESERVATION); + dotest(reservation_test_ticket_ticket, SUCCESS, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("try"); + dotest(reservation_test_try_block, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_try_try, SUCCESS, LOCKTYPE_RESERVATION); + dotest(reservation_test_try_ticket, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("block"); + dotest(reservation_test_block_block, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_block_try, SUCCESS, LOCKTYPE_RESERVATION); + dotest(reservation_test_block_ticket, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); + + print_testname("spinlock"); + dotest(reservation_test_fence_block, FAILURE, LOCKTYPE_RESERVATION); + dotest(reservation_test_fence_try, SUCCESS, LOCKTYPE_RESERVATION); + dotest(reservation_test_fence_ticket, FAILURE, LOCKTYPE_RESERVATION); + printk("\n"); +} void locking_selftest(void) { @@ -1188,6 +1736,8 @@ void locking_selftest(void) DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion); // DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2); + reservation_tests(); + if (unexpected_testcase_failures) { printk("-----------------------------------------------------------------\n"); debug_locks = 0;