The following changes since commit 225ba9e3433cf27d8ff7b213d9f78b7ef2776c70:
Branch and cache miss speedups (2014-02-26 14:31:15 -0800)
are available in the git repository at:
git://git.kernel.dk/fio.git master
for you to fetch changes up to a1fc70fbb0497a4e0dc061bd8fc35c8d4d29d2dd:
windows: fix fio_cpu_count() definition (2014-02-27 16:24:15 -0800)
----------------------------------------------------------------
Jens Axboe (4):
Add support for cpus_allowed_policy
Update IO engine version
windows: add proper header for hweight64()
windows: fix fio_cpu_count() definition
HOWTO | 11 +++++++++++
backend.c | 9 +++++++++
cconv.c | 2 ++
fio.1 | 19 +++++++++++++++++++
fio.h | 5 +++++
ioengine.h | 2 +-
options.c | 36 ++++++++++++++++++++++++++++++++++++
os/os-freebsd.h | 1 +
os/os-linux.h | 1 +
os/os-solaris.h | 10 ++++++++++
os/os-windows.h | 6 ++++++
os/os.h | 3 +++
server.h | 2 +-
thread_options.h | 2 ++
14 files changed, 107 insertions(+), 2 deletions(-)
---
Diff of recent changes:
diff --git a/HOWTO b/HOWTO
index 4dacd98..ef2b631 100644
--- a/HOWTO
+++ b/HOWTO
@@ -928,6 +928,17 @@ cpus_allowed=str Controls the same options as cpumask, but
it allows a text
allows a range of CPUs. Say you wanted a binding to CPUs
1, 5, and 8-15, you would set cpus_allowed=1,5,8-15.
+cpus_allowed_policy=str Set the policy of how fio distributes the CPUs
+ specified by cpus_allowed or cpumask. Two policies are
+ supported:
+
+ shared All jobs will share the CPU set specified.
+ split Each job will get a unique CPU from the CPU set.
+
+ 'shared' is the default behaviour, if the option isn't
+ specified. If split is specified, then fio will error out if
+ there are more jobs defined than CPUs given in the set.
+
numa_cpu_nodes=str Set this job running on spcified NUMA nodes' CPUs. The
arguments allow comma delimited list of cpu numbers,
A-B ranges, or 'all'. Note, to enable numa options support,
diff --git a/backend.c b/backend.c
index ee395bd..12c76d8 100644
--- a/backend.c
+++ b/backend.c
@@ -1278,6 +1278,15 @@ static void *thread_main(void *data)
* allocations.
*/
if (o->cpumask_set) {
+ if (o->cpus_allowed_policy == FIO_CPUS_SPLIT) {
+ ret = fio_cpus_split(&o->cpumask, td->thread_number);
+ if (!ret) {
+ log_err("fio: no CPUs set\n");
+ log_err("fio: Try increasing number of
available CPUs\n");
+ td_verror(td, EINVAL, "cpus_split");
+ goto err;
+ }
+ }
ret = fio_setaffinity(td->pid, o->cpumask);
if (ret == -1) {
td_verror(td, errno, "cpu_set_affinity");
diff --git a/cconv.c b/cconv.c
index fd8d0ad..357a784 100644
--- a/cconv.c
+++ b/cconv.c
@@ -188,6 +188,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
o->numjobs = le32_to_cpu(top->numjobs);
o->cpumask_set = le32_to_cpu(top->cpumask_set);
o->verify_cpumask_set = le32_to_cpu(top->verify_cpumask_set);
+ o->cpus_allowed_policy = le32_to_cpu(top->cpus_allowed_policy);
o->iolog = le32_to_cpu(top->iolog);
o->rwmixcycle = le32_to_cpu(top->rwmixcycle);
o->nice = le32_to_cpu(top->nice);
@@ -343,6 +344,7 @@ void convert_thread_options_to_net(struct
thread_options_pack *top,
top->numjobs = cpu_to_le32(o->numjobs);
top->cpumask_set = cpu_to_le32(o->cpumask_set);
top->verify_cpumask_set = cpu_to_le32(o->verify_cpumask_set);
+ top->cpus_allowed_policy = cpu_to_le32(o->cpus_allowed_policy);
top->iolog = cpu_to_le32(o->iolog);
top->rwmixcycle = cpu_to_le32(o->rwmixcycle);
top->nice = cpu_to_le32(o->nice);
diff --git a/fio.1 b/fio.1
index c530d84..863b0e0 100644
--- a/fio.1
+++ b/fio.1
@@ -833,6 +833,25 @@ may run on. See \fBsched_setaffinity\fR\|(2).
.BI cpus_allowed \fR=\fPstr
Same as \fBcpumask\fR, but allows a comma-delimited list of CPU numbers.
.TP
+.BI cpus_allowed_policy \fR=\fPstr
+Set the policy of how fio distributes the CPUs specified by \fBcpus_allowed\fR
+or \fBcpumask\fR. Two policies are supported:
+.RS
+.RS
+.TP
+.B shared
+All jobs will share the CPU set specified.
+.TP
+.B split
+Each job will get a unique CPU from the CPU set.
+.RE
+.P
+\fBshared\fR is the default behaviour, if the option isn't specified. If
+\fBsplit\fR is specified, then fio will error out if there are more jobs
+defined than CPUs given in the set.
+.RE
+.P
+.TP
.BI numa_cpu_nodes \fR=\fPstr
Set this job running on specified NUMA nodes' CPUs. The arguments allow
comma delimited list of cpu numbers, A-B ranges, or 'all'.
diff --git a/fio.h b/fio.h
index 9159b0c..6f5f29f 100644
--- a/fio.h
+++ b/fio.h
@@ -629,4 +629,9 @@ enum {
FIO_RAND_GEN_LFSR,
};
+enum {
+ FIO_CPUS_SHARED = 0,
+ FIO_CPUS_SPLIT,
+};
+
#endif
diff --git a/ioengine.h b/ioengine.h
index 7e0707b..6e3c717 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -15,7 +15,7 @@
#include <guasi.h>
#endif
-#define FIO_IOOPS_VERSION 17
+#define FIO_IOOPS_VERSION 18
enum {
IO_U_F_FREE = 1 << 0,
diff --git a/options.c b/options.c
index 6d3956e..c1a8f32 100644
--- a/options.c
+++ b/options.c
@@ -394,6 +394,21 @@ static int str_exitall_cb(void)
}
#ifdef FIO_HAVE_CPU_AFFINITY
+int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu)
+{
+ const long max_cpu = cpus_online();
+ unsigned int i;
+
+ for (i = 0; i < max_cpu; i++) {
+ if (cpu != i) {
+ fio_cpu_clear(mask, i);
+ continue;
+ }
+ }
+
+ return fio_cpu_count(mask);
+}
+
static int str_cpumask_cb(void *data, unsigned long long *val)
{
struct thread_data *td = data;
@@ -2875,6 +2890,27 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_CRED,
},
+ {
+ .name = "cpus_allowed_policy",
+ .lname = "CPUs allowed distribution policy",
+ .type = FIO_OPT_STR,
+ .off1 = td_var_offset(cpus_allowed_policy),
+ .help = "Distribution policy for cpus_allowed",
+ .parent = "cpus_allowed",
+ .prio = 1,
+ .posval = {
+ { .ival = "shared",
+ .oval = FIO_CPUS_SHARED,
+ .help = "Mask shared between threads",
+ },
+ { .ival = "split",
+ .oval = FIO_CPUS_SPLIT,
+ .help = "Mask split between threads",
+ },
+ },
+ .category = FIO_OPT_C_GENERAL,
+ .group = FIO_OPT_G_CRED,
+ },
#endif
#ifdef CONFIG_LIBNUMA
{
diff --git a/os/os-freebsd.h b/os/os-freebsd.h
index 57ce409..402792a 100644
--- a/os/os-freebsd.h
+++ b/os/os-freebsd.h
@@ -32,6 +32,7 @@ typedef cpuset_t os_cpu_mask_t;
#define fio_cpu_clear(mask, cpu) (void) CPU_CLR((cpu), (mask))
#define fio_cpu_set(mask, cpu) (void) CPU_SET((cpu), (mask))
+#define fio_cpu_count(maks) CPU_COUNT((mask))
static inline int fio_cpuset_init(os_cpu_mask_t *mask)
{
diff --git a/os/os-linux.h b/os/os-linux.h
index 5d1d62d..3ed8c2e 100644
--- a/os/os-linux.h
+++ b/os/os-linux.h
@@ -61,6 +61,7 @@ typedef struct drand48_data os_random_state_t;
#define fio_cpu_clear(mask, cpu) (void) CPU_CLR((cpu), (mask))
#define fio_cpu_set(mask, cpu) (void) CPU_SET((cpu), (mask))
+#define fio_cpu_count(maks) CPU_COUNT((mask))
static inline int fio_cpuset_init(os_cpu_mask_t *mask)
{
diff --git a/os/os-solaris.h b/os/os-solaris.h
index e661211..7a0a3f0 100644
--- a/os/os-solaris.h
+++ b/os/os-solaris.h
@@ -111,6 +111,16 @@ static inline int fio_cpuset_init(os_cpu_mask_t *mask)
return 0;
}
+static inline int fio_cpuset_count(os_cpu_mask_t *mask)
+{
+ unsigned int num_cpus;
+
+ if (pset_info(*mask, NULL, &num_cpus, NULL) < 0)
+ return 0;
+
+ return num_cpus;
+}
+
static inline int fio_cpuset_exit(os_cpu_mask_t *mask)
{
if (pset_destroy(*mask) < 0)
diff --git a/os/os-windows.h b/os/os-windows.h
index de120b6..243edc6 100644
--- a/os/os-windows.h
+++ b/os/os-windows.h
@@ -15,6 +15,7 @@
#include "../smalloc.h"
#include "../file.h"
#include "../log.h"
+#include "../lib/hweight.h"
#include "windows/posix.h"
@@ -214,6 +215,11 @@ static inline void fio_cpu_set(os_cpu_mask_t *mask, int
cpu)
*mask |= 1 << cpu;
}
+static inline int fio_cpu_count(os_cpu_mask_t *mask)
+{
+ return hweight64(*mask);
+}
+
static inline int fio_cpuset_init(os_cpu_mask_t *mask)
{
*mask = 0;
diff --git a/os/os.h b/os/os.h
index 03d1e9a..a6bc17f 100644
--- a/os/os.h
+++ b/os/os.h
@@ -80,7 +80,10 @@ typedef struct aiocb os_aiocb_t;
#define fio_getaffinity(pid, mask) do { } while (0)
#define fio_cpu_clear(mask, cpu) do { } while (0)
#define fio_cpuset_exit(mask) (-1)
+#define fio_cpus_split(mask, cpu) (0)
typedef unsigned long os_cpu_mask_t;
+#else
+extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu);
#endif
#ifndef FIO_HAVE_IOPRIO
diff --git a/server.h b/server.h
index 85d9d7e..8f79c14 100644
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@ struct fio_net_cmd_reply {
};
enum {
- FIO_SERVER_VER = 31,
+ FIO_SERVER_VER = 32,
FIO_SERVER_MAX_FRAGMENT_PDU = 1024,
diff --git a/thread_options.h b/thread_options.h
index 14a4e54..4ea6ebd 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -155,6 +155,7 @@ struct thread_options {
unsigned int cpumask_set;
os_cpu_mask_t verify_cpumask;
unsigned int verify_cpumask_set;
+ unsigned int cpus_allowed_policy;
#ifdef CONFIG_LIBNUMA
struct bitmask *numa_cpunodesmask;
unsigned int numa_cpumask_set;
@@ -378,6 +379,7 @@ struct thread_options_pack {
uint32_t cpumask_set;
uint8_t verify_cpumask[FIO_TOP_STR_MAX];
uint32_t verify_cpumask_set;
+ uint32_t cpus_allowed_policy;
uint32_t iolog;
uint32_t rwmixcycle;
uint32_t rwmix[DDIR_RWDIR_CNT];
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html