Pārlūkot izejas kodu

qcacmn: Add API to print scheduler history

The scheduler maintains a history of the recent messages
in the scheduler that were queued, started or completed execution.

This information can be reviewed while debugging issues
if the scheduler is taking longer to process any message.

The new API will print the scheduler history on request.

Change-Id: I2ed7989296f6891cfd9779e7b96383253d680f51
CRs-Fixed: 2599281
Vivek 5 gadi atpakaļ
vecāks
revīzija
f28396d060
2 mainītis faili ar 60 papildinājumiem un 2 dzēšanām
  1. 10 1
      scheduler/inc/scheduler_api.h
  2. 50 1
      scheduler/src/scheduler_core.c

+ 10 - 1
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);
 

+ 50 - 1
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 */