* [PATCH v1 1/1] process: export symbols for fork/exit tracing functions
@ 2023-06-12 15:15 jim.tsai
2023-06-12 16:35 ` Greg Kroah-Hartman
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: jim.tsai @ 2023-06-12 15:15 UTC (permalink / raw)
To: linux-kernel, Arnd Bergmann, Greg Kroah-Hartman, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: wsd_upstream, wei-chin.tsai, mel.lee, ivan.tseng, jim.tsai,
linux-arm-kernel, linux-mediatek
Export the tracing function "sched_process_fork" and
"sched_process_exit" for process statistics.
Change-Id: I67dcdcb26371cd7a495ff0b210361742b1a2088e
Signed-off-by: jim.tsai <Wei-chin.Tsai@mediatek.com>
---
drivers/misc/mediatek_mbraink/Kconfig | 7 +
drivers/misc/mediatek_mbraink/Makefile | 5 +
drivers/misc/mediatek_mbraink/mbraink_data.c | 417 ++++++++++++++++++
drivers/misc/mediatek_mbraink/mbraink_data.h | 67 +++
.../mbraink_ioctl_struct_define.h | 44 ++
drivers/misc/mediatek_mbraink/mbraink_main.c | 277 ++++++++++++
drivers/misc/mediatek_mbraink/mbraink_main.h | 32 ++
kernel/exit.c | 2 +
kernel/fork.c | 2 +
9 files changed, 853 insertions(+)
create mode 100644 drivers/misc/mediatek_mbraink/Kconfig
create mode 100644 drivers/misc/mediatek_mbraink/Makefile
create mode 100644 drivers/misc/mediatek_mbraink/mbraink_data.c
create mode 100644 drivers/misc/mediatek_mbraink/mbraink_data.h
create mode 100644 drivers/misc/mediatek_mbraink/mbraink_ioctl_struct_define.h
create mode 100644 drivers/misc/mediatek_mbraink/mbraink_main.c
create mode 100644 drivers/misc/mediatek_mbraink/mbraink_main.h
diff --git a/drivers/misc/mediatek_mbraink/Kconfig b/drivers/misc/mediatek_mbraink/Kconfig
new file mode 100644
index 000000000000..615c1043a866
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/Kconfig
@@ -0,0 +1,7 @@
+config MTK_MBRAINK
+ tristate "MTK MBRAINK support"
+ help
+ MBRAINK is a MediaTek in-house kernel module which can
+ communicate with android MBrain.
+ Set Y to enable this feature.
+ If unsure, Set N to stay with legancy feature.
diff --git a/drivers/misc/mediatek_mbraink/Makefile b/drivers/misc/mediatek_mbraink/Makefile
new file mode 100644
index 000000000000..8d75b41a8097
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/Makefile
@@ -0,0 +1,5 @@
+subdir-ccflags-y += -Wformat
+
+obj-${CONFIG_MTK_MBRAINK} += mtk_mbraink.o
+
+mtk_mbraink-objs += mbraink_data.o mbraink_main.o
diff --git a/drivers/misc/mediatek_mbraink/mbraink_data.c b/drivers/misc/mediatek_mbraink/mbraink_data.c
new file mode 100644
index 000000000000..5c793a8c262d
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/mbraink_data.c
@@ -0,0 +1,417 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/rtc.h>
+#include <linux/sched/clock.h>
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/proc_fs.h>
+#include <linux/sched/signal.h>
+#include <linux/pid_namespace.h>
+#include <linux/mm.h>
+#include <linux/sched/mm.h>
+#include <linux/sched/task.h>
+#include <linux/pagewalk.h>
+#include <linux/shmem_fs.h>
+#include <linux/pagemap.h>
+#include <linux/mempolicy.h>
+#include <linux/rmap.h>
+#include <linux/sched/cputime.h>
+#include <linux/math64.h>
+#include <linux/refcount.h>
+#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <linux/cred.h>
+#include <linux/spinlock.h>
+#include <linux/rtc.h>
+#include <linux/sched/clock.h>
+#include <trace/events/sched.h>
+#include <linux/mm_inline.h>
+
+#include "mbraink_data.h"
+
+/*spinlock for mbraink tracing pidlist*/
+static DEFINE_SPINLOCK(tracing_pidlist_lock);
+/*Please make sure that tracing pidlist is protected by spinlock*/
+struct mbraink_tracing_pidlist mbraink_tracing_pidlist_data[MAX_TRACE_NUM];
+
+#if IS_ENABLED(CONFIG_ANON_VMA_NAME)
+struct anon_vma_name *mbraink_anon_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_file)
+ return NULL;
+
+ return vma->anon_name;
+}
+#else
+struct anon_vma_name *mbraink_anon_vma_name(struct vm_area_struct *vma)
+{
+ return NULL;
+}
+#endif
+
+void mbraink_map_vma(struct vm_area_struct *vma, unsigned long cur_pss,
+ unsigned long *native_heap, unsigned long *java_heap)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ const char *name = NULL;
+
+ if (vma->vm_file)
+ return;
+ /*
+ * Print the dentry name for named mappings, and a
+ * special [heap] marker for the heap:
+ */
+
+ if (vma->vm_ops && vma->vm_ops->name) {
+ name = vma->vm_ops->name(vma);
+ if (name) {
+ if (strncmp(name, "dev/ashmem/libc malloc", 23) == 0)
+ (*native_heap) += cur_pss;
+ return;
+ }
+ }
+
+ name = arch_vma_name(vma);
+ if (!name) {
+ struct anon_vma_name *anon_name;
+
+ if (!mm)
+ return;
+
+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
+ (*native_heap) += cur_pss;
+ return;
+ }
+
+ if (vma->vm_start <= vma->vm_mm->start_stack &&
+ vma->vm_end >= vma->vm_mm->start_stack)
+ return;
+
+ anon_name = mbraink_anon_vma_name(vma);
+ if (anon_name) {
+ if (strstr(anon_name->name, "scudo"))
+ (*native_heap) += cur_pss;
+ else if (strstr(anon_name->name, "libc_malloc"))
+ (*native_heap) += cur_pss;
+ else if (strstr(anon_name->name, "GWP-ASan"))
+ (*native_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-alloc space"))
+ (*java_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-main space"))
+ (*java_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-large object space"))
+ (*java_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-free list large object space"))
+ (*java_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-non moving space"))
+ (*java_heap) += cur_pss;
+ else if (strstr(anon_name->name, "dalvik-zygote space"))
+ (*java_heap) += cur_pss;
+ }
+ }
+}
+
+void mbraink_get_process_memory_info(pid_t current_pid,
+ struct mbraink_process_memory_data *process_memory_buffer)
+{
+ struct task_struct *t = NULL;
+ struct mm_struct *mm = NULL;
+ struct vm_area_struct *vma = NULL;
+ struct mem_size_stats mss;
+ unsigned short pid_count = 0;
+ unsigned long pss, uss, rss, swap, cur_pss;
+ unsigned long java_heap = 0, native_heap = 0;
+ struct vma_iterator vmi;
+
+ memset(process_memory_buffer, 0, sizeof(struct mbraink_process_memory_data));
+ process_memory_buffer->pid = 0;
+
+ read_lock(&tasklist_lock);
+ for_each_process(t) {
+ if (t->pid <= current_pid)
+ continue;
+
+ mm = t->mm;
+ if (mm) {
+ java_heap = 0;
+ native_heap = 0;
+ pid_count = process_memory_buffer->pid_count;
+
+ process_memory_buffer->drv_data[pid_count].pid =
+ (unsigned short)(t->pid);
+ process_memory_buffer->pid =
+ (unsigned short)(t->pid);
+
+ memset(&mss, 0, sizeof(mss));
+ get_task_struct(t);
+ mmgrab(mm);
+ read_unlock(&tasklist_lock);
+ mmap_read_lock(mm);
+ vma_iter_init(&vmi, mm, 0);
+ for_each_vma(vmi, vma) {
+ cur_pss = (unsigned long)(mss.pss >> PSS_SHIFT);
+ smap_gather_stats(vma, &mss, 0);
+ cur_pss =
+ ((unsigned long)(mss.pss >> PSS_SHIFT)) - cur_pss;
+ cur_pss = cur_pss / 1024;
+ mbraink_map_vma(vma, cur_pss, &native_heap, &java_heap);
+ }
+ mmap_read_unlock(mm);
+ read_lock(&tasklist_lock);
+ mmdrop(mm);
+ put_task_struct(t);
+
+ pss = (unsigned long)(mss.pss >> PSS_SHIFT) / 1024;
+ uss = (mss.private_clean + mss.private_dirty) / 1024;
+ rss = (mss.resident) / 1024;
+ swap = (mss.swap) / 1024;
+
+ process_memory_buffer->drv_data[pid_count].pss = pss;
+ process_memory_buffer->drv_data[pid_count].uss = uss;
+ process_memory_buffer->drv_data[pid_count].rss = rss;
+ process_memory_buffer->drv_data[pid_count].swap = swap;
+ process_memory_buffer->drv_data[pid_count].java_heap =
+ java_heap;
+ process_memory_buffer->drv_data[pid_count].native_heap =
+ native_heap;
+ process_memory_buffer->pid_count++;
+
+ break;
+ }
+ }
+ read_unlock(&tasklist_lock);
+}
+
+/*****************************************************************
+ * Note: this function can only be used during tracing function
+ * This function is only used in tracing function so that there
+ * is no need for task t spinlock protection
+ *****************************************************************/
+static u64 mbraink_get_specific_process_jiffies(struct task_struct *t)
+{
+ u64 stime = 0, utime = 0, cutime = 0, cstime = 0;
+ u64 process_jiffies = 0;
+
+ if (t->pid == t->tgid) {
+ cutime = t->signal->cutime;
+ cstime = t->signal->cstime;
+ if (t->flags & PF_KTHREAD)
+ task_cputime_adjusted(t, &utime, &stime);
+ else
+ thread_group_cputime_adjusted(t, &utime, &stime);
+
+ process_jiffies = nsec_to_clock_t(utime) +
+ nsec_to_clock_t(stime) +
+ nsec_to_clock_t(cutime) +
+ nsec_to_clock_t(cstime);
+ } else {
+ task_cputime_adjusted(t, &utime, &stime);
+ process_jiffies = nsec_to_clock_t(utime) + nsec_to_clock_t(stime);
+ }
+
+ return process_jiffies;
+}
+
+/***************************************************************
+ * Note: this function can only be used during tracing function
+ * This function is only used in tracing function so that there
+ * is no need for task t spinlock protection
+ **************************************************************/
+static u16 mbraink_get_specific_process_uid(struct task_struct *t)
+{
+ const struct cred *cred = NULL;
+ u16 val = 0;
+
+ cred = get_task_cred(t);
+ val = cred->uid.val;
+ put_cred(cred);
+
+ return val;
+}
+
+static void mbraink_trace_sched_process_exit(void *data, struct task_struct *t)
+{
+ int i = 0;
+ struct timespec64 tv = { 0 };
+ unsigned long flags;
+
+ if (t->pid == t->tgid) {
+ spin_lock_irqsave(&tracing_pidlist_lock, flags);
+ for (i = 0; i < MAX_TRACE_NUM; i++) {
+ if (mbraink_tracing_pidlist_data[i].pid == (unsigned short)t->pid) {
+ ktime_get_real_ts64(&tv);
+ mbraink_tracing_pidlist_data[i].end =
+ (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
+ mbraink_tracing_pidlist_data[i].jiffies =
+ mbraink_get_specific_process_jiffies(t);
+ mbraink_tracing_pidlist_data[i].dirty = true;
+
+ break;
+ }
+ }
+ if (i == MAX_TRACE_NUM) {
+ for (i = 0; i < MAX_TRACE_NUM; i++) {
+ if (mbraink_tracing_pidlist_data[i].pid == 0) {
+ mbraink_tracing_pidlist_data[i].pid =
+ (unsigned short)(t->pid);
+ mbraink_tracing_pidlist_data[i].tgid =
+ (unsigned short)(t->tgid);
+ mbraink_tracing_pidlist_data[i].uid =
+ mbraink_get_specific_process_uid(t);
+ mbraink_tracing_pidlist_data[i].priority =
+ t->prio - MAX_RT_PRIO;
+ memcpy(mbraink_tracing_pidlist_data[i].name,
+ t->comm, TASK_COMM_LEN);
+ ktime_get_real_ts64(&tv);
+ mbraink_tracing_pidlist_data[i].end =
+ (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
+ mbraink_tracing_pidlist_data[i].jiffies =
+ mbraink_get_specific_process_jiffies(t);
+ mbraink_tracing_pidlist_data[i].dirty = true;
+
+ break;
+ }
+ }
+ if (i == MAX_TRACE_NUM) {
+ pr_info("%s pid=%u:%s.\n", __func__, t->pid, t->comm);
+ memset(mbraink_tracing_pidlist_data, 0,
+ sizeof(struct mbraink_tracing_pidlist) * MAX_TRACE_NUM);
+ }
+ }
+ spin_unlock_irqrestore(&tracing_pidlist_lock, flags);
+ }
+}
+
+static void mbraink_trace_sched_process_fork(void *data, struct task_struct *t,
+ struct task_struct *p)
+{
+ int i = 0;
+ struct timespec64 tv = { 0 };
+ unsigned long flags;
+
+ if (p->pid == p->tgid) {
+ spin_lock_irqsave(&tracing_pidlist_lock, flags);
+ for (i = 0; i < MAX_TRACE_NUM; i++) {
+ if (mbraink_tracing_pidlist_data[i].pid == 0) {
+ mbraink_tracing_pidlist_data[i].pid = (unsigned short)(p->pid);
+ mbraink_tracing_pidlist_data[i].tgid = (unsigned short)(p->tgid);
+ mbraink_tracing_pidlist_data[i].uid =
+ mbraink_get_specific_process_uid(p);
+ mbraink_tracing_pidlist_data[i].priority = p->prio - MAX_RT_PRIO;
+ memcpy(mbraink_tracing_pidlist_data[i].name,
+ p->comm, TASK_COMM_LEN);
+ ktime_get_real_ts64(&tv);
+ mbraink_tracing_pidlist_data[i].start =
+ (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
+ mbraink_tracing_pidlist_data[i].dirty = true;
+ break;
+ }
+ }
+
+ if (i == MAX_TRACE_NUM) {
+ pr_info("%s child_pid=%u:%s.\n", __func__, p->pid, p->comm);
+ memset(mbraink_tracing_pidlist_data, 0,
+ sizeof(struct mbraink_tracing_pidlist) * MAX_TRACE_NUM);
+ }
+ spin_unlock_irqrestore(&tracing_pidlist_lock, flags);
+ }
+}
+
+int mbraink_process_tracer_init(void)
+{
+ int ret = 0;
+
+ memset(mbraink_tracing_pidlist_data, 0,
+ sizeof(struct mbraink_tracing_pidlist) * MAX_TRACE_NUM);
+
+ ret = register_trace_sched_process_fork(mbraink_trace_sched_process_fork, NULL);
+ if (ret) {
+ pr_notice("register_trace_sched_process_fork failed.\n");
+ goto register_trace_sched_process_fork;
+ }
+ ret = register_trace_sched_process_exit(mbraink_trace_sched_process_exit, NULL);
+ if (ret) {
+ pr_notice("register register_trace_sched_process_exit failed.\n");
+ goto register_trace_sched_process_exit;
+ }
+
+ return ret;
+
+register_trace_sched_process_exit:
+ unregister_trace_sched_process_fork(mbraink_trace_sched_process_fork, NULL);
+register_trace_sched_process_fork:
+ return ret;
+}
+
+void mbraink_process_tracer_exit(void)
+{
+ unregister_trace_sched_process_fork(mbraink_trace_sched_process_fork, NULL);
+ unregister_trace_sched_process_exit(mbraink_trace_sched_process_exit, NULL);
+}
+
+void mbraink_get_tracing_pid_info(unsigned short current_idx,
+ struct mbraink_tracing_pid_data *tracing_pid_buffer)
+{
+ int i = 0;
+ int ret = 0;
+ unsigned long flags;
+ unsigned short tracing_count = 0;
+
+ spin_lock_irqsave(&tracing_pidlist_lock, flags);
+
+ memset(tracing_pid_buffer, 0, sizeof(struct mbraink_tracing_pid_data));
+
+ for (i = current_idx; i < MAX_TRACE_NUM; i++) {
+ if (mbraink_tracing_pidlist_data[i].dirty == false) {
+ continue;
+ } else {
+ tracing_count = tracing_pid_buffer->tracing_count;
+ if (tracing_count < MAX_TRACE_PID_NUM) {
+ tracing_pid_buffer->drv_data[tracing_count].pid =
+ mbraink_tracing_pidlist_data[i].pid;
+ tracing_pid_buffer->drv_data[tracing_count].tgid =
+ mbraink_tracing_pidlist_data[i].tgid;
+ tracing_pid_buffer->drv_data[tracing_count].uid =
+ mbraink_tracing_pidlist_data[i].uid;
+ tracing_pid_buffer->drv_data[tracing_count].priority =
+ mbraink_tracing_pidlist_data[i].priority;
+ memcpy(tracing_pid_buffer->drv_data[tracing_count].name,
+ mbraink_tracing_pidlist_data[i].name, TASK_COMM_LEN);
+ tracing_pid_buffer->drv_data[tracing_count].start =
+ mbraink_tracing_pidlist_data[i].start;
+ tracing_pid_buffer->drv_data[tracing_count].end =
+ mbraink_tracing_pidlist_data[i].end;
+ tracing_pid_buffer->drv_data[tracing_count].jiffies =
+ mbraink_tracing_pidlist_data[i].jiffies;
+ tracing_pid_buffer->tracing_count++;
+ /*Deal with the end process record*/
+ if (mbraink_tracing_pidlist_data[i].end != 0) {
+ mbraink_tracing_pidlist_data[i].pid = 0;
+ mbraink_tracing_pidlist_data[i].tgid = 0;
+ mbraink_tracing_pidlist_data[i].uid = 0;
+ mbraink_tracing_pidlist_data[i].priority = 0;
+ memset(mbraink_tracing_pidlist_data[i].name,
+ 0, TASK_COMM_LEN);
+ mbraink_tracing_pidlist_data[i].start = 0;
+ mbraink_tracing_pidlist_data[i].end = 0;
+ mbraink_tracing_pidlist_data[i].jiffies = 0;
+ mbraink_tracing_pidlist_data[i].dirty = false;
+ } else {
+ mbraink_tracing_pidlist_data[i].dirty = false;
+ }
+ } else {
+ ret = -1;
+ tracing_pid_buffer->tracing_idx = i;
+ break;
+ }
+ }
+ }
+ pr_info("%s: current_idx = %u, count = %u\n",
+ __func__, tracing_pid_buffer->tracing_idx, tracing_pid_buffer->tracing_count);
+ spin_unlock_irqrestore(&tracing_pidlist_lock, flags);
+}
diff --git a/drivers/misc/mediatek_mbraink/mbraink_data.h b/drivers/misc/mediatek_mbraink/mbraink_data.h
new file mode 100644
index 000000000000..c10ec1083b79
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/mbraink_data.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+#ifndef MBRAINK_DATA_H
+#define MBRAINK_DATA_H
+#include <linux/string_helpers.h>
+#include <linux/sched.h>
+#include <linux/sched/task.h>
+#include <linux/mm_types.h>
+#include <linux/pid.h>
+
+#include "mbraink_ioctl_struct_define.h"
+
+#define PSS_SHIFT 12
+#define MAX_RT_PRIO 100
+#define MAX_TRACE_NUM 3072
+
+struct mbraink_tracing_pidlist {
+ unsigned short pid;
+ unsigned short tgid;
+ unsigned short uid;
+ int priority;
+ char name[TASK_COMM_LEN];
+ long long start;
+ long long end;
+ u64 jiffies;
+ bool dirty;
+};
+
+struct mem_size_stats {
+ unsigned long resident;
+ unsigned long shared_clean;
+ unsigned long shared_dirty;
+ unsigned long private_clean;
+ unsigned long private_dirty;
+ unsigned long referenced;
+ unsigned long anonymous;
+ unsigned long lazyfree;
+ unsigned long anonymous_thp;
+ unsigned long shmem_thp;
+ unsigned long file_thp;
+ unsigned long swap;
+ unsigned long shared_hugetlb;
+ unsigned long private_hugetlb;
+ u64 pss;
+ u64 pss_anon;
+ u64 pss_file;
+ u64 pss_shmem;
+ u64 pss_locked;
+ u64 swap_pss;
+ bool check_shmem_swap;
+};
+
+void mbraink_get_process_memory_info(pid_t current_pid,
+ struct mbraink_process_memory_data *process_memory_buffer);
+int mbraink_process_tracer_init(void);
+void mbraink_process_tracer_exit(void);
+void mbraink_get_tracing_pid_info(unsigned short current_idx,
+ struct mbraink_tracing_pid_data *tracing_pid_buffer);
+void smap_gather_stats(struct vm_area_struct *vma,
+ struct mem_size_stats *mss, unsigned long start);
+
+void task_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st);
+void thread_group_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st);
+u64 nsec_to_clock_t(u64 x);
+#endif
diff --git a/drivers/misc/mediatek_mbraink/mbraink_ioctl_struct_define.h b/drivers/misc/mediatek_mbraink/mbraink_ioctl_struct_define.h
new file mode 100644
index 000000000000..8395cf3b3702
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/mbraink_ioctl_struct_define.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+#ifndef MBRAINK_IOCTL_STRUCT_H
+#define MBRAINK_IOCTL_STRUCT_H
+
+#define MAX_MEM_STRUCT_SZ 4
+#define MAX_TRACE_PID_NUM 16
+
+struct mbraink_process_memory_struct {
+ unsigned short pid;
+ unsigned long pss;
+ unsigned long uss;
+ unsigned long rss;
+ unsigned long swap;
+ unsigned long java_heap;
+ unsigned long native_heap;
+};
+
+struct mbraink_process_memory_data {
+ unsigned short pid;
+ unsigned short pid_count;
+ struct mbraink_process_memory_struct drv_data[MAX_MEM_STRUCT_SZ];
+};
+
+struct mbraink_tracing_pid {
+ unsigned short pid;
+ unsigned short tgid;
+ unsigned short uid;
+ int priority;
+ char name[TASK_COMM_LEN];
+ long long start;
+ long long end;
+ u64 jiffies;
+};
+
+struct mbraink_tracing_pid_data {
+ unsigned short tracing_idx;
+ unsigned short tracing_count;
+ struct mbraink_tracing_pid drv_data[MAX_TRACE_PID_NUM];
+};
+
+#endif
diff --git a/drivers/misc/mediatek_mbraink/mbraink_main.c b/drivers/misc/mediatek_mbraink/mbraink_main.c
new file mode 100644
index 000000000000..34bbc152b448
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/mbraink_main.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/compat.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/device.h>
+#include <linux/kdev_t.h>
+
+#include "mbraink_main.h"
+#include "mbraink_data.h"
+
+struct mbraink_data mbraink_priv;
+
+static int mbraink_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int mbraink_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static long mbraink_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ long ret = 0;
+
+ switch (cmd) {
+ case RO_PROCESS_MEMORY:
+ {
+ struct mbraink_process_memory_data process_memory_buffer;
+
+ pid_t pid = 1;
+
+ if (copy_from_user(&process_memory_buffer,
+ (struct mbraink_process_memory_data *)arg,
+ sizeof(process_memory_buffer))) {
+ pr_notice("copy process memory info from user Err!\n");
+ return -EPERM;
+ }
+
+ if (process_memory_buffer.pid > PID_MAX_DEFAULT ||
+ process_memory_buffer.pid_count > PID_MAX_DEFAULT) {
+ pr_notice("process memory: Invalid pid_idx %u or pid_count %u\n",
+ process_memory_buffer.pid, process_memory_buffer.pid_count);
+ return -EINVAL;
+ }
+ pid = process_memory_buffer.pid;
+
+ mbraink_get_process_memory_info(pid, &process_memory_buffer);
+
+ if (copy_to_user((struct mbraink_process_memory_data *)arg,
+ &process_memory_buffer,
+ sizeof(process_memory_buffer))) {
+ pr_notice("Copy process_memory_info to UserSpace error!\n");
+ return -EPERM;
+ }
+ break;
+ }
+ case RO_TRACE_PROCESS:
+ {
+ struct mbraink_tracing_pid_data tracing_pid_buffer;
+
+ unsigned short tracing_idx = 0;
+
+ if (copy_from_user(&tracing_pid_buffer,
+ (struct mbraink_tracing_pid_data *)arg,
+ sizeof(tracing_pid_buffer))) {
+ pr_notice("copy tracing_pid_buffer data from user Err!\n");
+ return -EPERM;
+ }
+
+ if (tracing_pid_buffer.tracing_idx > MAX_TRACE_NUM) {
+ pr_notice("invalid tracing_idx %u !\n",
+ tracing_pid_buffer.tracing_idx);
+ return -EINVAL;
+ }
+ tracing_idx = tracing_pid_buffer.tracing_idx;
+
+ mbraink_get_tracing_pid_info(tracing_idx, &tracing_pid_buffer);
+
+ if (copy_to_user((struct mbraink_tracing_pid_data *)arg,
+ &tracing_pid_buffer,
+ sizeof(tracing_pid_buffer))) {
+ pr_notice("Copy tracing_pid_buffer to UserSpace error!\n");
+ return -EPERM;
+ }
+ break;
+ }
+ default:
+ pr_notice("illegal ioctl number %u.\n", cmd);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+#if IS_ENABLED(CONFIG_COMPAT)
+static long mbraink_compat_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ return mbraink_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations mbraink_fops = {
+ .owner = THIS_MODULE,
+ .open = mbraink_open,
+ .release = mbraink_release,
+ .unlocked_ioctl = mbraink_ioctl,
+#if IS_ENABLED(CONFIG_COMPAT)
+ .compat_ioctl = mbraink_compat_ioctl,
+#endif
+};
+
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+static int mbraink_suspend(struct device *dev)
+{
+ int ret;
+
+ ret = pm_generic_suspend(dev);
+
+ return ret;
+}
+
+static int mbraink_resume(struct device *dev)
+{
+ int ret;
+
+ ret = pm_generic_resume(dev);
+
+ return ret;
+}
+
+static const struct dev_pm_ops mbraink_class_dev_pm_ops = {
+ .suspend = mbraink_suspend,
+ .resume = mbraink_resume,
+};
+
+#define MBRAINK_CLASS_DEV_PM_OPS (&mbraink_class_dev_pm_ops)
+#else
+#define MBRAINK_CLASS_DEV_PM_OPS NULL
+#endif /*end of CONFIG_PM_SLEEP*/
+
+static void class_create_release(struct class *cls)
+{
+ /*do nothing because the mbraink class is not from malloc*/
+}
+
+static struct class mbraink_class = {
+ .name = "mbraink_host",
+ .owner = THIS_MODULE,
+ .class_release = class_create_release,
+ .pm = MBRAINK_CLASS_DEV_PM_OPS,
+};
+
+static void device_create_release(struct device *dev)
+{
+ /*do nothing because the mbraink device is not from malloc*/
+}
+
+static struct device mbraink_device = {
+ .init_name = "mbraink",
+ .release = device_create_release,
+ .parent = NULL,
+ .driver_data = NULL,
+ .class = NULL,
+ .devt = 0,
+};
+
+static int mbraink_dev_init(void)
+{
+ dev_t mbraink_dev_no = 0;
+
+ /*Allocating Major number*/
+ if ((alloc_chrdev_region(&mbraink_dev_no, 0, 1, CHRDEV_NAME)) < 0) {
+ pr_notice("Cannot allocate major number %u\n",
+ mbraink_dev_no);
+ return -EBADF;
+ }
+ pr_info("[MBK_INFO] %s: Major = %u Minor = %u\n",
+ __func__, MAJOR(mbraink_dev_no),
+ MINOR(mbraink_dev_no));
+
+ /*Initialize cdev structure*/
+ cdev_init(&mbraink_priv.mbraink_cdev, &mbraink_fops);
+
+ /*Adding character device to the system*/
+ if ((cdev_add(&mbraink_priv.mbraink_cdev, mbraink_dev_no, 1)) < 0) {
+ pr_notice("Cannot add the device to the system\n");
+ goto r_class;
+ }
+
+ /*Register mbraink class*/
+ if (class_register(&mbraink_class)) {
+ pr_notice("Cannot register the mbraink class %s\n",
+ mbraink_class.name);
+ goto r_class;
+ }
+
+ /*add mbraink device into mbraink_class host,
+ *and assign the character device id to mbraink device
+ */
+
+ mbraink_device.devt = mbraink_dev_no;
+ mbraink_device.class = &mbraink_class;
+
+ /*Register mbraink device*/
+ if (device_register(&mbraink_device)) {
+ pr_notice("Cannot register the Device %s\n",
+ mbraink_device.init_name);
+ goto r_device;
+ }
+ pr_info("[MBK_INFO] %s: Mbraink device init done.\n", __func__);
+
+ return 0;
+
+r_device:
+ class_unregister(&mbraink_class);
+r_class:
+ unregister_chrdev_region(mbraink_dev_no, 1);
+
+ return -EPERM;
+}
+
+static int mbraink_init(void)
+{
+ int ret = 0;
+
+ ret = mbraink_dev_init();
+ if (ret)
+ pr_notice("mbraink device init failed.\n");
+
+ ret = mbraink_process_tracer_init();
+ if (ret)
+ pr_notice("mbraink tracer init failed.\n");
+
+ return ret;
+}
+
+static void mbraink_dev_exit(void)
+{
+ device_unregister(&mbraink_device);
+ mbraink_device.class = NULL;
+
+ class_unregister(&mbraink_class);
+ cdev_del(&mbraink_priv.mbraink_cdev);
+ unregister_chrdev_region(mbraink_device.devt, 1);
+
+ pr_info("[MBK_INFO] %s: MBraink device exit done, major:minor %u:%u\n",
+ __func__,
+ MAJOR(mbraink_device.devt),
+ MINOR(mbraink_device.devt));
+}
+
+static void mbraink_exit(void)
+{
+ mbraink_dev_exit();
+ mbraink_process_tracer_exit();
+}
+
+module_init(mbraink_init);
+module_exit(mbraink_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("<Wei-chin.Tsai@mediatek.com>");
+MODULE_DESCRIPTION("MBraink Linux Device Driver");
+MODULE_VERSION("1.0");
diff --git a/drivers/misc/mediatek_mbraink/mbraink_main.h b/drivers/misc/mediatek_mbraink/mbraink_main.h
new file mode 100644
index 000000000000..0bb3847cdffb
--- /dev/null
+++ b/drivers/misc/mediatek_mbraink/mbraink_main.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MBRAINK_MAIN_H
+#define MBRAINK_MAIN_H
+
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/pid.h>
+
+#include "mbraink_ioctl_struct_define.h"
+
+#define IOC_MAGIC 'k'
+
+/*Mbrain Delegate Info List*/
+#define PROCESS_MEMORY_INFO '4'
+#define TRACE_PROCESS_INFO 'a'
+
+/*Mbrain Delegate IOCTL List*/
+#define RO_PROCESS_MEMORY _IOR(IOC_MAGIC, PROCESS_MEMORY_INFO, \
+ struct mbraink_process_memory_data*)
+#define RO_TRACE_PROCESS _IOR(IOC_MAGIC, TRACE_PROCESS_INFO, \
+ struct mbraink_tracing_pid_data*)
+
+struct mbraink_data {
+#define CHRDEV_NAME "mbraink_chrdev"
+ struct cdev mbraink_cdev;
+};
+
+#endif /*end of MBRAINK_MAIN_H*/
diff --git a/kernel/exit.c b/kernel/exit.c
index edb50b4c9972..410a3de14e09 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -81,6 +81,8 @@
*/
static unsigned int oops_limit = 10000;
+EXPORT_TRACEPOINT_SYMBOL_GPL(sched_process_exit);
+
#ifdef CONFIG_SYSCTL
static struct ctl_table kern_exit_table[] = {
{
diff --git a/kernel/fork.c b/kernel/fork.c
index f81985dcc4bd..8fba356fb7c2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -142,6 +142,8 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0;
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
+EXPORT_TRACEPOINT_SYMBOL_GPL(sched_process_fork);
+
#ifdef CONFIG_PROVE_RCU
int lockdep_tasklist_lock_is_held(void)
{
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] process: export symbols for fork/exit tracing functions
2023-06-12 15:15 [PATCH v1 1/1] process: export symbols for fork/exit tracing functions jim.tsai
@ 2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:37 ` Greg Kroah-Hartman
2 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2023-06-12 16:35 UTC (permalink / raw)
To: jim.tsai
Cc: linux-kernel, Arnd Bergmann, Matthias Brugger,
AngeloGioacchino Del Regno, wsd_upstream, mel.lee, ivan.tseng,
linux-arm-kernel, linux-mediatek
On Mon, Jun 12, 2023 at 11:15:41PM +0800, jim.tsai wrote:
> Export the tracing function "sched_process_fork" and
> "sched_process_exit" for process statistics.
>
> Change-Id: I67dcdcb26371cd7a495ff0b210361742b1a2088e
> Signed-off-by: jim.tsai <Wei-chin.Tsai@mediatek.com>
You might want to run scripts/checkpatch.pl on your patch before you
send it out again, you don't need a change-id line.
Also, here's what my bot says:
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- Your patch contains warnings and/or errors noticed by the
scripts/checkpatch.pl tool.
- You did not specify a description of why the patch is needed, or
possibly, any description at all, in the email body. Please read the
section entitled "The canonical patch format" in the kernel file,
Documentation/process/submitting-patches.rst for what is needed in
order to properly describe the change.
- You did not write a descriptive Subject: for the patch, allowing Greg,
and everyone else, to know what this patch is all about. Please read
the section entitled "The canonical patch format" in the kernel file,
Documentation/process/submitting-patches.rst for what a proper
Subject: line should look like.
- It looks like you did not use your "real" name for the patch on either
the Signed-off-by: line, or the From: line (both of which have to
match). Please read the kernel file,
Documentation/process/submitting-patches.rst for how to do this
correctly.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] process: export symbols for fork/exit tracing functions
2023-06-12 15:15 [PATCH v1 1/1] process: export symbols for fork/exit tracing functions jim.tsai
2023-06-12 16:35 ` Greg Kroah-Hartman
@ 2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:37 ` Greg Kroah-Hartman
2 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2023-06-12 16:35 UTC (permalink / raw)
To: jim.tsai
Cc: linux-kernel, Arnd Bergmann, Matthias Brugger,
AngeloGioacchino Del Regno, wsd_upstream, mel.lee, ivan.tseng,
linux-arm-kernel, linux-mediatek
On Mon, Jun 12, 2023 at 11:15:41PM +0800, jim.tsai wrote:
> --- /dev/null
> +++ b/drivers/misc/mediatek_mbraink/mbraink_data.c
> @@ -0,0 +1,417 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
It's 2023 :)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] process: export symbols for fork/exit tracing functions
2023-06-12 15:15 [PATCH v1 1/1] process: export symbols for fork/exit tracing functions jim.tsai
2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:35 ` Greg Kroah-Hartman
@ 2023-06-12 16:37 ` Greg Kroah-Hartman
[not found] ` <8fa623a77edd2d8b6ade77903d40b4c4c5992965.camel@mediatek.com>
2 siblings, 1 reply; 5+ messages in thread
From: Greg Kroah-Hartman @ 2023-06-12 16:37 UTC (permalink / raw)
To: jim.tsai
Cc: linux-kernel, Arnd Bergmann, Matthias Brugger,
AngeloGioacchino Del Regno, wsd_upstream, mel.lee, ivan.tseng,
linux-arm-kernel, linux-mediatek
On Mon, Jun 12, 2023 at 11:15:41PM +0800, jim.tsai wrote:
> +static void class_create_release(struct class *cls)
> +{
> + /*do nothing because the mbraink class is not from malloc*/
> +}
Then the code is totally broken and wrong :(
Please just use the misc device api instead, it is much simpler and
doesn't have these types of errors.
thanks,
greg k-h
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] process: export symbols for fork/exit tracing functions
[not found] ` <8fa623a77edd2d8b6ade77903d40b4c4c5992965.camel@mediatek.com>
@ 2023-06-13 9:18 ` gregkh
0 siblings, 0 replies; 5+ messages in thread
From: gregkh @ 2023-06-13 9:18 UTC (permalink / raw)
To: Wei-chin Tsai (蔡維晉)
Cc: linux-kernel@vger.kernel.org, Mel Lee (李奇錚),
linux-mediatek@lists.infradead.org, wsd_upstream,
linux-arm-kernel@lists.infradead.org, matthias.bgg@gmail.com,
arnd@arndb.de, Ivan Tseng (曾志軒),
angelogioacchino.delregno@collabora.com
On Tue, Jun 13, 2023 at 09:12:38AM +0000, Wei-chin Tsai (蔡維晉) wrote:
> On Mon, 2023-06-12 at 18:37 +0200, Greg Kroah-Hartman wrote:
> >
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> > On Mon, Jun 12, 2023 at 11:15:41PM +0800, jim.tsai wrote:
> > > +static void class_create_release(struct class *cls)
> > > +{
> > > +/*do nothing because the mbraink class is not from malloc*/
> > > +}
> >
> > Then the code is totally broken and wrong :(
> >
> > Please just use the misc device api instead, it is much simpler and
> > doesn't have these types of errors.
> >
> > thanks,
> >
> > greg k-h
>
>
> Sorry, I did not really get the point from above comments because It
> works well for me for the mbraink_main.c and no compiler errors or
> runtime errors?
Think about why the kernel is trying to check if you have a release
function or not. Would an "empty" function be the same thing?
That check was added to tell you that your design is wrong and needs to
be fixed, do NOT just try to paper over warnings from the kernel as
someone spent the time to try to be nice and tell you that the code is
incorrect :)
Anyway, almost all of these (if not all), can just go away if you move
to use the miscdevice api instead.
Also, please don't send HTML email, the mailing lists reject it :(
thanks,
greg k-h
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-06-13 9:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-12 15:15 [PATCH v1 1/1] process: export symbols for fork/exit tracing functions jim.tsai
2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:35 ` Greg Kroah-Hartman
2023-06-12 16:37 ` Greg Kroah-Hartman
[not found] ` <8fa623a77edd2d8b6ade77903d40b4c4c5992965.camel@mediatek.com>
2023-06-13 9:18 ` gregkh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox