@@ -35,6 +35,7 @@ MODULE_DESCRIPTION("LKP book:ch13/2_percpu: demo of using percpu variables");
35
35
MODULE_LICENSE ("Dual MIT/GPL" );
36
36
MODULE_VERSION ("0.1" );
37
37
38
+
38
39
#define SHOW_CPU_CTX () do { \
39
40
pr_info("*** kthread PID %d on cpu %d now ***\n",\
40
41
current->pid, smp_processor_id()); \
@@ -44,7 +45,12 @@ MODULE_VERSION("0.1");
44
45
#define THRD0_ITERS 3
45
46
#define THRD1_ITERS 3
46
47
47
- static long (* ptr_sched_setaffinity )(pid_t , const struct cpumask * );
48
+ static unsigned long func_ptr ;
49
+ module_param (func_ptr , ulong , 0 );
50
+
51
+ // schedsa_ptr is our function pointer to the sched_setaffinity() function
52
+ unsigned long (* schedsa_ptr )(pid_t , const struct cpumask * ) = NULL ;
53
+
48
54
static struct task_struct * arr_tsk [MAX_KTHRDS ];
49
55
50
56
/*--- The percpu variables, an integer 'pcpa' and a data structure --- */
@@ -79,12 +85,13 @@ static long set_cpuaffinity(unsigned int cpu)
79
85
{
80
86
struct cpumask mask ;
81
87
long ret = 0 ;
88
+
82
89
unsigned int euid = from_kuid (& init_user_ns , current_euid ());
83
90
struct cred * new ;
84
91
85
92
/*
86
93
* Not root? get root! (hey, we're in kernel mode :)
87
- * This isn't really required; we're just showing how to ...
94
+ * This isn't really required; we're just showing off ...
88
95
*/
89
96
if (unlikely (euid )) {
90
97
pr_info ("%s(): before commit_creds(): uid=%u euid=%u\n" ,
@@ -109,8 +116,9 @@ static long set_cpuaffinity(unsigned int cpu)
109
116
cpumask_set_cpu (cpu , & mask ); // 1st param is the CPU number, not bitmask
110
117
/* !HACK! sched_setaffinity() is NOT exported, we can't call it
111
118
* sched_setaffinity(0, &mask); // 0 => on self
112
- * so we invoke it via it's function pointer */
113
- ret = (* ptr_sched_setaffinity )(0 , & mask ); // 0 => on self
119
+ * so we invoke it via it's function pointer
120
+ */
121
+ ret = (* schedsa_ptr )(0 , & mask ); // 0 => on self
114
122
115
123
return ret ;
116
124
}
@@ -190,27 +198,34 @@ static int run_kthrd(char *kname, long thrdnum)
190
198
return 0 ;
191
199
}
192
200
201
+
193
202
static int __init init_percpu_var (void )
194
203
{
195
204
int ret = 0 ;
196
205
197
206
pr_info ("inserted\n" );
198
207
199
- /* WARNING! This is considered a hack.
208
+ /* ! WARNING! This is considered a hack.
200
209
* As sched_setaffinity() isn't exported, we don't have access to it
201
- * within this kernel module. So, here we resort to a hack: we use
202
- * kallsyms_lookup_name() (which works when CONFIG_KALLSYMS is defined)
203
- * to retrieve the function pointer, subsequently calling the function
204
- * via it's pointer (with 'C' what you do is only limited by your
205
- * imagination :). Not pedantically right, but hey, it works.
210
+ * within this kernel module. So, here we resort to a hack:
211
+ * a) Until 5.7, we could directly use the kallsyms_lookup_name() function
212
+ * (which works when CONFIG_KALLSYMS is defined) to retrieve the function
213
+ * pointer, and subsequently call the function via it's pointer (with 'C'
214
+ * what you do is only limited by your imagination :).
215
+ * b) From 5.7 on, the kernel devs unexported the kallsyms_lookup_name()!
216
+ * (Rationale: https://lwn.net/Articles/813350/). With it gone, we now
217
+ * simply use this approach: a helper script greps the kallsyms_lookup_name()
218
+ * address and passes it to this module! We equate it to the exepcted
219
+ * function signature - that of sched_setaffinity() - and use it.
220
+ * *Not* pedantically right, but hey, it works. Don't do this in production.
206
221
*/
207
222
ret = - ENOSYS ;
208
- ptr_sched_setaffinity = (void * )kallsyms_lookup_name ("sched_setaffinity" );
209
- if (!ptr_sched_setaffinity ) {
223
+ if (!func_ptr ) {
210
224
pr_warn ("%s: couldn't obtain sched_setaffinity() addr via "
211
- "kallsyms_lookup_name() , aborting ...\n" , OURMODNAME );
225
+ "module param , aborting ...\n" , OURMODNAME );
212
226
return ret ;
213
227
}
228
+ schedsa_ptr = (unsigned long (* )(pid_t pid , const struct cpumask * in_mask ))func_ptr ;
214
229
215
230
/* Dynamically allocate the percpu structures */
216
231
ret = - ENOMEM ;
0 commit comments