summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlinyuny <linyuny@google.com>2022-12-13 01:55:44 +0000
committerYunyun Lin <linyuny@google.com>2022-12-13 20:47:00 +0000
commit1e860ff2e99b403f697b7e09991bff0c384dd2d6 (patch)
tree1a83af06aaaec015213565a5b5a15f22ef97755b
parente80e9a9a7619746a1bd527dd78d3345905b6a6ce (diff)
downloadlwis-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.c45
-rw-r--r--lwis_debug.h2
-rw-r--r--lwis_device.c14
-rw-r--r--lwis_device.h7
-rw-r--r--platform/anchorage/lwis_platform_anchorage.c2
-rw-r--r--platform/busan/lwis_platform_busan.c2
-rw-r--r--platform/casablanca/lwis_platform_casablanca.c2
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");