diff --git a/scheduler/inc/scheduler_api.h b/scheduler/inc/scheduler_api.h index fa13775753..b4e98a4d21 100644 --- a/scheduler/inc/scheduler_api.h +++ b/scheduler/inc/scheduler_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -92,6 +92,15 @@ struct scheduler_msg { #endif /* WLAN_SCHED_HISTORY_SIZE */ }; +/** + * sched_history_print() - print scheduler history + * + * This API prints the scheduler history. + * + * Return: None + */ +void sched_history_print(void); + typedef QDF_STATUS (*scheduler_msg_process_fn_t) (struct scheduler_msg *msg); typedef void (*hdd_suspend_callback)(void); diff --git a/scheduler/src/scheduler_core.c b/scheduler/src/scheduler_core.c index 055af4fff5..10d90548ab 100644 --- a/scheduler/src/scheduler_core.c +++ b/scheduler/src/scheduler_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,6 +28,15 @@ DEFINE_QDF_FLEX_MEM_POOL(sched_pool, sizeof(struct scheduler_msg), #ifdef WLAN_SCHED_HISTORY_SIZE +#define SCHEDULER_HISTORY_HEADER "|Callback "\ + "|Message Type" \ + "|Queue Duration(us)|Queue Depth" \ + "|Run Duration(us)|" + +#define SCHEDULER_HISTORY_LINE "--------------------------------------" \ + "--------------------------------------" \ + "--------------------------------------" + /** * struct sched_history_item - metrics for a scheduler message * @callback: the message's execution callback @@ -87,12 +96,52 @@ static void sched_history_stop(void) sched_history_index %= WLAN_SCHED_HISTORY_SIZE; } +void sched_history_print(void) +{ + struct sched_history_item *history, *item; + uint32_t history_idx; + uint32_t idx, index; + + history = qdf_mem_malloc(sizeof(*history) * WLAN_SCHED_HISTORY_SIZE); + + if (!history) { + sched_err("Mem alloc failed"); + return; + } + + qdf_mem_copy(history, &sched_history, + (sizeof(*history) * WLAN_SCHED_HISTORY_SIZE)); + history_idx = sched_history_index; + + sched_nofl_fatal(SCHEDULER_HISTORY_LINE); + sched_nofl_fatal(SCHEDULER_HISTORY_HEADER); + sched_nofl_fatal(SCHEDULER_HISTORY_LINE); + + for (idx = 0; idx < WLAN_SCHED_HISTORY_SIZE; idx++) { + index = (history_idx + idx) % WLAN_SCHED_HISTORY_SIZE; + item = history + index; + + if (!item->callback) + continue; + + sched_nofl_fatal("%40pF|%12d|%18d|%11d|%16d|", + item->callback, item->type_id, + item->queue_duration_us, + item->queue_depth, + item->run_duration_us); + } + + sched_nofl_fatal(SCHEDULER_HISTORY_LINE); + + qdf_mem_free(history); +} #else /* WLAN_SCHED_HISTORY_SIZE */ static inline void sched_history_queue(struct scheduler_mq_type *queue, struct scheduler_msg *msg) { } static inline void sched_history_start(struct scheduler_msg *msg) { } static inline void sched_history_stop(void) { } +void sched_history_print(void) { } #endif /* WLAN_SCHED_HISTORY_SIZE */