From: Lakshmi Narayana Kalavala Date: Mon, 26 Feb 2018 23:06:22 +0000 (-0800) Subject: drm/msm: limit sde_dbg_dump output to current entries X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1f9861ad386a36c435cf664c5a99e0e15de54c00;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git drm/msm: limit sde_dbg_dump output to current entries 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 Signed-off-by: Lakshmi Narayana Kalavala --- diff --git a/drivers/gpu/drm/msm/sde_dbg.c b/drivers/gpu/drm/msm/sde_dbg.c index 66c9844fdf26..c886950e5212 100644 --- a/drivers/gpu/drm/msm/sde_dbg.c +++ b/drivers/gpu/drm/msm/sde_dbg.c @@ -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; diff --git a/drivers/gpu/drm/msm/sde_dbg.h b/drivers/gpu/drm/msm/sde_dbg.h index 95528eff6afa..ce36cba08039 100644 --- a/drivers/gpu/drm/msm/sde_dbg.h +++ b/drivers/gpu/drm/msm/sde_dbg.h @@ -17,9 +17,10 @@ #include #include -#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; } diff --git a/drivers/gpu/drm/msm/sde_dbg_evtlog.c b/drivers/gpu/drm/msm/sde_dbg_evtlog.c index 759bdab48840..70ba127ceb08 100644 --- a/drivers/gpu/drm/msm/sde_dbg_evtlog.c +++ b/drivers/gpu/drm/msm/sde_dbg_evtlog.c @@ -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)