From 3706435bad81f9844e3f58a16a73479148e6081d Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Wed, 6 Sep 2023 15:12:14 +0800 Subject: [PATCH 1/6] add unified collection driver Signed-off-by: zhouhaifeng --- drivers/staging/Kconfig | 1 + drivers/staging/Makefile | 1 + drivers/staging/ucollection/Kconfig | 5 + drivers/staging/ucollection/Makefile | 3 + .../ucollection/ucollection_process_cpu.c | 114 ++++++++++++++++++ .../ucollection/ucollection_process_cpu.h | 5 + .../ucollection/unified_collection_data.h | 22 ++++ .../ucollection/unified_collection_driver.c | 93 ++++++++++++++ 8 files changed, 244 insertions(+) create mode 100644 drivers/staging/ucollection/Kconfig create mode 100644 drivers/staging/ucollection/Makefile create mode 100644 drivers/staging/ucollection/ucollection_process_cpu.c create mode 100644 drivers/staging/ucollection/ucollection_process_cpu.h create mode 100644 drivers/staging/ucollection/unified_collection_data.h create mode 100644 drivers/staging/ucollection/unified_collection_driver.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 6efe436abd9b..51fb00602a14 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -130,4 +130,5 @@ source "drivers/staging/hungtask/Kconfig" source "drivers/staging/blackbox/Kconfig" +source "drivers/staging/ucollection/Kconfig" endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 9dacda71f751..a8824bb550b4 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -55,3 +55,4 @@ obj-$(CONFIG_HISYSEVENT) += hisysevent/ obj-$(CONFIG_DFX_ZEROHUNG) += zerohung/ obj-$(CONFIG_DFX_HUNGTASK) += hungtask/ obj-$(CONFIG_BLACKBOX) += blackbox/ +obj-$(CONFIG_UNIFIED_COLLECTION) += ucollection/ diff --git a/drivers/staging/ucollection/Kconfig b/drivers/staging/ucollection/Kconfig new file mode 100644 index 000000000000..c356bbea11f5 --- /dev/null +++ b/drivers/staging/ucollection/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +config UNIFIED_COLLECTION + tristate "Enable unified collection" + help + unified collection \ No newline at end of file diff --git a/drivers/staging/ucollection/Makefile b/drivers/staging/ucollection/Makefile new file mode 100644 index 000000000000..5d1b45ebc9fd --- /dev/null +++ b/drivers/staging/ucollection/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_UNIFIED_COLLECTION) += ucollection_process_cpu.o +obj-$(CONFIG_UNIFIED_COLLECTION) += unified_collection_driver.o \ No newline at end of file diff --git a/drivers/staging/ucollection/ucollection_process_cpu.c b/drivers/staging/ucollection/ucollection_process_cpu.c new file mode 100644 index 000000000000..9f8a083c3f8e --- /dev/null +++ b/drivers/staging/ucollection/ucollection_process_cpu.c @@ -0,0 +1,114 @@ +#include "ucollection_process_cpu.h" + +#ifdef CONFIG_CPU_FREQ_TIMES +#include +#endif // CONFIG_CPU_FREQ_TIMES +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) +#include +#include +#include +#endif // LINUX_VERSION_CODE +#ifdef CONFIG_SMT_MODE_GOV +#include +#endif // CONFIG_SMT_MODE_GOV + +#include "unified_collection_data.h" + +#define DMIPS_NUM 16 +#define NS_TO_MS 1000000 +static char dmips_values[DMIPS_NUM]; + +unsigned long long __attribute__((weak)) +get_proc_cpu_load(struct task_struct *task, char dmips_values[], unsigned int dmips_num) +{ + return 0; +} + +static int get_cpu_num(void) +{ + int core_num = 0; + int i = 0; + for_each_possible_cpu(i) + core_num++; + return core_num; +} + +static unsigned long long get_process_load_cputime(struct task_struct *task) +{ + unsigned long long proc_load_cputime = 0; + proc_load_cputime = get_proc_cpu_load(task, dmips_values, DMIPS_NUM); + return proc_load_cputime; +} + +static unsigned long long get_process_usage_cputime(struct task_struct *task) +{ + unsigned long long utime, stime, sum_time; + unsigned long long cputime; + + thread_group_cputime_adjusted(task, &utime, &stime); + sum_time = utime + stime + task->signal->cutime + task->signal->cstime; + cputime = (unsigned long)(sum_time / NS_TO_MS); + return cputime; +} + +static int get_process_load(struct task_struct *task, int cpu_num, int cur_count, struct ucollection_process_cpu_entry __user *entry) +{ + struct ucollection_process_cpu_item proc_cpu_entry; + memset(&proc_cpu_entry, 0, sizeof(struct ucollection_process_cpu_item)); + proc_cpu_entry.pid = task->pid; + proc_cpu_entry.cpu_load_time = get_process_load_cputime(task); + proc_cpu_entry.cpu_usage_time = get_process_usage_cputime(task); + copy_to_user(&entry->datas[cur_count], &proc_cpu_entry, sizeof(struct ucollection_process_cpu_item)); + return 0; +} + +static long collect_process_cpu(void __user *argp) +{ + int cpu_num = 0; + struct task_struct *task = NULL; + struct ucollection_process_cpu_entry kentry; + struct ucollection_process_cpu_entry __user *entry = argp; + pr_info("do collect process cpu"); + if (entry == NULL) { + pr_err("cpu entry is null"); + return -EINVAL; + } + + memset(&kentry, 0, sizeof(struct ucollection_process_cpu_entry)); + copy_from_user(&kentry, entry, sizeof(struct ucollection_process_cpu_entry)); + + cpu_num = get_cpu_num(); + rcu_read_lock(); + task = &init_task; + for_each_process(task) { + if (task->pid != task->tgid) + continue; + + if (kentry.cur_count >= kentry.total_count) { + pr_err("process over total count"); + break; + } + get_process_load(task, cpu_num, kentry.cur_count, entry); + kentry.cur_count++; + } + put_user(kentry.cur_count, &entry->cur_count); + rcu_read_unlock(); + return 0; +} + +long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp) +{ + long ret = 0; + pr_info("handle ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); + switch(cmd) { + case IOCTRL_COLLECT_CPU: + ret = collect_process_cpu(argp); + break; + default: + ret = 0; + } + return ret; +} \ No newline at end of file diff --git a/drivers/staging/ucollection/ucollection_process_cpu.h b/drivers/staging/ucollection/ucollection_process_cpu.h new file mode 100644 index 000000000000..9ec5c2ae8f09 --- /dev/null +++ b/drivers/staging/ucollection/ucollection_process_cpu.h @@ -0,0 +1,5 @@ +#ifndef __UCOLLECTION_PROCESS_CPU__ +#define __UCOLLECTION_PROCESS_CPU__ + +long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp); +#endif // __UCOLLECTION_PROCESS_CPU__ diff --git a/drivers/staging/ucollection/unified_collection_data.h b/drivers/staging/ucollection/unified_collection_data.h new file mode 100644 index 000000000000..f5bac3403f88 --- /dev/null +++ b/drivers/staging/ucollection/unified_collection_data.h @@ -0,0 +1,22 @@ +#ifndef __UNIFIED_COLLECTION_DATA__ +#define __UNIFIED_COLLECTION_DATA__ + +#include + +struct ucollection_process_cpu_item { + int pid; + unsigned long long cpu_usage_time; + unsigned long long cpu_load_time; +}; + +struct ucollection_process_cpu_entry { + int magic; + int total_count; + int cur_count; + struct ucollection_process_cpu_item datas[]; +}; + +#define IOCTRL_COLLECT_CPU_BASE 0 +#define IOCTRL_COLLECT_CPU _IOWR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) + +#endif // __UNIFIED_COLLECTION_DATA__ \ No newline at end of file diff --git a/drivers/staging/ucollection/unified_collection_driver.c b/drivers/staging/ucollection/unified_collection_driver.c new file mode 100644 index 000000000000..4f82f0022f35 --- /dev/null +++ b/drivers/staging/ucollection/unified_collection_driver.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +#ifdef CONFIG_COMPAT +#include +#endif // CONFIG_COMPAT + +#include "ucollection_process_cpu.h" + +#define PROCESS_NAME "hiview" + +static long (*unified_collection_ioctl_cb[])(unsigned int cmd, void __user *argp) = { + unified_collection_collect_process_cpu /* IOCTRL_COLLECT_CPU */ +}; + +static long unified_collection_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + void __user *argp = u64_to_user_ptr(arg); + const char *comm = NULL; + + pr_info("recv ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); + comm = current->group_leader ? current->group_leader->comm : current->comm; + // if (!strstr(comm, PROCESS_NAME)) + // return -EINVAL; + + if ((_IOC_TYPE(cmd) >= ARRAY_SIZE(unified_collection_ioctl_cb)) || + (unified_collection_ioctl_cb[_IOC_TYPE(cmd)] == NULL)) { + pr_err("invalid ioctrl type %u\n", _IOC_TYPE(cmd)); + return -EINVAL; + } + + return unified_collection_ioctl_cb[_IOC_TYPE(cmd)](cmd, argp); +} + +#ifdef CONFIG_COMPAT +static long unified_collection_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return unified_collection_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); +} +#endif // CONFIG_COMPAT + +static int unified_collection_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int unified_collection_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static const struct file_operations unified_collection_device_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = unified_collection_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = unified_collection_compat_ioctl, +#endif // CONFIG_COMPAT + .open = unified_collection_open, + .release = unified_collection_release, +}; + +static struct miscdevice unified_collection_device = { + .name = "ucollection", + .fops = &unified_collection_device_fops, + .minor = MISC_DYNAMIC_MINOR, +}; + +static int __init unified_collection_init(void) +{ + int ret = misc_register(&unified_collection_device); + if (ret) { + pr_err("failed to register unified collection device"); + return ret; + } + + pr_info("register unified collection device successful"); + return 0; +} + +static void __exit unified_collection_exit(void) +{ + pr_info("deregister unified collection device successful"); + misc_deregister(&unified_collection_device); +} + +module_init(unified_collection_init); +module_exit(unified_collection_exit); + +MODULE_AUTHOR("OHOS"); +MODULE_DESCRIPTION("Unified Collection Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file -- Gitee From 3945dcb9c1501b190e17e7df04809096b02d68a6 Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Fri, 8 Sep 2023 12:26:44 +0800 Subject: [PATCH 2/6] add set cpu dmips Signed-off-by: zhouhaifeng --- .../ucollection/ucollection_process_cpu.c | 25 ++++++++++++++++--- .../ucollection/unified_collection_data.h | 11 +++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ucollection/ucollection_process_cpu.c b/drivers/staging/ucollection/ucollection_process_cpu.c index 9f8a083c3f8e..5b28a428f8f0 100644 --- a/drivers/staging/ucollection/ucollection_process_cpu.c +++ b/drivers/staging/ucollection/ucollection_process_cpu.c @@ -17,7 +17,6 @@ #include "unified_collection_data.h" -#define DMIPS_NUM 16 #define NS_TO_MS 1000000 static char dmips_values[DMIPS_NUM]; @@ -65,7 +64,7 @@ static int get_process_load(struct task_struct *task, int cpu_num, int cur_count return 0; } -static long collect_process_cpu(void __user *argp) +static long ioctrl_collect_process_cpu(void __user *argp) { int cpu_num = 0; struct task_struct *task = NULL; @@ -99,13 +98,33 @@ static long collect_process_cpu(void __user *argp) return 0; } +static long ioctrl_set_cpu_dmips(void __user *argp) +{ + int i; + struct ucollection_cpu_dmips kentry; + struct ucollection_cpu_dmips __user *entry = argp; + memset(&kentry, 0, sizeof(struct ucollection_cpu_dmips)); + copy_from_user(&kentry, entry, sizeof(struct ucollection_cpu_dmips)); + pr_info("set dimps %d cpus\n", kentry.total_count); + for (i = 0; i < DMIPS_NUM; i++) { + if (i >= kentry.total_count) + break; + get_user(dmips_values[i], &entry->dmips[i]); + pr_info("set dimps cpu[%d]=%d\n", i, dmips_values[i]); + } + return 0; +} + long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp) { long ret = 0; pr_info("handle ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); switch(cmd) { case IOCTRL_COLLECT_CPU: - ret = collect_process_cpu(argp); + ret = ioctrl_collect_process_cpu(argp); + break; + case IOCTRL_SET_CPU_DMIPS: + ret = ioctrl_set_cpu_dmips(argp); break; default: ret = 0; diff --git a/drivers/staging/ucollection/unified_collection_data.h b/drivers/staging/ucollection/unified_collection_data.h index f5bac3403f88..84bb6cd6792a 100644 --- a/drivers/staging/ucollection/unified_collection_data.h +++ b/drivers/staging/ucollection/unified_collection_data.h @@ -16,7 +16,16 @@ struct ucollection_process_cpu_entry { struct ucollection_process_cpu_item datas[]; }; +struct ucollection_cpu_dmips { + int magic; + int total_count; + char dmips[]; +}; + +#define DMIPS_NUM 64 +#define IOCTRL_COLLECT_CPU_MAGIC 19990101 + #define IOCTRL_COLLECT_CPU_BASE 0 #define IOCTRL_COLLECT_CPU _IOWR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) - +#define IOCTRL_SET_CPU_DMIPS _IOWR(IOCTRL_COLLECT_CPU_BASE, 2, struct ucollection_cpu_dmips) #endif // __UNIFIED_COLLECTION_DATA__ \ No newline at end of file -- Gitee From bcf65c34da174f7a1c46eb05be02846ce8b9e433 Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Sat, 9 Sep 2023 21:16:24 +0800 Subject: [PATCH 3/6] fix with coe review Signed-off-by: zhouhaifeng --- .../staging/ucollection/ucollection_process_cpu.c | 4 ++++ .../staging/ucollection/ucollection_process_cpu.h | 4 ++++ .../staging/ucollection/unified_collection_data.h | 14 ++++++++------ .../ucollection/unified_collection_driver.c | 9 ++++----- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/staging/ucollection/ucollection_process_cpu.c b/drivers/staging/ucollection/ucollection_process_cpu.c index 5b28a428f8f0..c9995cb4b2ea 100644 --- a/drivers/staging/ucollection/ucollection_process_cpu.c +++ b/drivers/staging/ucollection/ucollection_process_cpu.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Huawei Technologies Co., Ltd. All rights reserved. + */ #include "ucollection_process_cpu.h" #ifdef CONFIG_CPU_FREQ_TIMES diff --git a/drivers/staging/ucollection/ucollection_process_cpu.h b/drivers/staging/ucollection/ucollection_process_cpu.h index 9ec5c2ae8f09..69bb25bf3c68 100644 --- a/drivers/staging/ucollection/ucollection_process_cpu.h +++ b/drivers/staging/ucollection/ucollection_process_cpu.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Huawei Technologies Co., Ltd. All rights reserved. + */ #ifndef __UCOLLECTION_PROCESS_CPU__ #define __UCOLLECTION_PROCESS_CPU__ diff --git a/drivers/staging/ucollection/unified_collection_data.h b/drivers/staging/ucollection/unified_collection_data.h index 84bb6cd6792a..eac341fa080f 100644 --- a/drivers/staging/ucollection/unified_collection_data.h +++ b/drivers/staging/ucollection/unified_collection_data.h @@ -1,8 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Huawei Technologies Co., Ltd. All rights reserved. + */ #ifndef __UNIFIED_COLLECTION_DATA__ #define __UNIFIED_COLLECTION_DATA__ #include +// kernel struct, modify at the same time struct ucollection_process_cpu_item { int pid; unsigned long long cpu_usage_time; @@ -10,22 +15,19 @@ struct ucollection_process_cpu_item { }; struct ucollection_process_cpu_entry { - int magic; int total_count; int cur_count; struct ucollection_process_cpu_item datas[]; }; struct ucollection_cpu_dmips { - int magic; int total_count; char dmips[]; }; -#define DMIPS_NUM 64 -#define IOCTRL_COLLECT_CPU_MAGIC 19990101 +#define DMIPS_NUM 128 #define IOCTRL_COLLECT_CPU_BASE 0 -#define IOCTRL_COLLECT_CPU _IOWR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) -#define IOCTRL_SET_CPU_DMIPS _IOWR(IOCTRL_COLLECT_CPU_BASE, 2, struct ucollection_cpu_dmips) +#define IOCTRL_COLLECT_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) +#define IOCTRL_SET_CPU_DMIPS _IOW(IOCTRL_COLLECT_CPU_BASE, 2, struct ucollection_cpu_dmips) #endif // __UNIFIED_COLLECTION_DATA__ \ No newline at end of file diff --git a/drivers/staging/ucollection/unified_collection_driver.c b/drivers/staging/ucollection/unified_collection_driver.c index 4f82f0022f35..e2a02bd91bb1 100644 --- a/drivers/staging/ucollection/unified_collection_driver.c +++ b/drivers/staging/ucollection/unified_collection_driver.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Huawei Technologies Co., Ltd. All rights reserved. + */ #include #include #include @@ -9,8 +13,6 @@ #include "ucollection_process_cpu.h" -#define PROCESS_NAME "hiview" - static long (*unified_collection_ioctl_cb[])(unsigned int cmd, void __user *argp) = { unified_collection_collect_process_cpu /* IOCTRL_COLLECT_CPU */ }; @@ -21,9 +23,6 @@ static long unified_collection_ioctl(struct file *filp, unsigned int cmd, unsign const char *comm = NULL; pr_info("recv ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); - comm = current->group_leader ? current->group_leader->comm : current->comm; - // if (!strstr(comm, PROCESS_NAME)) - // return -EINVAL; if ((_IOC_TYPE(cmd) >= ARRAY_SIZE(unified_collection_ioctl_cb)) || (unified_collection_ioctl_cb[_IOC_TYPE(cmd)] == NULL)) { -- Gitee From 87edf470f44dda4636d206735d972959362e5af8 Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Sat, 9 Sep 2023 21:28:34 +0800 Subject: [PATCH 4/6] fix cput time Signed-off-by: zhouhaifeng --- drivers/staging/ucollection/ucollection_process_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ucollection/ucollection_process_cpu.c b/drivers/staging/ucollection/ucollection_process_cpu.c index c9995cb4b2ea..4fd741535eaf 100644 --- a/drivers/staging/ucollection/ucollection_process_cpu.c +++ b/drivers/staging/ucollection/ucollection_process_cpu.c @@ -53,7 +53,7 @@ static unsigned long long get_process_usage_cputime(struct task_struct *task) thread_group_cputime_adjusted(task, &utime, &stime); sum_time = utime + stime + task->signal->cutime + task->signal->cstime; - cputime = (unsigned long)(sum_time / NS_TO_MS); + cputime = (unsigned long long)(sum_time / NS_TO_MS); return cputime; } -- Gitee From 882ac8578071768903ac2fefdafb8d4431223f16 Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Sat, 9 Sep 2023 21:32:00 +0800 Subject: [PATCH 5/6] convert to tab Signed-off-by: zhouhaifeng --- .../ucollection/unified_collection_data.h | 16 ++--- .../ucollection/unified_collection_driver.c | 62 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/staging/ucollection/unified_collection_data.h b/drivers/staging/ucollection/unified_collection_data.h index eac341fa080f..80f6aa871863 100644 --- a/drivers/staging/ucollection/unified_collection_data.h +++ b/drivers/staging/ucollection/unified_collection_data.h @@ -9,20 +9,20 @@ // kernel struct, modify at the same time struct ucollection_process_cpu_item { - int pid; - unsigned long long cpu_usage_time; - unsigned long long cpu_load_time; + int pid; + unsigned long long cpu_usage_time; + unsigned long long cpu_load_time; }; struct ucollection_process_cpu_entry { - int total_count; - int cur_count; - struct ucollection_process_cpu_item datas[]; + int total_count; + int cur_count; + struct ucollection_process_cpu_item datas[]; }; struct ucollection_cpu_dmips { - int total_count; - char dmips[]; + int total_count; + char dmips[]; }; #define DMIPS_NUM 128 diff --git a/drivers/staging/ucollection/unified_collection_driver.c b/drivers/staging/ucollection/unified_collection_driver.c index e2a02bd91bb1..3b7b95c10aea 100644 --- a/drivers/staging/ucollection/unified_collection_driver.c +++ b/drivers/staging/ucollection/unified_collection_driver.c @@ -14,74 +14,74 @@ #include "ucollection_process_cpu.h" static long (*unified_collection_ioctl_cb[])(unsigned int cmd, void __user *argp) = { - unified_collection_collect_process_cpu /* IOCTRL_COLLECT_CPU */ + unified_collection_collect_process_cpu /* IOCTRL_COLLECT_CPU */ }; static long unified_collection_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - void __user *argp = u64_to_user_ptr(arg); - const char *comm = NULL; + void __user *argp = u64_to_user_ptr(arg); + const char *comm = NULL; - pr_info("recv ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); + pr_info("recv ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); - if ((_IOC_TYPE(cmd) >= ARRAY_SIZE(unified_collection_ioctl_cb)) || - (unified_collection_ioctl_cb[_IOC_TYPE(cmd)] == NULL)) { - pr_err("invalid ioctrl type %u\n", _IOC_TYPE(cmd)); - return -EINVAL; - } + if ((_IOC_TYPE(cmd) >= ARRAY_SIZE(unified_collection_ioctl_cb)) || + (unified_collection_ioctl_cb[_IOC_TYPE(cmd)] == NULL)) { + pr_err("invalid ioctrl type %u\n", _IOC_TYPE(cmd)); + return -EINVAL; + } - return unified_collection_ioctl_cb[_IOC_TYPE(cmd)](cmd, argp); + return unified_collection_ioctl_cb[_IOC_TYPE(cmd)](cmd, argp); } #ifdef CONFIG_COMPAT static long unified_collection_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - return unified_collection_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); + return unified_collection_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); } #endif // CONFIG_COMPAT static int unified_collection_open(struct inode *inode, struct file *filp) { - return 0; + return 0; } static int unified_collection_release(struct inode *inode, struct file *filp) { - return 0; + return 0; } static const struct file_operations unified_collection_device_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = unified_collection_ioctl, + .owner = THIS_MODULE, + .unlocked_ioctl = unified_collection_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = unified_collection_compat_ioctl, + .compat_ioctl = unified_collection_compat_ioctl, #endif // CONFIG_COMPAT - .open = unified_collection_open, - .release = unified_collection_release, + .open = unified_collection_open, + .release = unified_collection_release, }; static struct miscdevice unified_collection_device = { - .name = "ucollection", - .fops = &unified_collection_device_fops, - .minor = MISC_DYNAMIC_MINOR, + .name = "ucollection", + .fops = &unified_collection_device_fops, + .minor = MISC_DYNAMIC_MINOR, }; static int __init unified_collection_init(void) { - int ret = misc_register(&unified_collection_device); - if (ret) { - pr_err("failed to register unified collection device"); - return ret; - } - - pr_info("register unified collection device successful"); - return 0; + int ret = misc_register(&unified_collection_device); + if (ret) { + pr_err("failed to register unified collection device"); + return ret; + } + + pr_info("register unified collection device successful"); + return 0; } static void __exit unified_collection_exit(void) { - pr_info("deregister unified collection device successful"); - misc_deregister(&unified_collection_device); + pr_info("deregister unified collection device successful"); + misc_deregister(&unified_collection_device); } module_init(unified_collection_init); -- Gitee From afb09974440ab107748208e403234bc26fa29c24 Mon Sep 17 00:00:00 2001 From: zhouhaifeng Date: Mon, 11 Sep 2023 19:11:56 +0800 Subject: [PATCH 6/6] add collect the process cpu load Signed-off-by: zhouhaifeng --- .../ucollection/ucollection_process_cpu.c | 56 ++++++++++++++++--- .../ucollection/unified_collection_data.h | 20 ++++++- .../ucollection/unified_collection_driver.c | 4 +- 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/drivers/staging/ucollection/ucollection_process_cpu.c b/drivers/staging/ucollection/ucollection_process_cpu.c index 4fd741535eaf..cf66816ccc90 100644 --- a/drivers/staging/ucollection/ucollection_process_cpu.c +++ b/drivers/staging/ucollection/ucollection_process_cpu.c @@ -46,15 +46,15 @@ static unsigned long long get_process_load_cputime(struct task_struct *task) return proc_load_cputime; } -static unsigned long long get_process_usage_cputime(struct task_struct *task) +static void get_process_usage_cputime(struct task_struct *task, unsigned long long *ut, unsigned long long *st) { unsigned long long utime, stime, sum_time; - unsigned long long cputime; thread_group_cputime_adjusted(task, &utime, &stime); - sum_time = utime + stime + task->signal->cutime + task->signal->cstime; - cputime = (unsigned long long)(sum_time / NS_TO_MS); - return cputime; + utime = utime + task->signal->cutime; + stime = stime + task->signal->cstime; + *ut = (unsigned long long)(utime / NS_TO_MS); + *st = (unsigned long long)(stime / NS_TO_MS); } static int get_process_load(struct task_struct *task, int cpu_num, int cur_count, struct ucollection_process_cpu_entry __user *entry) @@ -63,7 +63,7 @@ static int get_process_load(struct task_struct *task, int cpu_num, int cur_count memset(&proc_cpu_entry, 0, sizeof(struct ucollection_process_cpu_item)); proc_cpu_entry.pid = task->pid; proc_cpu_entry.cpu_load_time = get_process_load_cputime(task); - proc_cpu_entry.cpu_usage_time = get_process_usage_cputime(task); + get_process_usage_cputime(task, &proc_cpu_entry.cpu_usage_utime, &proc_cpu_entry.cpu_usage_stime); copy_to_user(&entry->datas[cur_count], &proc_cpu_entry, sizeof(struct ucollection_process_cpu_item)); return 0; } @@ -74,7 +74,6 @@ static long ioctrl_collect_process_cpu(void __user *argp) struct task_struct *task = NULL; struct ucollection_process_cpu_entry kentry; struct ucollection_process_cpu_entry __user *entry = argp; - pr_info("do collect process cpu"); if (entry == NULL) { pr_err("cpu entry is null"); return -EINVAL; @@ -94,6 +93,7 @@ static long ioctrl_collect_process_cpu(void __user *argp) pr_err("process over total count"); break; } + get_process_load(task, cpu_num, kentry.cur_count, entry); kentry.cur_count++; } @@ -102,6 +102,41 @@ static long ioctrl_collect_process_cpu(void __user *argp) return 0; } +static long ioctrl_collect_the_process_cpu(void __user *argp) +{ + int cpu_num = 0; + struct task_struct *task = NULL; + struct ucollection_process_cpu_entry kentry; + struct ucollection_process_cpu_entry __user *entry = argp; + if (entry == NULL) { + pr_err("cpu entry is null"); + return -EINVAL; + } + + memset(&kentry, 0, sizeof(struct ucollection_process_cpu_entry)); + copy_from_user(&kentry, entry, sizeof(struct ucollection_process_cpu_entry)); + + if (kentry.cur_count >= kentry.total_count) { + pr_err("current count over total count"); + return -EINVAL; + } + + rcu_read_lock(); + task = find_task_by_vpid(kentry.filter.pid); + if (task == NULL) { + pr_err("can not get pid=%d", task->pid); + rcu_read_unlock(); + return -EINVAL; + } + + cpu_num = get_cpu_num(); + get_process_load(task, cpu_num, kentry.cur_count, entry); + kentry.cur_count++; + put_user(kentry.cur_count, &entry->cur_count); + rcu_read_unlock(); + return 0; +} + static long ioctrl_set_cpu_dmips(void __user *argp) { int i; @@ -122,15 +157,18 @@ static long ioctrl_set_cpu_dmips(void __user *argp) long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp) { long ret = 0; - pr_info("handle ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); switch(cmd) { - case IOCTRL_COLLECT_CPU: + case IOCTRL_COLLECT_ALL_PROC_CPU: ret = ioctrl_collect_process_cpu(argp); break; + case IOCTRL_COLLECT_THE_PROC_CPU: + ret = ioctrl_collect_the_process_cpu(argp); + break; case IOCTRL_SET_CPU_DMIPS: ret = ioctrl_set_cpu_dmips(argp); break; default: + pr_err("handle ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); ret = 0; } return ret; diff --git a/drivers/staging/ucollection/unified_collection_data.h b/drivers/staging/ucollection/unified_collection_data.h index 80f6aa871863..c9fe49e75f1b 100644 --- a/drivers/staging/ucollection/unified_collection_data.h +++ b/drivers/staging/ucollection/unified_collection_data.h @@ -10,24 +10,38 @@ // kernel struct, modify at the same time struct ucollection_process_cpu_item { int pid; - unsigned long long cpu_usage_time; + unsigned long long cpu_usage_utime; + unsigned long long cpu_usage_stime; unsigned long long cpu_load_time; }; +struct ucollection_process_filter { + int uid; + int pid; + int tid; +}; + struct ucollection_process_cpu_entry { + int magic; int total_count; int cur_count; + struct ucollection_process_filter filter; struct ucollection_process_cpu_item datas[]; }; struct ucollection_cpu_dmips { + int magic; int total_count; char dmips[]; }; +#define IOCTRL_COLLECT_ALL_PROC_CPU_MAGIC 1 +#define IOCTRL_COLLECT_THE_PROC_CPU_MAGIC 1 +#define IOCTRL_SET_CPU_DMIPS_MAGIC 1 #define DMIPS_NUM 128 #define IOCTRL_COLLECT_CPU_BASE 0 -#define IOCTRL_COLLECT_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) -#define IOCTRL_SET_CPU_DMIPS _IOW(IOCTRL_COLLECT_CPU_BASE, 2, struct ucollection_cpu_dmips) +#define IOCTRL_COLLECT_ALL_PROC_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, 1, struct ucollection_process_cpu_entry) +#define IOCTRL_COLLECT_THE_PROC_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, 2, struct ucollection_process_cpu_entry) +#define IOCTRL_SET_CPU_DMIPS _IOW(IOCTRL_COLLECT_CPU_BASE, 3, struct ucollection_cpu_dmips) #endif // __UNIFIED_COLLECTION_DATA__ \ No newline at end of file diff --git a/drivers/staging/ucollection/unified_collection_driver.c b/drivers/staging/ucollection/unified_collection_driver.c index 3b7b95c10aea..dc084724753c 100644 --- a/drivers/staging/ucollection/unified_collection_driver.c +++ b/drivers/staging/ucollection/unified_collection_driver.c @@ -22,11 +22,9 @@ static long unified_collection_ioctl(struct file *filp, unsigned int cmd, unsign void __user *argp = u64_to_user_ptr(arg); const char *comm = NULL; - pr_info("recv ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); - if ((_IOC_TYPE(cmd) >= ARRAY_SIZE(unified_collection_ioctl_cb)) || (unified_collection_ioctl_cb[_IOC_TYPE(cmd)] == NULL)) { - pr_err("invalid ioctrl type %u\n", _IOC_TYPE(cmd)); + pr_err("invalid ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); return -EINVAL; } -- Gitee