backend: do_dry_run(): get_io_u() can return an error pointer
[fio.git] / iolog.h
CommitLineData
5995a6a4
JA
1#ifndef FIO_IOLOG_H
2#define FIO_IOLOG_H
3
05775438 4#include "lib/rbtree.h"
c7c6cb4c 5#include "lib/ieee754.h"
836fcc0f 6#include "flist.h"
ec41265e 7#include "ioengine.h"
802ad4a8 8
5995a6a4
JA
9/*
10 * Use for maintaining statistics
11 */
12struct io_stat {
7b9f733a
JA
13 uint64_t max_val;
14 uint64_t min_val;
15 uint64_t samples;
5995a6a4 16
802ad4a8
JA
17 fio_fp64_t mean;
18 fio_fp64_t S;
5995a6a4
JA
19};
20
21/*
22 * A single data sample
23 */
24struct io_sample {
1b42725f
JA
25 uint64_t time;
26 uint64_t val;
b26317c9 27 uint32_t __ddir;
1b42725f 28 uint32_t bs;
5995a6a4
JA
29};
30
ae588852
JA
31struct io_sample_offset {
32 struct io_sample s;
33 uint64_t offset;
34};
35
ea51b956
JA
36enum {
37 IO_LOG_TYPE_LAT = 1,
38 IO_LOG_TYPE_CLAT,
39 IO_LOG_TYPE_SLAT,
40 IO_LOG_TYPE_BW,
41 IO_LOG_TYPE_IOPS,
42};
43
6d37f67f 44#define DEF_LOG_ENTRIES 1024
7e419452
JA
45#define MAX_LOG_ENTRIES (1024 * DEF_LOG_ENTRIES)
46
7e419452
JA
47struct io_logs {
48 struct flist_head list;
49 uint64_t nr_samples;
50 uint64_t max_samples;
51 void *log;
52};
6d37f67f 53
5995a6a4
JA
54/*
55 * Dynamically growing data sample log
56 */
57struct io_log {
b8bc8cba
JA
58 /*
59 * Entries already logged
60 */
7e419452
JA
61 struct flist_head io_logs;
62 uint32_t cur_log_max;
b8bc8cba 63
1fed2080
JA
64 /*
65 * When the current log runs out of space, store events here until
66 * we have a chance to regrow
67 */
68 struct io_logs *pending;
69
b26317c9
JA
70 unsigned int log_ddir_mask;
71
cb7e0ace
JA
72 char *filename;
73
aee2ab67
JA
74 struct thread_data *td;
75
1b42725f 76 unsigned int log_type;
ea51b956 77
3c568239
JA
78 /*
79 * If we fail extending the log, stop collecting more entries.
80 */
7e419452 81 bool disabled;
3c568239 82
ae588852
JA
83 /*
84 * Log offsets
85 */
86 unsigned int log_offset;
87
aee2ab67
JA
88 /*
89 * Max size of log entries before a chunk is compressed
90 */
91 unsigned int log_gz;
92
b26317c9
JA
93 /*
94 * Don't deflate for storing, just store the compressed bits
95 */
96 unsigned int log_gz_store;
97
b8bc8cba
JA
98 /*
99 * Windowed average, for logging single entries average over some
100 * period of time.
101 */
6eaf09d6 102 struct io_stat avg_window[DDIR_RWDIR_CNT];
b8bc8cba
JA
103 unsigned long avg_msec;
104 unsigned long avg_last;
aee2ab67
JA
105
106 pthread_mutex_t chunk_lock;
107 unsigned int chunk_seq;
108 struct flist_head chunk_list;
5995a6a4
JA
109};
110
49e98daa
JA
111/*
112 * If the upper bit is set, then we have the offset as well
113 */
114#define LOG_OFFSET_SAMPLE_BIT 0x80000000U
115#define io_sample_ddir(io) ((io)->__ddir & ~LOG_OFFSET_SAMPLE_BIT)
b26317c9
JA
116
117static inline void io_sample_set_ddir(struct io_log *log,
118 struct io_sample *io,
119 enum fio_ddir ddir)
120{
121 io->__ddir = ddir | log->log_ddir_mask;
122}
123
ae588852
JA
124static inline size_t __log_entry_sz(int log_offset)
125{
126 if (log_offset)
127 return sizeof(struct io_sample_offset);
128 else
129 return sizeof(struct io_sample);
130}
131
132static inline size_t log_entry_sz(struct io_log *log)
133{
134 return __log_entry_sz(log->log_offset);
135}
136
137static inline struct io_sample *__get_sample(void *samples, int log_offset,
138 uint64_t sample)
139{
6f9bbb55
CB
140 uint64_t sample_offset = sample * __log_entry_sz(log_offset);
141 return (struct io_sample *) ((char *) samples + sample_offset);
ae588852
JA
142}
143
7e419452
JA
144struct io_logs *iolog_cur_log(struct io_log *);
145uint64_t iolog_nr_samples(struct io_log *);
1fed2080 146void regrow_logs(struct thread_data *);
7e419452 147
ae588852 148static inline struct io_sample *get_sample(struct io_log *iolog,
7e419452 149 struct io_logs *cur_log,
ae588852
JA
150 uint64_t sample)
151{
7e419452 152 return __get_sample(cur_log->log, iolog->log_offset, sample);
ae588852
JA
153}
154
0d29de83
JA
155enum {
156 IP_F_ONRB = 1,
157 IP_F_ONLIST = 2,
158 IP_F_TRIMMED = 4,
f9401285 159 IP_F_IN_FLIGHT = 8,
0d29de83
JA
160};
161
5995a6a4
JA
162/*
163 * When logging io actions, this matches a single sent io_u
164 */
165struct io_piece {
166 union {
167 struct rb_node rb_node;
168 struct flist_head list;
169 };
0d29de83 170 struct flist_head trim_list;
5995a6a4
JA
171 union {
172 int fileno;
173 struct fio_file *file;
174 };
175 unsigned long long offset;
da0a7bd2 176 unsigned short numberio;
5995a6a4 177 unsigned long len;
a917a8b3 178 unsigned int flags;
5995a6a4
JA
179 enum fio_ddir ddir;
180 union {
181 unsigned long delay;
182 unsigned int file_action;
183 };
184};
185
186/*
187 * Log exports
188 */
189enum file_log_act {
190 FIO_LOG_ADD_FILE,
191 FIO_LOG_OPEN_FILE,
192 FIO_LOG_CLOSE_FILE,
193 FIO_LOG_UNLINK_FILE,
194};
195
8062f527 196struct io_u;
5995a6a4 197extern int __must_check read_iolog_get(struct thread_data *, struct io_u *);
1f440ece 198extern void log_io_u(const struct thread_data *, const struct io_u *);
5995a6a4
JA
199extern void log_file(struct thread_data *, struct fio_file *, enum file_log_act);
200extern int __must_check init_iolog(struct thread_data *td);
201extern void log_io_piece(struct thread_data *, struct io_u *);
890b6656 202extern void unlog_io_piece(struct thread_data *, struct io_u *);
1f440ece 203extern void trim_io_piece(struct thread_data *, const struct io_u *);
5995a6a4
JA
204extern void queue_io_piece(struct thread_data *, struct io_piece *);
205extern void prune_io_piece_log(struct thread_data *);
206extern void write_iolog_close(struct thread_data *);
24660963 207extern int iolog_compress_init(struct thread_data *, struct sk_out *);
155f2f02 208extern void iolog_compress_exit(struct thread_data *);
0cba0f91 209extern size_t log_chunk_sizes(struct io_log *);
5995a6a4 210
b26317c9
JA
211#ifdef CONFIG_ZLIB
212extern int iolog_file_inflate(const char *);
213#endif
214
5995a6a4
JA
215/*
216 * Logging
217 */
aee2ab67
JA
218struct log_params {
219 struct thread_data *td;
220 unsigned long avg_msec;
221 int log_type;
222 int log_offset;
223 int log_gz;
b26317c9 224 int log_gz_store;
aee2ab67
JA
225 int log_compress;
226};
227
a47591e4
JA
228static inline bool per_unit_log(struct io_log *log)
229{
230 return log && !log->avg_msec;
231}
232
b392f36d
JA
233static inline bool inline_log(struct io_log *log)
234{
235 return log->log_type == IO_LOG_TYPE_LAT ||
236 log->log_type == IO_LOG_TYPE_CLAT ||
237 log->log_type == IO_LOG_TYPE_SLAT;
238}
239
a47591e4 240extern void finalize_logs(struct thread_data *td, bool);
aee2ab67 241extern void setup_log(struct io_log **, struct log_params *, const char *);
60a25727 242extern void flush_log(struct io_log *, bool);
bead01d7 243extern void flush_samples(FILE *, void *, uint64_t);
518dac09 244extern void free_log(struct io_log *);
a47591e4
JA
245extern void fio_writeout_logs(bool);
246extern void td_writeout_logs(struct thread_data *, bool);
7e419452 247extern int iolog_cur_flush(struct io_log *, struct io_logs *);
5995a6a4 248
0d29de83
JA
249static inline void init_ipo(struct io_piece *ipo)
250{
251 memset(ipo, 0, sizeof(*ipo));
252 INIT_FLIST_HEAD(&ipo->trim_list);
253}
254
0cba0f91
JA
255struct iolog_compress {
256 struct flist_head list;
257 void *buf;
258 size_t len;
259 unsigned int seq;
260};
261
5995a6a4 262#endif