t/nvmept_trim: increase transfer size for some tests
[fio.git] / dataplacement.c
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>
12 #include "fio.h"
13 #include "file.h"
14
15 #include "pshared.h"
16 #include "dataplacement.h"
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
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) {
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                 }
35         } else {
36                 log_err("%s: engine (%s) lacks fetch ruhs\n",
37                         f->file_name, td->io_ops->name);
38         }
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
48         ruhs = scalloc(1, sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(*ruhs->plis));
49         if (!ruhs)
50                 return -ENOMEM;
51
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
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
73         if (ruhs->nr_ruhs > FDP_MAX_RUHS)
74                 ruhs->nr_ruhs = FDP_MAX_RUHS;
75
76         if (td->o.dp_nr_ids == 0) {
77                 f->ruhs_info = ruhs;
78                 return 0;
79         }
80
81         for (i = 0; i < td->o.dp_nr_ids; i++) {
82                 if (td->o.dp_ids[i] >= ruhs->nr_ruhs) {
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
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]];
97         f->ruhs_info = tmp;
98 out:
99         sfree(ruhs);
100         return ret;
101 }
102
103 int dp_init(struct thread_data *td)
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
124 void dp_fill_dspec_data(struct thread_data *td, struct io_u *io_u)
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
136         if (td->o.dp_id_select == FIO_DP_RR) {
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         }
145
146         io_u->dtype = td->o.dp_type == FIO_DP_FDP ? FDP_DIR_DTYPE : STREAMS_DIR_DTYPE;
147         io_u->dspec = dspec;
148         dprint(FD_IO, "dtype set to 0x%x, dspec set to 0x%x\n", io_u->dtype, io_u->dspec);
149 }