docs: move rate_cycle description
[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>
a7e8aae0 12#include "fio.h"
7d352b12 13#include "file.h"
a7e8aae0
KB
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
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
43static 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) + 128 * sizeof(*ruhs->plis));
49 if (!ruhs)
50 return -ENOMEM;
51
52 ret = fdp_ruh_info(td, f, ruhs);
53 if (ret) {
54 log_info("fio: ruh info failed for %s (%d)\n",
55 f->file_name, -ret);
56 goto out;
57 }
58
59 if (ruhs->nr_ruhs > 128)
60 ruhs->nr_ruhs = 128;
61
62 if (td->o.fdp_nrpli == 0) {
63 f->ruhs_info = ruhs;
64 return 0;
65 }
66
67 for (i = 0; i < td->o.fdp_nrpli; i++) {
68 if (td->o.fdp_plis[i] > ruhs->nr_ruhs) {
69 ret = -EINVAL;
70 goto out;
71 }
72 }
73
74 tmp = scalloc(1, sizeof(*tmp) + ruhs->nr_ruhs * sizeof(*tmp->plis));
75 if (!tmp) {
76 ret = -ENOMEM;
77 goto out;
78 }
79
80 tmp->nr_ruhs = td->o.fdp_nrpli;
81 for (i = 0; i < td->o.fdp_nrpli; i++)
82 tmp->plis[i] = ruhs->plis[td->o.fdp_plis[i]];
83 f->ruhs_info = tmp;
84out:
85 sfree(ruhs);
86 return ret;
87}
88
89int fdp_init(struct thread_data *td)
90{
91 struct fio_file *f;
92 int i, ret = 0;
93
94 for_each_file(td, f, i) {
95 ret = init_ruh_info(td, f);
96 if (ret)
97 break;
98 }
99 return ret;
100}
101
102void fdp_free_ruhs_info(struct fio_file *f)
103{
104 if (!f->ruhs_info)
105 return;
106 sfree(f->ruhs_info);
107 f->ruhs_info = NULL;
108}
109
110void fdp_fill_dspec_data(struct thread_data *td, struct io_u *io_u)
111{
112 struct fio_file *f = io_u->file;
113 struct fio_ruhs_info *ruhs = f->ruhs_info;
114 int dspec;
115
116 if (!ruhs || io_u->ddir != DDIR_WRITE) {
117 io_u->dtype = 0;
118 io_u->dspec = 0;
119 return;
120 }
121
3b3c9877
AK
122 if (ruhs->pli_loc >= ruhs->nr_ruhs)
123 ruhs->pli_loc = 0;
124
125 dspec = ruhs->plis[ruhs->pli_loc++];
a7e8aae0
KB
126 io_u->dtype = 2;
127 io_u->dspec = dspec;
128}