cpumask can be cumbersome to use, since it requires you to calculate
a decimal mask to pass to fio. So add a cpus_allowed option that
takes a text list of allowed cpus, ala: cpus_allowed=1,3,8 will set
the affinity mask for CPUS 1, 3, and 8.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
sched_setaffinity(2). This may not work on all supported
operating systems or kernel versions.
sched_setaffinity(2). This may not work on all supported
operating systems or kernel versions.
+cpus_allowed=str Controls the same options as cpumask, but it allows a text
+ setting of the permitted CPUs instead. So to use CPUs 1 and
+ 5, you would specify cpus_allowed=1,5.
+
startdelay=int Start this job the specified number of seconds after fio
has started. Only useful if the job file contains several
jobs, and you want to delay starting some jobs to a certain
startdelay=int Start this job the specified number of seconds after fio
has started. Only useful if the job file contains several
jobs, and you want to delay starting some jobs to a certain
ratemin=x Quit if rate of x KiB/sec can't be met
ratecycle=x ratemin averaged over x msecs
cpumask=x Only allow job to run on CPUs defined by mask.
ratemin=x Quit if rate of x KiB/sec can't be met
ratecycle=x ratemin averaged over x msecs
cpumask=x Only allow job to run on CPUs defined by mask.
+ cpus_allowed=x Like 'cpumask', but allow text setting of CPU affinity.
fsync=x If writing with buffered IO, fsync after every
'x' blocks have been written.
end_fsync=x If 'x', run fsync() after end-of-job.
fsync=x If writing with buffered IO, fsync after every
'x' blocks have been written.
end_fsync=x If 'x', run fsync() after end-of-job.
-static void fill_cpu_mask(os_cpu_mask_t *cpumask, int cpu)
-{
#ifdef FIO_HAVE_CPU_AFFINITY
#ifdef FIO_HAVE_CPU_AFFINITY
+static int str_cpumask_cb(void *data, unsigned int *val)
+{
+ struct thread_data *td = data;
+ CPU_ZERO(&td->o.cpumask);
for (i = 0; i < sizeof(int) * 8; i++)
for (i = 0; i < sizeof(int) * 8; i++)
- if ((1 << i) & cpu)
- CPU_SET(i, cpumask);
-#endif
+ if ((1 << i) & *val)
+ CPU_SET(*val, &td->o.cpumask);
+
+ td->o.cpumask_set = 1;
+ return 0;
-static int str_cpumask_cb(void *data, unsigned int *val)
+static int str_cpus_allowed_cb(void *data, const char *input)
{
struct thread_data *td = data;
{
struct thread_data *td = data;
+ char *cpu, *str, *p;
+
+ CPU_ZERO(&td->o.cpumask);
+
+ p = str = strdup(input);
- fill_cpu_mask(&td->o.cpumask, *val);
+ strip_blank_front(&str);
+ strip_blank_end(str);
+
+ while ((cpu = strsep(&str, ",")) != NULL) {
+ if (!strlen(cpu))
+ break;
+ CPU_SET(atoi(cpu), &td->o.cpumask);
+ }
+
+ free(p);
static int str_fst_cb(void *data, const char *str)
{
static int str_fst_cb(void *data, const char *str)
{
.cb = str_cpumask_cb,
.help = "CPU affinity mask",
},
.cb = str_cpumask_cb,
.help = "CPU affinity mask",
},
+ {
+ .name = "cpus_allowed",
+ .type = FIO_OPT_STR,
+ .cb = str_cpus_allowed_cb,
+ .help = "Set CPUs allowed",
+ },
#endif
{
.name = "end_fsync",
#endif
{
.name = "end_fsync",