lockdep: Print proper scenario if cross deadlock detected at acquisition time For a potential deadlock about CROSSRELEASE as follow: P1 P2 =========== ============= lock(A) lock(X) lock(A) commit(X) A: normal lock, X: cross lock , we could detect it at two places: 1. commit time: We have run P1 first, and have dependency A --> X in graph, and then we run P2, and find the deadlock. 2. acquisition time: We have run P2 first, and have dependency X --> A, in graph(because another P3 may run previously and is acquiring for lock X), and then we run P1 and find the deadlock. In current print_circular_lock_scenario(), for 1) we could print the right scenario and note that's a deadlock related to CROSSRELEASE, however for 2) we print the scenario as a normal lockdep deadlock. It's better to print a proper scenario related to CROSSRELEASE to help users find their bugs more easily, so improve this. Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 48440f1..4a60b41 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c
@@ -1156,6 +1156,23 @@ print_circular_lock_scenario(struct held_lock *src, __print_lock_name(target); printk(KERN_CONT ");\n"); printk("\n *** DEADLOCK ***\n\n"); + } else if (cross_lock(src->instance)) { + printk(" Possible unsafe locking scenario by crosslock:\n\n"); + printk(" CPU0 CPU1\n"); + printk(" ---- ----\n"); + printk(" lock("); + __print_lock_name(target); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(source); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(parent == source ? target : parent); + printk(KERN_CONT ");\n"); + printk(" unlock("); + __print_lock_name(source); + printk(KERN_CONT ");\n"); + printk("\n *** DEADLOCK ***\n\n"); } else { printk(" Possible unsafe locking scenario:\n\n"); printk(" CPU0 CPU1\n");