@@ -56,6 +56,55 @@ module_param(torture_type, charp, 0444);
5656MODULE_PARM_DESC (torture_type ,
5757 "Type of lock to torture (spin_lock, spin_lock_irq, mutex_lock, ...)" );
5858
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+
59108static struct task_struct * stats_task ;
60109static struct task_struct * * writer_tasks ;
61110static struct task_struct * * reader_tasks ;
@@ -986,16 +1035,23 @@ static int lock_torture_stats(void *arg)
9861035 return 0 ;
9871036}
9881037
1038+
9891039static inline void
9901040lock_torture_print_module_parms (struct lock_torture_ops * cur_ops ,
9911041 const char * tag )
9921042{
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 );
9931048 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" ,
9951050 torture_type , tag , cxt .debug_lock ? " [debug]" : "" ,
9961051 cxt .nrealwriters_stress , cxt .nrealreaders_stress ,
9971052 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 ));
9991055}
10001056
10011057static void lock_torture_cleanup (void )
@@ -1250,6 +1306,8 @@ static int __init lock_torture_init(void)
12501306 writer_fifo ? sched_set_fifo : NULL );
12511307 if (torture_init_error (firsterr ))
12521308 goto unwind ;
1309+ if (cpumask_nonempty (writers_bind ))
1310+ torture_sched_setaffinity (writer_tasks [i ]-> pid , writers_bind );
12531311
12541312 create_reader :
12551313 if (cxt .cur_ops -> readlock == NULL || (j >= cxt .nrealreaders_stress ))
@@ -1259,6 +1317,8 @@ static int __init lock_torture_init(void)
12591317 reader_tasks [j ]);
12601318 if (torture_init_error (firsterr ))
12611319 goto unwind ;
1320+ if (cpumask_nonempty (readers_bind ))
1321+ torture_sched_setaffinity (reader_tasks [j ]-> pid , readers_bind );
12621322 }
12631323 if (stat_interval > 0 ) {
12641324 firsterr = torture_create_kthread (lock_torture_stats , NULL ,
0 commit comments