[ERD][NEUS7920-76] [COMMON] lib: dss: support to output notifier call functions
authorHosung Kim <hosung0.kim@samsung.com>
Wed, 11 Jul 2018 06:31:00 +0000 (15:31 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 30 Aug 2019 07:58:56 +0000 (16:58 +0900)
On reboot/panic/occuring itmon, notifier call adding from device
function breaks system sometime.
This commit prevents such a situation to output reboot/panic notifier
like following.

debug-snapshot: panic_notifier_list -> hung_task_panic call +
debug-snapshot: panic_notifier_list -> hung_task_panic call -
debug-snapshot: panic_notifier_list -> exynos_cs_panic_handler call +
debug-snapshot: panic_notifier_list -> exynos_cs_panic_handler call -

Change-Id: Iec9bc3afe77a928a12d1138acd42bf02e3706bb4
Signed-off-by: Hosung Kim <hosung0.kim@samsung.com>
drivers/soc/samsung/debug/exynos9610-itmon.c
include/linux/debug-snapshot.h
kernel/notifier.c
kernel/reboot.c
lib/debug-snapshot-log.c

index 1f0e0c0bbf65d0dd3e00c4ea18da90683beb70af..69f0b0a8492e0684f879b01ce28aa4638ade8db8 100644 (file)
@@ -491,7 +491,7 @@ struct itmon_panic_block {
 };
 
 /* declare notifier_list */
-static ATOMIC_NOTIFIER_HEAD(itmon_notifier_list);
+ATOMIC_NOTIFIER_HEAD(itmon_notifier_list);
 
 static const struct of_device_id itmon_dt_match[] = {
        {.compatible = "samsung,exynos-itmon",
index 00aef34ccdb4f3eea9581ab6aff6eb0744e870e7..7605449b1673dbf0a1c9aa18064760bf4c211a45 100644 (file)
@@ -25,6 +25,7 @@ extern void dbg_snapshot_work(void *worker, void *v_task, void *fn, int en);
 extern void dbg_snapshot_cpuidle(char *modes, unsigned state, int diff, int en);
 extern void dbg_snapshot_suspend(void *fn, void *dev, int en);
 extern void dbg_snapshot_irq(int irq, void *fn, void *val, int en);
+extern void dbg_snapshot_print_notifier_call(void **nl, unsigned long func, int en);
 extern int dbg_snapshot_try_enable(const char *name, unsigned long long duration);
 extern int dbg_snapshot_set_enable(const char *name, int en);
 extern int dbg_snapshot_get_enable(const char *name);
@@ -256,6 +257,13 @@ extern void dbg_snapshot_soc_helper_init(void);
 static inline void dbg_snapshot_bug_func(void) {BUG();}
 static inline void dbg_snapshot_spin_func(void) {do {wfi();} while(1);}
 
+extern struct atomic_notifier_head restart_handler_list;
+extern struct blocking_notifier_head reboot_notifier_list;
+
+#ifdef CONFIG_EXYNOS_ITMON
+extern struct atomic_notifier_head itmon_notifier_list;
+#endif
+
 /**
  * dsslog_flag - added log information supported.
  * @DSS_FLAG_REQ: Generally, marking starting request something
index 6196af8a82230024ba98647c7fe946bf842bd102..04cdce49998a35c3723ad953a9e018c4a7f0f6ac 100644 (file)
@@ -90,7 +90,11 @@ static int notifier_call_chain(struct notifier_block **nl,
                        continue;
                }
 #endif
+               dbg_snapshot_print_notifier_call((void **)nl,
+                               (unsigned long)nb->notifier_call, DSS_FLAG_IN);
                ret = nb->notifier_call(nb, val, v);
+               dbg_snapshot_print_notifier_call((void **)nl,
+                               (unsigned long)nb->notifier_call, DSS_FLAG_OUT);
 
                if (nr_calls)
                        (*nr_calls)++;
index bd30a973fe946b03916a1eeb873928adfe1b32b0..f56409a3e1b53895fec1f8065e43802f451b5622 100644 (file)
@@ -108,7 +108,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
  *     Notifier list for kernel code which wants to be called
  *     to restart the system.
  */
-static ATOMIC_NOTIFIER_HEAD(restart_handler_list);
+ATOMIC_NOTIFIER_HEAD(restart_handler_list);
 
 /**
  *     register_restart_handler - Register function to be called to reset
index 2073fd214afb302eadf2a5e3c9dc5f9266257e9b..028c2fc48cd1f1e6378758f114d7760f1aba7e31 100644 (file)
@@ -1056,6 +1056,36 @@ void dbg_snapshot_pmu(int id, const char *func_name, int mode)
 }
 #endif
 
+static struct notifier_block **dss_should_check_nl[] = {
+       (struct notifier_block **)(&panic_notifier_list.head),
+       (struct notifier_block **)(&reboot_notifier_list.head),
+       (struct notifier_block **)(&restart_handler_list.head),
+#ifdef CONFIG_EXYNOS_ITMON
+       (struct notifier_block **)(&itmon_notifier_list.head),
+#endif
+};
+
+void dbg_snapshot_print_notifier_call(void **nl, unsigned long func, int en)
+{
+       struct notifier_block **nl_org = (struct notifier_block **)nl;
+       char notifier_name[KSYM_NAME_LEN];
+       char notifier_func_name[KSYM_NAME_LEN];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dss_should_check_nl); i++) {
+               if (nl_org == dss_should_check_nl[i]) {
+                       lookup_symbol_name((unsigned long)nl_org, notifier_name);
+                       lookup_symbol_name((unsigned long)func, notifier_func_name);
+
+                       pr_info("debug-snapshot: %s -> %s call %s\n",
+                               notifier_name,
+                               notifier_func_name,
+                               en == DSS_FLAG_IN ? "+" : "-");
+                       break;
+               }
+       }
+}
+
 #ifdef CONFIG_DEBUG_SNAPSHOT_FREQ
 static void dbg_snapshot_print_freqinfo(void)
 {