import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / lib / spinlock_debug.c
index 0374a596cffac8439d36875ba2bd248753caf886..ef1d767f4bc6b596d567ab47f5576bd0a9c6f8aa 100644 (file)
 #include <linux/debug_locks.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/aee.h>
+
+extern int InDumpAllStack;
+
 
 void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
                          struct lock_class_key *key)
@@ -59,20 +64,28 @@ static void spin_dump(raw_spinlock_t *lock, const char *msg)
                msg, raw_smp_processor_id(),
                current->comm, task_pid_nr(current));
        printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "
-                       ".owner_cpu: %d\n",
+                       ".owner_cpu: %d value:0x%08x\n",
                lock, lock->magic,
                owner ? owner->comm : "<none>",
                owner ? task_pid_nr(owner) : -1,
-               lock->owner_cpu);
+               lock->owner_cpu, *((unsigned int *)&lock->raw_lock));
        dump_stack();
 }
 
 static void spin_bug(raw_spinlock_t *lock, const char *msg)
 {
-       if (!debug_locks_off())
-               return;
-
-       spin_dump(lock, msg);
+    char aee_str[50];
+//  if (!debug_locks_off())
+//      return;
+
+    spin_dump(lock, msg);
+    snprintf( aee_str, 50, "Spinlock %s :%s\n", current->comm, msg);
+    if(!strcmp(msg,"bad magic")){
+        printk("[spin lock debug] bad magic:%08x, should be %08x, may use an un-initial spin_lock or mem corrupt\n", lock->magic, SPINLOCK_MAGIC);
+        printk(">>>>>>>>>>>>>> Let's KE <<<<<<<<<<<<<<\n");
+        BUG_ON(1);
+    }
+    aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DUMMY_DUMP | DB_OPT_FTRACE, aee_str,"spinlock debugger\n");
 }
 
 #define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
@@ -103,11 +116,57 @@ static inline void debug_spin_unlock(raw_spinlock_t *lock)
        lock->owner_cpu = -1;
 }
 
+/*
+ Select appropriate loop counts to 1~2sec
+*/
+#if HZ == 100
+#define LOOP_HZ 100 // temp 10 
+#elif HZ == 10
+#define LOOP_HZ 2 // temp 2
+#else
+#define LOOP_HZ HZ
+#endif
+#define WARNING_TIME 1000000000                // warning time 1 seconds
 static void __spin_lock_debug(raw_spinlock_t *lock)
 {
+#ifdef CONFIG_MTK_MUTATION
        u64 i;
-       u64 loops = loops_per_jiffy * HZ;
+       u64 loops = loops_per_jiffy * LOOP_HZ;
+       int print_once = 1;
+    char aee_str[50];
+    unsigned long long t1,t2;
+    t1 = sched_clock();
+    t2 = t1;
+       for (;;) {
+               for (i = 0; i < loops; i++) {
+                       if (arch_spin_trylock(&lock->raw_lock))
+                               return;
+                       __delay(1);
+               }
+               if(sched_clock() - t2 < WARNING_TIME*3) continue;
+               t2 = sched_clock();
+#ifdef CONFIG_MTK_AEE_FEATURE
+               if((oops_in_progress != 0) || (InDumpAllStack == 1)) continue;  // in exception follow, printk maybe spinlock error
+#else
+               if(oops_in_progress != 0) continue;  // in exception follow, printk maybe spinlock error
+#endif
+               /* lockup suspected: */
+        printk("spin time: %llu ns(start:%llu ns, lpj:%lu, LPHZ:%d), value: 0x%08x\n", sched_clock() - t1, t1, loops_per_jiffy, (int)LOOP_HZ, *((unsigned int *)&lock->raw_lock));
+               if (print_once) {
+                       print_once = 0;
+               spin_dump(lock, "lockup suspected");
+#ifdef CONFIG_SMP
+                       trigger_all_cpu_backtrace();
+#endif
+            debug_show_all_locks();
+            snprintf( aee_str, 50, "Spinlock lockup:%s\n", current->comm);
+            aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DUMMY_DUMP | DB_OPT_FTRACE, aee_str,"spinlock debugger\n");
 
+               }
+       }
+#else //CONFIG_MTK_MUTATION
+       u64 i;
+       u64 loops = loops_per_jiffy * HZ;
        for (i = 0; i < loops; i++) {
                if (arch_spin_trylock(&lock->raw_lock))
                        return;
@@ -128,6 +187,7 @@ static void __spin_lock_debug(raw_spinlock_t *lock)
         * progress.
         */
        arch_spin_lock(&lock->raw_lock);
+#endif //CONFIG_MTK_MUTATION
 }
 
 void do_raw_spin_lock(raw_spinlock_t *lock)