* this code maps all the lock dependencies as they occur in a live kernel
* and will warn about the following classes of locking bugs:
*
- * - lock inversion scenarios
- * - circular lock dependencies
+ * - lock inversion scenarios * - circular lock dependencies
* - hardirq/softirq safe/unsafe locking bugs
*
* Bugs are reported even if the current locking scenario does not cause
#include <linux/bitops.h>
#include <linux/gfp.h>
#include <linux/kmemcheck.h>
+#include <linux/aee.h>
#include <asm/sections.h>
#define lock_stat 0
#endif
+static void lockdep_aee(void)
+{
+ char aee_str[40];
+ snprintf( aee_str, 40, "[%s]LockProve Warning", current->comm);
+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DUMMY_DUMP | DB_OPT_FTRACE, aee_str,"LockProve Debug\n");
+
+}
+
/*
* lockdep_lock: protects the lockdep graph, the hashes and the
* class/list/hash allocators.
static void print_lock(struct held_lock *hlock)
{
- print_lock_name(hlock_class(hlock));
- printk(", at: ");
- print_ip_sym(hlock->acquire_ip);
+ struct lock_class *lock = hlock_class(hlock);
+ if(lock != NULL){
+ print_lock_name(lock);
+ printk(", at: ");
+ print_ip_sym(hlock->acquire_ip);
+ }
}
static void lockdep_print_held_locks(struct task_struct *curr)
printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr));
return;
}
+ if (curr->state == TASK_RUNNING)
+ printk("[Caution!] %s/%d is runable state\n", curr->comm, curr->pid);
printk("%d lock%s held by %s/%d:\n",
depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr));
if (debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
printk("\n");
printk("======================================================\n");
- printk("[ INFO: possible circular locking dependency detected ]\n");
+ printk("[ ProveLock INFO: possible circular locking dependency detected ]\n");
print_kernel_ident();
printk("-------------------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("======================================================\n");
- printk("[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
+ printk("[ ProveLock INFO: %s-safe -> %s-unsafe lock order detected ]\n",
irqclass, irqclass);
print_kernel_ident();
printk("------------------------------------------------------\n");
if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=============================================\n");
- printk("[ INFO: possible recursive locking detected ]\n");
+ printk("[ ProveLock INFO: possible recursive locking detected ]\n");
print_kernel_ident();
printk("---------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=================================\n");
- printk("[ INFO: inconsistent lock state ]\n");
+ printk("[ ProveLock INFO: inconsistent lock state ]\n");
print_kernel_ident();
printk("---------------------------------\n");
if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=========================================================\n");
- printk("[ INFO: possible irq lock inversion dependency detected ]\n");
+ printk("[ ProveLock INFO: possible irq lock inversion dependency detected ]\n");
print_kernel_ident();
printk("---------------------------------------------------------\n");
printk("%s/%d just changed the state of lock:\n",
if (debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=====================================\n");
- printk("[ BUG: bad unlock balance detected! ]\n");
+ printk("[ ProveLock BUG: bad unlock balance detected! ]\n");
print_kernel_ident();
printk("-------------------------------------\n");
printk("%s/%d is trying to release lock (",
struct lockdep_map *nest_lock, unsigned long ip)
{
unsigned long flags;
-
+ if (unlikely(!debug_locks))
+ return;
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(lock->skip==1))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
unsigned long ip)
{
unsigned long flags;
+ if (unlikely(!debug_locks))
+ return;
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(lock->skip==1))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
if (debug_locks_silent)
return 0;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=================================\n");
- printk("[ BUG: bad contention detected! ]\n");
+ printk("[ ProveLock BUG: bad contention detected! ]\n");
print_kernel_ident();
printk("---------------------------------\n");
printk("%s/%d is trying to contend lock (",
if (debug_locks_silent)
return;
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("=========================\n");
- printk("[ BUG: held lock freed! ]\n");
+ printk("[ ProveLock BUG: held lock freed! ]\n");
print_kernel_ident();
printk("-------------------------\n");
printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
}
EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
-static void print_held_locks_bug(struct task_struct *curr)
+static void print_held_locks_bug(void)
{
if (!debug_locks_off())
return;
if (debug_locks_silent)
return;
+ printk("[ ProveLock BUG: %s/%d still has locks held! ]\n",
+ current->comm, task_pid_nr(current));
+ return;
+
+ //Add by Mtk
+ lockdep_aee();
printk("\n");
printk("=====================================\n");
- printk("[ BUG: lock held at task exit time! ]\n");
+ printk("[ ProveLock BUG: %s/%d still has locks held! ]\n",
+ current->comm, task_pid_nr(current));
print_kernel_ident();
printk("-------------------------------------\n");
- printk("%s/%d is exiting with locks still held!\n",
- curr->comm, task_pid_nr(curr));
- lockdep_print_held_locks(curr);
-
+ lockdep_print_held_locks(current);
printk("\nstack backtrace:\n");
dump_stack();
}
-void debug_check_no_locks_held(struct task_struct *task)
+void debug_check_no_locks_held(void)
{
- if (unlikely(task->lockdep_depth > 0))
- print_held_locks_bug(task);
+ if (unlikely(current->lockdep_depth > 0))
+ print_held_locks_bug();
}
+EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
void debug_show_all_locks(void)
{
* if it's not sleeping (or if it's not the current
* task):
*/
- if (p->state == TASK_RUNNING && p != current)
+ if (p->state == TASK_RUNNING && p != current){
+ printk("[Caution!] %s/%d is running now\n", p->comm, p->pid);
continue;
+ }
if (p->lockdep_depth)
lockdep_print_held_locks(p);
if (!unlock)
#ifndef CONFIG_PROVE_RCU_REPEATEDLY
if (!debug_locks_off())
return;
+
#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
/* Note: the following can be executed concurrently, so be careful. */
+ //Add by Mtk
+ lockdep_aee();
+
printk("\n");
printk("===============================\n");
- printk("[ INFO: suspicious RCU usage. ]\n");
+ printk("[ ProveLock INFO: suspicious RCU usage. ]\n");
print_kernel_ident();
printk("-------------------------------\n");
printk("%s:%d %s!\n", file, line, s);