diff options
author | linyuny <linyuny@google.com> | 2022-12-13 01:55:44 +0000 |
---|---|---|
committer | Yunyun Lin <linyuny@google.com> | 2022-12-13 20:47:00 +0000 |
commit | 1e860ff2e99b403f697b7e09991bff0c384dd2d6 (patch) | |
tree | 1a83af06aaaec015213565a5b5a15f22ef97755b | |
parent | e80e9a9a7619746a1bd527dd78d3345905b6a6ce (diff) | |
download | lwis-1e860ff2e99b403f697b7e09991bff0c384dd2d6.tar.gz |
Dump LWIS info in case of a userspace crash
1. Dump current kernel time
2. Dump Last 5 events.
Bug: 243704502
Test: manual
Change-Id: Ibc74114fa5bd619297b5ff99296d574288504320
Signed-off-by: linyuny <linyuny@google.com>
-rw-r--r-- | lwis_debug.c | 45 | ||||
-rw-r--r-- | lwis_debug.h | 2 | ||||
-rw-r--r-- | lwis_device.c | 14 | ||||
-rw-r--r-- | lwis_device.h | 7 | ||||
-rw-r--r-- | platform/anchorage/lwis_platform_anchorage.c | 2 | ||||
-rw-r--r-- | platform/busan/lwis_platform_busan.c | 2 | ||||
-rw-r--r-- | platform/casablanca/lwis_platform_casablanca.c | 2 |
7 files changed, 60 insertions, 14 deletions
diff --git a/lwis_debug.c b/lwis_debug.c index 7f35d71..90eaaeb 100644 --- a/lwis_debug.c +++ b/lwis_debug.c @@ -177,7 +177,7 @@ static int generate_device_info(struct lwis_device *lwis_dev, char *buffer, size } static int generate_event_states_info(struct lwis_device *lwis_dev, char *buffer, - size_t buffer_size) + size_t buffer_size, int lwis_event_dump_cnt) { /* Temporary buffer to be concatenated to the main buffer. */ char tmp_buf[96] = {}; @@ -186,13 +186,27 @@ static int generate_event_states_info(struct lwis_device *lwis_dev, char *buffer unsigned long flags; struct lwis_device_event_state *state; bool enabled_event_present = false; + int traverse_last_events_size; if (lwis_dev == NULL) { pr_err("Unknown LWIS device pointer\n"); return -EINVAL; } - scnprintf(buffer, buffer_size, "=== LWIS EVENT STATES INFO: %s ===\n", lwis_dev->name); + if (lwis_event_dump_cnt >= 0 && lwis_event_dump_cnt <= EVENT_DEBUG_HISTORY_SIZE) { + scnprintf(tmp_buf, sizeof(tmp_buf), "=== LWIS DUMP LAST %d Received Events ===\n", + lwis_event_dump_cnt); + strlcat(buffer, tmp_buf, buffer_size); + traverse_last_events_size = lwis_event_dump_cnt; + } else if (lwis_event_dump_cnt > EVENT_DEBUG_HISTORY_SIZE) { + pr_err("lwis_event_dump_cnt (%d) exceed EVENT_DEBUG_HISTORY_SIZE (%d) \n", + lwis_event_dump_cnt, EVENT_DEBUG_HISTORY_SIZE); + return -EINVAL; + } else { + scnprintf(buffer, buffer_size, "=== LWIS EVENT STATES INFO: %s ===\n", + lwis_dev->name); + traverse_last_events_size = EVENT_DEBUG_HISTORY_SIZE; + } spin_lock_irqsave(&lwis_dev->lock, flags); if (hash_empty(lwis_dev->event_states)) { @@ -211,9 +225,18 @@ static int generate_event_states_info(struct lwis_device *lwis_dev, char *buffer if (!enabled_event_present) { strlcat(buffer, "No enabled events\n", buffer_size); } - strlcat(buffer, "Last Events:\n", buffer_size); + if (lwis_event_dump_cnt < 0) { + strlcat(buffer, "Last Events:\n", buffer_size); + } + idx = lwis_dev->debug_info.cur_event_hist_idx; - for (i = 0; i < EVENT_DEBUG_HISTORY_SIZE; ++i) { + for (i = 0; i < traverse_last_events_size; ++i) { + if (lwis_event_dump_cnt >= 0) { + if (idx == 0) { + idx = EVENT_DEBUG_HISTORY_SIZE; + } + idx--; + } state = &lwis_dev->debug_info.event_hist[idx].state; /* Skip uninitialized entries */ if (state->event_id != 0) { @@ -223,9 +246,11 @@ static int generate_event_states_info(struct lwis_device *lwis_dev, char *buffer lwis_dev->debug_info.event_hist[idx].timestamp); strlcat(buffer, tmp_buf, buffer_size); } - idx++; - if (idx >= EVENT_DEBUG_HISTORY_SIZE) { - idx = 0; + if (lwis_event_dump_cnt < 0) { + idx++; + if (idx >= EVENT_DEBUG_HISTORY_SIZE) { + idx = 0; + } } } @@ -386,7 +411,7 @@ int lwis_debug_print_device_info(struct lwis_device *lwis_dev) return 0; } -int lwis_debug_print_event_states_info(struct lwis_device *lwis_dev) +int lwis_debug_print_event_states_info(struct lwis_device *lwis_dev, int lwis_event_dump_cnt) { int ret = 0; /* Buffer to store information */ @@ -397,7 +422,7 @@ int lwis_debug_print_event_states_info(struct lwis_device *lwis_dev) return -ENOMEM; } - ret = generate_event_states_info(lwis_dev, buffer, buffer_size); + ret = generate_event_states_info(lwis_dev, buffer, buffer_size, lwis_event_dump_cnt); if (ret) { dev_err(lwis_dev->dev, "Failed to generate event states info"); goto exit; @@ -485,7 +510,7 @@ static ssize_t event_states_read(struct file *fp, char __user *user_buf, size_t return -ENOMEM; } - ret = generate_event_states_info(lwis_dev, buffer, buffer_size); + ret = generate_event_states_info(lwis_dev, buffer, buffer_size, /*lwis_event_dump_cnt=*/-1); if (ret) { dev_err(lwis_dev->dev, "Failed to generate event states info"); goto exit; diff --git a/lwis_debug.h b/lwis_debug.h index f3defd7..4978606 100644 --- a/lwis_debug.h +++ b/lwis_debug.h @@ -16,7 +16,7 @@ void lwis_debug_save_register_io_to_history(struct lwis_device *lwis_dev, /* Functions to print debugging info */ int lwis_debug_print_device_info(struct lwis_device *lwis_dev); -int lwis_debug_print_event_states_info(struct lwis_device *lwis_dev); +int lwis_debug_print_event_states_info(struct lwis_device *lwis_dev, int lwis_event_dump_cnt); int lwis_debug_print_transaction_info(struct lwis_device *lwis_dev); int lwis_debug_print_register_io_history(struct lwis_device *lwis_dev); int lwis_debug_print_buffer_info(struct lwis_device *lwis_dev); diff --git a/lwis_device.c b/lwis_device.c index 2387f75..b6ad02a 100644 --- a/lwis_device.c +++ b/lwis_device.c @@ -236,6 +236,7 @@ static int lwis_release(struct inode *node, struct file *fp) mutex_lock(&lwis_dev->client_lock); /* Release power if client closed without power down called */ if (is_client_enabled && lwis_dev->enabled > 0) { + lwis_device_crash_info_dump(lwis_dev); lwis_dev->enabled--; if (lwis_dev->enabled == 0) { dev_info(lwis_dev->dev, "No more client, power down\n"); @@ -1160,6 +1161,19 @@ void lwis_device_info_dump(const char *name, void (*func)(struct lwis_device *)) mutex_unlock(&core.lock); } +void lwis_device_crash_info_dump(struct lwis_device *lwis_dev) +{ + int dump_cnt = 5; + int64_t timestamp; + + pr_info("LWIS Device (%s) Crash Info Dump:\n", lwis_dev->name); + + /* Dump Current kernel timestamp && Last 5 Received Event*/ + timestamp = ktime_to_ns(lwis_get_time()); + dev_info(lwis_dev->dev, " AT %lld Dump Last %d Received Events:\n\n", timestamp, dump_cnt); + lwis_debug_print_event_states_info(lwis_dev, /*lwis_event_dump_cnt=*/dump_cnt); +} + /* * lwis_base_probe: Create a device instance for each of the LWIS device. */ diff --git a/lwis_device.h b/lwis_device.h index cac60d2..ea62088 100644 --- a/lwis_device.h +++ b/lwis_device.h @@ -413,4 +413,11 @@ void lwis_dev_power_seq_list_print(struct lwis_device_power_sequence_list *list) */ void lwis_device_info_dump(const char *name, void (*func)(struct lwis_device *)); +/* + * lwis_device_crash_info_dump: + * Use the customized function handle to print information from each device registered in LWIS + * when usersapce crash. + */ +void lwis_device_crash_info_dump(struct lwis_device *lwis_dev); + #endif /* LWIS_DEVICE_H_ */ diff --git a/platform/anchorage/lwis_platform_anchorage.c b/platform/anchorage/lwis_platform_anchorage.c index 5f48c59..26355f9 100644 --- a/platform/anchorage/lwis_platform_anchorage.c +++ b/platform/anchorage/lwis_platform_anchorage.c @@ -80,7 +80,7 @@ static int lwis_iommu_fault_handler(struct iommu_fault *fault, void *param) pr_err("\n"); lwis_debug_print_transaction_info(lwis_dev); pr_err("\n"); - lwis_debug_print_event_states_info(lwis_dev); + lwis_debug_print_event_states_info(lwis_dev, /*lwis_event_dump_cnt=*/-1); pr_err("\n"); lwis_debug_print_buffer_info(lwis_dev); pr_err("\n"); diff --git a/platform/busan/lwis_platform_busan.c b/platform/busan/lwis_platform_busan.c index a6ac6a9..a34f892 100644 --- a/platform/busan/lwis_platform_busan.c +++ b/platform/busan/lwis_platform_busan.c @@ -77,7 +77,7 @@ static int lwis_iommu_fault_handler(struct iommu_fault *fault, void *param) pr_err("\n"); lwis_debug_print_transaction_info(lwis_dev); pr_err("\n"); - lwis_debug_print_event_states_info(lwis_dev); + lwis_debug_print_event_states_info(lwis_dev, /*lwis_event_dump_cnt=*/-1); pr_err("\n"); lwis_debug_print_buffer_info(lwis_dev); pr_err("\n"); diff --git a/platform/casablanca/lwis_platform_casablanca.c b/platform/casablanca/lwis_platform_casablanca.c index e2ce435..5fb952b 100644 --- a/platform/casablanca/lwis_platform_casablanca.c +++ b/platform/casablanca/lwis_platform_casablanca.c @@ -82,7 +82,7 @@ static int lwis_iommu_fault_handler(struct iommu_fault *fault, void *param) pr_err("\n"); lwis_debug_print_transaction_info(lwis_dev); pr_err("\n"); - lwis_debug_print_event_states_info(lwis_dev); + lwis_debug_print_event_states_info(lwis_dev, /*lwis_event_dump_cnt=*/-1); pr_err("\n"); lwis_debug_print_buffer_info(lwis_dev); pr_err("\n"); |