From f96cff7f859c9486aec6db8d540c97c31f83cd30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=96=E7=90=A6=5Fhw?= <670097973@qq.com> Date: Tue, 19 Mar 2024 21:15:44 +0800 Subject: [PATCH 1/4] collect thread info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨世琦_hw <670097973@qq.com> --- ucollection/ucollection_process_cpu.c | 163 ++++++++++++++++++++------ ucollection/unified_collection_data.h | 53 +++++++-- 2 files changed, 170 insertions(+), 46 deletions(-) diff --git a/ucollection/ucollection_process_cpu.c b/ucollection/ucollection_process_cpu.c index 7238f25..0dd594c 100644 --- a/ucollection/ucollection_process_cpu.c +++ b/ucollection/ucollection_process_cpu.c @@ -31,15 +31,6 @@ unsigned long long __attribute__((weak)) get_proc_cpu_load(struct task_struct *t 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 void get_process_flt(struct task_struct *task, unsigned long long *min_flt, unsigned long long *maj_flt) { unsigned long tmp_min_flt = 0; @@ -82,7 +73,7 @@ static void get_process_usage_cputime(struct task_struct *task, unsigned long lo *st = stime; } -static void get_process_load(struct task_struct *task, int cpu_num, int cur_count, +static void get_process_load(struct task_struct *task, int cur_count, struct ucollection_process_cpu_entry __user *entry) { struct ucollection_process_cpu_item proc_cpu_entry; @@ -94,9 +85,25 @@ static void get_process_load(struct task_struct *task, int cpu_num, int cur_coun (void)copy_to_user(&entry->datas[cur_count], &proc_cpu_entry, sizeof(struct ucollection_process_cpu_item)); } +static void get_thread_load(struct task_struct *task, int cur_count, + struct ucollection_thread_cpu_entry __user *entry) +{ + struct ucollection_thread_cpu_item thread_cpu_item; + memset(&thread_cpu_item, 0, sizeof(struct ucollection_thread_cpu_item)); + unsigned long long utime, stime; + utime = task->utime; + stime = task->stime; + do_div(utime, NS_TO_MS); + do_div(stime, NS_TO_MS); + thread_cpu_item.tid = task->pid; + thread_cpu_item.cpu_usage_utime = utime; + thread_cpu_item.cpu_usage_stime = stime; + thread_cpu_item.cpu_load_time = 0; + (void)copy_to_user(&entry->datas[cur_count], &thread_cpu_item, sizeof(struct ucollection_thread_cpu_item)); +} + static long ioctrl_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; @@ -108,7 +115,6 @@ static long ioctrl_collect_process_cpu(void __user *argp) memset(&kentry, 0, sizeof(struct ucollection_process_cpu_entry)); (void)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) { @@ -120,7 +126,7 @@ static long ioctrl_collect_process_cpu(void __user *argp) break; } - get_process_load(task, cpu_num, kentry.cur_count, entry); + get_process_load(task, kentry.cur_count, entry); kentry.cur_count++; } put_user(kentry.cur_count, &entry->cur_count); @@ -138,9 +144,108 @@ static bool is_pid_alive(int pid) return pid_alive(task); } +static long ioctrl_collect_thread_count_cpu(void __user *argp) +{ + struct task_struct *task = NULL; + struct ucollection_process_thread_count kcount; + struct ucollection_process_thread_count __user *count = argp; + if (count == NULL) { + pr_err("cpu entry is null"); + return -EINVAL; + } + memset(&kcount, 0, sizeof(struct ucollection_process_thread_count)); + (void)copy_from_user(&kcount, count, sizeof(struct ucollection_process_thread_count)); + rcu_read_lock(); + if (!is_pid_alive(kcount.pid)) { + pr_err("pid=%d is not alive", kcount.pid); + rcu_read_unlock(); + return -EINVAL; + } + task = find_task_by_vpid(kcount.pid); + if (task == NULL) { + pr_err("can not get pid=%d", task->pid); + rcu_read_unlock(); + return -EINVAL; + } + uint32_t thread_count = 0; + struct task_struct *t = task; + do { + thread_count++; + } while_each_thread(task, t); + put_user(thread_count, &count->thread_count); + rcu_read_unlock(); + return 0; +} + +static long read_thread_info_locked(struct ucollection_thread_cpu_entry *kentry, + struct ucollection_thread_cpu_entry __user *entry) +{ + rcu_read_lock(); + if (!is_pid_alive(kentry->filter.pid)) { + pr_err("pid=%d is not alive", kentry->filter.pid); + rcu_read_unlock(); + return -EINVAL; + } + struct task_struct *task = NULL; + 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; + } + uint32_t thread_count = 0; + struct task_struct *t = task; + do { + if (thread_count >= kentry->total_count) { + pr_err("thread over total count"); + break; + } + get_thread_load(t, thread_count, entry); + thread_count++; + } while_each_thread(task, t); + put_user(thread_count, &entry->cur_count); + rcu_read_unlock(); + return 0; +} + +static long ioctrl_collect_app_thread_cpu(void __user *argp) +{ + struct ucollection_thread_cpu_entry kentry; + struct ucollection_thread_cpu_entry __user *entry = argp; + if (entry == NULL) { + pr_err("cpu entry is null"); + return -EINVAL; + } + memset(&kentry, 0, sizeof(struct ucollection_thread_cpu_entry)); + (void)copy_from_user(&kentry, entry, sizeof(struct ucollection_thread_cpu_entry)); + if (current->pid != kentry.filter.pid || kentry.cur_count >= kentry.total_count) { + pr_err("pid=%d is not self current:%d , or current count over total count" + , kentry.filter.pid, current->pid); + return -EINVAL; + } + return read_thread_info_locked(&kentry, entry); +} + +static long ioctrl_collect_the_thread_cpu(void __user *argp) +{ + struct ucollection_thread_cpu_entry kentry; + struct ucollection_thread_cpu_entry __user *entry = argp; + if (entry == NULL) { + pr_err("cpu entry is null"); + return -EINVAL; + } + memset(&kentry, 0, sizeof(struct ucollection_thread_cpu_entry)); + (void)copy_from_user(&kentry, entry, sizeof(struct ucollection_thread_cpu_entry)); + if (kentry.cur_count >= kentry.total_count) { + pr_err("pid=%d is not self current:%d , or current count over total count" + , kentry.filter.pid, current->pid); + return -EINVAL; + } + return read_thread_info_locked(&kentry, entry); +} + 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; @@ -171,31 +276,13 @@ static long ioctrl_collect_the_process_cpu(void __user *argp) return -EINVAL; } - cpu_num = get_cpu_num(); - get_process_load(task, cpu_num, kentry.cur_count, entry); + get_process_load(task, 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; - struct ucollection_cpu_dmips kentry; - struct ucollection_cpu_dmips __user *entry = argp; - memset(&kentry, 0, sizeof(struct ucollection_cpu_dmips)); - (void)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; @@ -206,8 +293,14 @@ long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp) 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); + case IOCTRL_COLLECT_THREAD_COUNT: + ret = ioctrl_collect_thread_count_cpu(argp); + break; + case IOCTRL_COLLECT_APP_THREAD: + ret = ioctrl_collect_app_thread_cpu(argp); + break; + case IOCTRL_COLLECT_THE_THREAD: + ret = ioctrl_collect_the_thread_cpu(argp); break; default: pr_err("handle ioctrl cmd %u, _IOC_TYPE(cmd)=%d", cmd, _IOC_TYPE(cmd)); diff --git a/ucollection/unified_collection_data.h b/ucollection/unified_collection_data.h index 2f3773f..faf9a69 100644 --- a/ucollection/unified_collection_data.h +++ b/ucollection/unified_collection_data.h @@ -31,19 +31,50 @@ struct ucollection_process_cpu_entry { struct ucollection_process_cpu_item datas[]; }; -struct ucollection_cpu_dmips { - int magic; - int total_count; - char dmips[]; +struct ucollection_process_thread_count { + uint32_t pid; + uint32_t thread_count; }; -#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 +struct ucollection_thread_cpu_item { + int tid; + unsigned long long cpu_usage_utime; + unsigned long long cpu_usage_stime; + unsigned long long cpu_load_time; +}; + +struct ucollection_thread_filter { + int uid; + int pid; + int tid; +}; +struct ucollection_thread_cpu_entry { + int magic; + unsigned int total_count; + unsigned int cur_count; + struct ucollection_thread_filter filter; + struct ucollection_thread_cpu_item datas[]; +}; + +enum collection_type { + COLLECT_ALL_PROC = 1, + COLLECT_THE_PROC, + COLLECT_APP_PROC, + COLLECT_PROC_COUNT, + COLLECT_THREAD_COUNT, + COLLECT_APP_THREAD, + COLLECT_THE_THREAD, +}; + +#define DMIPS_NUM 128 #define IOCTRL_COLLECT_CPU_BASE 0 -#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) +#define IOCTRL_COLLECT_ALL_PROC_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, COLLECT_ALL_PROC, \ + struct ucollection_process_cpu_entry) +#define IOCTRL_COLLECT_THE_PROC_CPU _IOR(IOCTRL_COLLECT_CPU_BASE, COLLECT_THE_PROC, \ + struct ucollection_process_cpu_entry) +#define IOCTRL_COLLECT_THREAD_COUNT _IOR(IOCTRL_COLLECT_CPU_BASE, COLLECT_THREAD_COUNT, \ + struct ucollection_process_thread_count) +#define IOCTRL_COLLECT_APP_THREAD _IOR(IOCTRL_COLLECT_CPU_BASE, COLLECT_APP_THREAD, struct ucollection_thread_cpu_entry) +#define IOCTRL_COLLECT_THE_THREAD _IOR(IOCTRL_COLLECT_CPU_BASE, COLLECT_THE_THREAD, struct ucollection_thread_cpu_entry) #endif // __UNIFIED_COLLECTION_DATA__ \ No newline at end of file -- Gitee From 008315222c5c541d24c76d2e2718d14541b5be82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=96=E7=90=A6=5Fhw?= <670097973@qq.com> Date: Tue, 26 Mar 2024 11:08:51 +0800 Subject: [PATCH 2/4] collector thread info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨世琦_hw <670097973@qq.com> --- ucollection/Makefile | 4 +++- ucollection/ucollection_process_cpu.c | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ucollection/Makefile b/ucollection/Makefile index 5d1b45e..d7e9d73 100644 --- a/ucollection/Makefile +++ b/ucollection/Makefile @@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +ifeq ($(CONFIG_UCOLLECTION),y) obj-$(CONFIG_UNIFIED_COLLECTION) += ucollection_process_cpu.o -obj-$(CONFIG_UNIFIED_COLLECTION) += unified_collection_driver.o \ No newline at end of file +obj-$(CONFIG_UNIFIED_COLLECTION) += unified_collection_driver.o +endif \ No newline at end of file diff --git a/ucollection/ucollection_process_cpu.c b/ucollection/ucollection_process_cpu.c index 0dd594c..206a5dc 100644 --- a/ucollection/ucollection_process_cpu.c +++ b/ucollection/ucollection_process_cpu.c @@ -65,8 +65,6 @@ static void get_process_usage_cputime(struct task_struct *task, unsigned long lo unsigned long long utime, stime; thread_group_cputime_adjusted(task, &utime, &stime); - utime = utime + task->signal->cutime; - stime = stime + task->signal->cstime; do_div(utime, NS_TO_MS); do_div(stime, NS_TO_MS); *ut = utime; @@ -99,7 +97,7 @@ static void get_thread_load(struct task_struct *task, int cur_count, thread_cpu_item.cpu_usage_utime = utime; thread_cpu_item.cpu_usage_stime = stime; thread_cpu_item.cpu_load_time = 0; - (void)copy_to_user(&entry->datas[cur_count], &thread_cpu_item, sizeof(struct ucollection_thread_cpu_item)); + (void)copy_to_user(&entry->datas[cur_count], &thread_cpu_item, sizeof(struct ucollection_thread_cpu_item)); } static long ioctrl_collect_process_cpu(void __user *argp) @@ -144,7 +142,7 @@ static bool is_pid_alive(int pid) return pid_alive(task); } -static long ioctrl_collect_thread_count_cpu(void __user *argp) +static long ioctrl_collect_thread_count(void __user *argp) { struct task_struct *task = NULL; struct ucollection_process_thread_count kcount; @@ -294,7 +292,7 @@ long unified_collection_collect_process_cpu(unsigned int cmd, void __user *argp) ret = ioctrl_collect_the_process_cpu(argp); break; case IOCTRL_COLLECT_THREAD_COUNT: - ret = ioctrl_collect_thread_count_cpu(argp); + ret = ioctrl_collect_thread_count(argp); break; case IOCTRL_COLLECT_APP_THREAD: ret = ioctrl_collect_app_thread_cpu(argp); -- Gitee From 2c01bf90a5ca3bd8a001cc353e00b3a92bdfbe03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=96=E7=90=A6=5Fhw?= <670097973@qq.com> Date: Tue, 26 Mar 2024 03:24:55 +0000 Subject: [PATCH 3/4] update ucollection/Makefile. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨世琦_hw <670097973@qq.com> --- ucollection/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ucollection/Makefile b/ucollection/Makefile index d7e9d73..5d1b45e 100644 --- a/ucollection/Makefile +++ b/ucollection/Makefile @@ -1,5 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -ifeq ($(CONFIG_UCOLLECTION),y) obj-$(CONFIG_UNIFIED_COLLECTION) += ucollection_process_cpu.o -obj-$(CONFIG_UNIFIED_COLLECTION) += unified_collection_driver.o -endif \ No newline at end of file +obj-$(CONFIG_UNIFIED_COLLECTION) += unified_collection_driver.o \ No newline at end of file -- Gitee From 78b4f7591ff2222d0bf965f714f1d5322fc068d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=96=E7=90=A6=5Fhw?= <670097973@qq.com> Date: Tue, 26 Mar 2024 03:36:06 +0000 Subject: [PATCH 4/4] update ucollection/ucollection_process_cpu.c. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨世琦_hw <670097973@qq.com> --- ucollection/ucollection_process_cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ucollection/ucollection_process_cpu.c b/ucollection/ucollection_process_cpu.c index 206a5dc..f914a78 100644 --- a/ucollection/ucollection_process_cpu.c +++ b/ucollection/ucollection_process_cpu.c @@ -65,6 +65,8 @@ static void get_process_usage_cputime(struct task_struct *task, unsigned long lo unsigned long long utime, stime; thread_group_cputime_adjusted(task, &utime, &stime); + utime = utime + task->signal->cutime; + stime = stime + task->signal->cstime; do_div(utime, NS_TO_MS); do_div(stime, NS_TO_MS); *ut = utime; -- Gitee