@@ -56,6 +56,55 @@ module_param(torture_type, charp, 0444);
56
56
MODULE_PARM_DESC (torture_type ,
57
57
"Type of lock to torture (spin_lock, spin_lock_irq, mutex_lock, ...)" );
58
58
59
+ static cpumask_var_t readers_bind ; // Bind the readers to the specified set of CPUs.
60
+ static cpumask_var_t writers_bind ; // Bind the writers to the specified set of CPUs.
61
+
62
+ // Parse a cpumask kernel parameter. If there are more users later on,
63
+ // this might need to got to a more central location.
64
+ static int param_set_cpumask (const char * val , const struct kernel_param * kp )
65
+ {
66
+ cpumask_var_t * cm_bind = kp -> arg ;
67
+ int ret ;
68
+ char * s ;
69
+
70
+ if (!alloc_cpumask_var (cm_bind , GFP_KERNEL )) {
71
+ s = "Out of memory" ;
72
+ ret = - ENOMEM ;
73
+ goto out_err ;
74
+ }
75
+ ret = cpulist_parse (val , * cm_bind );
76
+ if (!ret )
77
+ return ret ;
78
+ s = "Bad CPU range" ;
79
+ out_err :
80
+ pr_warn ("%s: %s, all CPUs set\n" , kp -> name , s );
81
+ cpumask_setall (* cm_bind );
82
+ return ret ;
83
+ }
84
+
85
+ // Output a cpumask kernel parameter.
86
+ static int param_get_cpumask (char * buffer , const struct kernel_param * kp )
87
+ {
88
+ cpumask_var_t * cm_bind = kp -> arg ;
89
+
90
+ return sprintf (buffer , "%*pbl" , cpumask_pr_args (* cm_bind ));
91
+ }
92
+
93
+ static bool cpumask_nonempty (cpumask_var_t mask )
94
+ {
95
+ return cpumask_available (mask ) && !cpumask_empty (mask );
96
+ }
97
+
98
+ static const struct kernel_param_ops lt_bind_ops = {
99
+ .set = param_set_cpumask ,
100
+ .get = param_get_cpumask ,
101
+ };
102
+
103
+ module_param_cb (readers_bind , & lt_bind_ops , & readers_bind , 0644 );
104
+ module_param_cb (writers_bind , & lt_bind_ops , & writers_bind , 0644 );
105
+
106
+ long torture_sched_setaffinity (pid_t pid , const struct cpumask * in_mask );
107
+
59
108
static struct task_struct * stats_task ;
60
109
static struct task_struct * * writer_tasks ;
61
110
static struct task_struct * * reader_tasks ;
@@ -986,16 +1035,23 @@ static int lock_torture_stats(void *arg)
986
1035
return 0 ;
987
1036
}
988
1037
1038
+
989
1039
static inline void
990
1040
lock_torture_print_module_parms (struct lock_torture_ops * cur_ops ,
991
1041
const char * tag )
992
1042
{
1043
+ static cpumask_t cpumask_all ;
1044
+ cpumask_t * rcmp = cpumask_nonempty (readers_bind ) ? readers_bind : & cpumask_all ;
1045
+ cpumask_t * wcmp = cpumask_nonempty (writers_bind ) ? writers_bind : & cpumask_all ;
1046
+
1047
+ cpumask_setall (& cpumask_all );
993
1048
pr_alert ("%s" TORTURE_FLAG
994
- "--- %s%s: nwriters_stress=%d nreaders_stress=%d nested_locks=%d stat_interval=%d verbose=%d shuffle_interval=%d stutter=%d shutdown_secs=%d onoff_interval=%d onoff_holdoff=%d\n" ,
1049
+ "--- %s%s: nwriters_stress=%d nreaders_stress=%d nested_locks=%d stat_interval=%d verbose=%d shuffle_interval=%d stutter=%d shutdown_secs=%d onoff_interval=%d onoff_holdoff=%d readers_bind=%*pbl writers_bind=%*pbl \n" ,
995
1050
torture_type , tag , cxt .debug_lock ? " [debug]" : "" ,
996
1051
cxt .nrealwriters_stress , cxt .nrealreaders_stress ,
997
1052
nested_locks , stat_interval , verbose , shuffle_interval ,
998
- stutter , shutdown_secs , onoff_interval , onoff_holdoff );
1053
+ stutter , shutdown_secs , onoff_interval , onoff_holdoff ,
1054
+ cpumask_pr_args (rcmp ), cpumask_pr_args (wcmp ));
999
1055
}
1000
1056
1001
1057
static void lock_torture_cleanup (void )
@@ -1250,6 +1306,8 @@ static int __init lock_torture_init(void)
1250
1306
writer_fifo ? sched_set_fifo : NULL );
1251
1307
if (torture_init_error (firsterr ))
1252
1308
goto unwind ;
1309
+ if (cpumask_nonempty (writers_bind ))
1310
+ torture_sched_setaffinity (writer_tasks [i ]-> pid , writers_bind );
1253
1311
1254
1312
create_reader :
1255
1313
if (cxt .cur_ops -> readlock == NULL || (j >= cxt .nrealreaders_stress ))
@@ -1259,6 +1317,8 @@ static int __init lock_torture_init(void)
1259
1317
reader_tasks [j ]);
1260
1318
if (torture_init_error (firsterr ))
1261
1319
goto unwind ;
1320
+ if (cpumask_nonempty (readers_bind ))
1321
+ torture_sched_setaffinity (reader_tasks [j ]-> pid , readers_bind );
1262
1322
}
1263
1323
if (stat_interval > 0 ) {
1264
1324
firsterr = torture_create_kthread (lock_torture_stats , NULL ,
0 commit comments