• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * drivers/auth_ctl/auth_qos_debug.c
4  *
5  * Copyright (c) 2022 Huawei Device Co., Ltd.
6  *
7  */
8 #include <linux/cred.h>
9 #include <linux/mutex.h>
10 #include <linux/errno.h>
11 #include <linux/fs.h>
12 #include <linux/miscdevice.h>
13 #include <linux/module.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/proc_fs.h>
18 #include <linux/seq_file.h>
19 #include <linux/sched/auth_ctrl.h>
20 #include <linux/sched/rtg_auth.h>
21 #include <linux/sched/qos_ctrl.h>
22 #include <linux/sched/qos_auth.h>
23 
24 #include "auth_ctrl.h"
25 #include "qos_ctrl.h"
26 
27 #define seq_printf_auth(m, x...) \
28 do { \
29 	if (m) \
30 		seq_printf(m, x); \
31 	else \
32 		printk(x); \
33 } while (0)
34 
print_auth_id(struct seq_file * file,const int tgid)35 static void print_auth_id(struct seq_file *file,
36 	const int tgid)
37 {
38 	seq_printf_auth(file, "AUTH_PID            :%d\n", tgid);
39 }
40 
print_auth_info(struct seq_file * file,const struct auth_struct * auth)41 static void print_auth_info(struct seq_file *file,
42 	const struct auth_struct *auth)
43 {
44 	seq_printf_auth(file, "AUTH_STATUS        :%d\n", auth->status);
45 #ifdef CONFIG_RTG_AUTHORITY
46 	seq_printf_auth(file, "RTG_FLAG           :%04x\n", auth->rtg_auth_flag);
47 #endif
48 #ifdef CONFIG_QOS_AUTHORITY
49 	seq_printf_auth(file, "QOS_FLAG           :%04x\n", auth->qos_auth_flag);
50 #endif
51 }
52 
print_qos_count(struct seq_file * file,const struct auth_struct * auth)53 static void print_qos_count(struct seq_file *file,
54 	const struct auth_struct *auth)
55 {
56 	int i;
57 
58 	for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i)
59 		seq_printf_auth(file, "QOS level %d thread nr  :%d\n", i, auth->num[i]);
60 }
61 
print_qos_thread(struct seq_file * file,const struct auth_struct * auth)62 static void print_qos_thread(struct seq_file *file,
63 	const struct auth_struct *auth)
64 {
65 	struct qos_task_struct *tmp, *next;
66 	struct task_struct *p;
67 	int i;
68 
69 	for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i) {
70 		seq_printf_auth(file, "QOS level %d threads:", i);
71 		list_for_each_entry_safe(tmp, next, &auth->tasks[i], qos_list) {
72 			p = container_of(tmp, struct task_struct, qts);
73 			seq_printf_auth(file, "%d ", p->pid);
74 		}
75 		seq_printf_auth(file, "\n");
76 	}
77 
78 }
79 
print_auth_struct(struct seq_file * file,struct auth_struct * auth)80 static inline void print_auth_struct(struct seq_file *file, struct auth_struct *auth)
81 {
82 	print_auth_info(file, auth);
83 	seq_printf_auth(file, "\n");
84 	print_qos_count(file, auth);
85 	seq_printf_auth(file, "\n");
86 #ifdef CONFIG_QOS_CTRL
87 	print_qos_thread(file, auth);
88 #endif
89 	seq_printf_auth(file, "---------------------------------------------------------\n");
90 
91 }
92 
authority_printf_handler(int id,void * p,void * para)93 int authority_printf_handler(int id, void *p, void *para)
94 {
95 	struct auth_struct *auth = (struct auth_struct *)p;
96 	struct seq_file *file = (struct seq_file *)para;
97 
98 	/*
99 	 * data consistency is not that important here
100 	 */
101 	seq_printf_auth(file, "\n\n");
102 	print_auth_id(file, id);
103 	seq_printf_auth(file, "\n");
104 
105 	/* no need to add refcount here, auth must alive in ua_idr_mutex */
106 	print_auth_struct(file, auth);
107 
108 	return 0;
109 }
110 
sched_auth_debug_show(struct seq_file * file,void * param)111 static int sched_auth_debug_show(struct seq_file *file, void *param)
112 {
113 	struct idr *ua_idr = get_auth_ctrl_idr();
114 	struct mutex *ua_idr_mutex = get_auth_idr_mutex();
115 	/*
116 	 * NOTICE:
117 	 * if mutex in authority_printf_handler, sleep may occur
118 	 * change ths spin_lock to mutex, or remove mutex in handler
119 	 */
120 
121 	mutex_lock(ua_idr_mutex);
122 	/* will never return 0 here, auth in ua_idr must alive */
123 	idr_for_each(ua_idr, authority_printf_handler, file);
124 	mutex_unlock(ua_idr_mutex);
125 
126 	return 0;
127 }
128 
sched_auth_debug_release(struct inode * inode,struct file * file)129 static int sched_auth_debug_release(struct inode *inode, struct file *file)
130 {
131 	seq_release(inode, file);
132 	return 0;
133 }
134 
sched_auth_debug_open(struct inode * inode,struct file * filp)135 static int sched_auth_debug_open(struct inode *inode, struct file *filp)
136 {
137 	return single_open(filp, sched_auth_debug_show, NULL);
138 }
139 
140 static const struct proc_ops sched_auth_debug_fops = {
141 	.proc_open = sched_auth_debug_open,
142 	.proc_read = seq_read,
143 	.proc_lseek = seq_lseek,
144 	.proc_release = sched_auth_debug_release,
145 };
146 
init_sched_auth_debug_procfs(void)147 int __init init_sched_auth_debug_procfs(void)
148 {
149 	struct proc_dir_entry *pe = NULL;
150 
151 	pe = proc_create("sched_auth_qos_debug",
152 		0400, NULL, &sched_auth_debug_fops);
153 	if (unlikely(!pe))
154 		return -ENOMEM;
155 	return 0;
156 }
157 
158