OSDN Git Service

drm/msm: limit sde_dbg_dump output to current entries
authorLakshmi Narayana Kalavala <lkalaval@codeaurora.org>
Mon, 26 Feb 2018 23:06:22 +0000 (15:06 -0800)
committerLakshmi Narayana Kalavala <lkalaval@codeaurora.org>
Sat, 17 Mar 2018 00:25:34 +0000 (17:25 -0700)
Update the sde_dbg_dump function to only dump event log
entries up to the time the dump is initiated, and increase
the number of recorded event log entries.

This places a limit on the total number of entries that are
output to the dmesg log even if more entries would have been
added while the dump is executing (e.g., interrupt events),
while still allowing the extra events to be recorded properly.

Change-Id: I66f850d21a2d0217f9049facffce074831b7e17d
Signed-off-by: Clarence Ip <cip@codeaurora.org>
Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
drivers/gpu/drm/msm/sde_dbg.c
drivers/gpu/drm/msm/sde_dbg.h
drivers/gpu/drm/msm/sde_dbg_evtlog.c

index 66c9844..c886950 100644 (file)
@@ -165,6 +165,7 @@ struct sde_dbg_vbif_debug_bus {
  * @enable_reg_dump: whether to dump registers into memory, kernel log, or both
  * @dbgbus_sde: debug bus structure for the sde
  * @dbgbus_vbif_rt: debug bus structure for the realtime vbif
+ * @dump_all: dump all entries in register dump
  */
 static struct sde_dbg_base {
        struct sde_dbg_evtlog *evtlog;
@@ -183,6 +184,7 @@ static struct sde_dbg_base {
 
        struct sde_dbg_sde_debug_bus dbgbus_sde;
        struct sde_dbg_vbif_debug_bus dbgbus_vbif_rt;
+       bool dump_all;
        u32 debugfs_ctrl;
 } sde_dbg_base;
 
@@ -1452,7 +1454,7 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
  */
 static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
        u32 len, bool do_panic, const char *name, bool dump_dbgbus_sde,
-       bool dump_dbgbus_vbif_rt)
+       bool dump_dbgbus_vbif_rt, bool dump_all)
 {
        int i;
 
@@ -1464,7 +1466,8 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
                                sde_dbg_base.enable_reg_dump);
        }
 
-       sde_evtlog_dump_all(sde_dbg_base.evtlog);
+       if (dump_all)
+               sde_evtlog_dump_all(sde_dbg_base.evtlog);
 
        if (dump_dbgbus_sde)
                _sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_sde);
@@ -1488,7 +1491,8 @@ static void _sde_dump_work(struct work_struct *work)
                ARRAY_SIZE(sde_dbg_base.req_dump_blks),
                sde_dbg_base.work_panic, "evtlog_workitem",
                sde_dbg_base.dbgbus_sde.cmn.include_in_deferred_work,
-               sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work);
+               sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work,
+               sde_dbg_base.dump_all);
 }
 
 void sde_dbg_dump(bool queue_work, const char *name, ...)
@@ -1497,6 +1501,7 @@ void sde_dbg_dump(bool queue_work, const char *name, ...)
        bool do_panic = false;
        bool dump_dbgbus_sde = false;
        bool dump_dbgbus_vbif_rt = false;
+       bool dump_all = false;
        va_list args;
        char *blk_name = NULL;
        struct sde_dbg_reg_base *blk_base = NULL;
@@ -1514,6 +1519,7 @@ void sde_dbg_dump(bool queue_work, const char *name, ...)
 
        memset(sde_dbg_base.req_dump_blks, 0,
                        sizeof(sde_dbg_base.req_dump_blks));
+       sde_dbg_base.dump_all = false;
 
        va_start(args, name);
        i = 0;
@@ -1535,6 +1541,8 @@ void sde_dbg_dump(bool queue_work, const char *name, ...)
                                                blk_name);
                        }
                }
+               if (!strcmp(blk_name, "all"))
+                       dump_all = true;
 
                if (!strcmp(blk_name, "dbg_bus"))
                        dump_dbgbus_sde = true;
@@ -1554,10 +1562,11 @@ void sde_dbg_dump(bool queue_work, const char *name, ...)
                                dump_dbgbus_sde;
                sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work =
                                dump_dbgbus_vbif_rt;
+               sde_dbg_base.dump_all = dump_all;
                schedule_work(&sde_dbg_base.dump_work);
        } else {
                _sde_dump_array(blk_arr, blk_len, do_panic, name,
-                               dump_dbgbus_sde, dump_dbgbus_vbif_rt);
+                               dump_dbgbus_sde, dump_dbgbus_vbif_rt, dump_all);
        }
 }
 
@@ -1633,7 +1642,7 @@ static ssize_t sde_evtlog_dump_read(struct file *file, char __user *buff,
                return -EINVAL;
 
        len = sde_evtlog_dump_to_buffer(sde_dbg_base.evtlog, evtlog_buf,
-                       SDE_EVTLOG_BUF_MAX);
+                       SDE_EVTLOG_BUF_MAX, true);
        if (copy_to_user(buff, evtlog_buf, len))
                return -EFAULT;
        *ppos += len;
index 95528ef..ce36cba 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/list.h>
 
-#define SDE_EVTLOG_DATA_LIMITER        (-1)
+#define SDE_EVTLOG_DATA_LIMITER        (0xC0DEBEEF)
 #define SDE_EVTLOG_FUNC_ENTRY  0x1111
 #define SDE_EVTLOG_FUNC_EXIT   0x2222
+#define SDE_EVTLOG_ERROR       0xebad
 
 #define SDE_DBG_DUMP_DATA_LIMITER (NULL)
 
@@ -52,7 +53,7 @@ enum sde_dbg_dump_flag {
  * number must be greater than print entry to prevent out of bound evtlog
  * entry array access.
  */
-#define SDE_EVTLOG_ENTRY       (SDE_EVTLOG_PRINT_ENTRY * 4)
+#define SDE_EVTLOG_ENTRY       (SDE_EVTLOG_PRINT_ENTRY * 8)
 #define SDE_EVTLOG_MAX_DATA 15
 #define SDE_EVTLOG_BUF_MAX 512
 #define SDE_EVTLOG_BUF_ALIGN 32
@@ -77,6 +78,7 @@ struct sde_dbg_evtlog {
        struct sde_dbg_evtlog_log logs[SDE_EVTLOG_ENTRY];
        u32 first;
        u32 last;
+       u32 last_dump;
        u32 curr;
        u32 next;
        u32 enable;
@@ -179,10 +181,12 @@ bool sde_evtlog_is_enabled(struct sde_dbg_evtlog *evtlog, u32 flag);
  * @evtlog:            pointer to evtlog
  * @evtlog_buf:                target buffer to print into
  * @evtlog_buf_size:   size of target buffer
+ * @update_last_entry:ยป       whether or not to stop at most recent entry
  * Returns:            number of bytes written to buffer
  */
 ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
-               char *evtlog_buf, ssize_t evtlog_buf_size);
+               char *evtlog_buf, ssize_t evtlog_buf_size,
+               bool update_last_entry);
 
 /**
  * sde_dbg_init_dbg_buses - initialize debug bus dumping support for the chipset
@@ -288,7 +292,8 @@ static inline bool sde_evtlog_is_enabled(struct sde_dbg_evtlog *evtlog,
 }
 
 static inline ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
-               char *evtlog_buf, ssize_t evtlog_buf_size)
+               char *evtlog_buf, ssize_t evtlog_buf_size,
+               bool update_last_entry)
 {
        return 0;
 }
index 759bdab..70ba127 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -75,7 +75,8 @@ void sde_evtlog_log(struct sde_dbg_evtlog *evtlog, const char *name, int line,
 }
 
 /* always dump the last entries which are not dumped yet */
-static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog)
+static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog,
+       bool update_last_entry)
 {
        bool need_dump = true;
        unsigned long flags;
@@ -87,21 +88,26 @@ static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog)
 
        evtlog->first = evtlog->next;
 
-       if (evtlog->last == evtlog->first) {
+       if (update_last_entry)
+               evtlog->last_dump = evtlog->last;
+
+       if (evtlog->last_dump == evtlog->first) {
                need_dump = false;
                goto dump_exit;
        }
 
-       if (evtlog->last < evtlog->first) {
+       if (evtlog->last_dump < evtlog->first) {
                evtlog->first %= SDE_EVTLOG_ENTRY;
-               if (evtlog->last < evtlog->first)
-                       evtlog->last += SDE_EVTLOG_ENTRY;
+               if (evtlog->last_dump < evtlog->first)
+                       evtlog->last_dump += SDE_EVTLOG_ENTRY;
        }
 
-       if ((evtlog->last - evtlog->first) > SDE_EVTLOG_PRINT_ENTRY) {
-               pr_warn("evtlog buffer overflow before dump: %d\n",
-                       evtlog->last - evtlog->first);
-               evtlog->first = evtlog->last - SDE_EVTLOG_PRINT_ENTRY;
+       if ((evtlog->last_dump - evtlog->first) > SDE_EVTLOG_PRINT_ENTRY) {
+               pr_info("evtlog skipping %d entries, last=%d\n",
+                       evtlog->last_dump - evtlog->first -
+                       SDE_EVTLOG_PRINT_ENTRY,
+                       evtlog->last_dump - 1);
+               evtlog->first = evtlog->last_dump - SDE_EVTLOG_PRINT_ENTRY;
        }
        evtlog->next = evtlog->first + 1;
 
@@ -112,7 +118,8 @@ dump_exit:
 }
 
 ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
-               char *evtlog_buf, ssize_t evtlog_buf_size)
+               char *evtlog_buf, ssize_t evtlog_buf_size,
+               bool update_last_entry)
 {
        int i;
        ssize_t off = 0;
@@ -123,7 +130,7 @@ ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
                return 0;
 
        /* update markers, exit if nothing to print */
-       if (!_sde_evtlog_dump_calc_range(evtlog))
+       if (!_sde_evtlog_dump_calc_range(evtlog, update_last_entry))
                return 0;
 
        spin_lock_irqsave(&evtlog->spin_lock, flags);
@@ -159,12 +166,16 @@ ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
 void sde_evtlog_dump_all(struct sde_dbg_evtlog *evtlog)
 {
        char buf[SDE_EVTLOG_BUF_MAX];
+       bool update_last_entry = true;
 
        if (!evtlog)
                return;
 
-       while (sde_evtlog_dump_to_buffer(evtlog, buf, sizeof(buf)))
+       while (sde_evtlog_dump_to_buffer(evtlog, buf, sizeof(buf),
+               update_last_entry)) {
                pr_info("%s", buf);
+               update_last_entry = false;
+       }
 }
 
 struct sde_dbg_evtlog *sde_evtlog_init(void)