fio: add fdp support for io_uring_cmd nvme engine
[fio.git] / fdp.c
CommitLineData
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>
12#include "file.h"
13#include "fio.h"
14
15#include "pshared.h"
16#include "fdp.h"
17
18static 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 && td->io_ops->fdp_fetch_ruhs) {
24 ret = td->io_ops->fdp_fetch_ruhs(td, f, ruhs);
25 if (ret < 0) {
26 td_verror(td, errno, "fdp fetch ruhs failed");
27 log_err("%s: fdp fetch ruhs failed (%d)\n",
28 f->file_name, errno);
29 }
30 } else
31 log_err("%s: engine (%s) lacks fetch ruhs\n",
32 f->file_name, td->io_ops->name);
33
34 return ret;
35}
36
37static int init_ruh_info(struct thread_data *td, struct fio_file *f)
38{
39 struct fio_ruhs_info *ruhs, *tmp;
40 int i, ret;
41
42 ruhs = scalloc(1, sizeof(*ruhs) + 128 * sizeof(*ruhs->plis));
43 if (!ruhs)
44 return -ENOMEM;
45
46 ret = fdp_ruh_info(td, f, ruhs);
47 if (ret) {
48 log_info("fio: ruh info failed for %s (%d)\n",
49 f->file_name, -ret);
50 goto out;
51 }
52
53 if (ruhs->nr_ruhs > 128)
54 ruhs->nr_ruhs = 128;
55
56 if (td->o.fdp_nrpli == 0) {
57 f->ruhs_info = ruhs;
58 return 0;
59 }
60
61 for (i = 0; i < td->o.fdp_nrpli; i++) {
62 if (td->o.fdp_plis[i] > ruhs->nr_ruhs) {
63 ret = -EINVAL;
64 goto out;
65 }
66 }
67
68 tmp = scalloc(1, sizeof(*tmp) + ruhs->nr_ruhs * sizeof(*tmp->plis));
69 if (!tmp) {
70 ret = -ENOMEM;
71 goto out;
72 }
73
74 tmp->nr_ruhs = td->o.fdp_nrpli;
75 for (i = 0; i < td->o.fdp_nrpli; i++)
76 tmp->plis[i] = ruhs->plis[td->o.fdp_plis[i]];
77 f->ruhs_info = tmp;
78out:
79 sfree(ruhs);
80 return ret;
81}
82
83int fdp_init(struct thread_data *td)
84{
85 struct fio_file *f;
86 int i, ret = 0;
87
88 for_each_file(td, f, i) {
89 ret = init_ruh_info(td, f);
90 if (ret)
91 break;
92 }
93 return ret;
94}
95
96void fdp_free_ruhs_info(struct fio_file *f)
97{
98 if (!f->ruhs_info)
99 return;
100 sfree(f->ruhs_info);
101 f->ruhs_info = NULL;
102}
103
104void fdp_fill_dspec_data(struct thread_data *td, struct io_u *io_u)
105{
106 struct fio_file *f = io_u->file;
107 struct fio_ruhs_info *ruhs = f->ruhs_info;
108 int dspec;
109
110 if (!ruhs || io_u->ddir != DDIR_WRITE) {
111 io_u->dtype = 0;
112 io_u->dspec = 0;
113 return;
114 }
115
116 dspec = ruhs->plis[ruhs->pli_loc++ % ruhs->nr_ruhs];
117 io_u->dtype = 2;
118 io_u->dspec = dspec;
119}