Doing spinlock, ticket, try, block tests, the spinlock tests are inverting lock between
spinlock and the other possibilities. Because the reservation is a locktype, those tests
will fail, FAILURE that lockdep caught an error. SUCCESS means lockdep thinks what you do
is ok:
syntax for object_reserve:
int object_reserve(object, interruptible, no_wait, ticket);
static void reservation_test_fail_reserve(void)
{
struct reservation_ticket t;
struct reservation_object o;
reservation_object_init(&o);
reservation_ticket_init(&t);
t.seqno++;
object_reserve(&o, false, false, &t);
/* No lockdep test, pure API */
WARN_ON(object_reserve(&o, false, true, &t) != -EDEADLK);
t.seqno--;
WARN_ON(object_reserve(&o, false, true, &t) != -EBUSY);
t.seqno += 2;
WARN_ON(object_reserve(&o, false, true, &t) != -EAGAIN);
object_unreserve(&o, NULL);
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);
object_reserve(&o, false, false, NULL);
object_unreserve(&o, NULL);
object_unreserve(&o, NULL);
}
static void reservation_test_fence_nest_unreserved(void)
{
struct reservation_object o;
reservation_object_init(&o);
spin_lock_nest_lock(&lock_A, &o);
spin_unlock(&lock_A);
}
static void reservation_test_ticket_block(void)
{
struct reservation_ticket t;
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
reservation_ticket_init(&t);
object_reserve(&o, false, false, &t);
object_reserve(&o2, false, false, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, &t);
reservation_ticket_fini(&t);
}
static void reservation_test_ticket_try(void)
{
struct reservation_ticket t;
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
reservation_ticket_init(&t);
object_reserve(&o, false, false, &t);
object_reserve(&o2, false, true, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, &t);
reservation_ticket_fini(&t);
}
static void reservation_test_ticket_ticket(void)
{
struct reservation_ticket t;
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
reservation_ticket_init(&t);
object_reserve(&o, false, false, &t);
object_reserve(&o2, false, false, &t);
object_unreserve(&o2, &t);
object_unreserve(&o, &t);
reservation_ticket_fini(&t);
}
static void reservation_test_try_block(void)
{
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, true, NULL);
object_reserve(&o2, false, false, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, NULL);
}
static void reservation_test_try_try(void)
{
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, true, NULL);
object_reserve(&o2, false, true, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, NULL);
}
static void reservation_test_try_ticket(void)
{
struct reservation_ticket t;
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, true, NULL);
reservation_ticket_init(&t);
object_reserve(&o2, false, false, &t);
object_unreserve(&o2, &t);
object_unreserve(&o, NULL);
reservation_ticket_fini(&t);
}
static void reservation_test_block_block(void)
{
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, false, NULL);
object_reserve(&o2, false, false, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, NULL);
}
static void reservation_test_block_try(void)
{
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, false, NULL);
object_reserve(&o2, false, true, NULL);
object_unreserve(&o2, NULL);
object_unreserve(&o, NULL);
}
static void reservation_test_block_ticket(void)
{
struct reservation_ticket t;
struct reservation_object o, o2;
reservation_object_init(&o);
reservation_object_init(&o2);
object_reserve(&o, false, false, NULL);
reservation_ticket_init(&t);
object_reserve(&o2, false, false, &t);
object_unreserve(&o2, &t);
object_unreserve(&o, NULL);
reservation_ticket_fini(&t);
}
static void reservation_test_fence_block(void)
{
struct reservation_object o;
reservation_object_init(&o);
spin_lock(&lock_A);
spin_unlock(&lock_A);
object_reserve(&o, false, false, NULL);
spin_lock(&lock_A);
spin_unlock(&lock_A);
object_unreserve(&o, NULL);
spin_lock(&lock_A);
object_reserve(&o, false, false, NULL);
object_unreserve(&o, NULL);
spin_unlock(&lock_A);
}
static void reservation_test_fence_try(void)
{
struct reservation_object o;
reservation_object_init(&o);
spin_lock(&lock_A);
spin_unlock(&lock_A);
object_reserve(&o, false, true, NULL);
spin_lock(&lock_A);
spin_unlock(&lock_A);
object_unreserve(&o, NULL);
spin_lock(&lock_A);
object_reserve(&o, false, true, NULL);
object_unreserve(&o, NULL);
spin_unlock(&lock_A);
}
static void reservation_test_fence_ticket(void)
{
struct reservation_ticket t;
struct reservation_object o;
reservation_object_init(&o);
spin_lock(&lock_A);
spin_unlock(&lock_A);
reservation_ticket_init(&t);
object_reserve(&o, false, false, &t);
spin_lock(&lock_A);
spin_unlock(&lock_A);
object_unreserve(&o, &t);
spin_lock(&lock_A);
object_reserve(&o, false, false, &t);
object_unreserve(&o, &t);
spin_unlock(&lock_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);
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");
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");
}