[][openwrt][mt7988][tops][add cpu utilization fetching]
[Description]
Add cpu utilization fetching and refactor debugfs of trm and tops
Via reading debugfs file(/sys/kernel/debug/tops/trm/cpu-utilization)
to fetch each core's cpu utilization
[Release-log]
N/A
Change-Id: Iff4c965294c3054a54ba92263191856cd5c722c7
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7907085
diff --git a/feed/tops-tool/src/inc/dump.h b/feed/tops-tool/src/inc/dump.h
index 0d331c9..69b4340 100644
--- a/feed/tops-tool/src/inc/dump.h
+++ b/feed/tops-tool/src/inc/dump.h
@@ -12,7 +12,7 @@
#define DUMP_INFO_NAME_MAX_LEN 32
#define RELAY_DUMP_SUBBUF_SIZE 2048
-#define DUMP_DATA_PATH "/sys/kernel/debug/tops/dump_data"
+#define DUMP_DATA_PATH "/sys/kernel/debug/tops/trm/dump-data"
#define DUMP_LOG_FMT(FMT) "[TOPS_TOOL] [%s]: " FMT, __func__
diff --git a/package-21.02/kernel/tops/src/Makefile b/package-21.02/kernel/tops/src/Makefile
index 820ebb4..845f657 100644
--- a/package-21.02/kernel/tops/src/Makefile
+++ b/package-21.02/kernel/tops/src/Makefile
@@ -24,6 +24,7 @@
tops-y += tdma.o
tops-y += trm-fs.o
tops-y += trm-mcu.o
+tops-y += trm-debugfs.o
tops-y += trm.o
tops-y += wdt.o
diff --git a/package-21.02/kernel/tops/src/inc/debugfs.h b/package-21.02/kernel/tops/src/inc/debugfs.h
new file mode 100644
index 0000000..ea1847c
--- /dev/null
+++ b/package-21.02/kernel/tops/src/inc/debugfs.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Alvin Kuo <alvin.kuo@mediatek.com>
+ */
+
+#ifndef _TOPS_DEBUGFS_H_
+#define _TOPS_DEBUGFS_H_
+
+extern struct dentry *tops_debugfs_root;
+
+#endif /* _TOPS_DEBUGFS_H_ */
diff --git a/package-21.02/kernel/tops/src/inc/mbox_id.h b/package-21.02/kernel/tops/src/inc/mbox_id.h
index bb46250..4ce3f6d 100644
--- a/package-21.02/kernel/tops/src/inc/mbox_id.h
+++ b/package-21.02/kernel/tops/src/inc/mbox_id.h
@@ -20,6 +20,7 @@
MBOX_AP2CM_CMD_CORE_CTRL = 0,
MBOX_AP2CM_CMD_NET = 1,
MBOX_AP2CM_CMD_WDT = 2,
+ MBOX_AP2CM_CMD_TRM = 3,
MBOX_AP2CM_CMD_TNL_OFFLOAD = 11,
MBOX_AP2CM_CMD_TEST = 31,
__MBOX_AP2CM_CMD_MAX = 32,
@@ -35,6 +36,7 @@
MBOX_AP2CX_CMD_CORE_CTRL = 0,
MBOX_AP2CX_CMD_NET = 1,
MBOX_AP2CX_CMD_WDT = 2,
+ MBOX_AP2CX_CMD_TRM = 3,
__MBOX_AP2CX_CMD_MAX = 32,
};
diff --git a/package-21.02/kernel/tops/src/inc/trm-debugfs.h b/package-21.02/kernel/tops/src/inc/trm-debugfs.h
new file mode 100644
index 0000000..5425485
--- /dev/null
+++ b/package-21.02/kernel/tops/src/inc/trm-debugfs.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Alvin Kuo <alvin.kuo@mediatek.com>
+ */
+
+#ifndef _TRM_DEBUGFS_H_
+#define _TRM_DEBUGFS_H_
+
+#include <linux/debugfs.h>
+
+extern struct dentry *trm_debugfs_root;
+
+int mtk_trm_debugfs_init(void);
+void mtk_trm_debugfs_deinit(void);
+#endif /* _TRM_DEBUGFS_H_ */
diff --git a/package-21.02/kernel/tops/src/inc/trm.h b/package-21.02/kernel/tops/src/inc/trm.h
index 4b5118f..2acf54a 100644
--- a/package-21.02/kernel/tops/src/inc/trm.h
+++ b/package-21.02/kernel/tops/src/inc/trm.h
@@ -56,6 +56,13 @@
#define TRM_RSN_FE_RESET (TRM_RSN(FE_RESET))
#define TRM_RSN_MCU_STATE_ACT_FAIL (TRM_RSN(MCU_STATE_ACT_FAIL))
+enum trm_cmd_type {
+ TRM_CMD_TYPE_NULL,
+ TRM_CMD_TYPE_CPU_UTILIZATION,
+
+ __TRM_CMD_TYPE_MAX,
+};
+
enum trm_config_flag {
TRM_CONFIG_F_ENABLE_BIT,
TRM_CONFIG_F_CORE_DUMP_BIT,
@@ -97,6 +104,7 @@
int (*trm_hw_dump)(void *dst, u32 ofs, u32 len);
};
+int mtk_trm_cpu_utilization(enum core_id core, u32 *cpu_utilization);
int mtk_trm_dump(u32 dump_rsn);
int mtk_trm_cfg_setup(char *name, u32 offset, u32 size, u8 enable);
int mtk_tops_trm_init(void);
diff --git a/package-21.02/kernel/tops/src/init.c b/package-21.02/kernel/tops/src/init.c
index 8c47546..05a7fe4 100644
--- a/package-21.02/kernel/tops/src/init.c
+++ b/package-21.02/kernel/tops/src/init.c
@@ -9,6 +9,7 @@
#include <linux/err.h>
#include <linux/device.h>
#include <linux/module.h>
+#include <linux/debugfs.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
@@ -29,6 +30,7 @@
#include "wdt.h"
struct device *tops_dev;
+struct dentry *tops_debugfs_root;
static int mtk_tops_post_init(struct platform_device *pdev)
{
@@ -200,6 +202,12 @@
static int __init mtk_tops_init(void)
{
+ tops_debugfs_root = debugfs_create_dir("tops", NULL);
+ if (IS_ERR(tops_debugfs_root)) {
+ TOPS_ERR("create tops debugfs root directory failed\n");
+ return PTR_ERR(tops_debugfs_root);
+ }
+
mtk_tops_mbox_init();
mtk_tops_hpdma_init();
@@ -218,6 +226,8 @@
mtk_tops_hpdma_exit();
mtk_tops_mbox_exit();
+
+ debugfs_remove_recursive(tops_debugfs_root);
}
module_init(mtk_tops_init);
diff --git a/package-21.02/kernel/tops/src/trm-debugfs.c b/package-21.02/kernel/tops/src/trm-debugfs.c
new file mode 100644
index 0000000..66c64f3
--- /dev/null
+++ b/package-21.02/kernel/tops/src/trm-debugfs.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Alvin Kuo <alvin.kuog@mediatek.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include "debugfs.h"
+#include "internal.h"
+#include "tops.h"
+#include "trm-debugfs.h"
+#include "trm.h"
+
+struct dentry *trm_debugfs_root;
+
+static int cpu_utilization_debug_read(struct seq_file *s, void *private)
+{
+ u32 cpu_utilization;
+ enum core_id core;
+ int ret;
+
+ seq_puts(s, "CPU Utilization:\n");
+ for (core = CORE_OFFLOAD_0; core <= CORE_MGMT; core++) {
+ ret = mtk_trm_cpu_utilization(core, &cpu_utilization);
+ if (ret) {
+ if (core <= CORE_OFFLOAD_3)
+ TOPS_ERR("fetch Core%d cpu utilization failed(%d)\n", core, ret);
+ else
+ TOPS_ERR("fetch CoreM cpu utilization failed(%d)\n", ret);
+
+ return ret;
+ }
+
+ if (core <= CORE_OFFLOAD_3)
+ seq_printf(s, "Core%d\t\t%u%%\n", core, cpu_utilization);
+ else
+ seq_printf(s, "CoreM\t\t%u%%\n", cpu_utilization);
+ }
+
+ return 0;
+}
+
+static int cpu_utilization_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cpu_utilization_debug_read, file->private_data);
+}
+
+static ssize_t cpu_utilization_debug_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *data)
+{
+ return count;
+}
+
+static const struct file_operations cpu_utilization_debug_ops = {
+ .open = cpu_utilization_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = cpu_utilization_debug_write,
+ .release = single_release,
+};
+
+int mtk_trm_debugfs_init(void)
+{
+ if (!tops_debugfs_root)
+ return -ENOENT;
+
+ if (!trm_debugfs_root) {
+ trm_debugfs_root = debugfs_create_dir("trm", tops_debugfs_root);
+ if (IS_ERR(trm_debugfs_root)) {
+ TOPS_ERR("create trm debugfs root directory failed\n");
+ return PTR_ERR(trm_debugfs_root);
+ }
+ }
+
+ debugfs_create_file("cpu-utilization", 0644, trm_debugfs_root, NULL,
+ &cpu_utilization_debug_ops);
+
+ return 0;
+}
+
+void mtk_trm_debugfs_deinit(void)
+{
+ debugfs_remove_recursive(trm_debugfs_root);
+}
diff --git a/package-21.02/kernel/tops/src/trm-fs.c b/package-21.02/kernel/tops/src/trm-fs.c
index 3728ee1..81ae77a 100644
--- a/package-21.02/kernel/tops/src/trm-fs.c
+++ b/package-21.02/kernel/tops/src/trm-fs.c
@@ -11,13 +11,13 @@
#include <linux/err.h>
#include <linux/relay.h>
+#include "trm-debugfs.h"
#include "trm-fs.h"
#include "trm-mcu.h"
#include "trm.h"
#define RLY_RETRY_NUM 3
-static struct dentry *debugfs_dir;
static struct rchan *relay;
static bool trm_fs_is_init;
@@ -56,7 +56,7 @@
{
struct dentry *debugfs_file;
- debugfs_file = debugfs_create_file("dump_data", mode,
+ debugfs_file = debugfs_create_file("dump-data", mode,
parent, buf,
&relay_file_operations);
@@ -80,39 +80,22 @@
};
int ret = 0;
- if (!debugfs_dir) {
- debugfs_dir = debugfs_create_dir("tops", NULL);
- if (IS_ERR(debugfs_dir)) {
- ret = PTR_ERR(debugfs_dir);
- goto out;
- }
- }
+ if (!trm_debugfs_root)
+ return -ENOENT;
if (!relay) {
- relay = relay_open("dump_data", debugfs_dir,
+ relay = relay_open("dump-data", trm_debugfs_root,
RLY_DUMP_SUBBUF_SZ,
RLY_DUMP_SUBBUF_NUM,
&relay_cb, NULL);
- if (!relay) {
- ret = -EINVAL;
- goto err_debugfs_remove;
- }
+ if (!relay)
+ return -EINVAL;
}
relay_reset(relay);
trm_fs_is_init = true;
-out:
- return ret;
-
-err_debugfs_remove:
- trm_fs_is_init = false;
-
- debugfs_remove(debugfs_dir);
-
- debugfs_dir = NULL;
-
return ret;
}
@@ -121,6 +104,4 @@
trm_fs_is_init = false;
relay_close(relay);
-
- debugfs_remove(debugfs_dir);
}
diff --git a/package-21.02/kernel/tops/src/trm-mcu.c b/package-21.02/kernel/tops/src/trm-mcu.c
index 4550122..b475dc0 100644
--- a/package-21.02/kernel/tops/src/trm-mcu.c
+++ b/package-21.02/kernel/tops/src/trm-mcu.c
@@ -14,6 +14,7 @@
#include "internal.h"
#include "mcu.h"
+#include "trm-debugfs.h"
#include "trm-fs.h"
#include "trm-mcu.h"
#include "trm.h"
@@ -342,6 +343,10 @@
if (!ocd.base)
return -ENOMEM;
+ ret = mtk_trm_debugfs_init();
+ if (ret)
+ return ret;
+
ret = mtk_trm_fs_init();
if (ret)
return ret;
@@ -355,6 +360,8 @@
{
mtk_trm_fs_deinit();
+ mtk_trm_debugfs_deinit();
+
return 0;
}
diff --git a/package-21.02/kernel/tops/src/trm.c b/package-21.02/kernel/tops/src/trm.c
index 5fdc909..a3f959f 100644
--- a/package-21.02/kernel/tops/src/trm.c
+++ b/package-21.02/kernel/tops/src/trm.c
@@ -17,6 +17,7 @@
#include <linux/relay.h>
#include <linux/types.h>
+#include "internal.h"
#include "mbox.h"
#include "mcu.h"
#include "netsys.h"
@@ -28,6 +29,11 @@
#define RLY_DUMP_SUBBUF_DATA_MAX (RLY_DUMP_SUBBUF_SZ - TRM_HDR_LEN)
+struct tops_runtime_monitor {
+ struct mailbox_dev mgmt_send_mdev;
+ struct mailbox_dev offload_send_mdev[CORE_OFFLOAD_NUM];
+};
+
struct trm_info {
char name[TRM_CONFIG_NAME_MAX_LEN];
u64 dump_time;
@@ -45,6 +51,15 @@
struct device *trm_dev;
+static struct tops_runtime_monitor trm = {
+ .mgmt_send_mdev = MBOX_SEND_MGMT_DEV(TRM),
+ .offload_send_mdev = {
+ [CORE_OFFLOAD_0] = MBOX_SEND_OFFLOAD_DEV(0, TRM),
+ [CORE_OFFLOAD_1] = MBOX_SEND_OFFLOAD_DEV(1, TRM),
+ [CORE_OFFLOAD_2] = MBOX_SEND_OFFLOAD_DEV(2, TRM),
+ [CORE_OFFLOAD_3] = MBOX_SEND_OFFLOAD_DEV(3, TRM),
+ },
+};
static struct trm_hw_config *trm_hw_configs[__TRM_HARDWARE_MAX];
struct mutex trm_lock;
@@ -202,6 +217,55 @@
mtk_trm_fs_relay_flush();
}
+ return 0;
+}
+
+static void trm_cpu_utilization_ret_handler(void *priv,
+ struct mailbox_msg *msg)
+{
+ u32 *cpu_utilization = priv;
+
+ /*
+ * msg1: ticks of idle task
+ * msg2: ticks of this statistic period
+ */
+ if (msg->msg2 != 0)
+ *cpu_utilization = (msg->msg2 - msg->msg1) * 100U / msg->msg2;
+}
+
+int mtk_trm_cpu_utilization(enum core_id core, u32 *cpu_utilization)
+{
+ struct mailbox_dev *send_mdev;
+ struct mailbox_msg msg;
+ int ret;
+
+ if (core > CORE_MGMT || !cpu_utilization)
+ return -EINVAL;
+
+ if (!mtk_tops_mcu_alive()) {
+ TRM_ERR("mcu not alive\n");
+ return -EAGAIN;
+ }
+
+ memset(&msg, 0, sizeof(struct mailbox_msg));
+ msg.msg1 = TRM_CMD_TYPE_CPU_UTILIZATION;
+
+ *cpu_utilization = 0;
+
+ if (core == CORE_MGMT)
+ send_mdev = &trm.mgmt_send_mdev;
+ else
+ send_mdev = &trm.offload_send_mdev[core];
+
+ ret = mbox_send_msg(send_mdev,
+ &msg,
+ cpu_utilization,
+ trm_cpu_utilization_ret_handler);
+ if (ret) {
+ TRM_ERR("send CPU_UTILIZATION cmd failed(%d)\n", ret);
+ return ret;
+ }
+
return 0;
}
@@ -253,15 +317,64 @@
return ret;
}
+static int mtk_tops_trm_register_mbox(void)
+{
+ int ret;
+ int i;
+
+ ret = register_mbox_dev(MBOX_SEND, &trm.mgmt_send_mdev);
+ if (ret) {
+ TRM_ERR("register trm mgmt mbox send failed: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < CORE_OFFLOAD_NUM; i++) {
+ ret = register_mbox_dev(MBOX_SEND, &trm.offload_send_mdev[i]);
+ if (ret) {
+ TRM_ERR("register trm offload %d mbox send failed: %d\n",
+ i, ret);
+ goto err_unregister_offload_mbox;
+ }
+ }
+
+ return ret;
+
+err_unregister_offload_mbox:
+ for (i -= 1; i >= 0; i--)
+ unregister_mbox_dev(MBOX_SEND, &trm.offload_send_mdev[i]);
+
+ unregister_mbox_dev(MBOX_SEND, &trm.mgmt_send_mdev);
+
+ return ret;
+}
+
+static void mtk_tops_trm_unregister_mbox(void)
+{
+ int i;
+
+ unregister_mbox_dev(MBOX_SEND, &trm.mgmt_send_mdev);
+
+ for (i = 0; i < CORE_OFFLOAD_NUM; i++)
+ unregister_mbox_dev(MBOX_SEND, &trm.offload_send_mdev[i]);
+}
+
int __init mtk_tops_trm_init(void)
{
+ int ret;
+
mutex_init(&trm_lock);
+ ret = mtk_tops_trm_register_mbox();
+ if (ret)
+ return ret;
+
return mtk_tops_trm_mcu_init();
}
void __exit mtk_tops_trm_exit(void)
{
+ mtk_tops_trm_unregister_mbox();
+
mtk_tops_trm_mcu_exit();
}