Commit | Line | Data |
---|---|---|
a7e8aae0 KB |
1 | /* |
2 | * Note: This is similar to a very basic setup | |
3 | * of ZBD devices | |
4 | * | |
5 | * Specify fdp=1 (With char devices /dev/ng0n1) | |
6 | */ | |
7 | ||
8 | #include <errno.h> | |
9 | #include <string.h> | |
10 | #include <stdlib.h> | |
11 | #include <unistd.h> | |
a7e8aae0 | 12 | #include "fio.h" |
7d352b12 | 13 | #include "file.h" |
a7e8aae0 KB |
14 | |
15 | #include "pshared.h" | |
c60d54ae | 16 | #include "dataplacement.h" |
a7e8aae0 KB |
17 | |
18 | static int fdp_ruh_info(struct thread_data *td, struct fio_file *f, | |
19 | struct fio_ruhs_info *ruhs) | |
20 | { | |
21 | int ret = -EINVAL; | |
22 | ||
5a85d6d8 JA |
23 | if (!td->io_ops) { |
24 | log_err("fio: no ops set in fdp init?!\n"); | |
25 | return ret; | |
26 | } | |
27 | ||
28 | if (td->io_ops->fdp_fetch_ruhs) { | |
a7e8aae0 KB |
29 | ret = td->io_ops->fdp_fetch_ruhs(td, f, ruhs); |
30 | if (ret < 0) { | |
31 | td_verror(td, errno, "fdp fetch ruhs failed"); | |
32 | log_err("%s: fdp fetch ruhs failed (%d)\n", | |
33 | f->file_name, errno); | |
34 | } | |
5a85d6d8 | 35 | } else { |
a7e8aae0 KB |
36 | log_err("%s: engine (%s) lacks fetch ruhs\n", |
37 | f->file_name, td->io_ops->name); | |
5a85d6d8 | 38 | } |
a7e8aae0 KB |
39 | |
40 | return ret; | |
41 | } | |
42 | ||
43 | static int init_ruh_info(struct thread_data *td, struct fio_file *f) | |
44 | { | |
45 | struct fio_ruhs_info *ruhs, *tmp; | |
46 | int i, ret; | |
47 | ||
98cd3c0e | 48 | ruhs = scalloc(1, sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(*ruhs->plis)); |
a7e8aae0 KB |
49 | if (!ruhs) |
50 | return -ENOMEM; | |
51 | ||
1a3a21b7 VF |
52 | /* set up the data structure used for FDP to work with the supplied stream IDs */ |
53 | if (td->o.dp_type == FIO_DP_STREAMS) { | |
54 | if (!td->o.dp_nr_ids) { | |
55 | log_err("fio: stream IDs must be provided for dataplacement=streams\n"); | |
56 | return -EINVAL; | |
57 | } | |
58 | ruhs->nr_ruhs = td->o.dp_nr_ids; | |
59 | for (int i = 0; i < ruhs->nr_ruhs; i++) | |
60 | ruhs->plis[i] = td->o.dp_ids[i]; | |
61 | ||
62 | f->ruhs_info = ruhs; | |
63 | return 0; | |
64 | } | |
65 | ||
a7e8aae0 KB |
66 | ret = fdp_ruh_info(td, f, ruhs); |
67 | if (ret) { | |
68 | log_info("fio: ruh info failed for %s (%d)\n", | |
69 | f->file_name, -ret); | |
70 | goto out; | |
71 | } | |
72 | ||
98cd3c0e AK |
73 | if (ruhs->nr_ruhs > FDP_MAX_RUHS) |
74 | ruhs->nr_ruhs = FDP_MAX_RUHS; | |
a7e8aae0 | 75 | |
65ca6791 | 76 | if (td->o.dp_nr_ids == 0) { |
a7e8aae0 KB |
77 | f->ruhs_info = ruhs; |
78 | return 0; | |
79 | } | |
80 | ||
65ca6791 VF |
81 | for (i = 0; i < td->o.dp_nr_ids; i++) { |
82 | if (td->o.dp_ids[i] >= ruhs->nr_ruhs) { | |
a7e8aae0 KB |
83 | ret = -EINVAL; |
84 | goto out; | |
85 | } | |
86 | } | |
87 | ||
88 | tmp = scalloc(1, sizeof(*tmp) + ruhs->nr_ruhs * sizeof(*tmp->plis)); | |
89 | if (!tmp) { | |
90 | ret = -ENOMEM; | |
91 | goto out; | |
92 | } | |
93 | ||
65ca6791 VF |
94 | tmp->nr_ruhs = td->o.dp_nr_ids; |
95 | for (i = 0; i < td->o.dp_nr_ids; i++) | |
96 | tmp->plis[i] = ruhs->plis[td->o.dp_ids[i]]; | |
a7e8aae0 KB |
97 | f->ruhs_info = tmp; |
98 | out: | |
99 | sfree(ruhs); | |
100 | return ret; | |
101 | } | |
102 | ||
c60d54ae | 103 | int dp_init(struct thread_data *td) |
a7e8aae0 KB |
104 | { |
105 | struct fio_file *f; | |
106 | int i, ret = 0; | |
107 | ||
108 | for_each_file(td, f, i) { | |
109 | ret = init_ruh_info(td, f); | |
110 | if (ret) | |
111 | break; | |
112 | } | |
113 | return ret; | |
114 | } | |
115 | ||
116 | void fdp_free_ruhs_info(struct fio_file *f) | |
117 | { | |
118 | if (!f->ruhs_info) | |
119 | return; | |
120 | sfree(f->ruhs_info); | |
121 | f->ruhs_info = NULL; | |
122 | } | |
123 | ||
c60d54ae | 124 | void dp_fill_dspec_data(struct thread_data *td, struct io_u *io_u) |
a7e8aae0 KB |
125 | { |
126 | struct fio_file *f = io_u->file; | |
127 | struct fio_ruhs_info *ruhs = f->ruhs_info; | |
128 | int dspec; | |
129 | ||
130 | if (!ruhs || io_u->ddir != DDIR_WRITE) { | |
131 | io_u->dtype = 0; | |
132 | io_u->dspec = 0; | |
133 | return; | |
134 | } | |
135 | ||
65ca6791 | 136 | if (td->o.dp_id_select == FIO_DP_RR) { |
d3e310c5 AK |
137 | if (ruhs->pli_loc >= ruhs->nr_ruhs) |
138 | ruhs->pli_loc = 0; | |
139 | ||
140 | dspec = ruhs->plis[ruhs->pli_loc++]; | |
141 | } else { | |
142 | ruhs->pli_loc = rand_between(&td->fdp_state, 0, ruhs->nr_ruhs - 1); | |
143 | dspec = ruhs->plis[ruhs->pli_loc]; | |
144 | } | |
3b3c9877 | 145 | |
1a3a21b7 | 146 | io_u->dtype = td->o.dp_type == FIO_DP_FDP ? FDP_DIR_DTYPE : STREAMS_DIR_DTYPE; |
a7e8aae0 | 147 | io_u->dspec = dspec; |
61d22139 | 148 | dprint(FD_IO, "dtype set to 0x%x, dspec set to 0x%x\n", io_u->dtype, io_u->dspec); |
a7e8aae0 | 149 | } |