t/io_uring: only calculate per-file depth if we have files
[fio.git] / iolog.h
CommitLineData
5995a6a4
JA
1#ifndef FIO_IOLOG_H
2#define FIO_IOLOG_H
3
3d2d14bc
SW
4#include <stdio.h>
5
05775438 6#include "lib/rbtree.h"
c7c6cb4c 7#include "lib/ieee754.h"
836fcc0f 8#include "flist.h"
618ee94c 9#include "ioengines.h"
802ad4a8 10
5995a6a4
JA
11/*
12 * Use for maintaining statistics
13 */
14struct io_stat {
7b9f733a
JA
15 uint64_t max_val;
16 uint64_t min_val;
17 uint64_t samples;
5995a6a4 18
802ad4a8
JA
19 fio_fp64_t mean;
20 fio_fp64_t S;
5995a6a4
JA
21};
22
1e613c9c
KC
23struct io_hist {
24 uint64_t samples;
25 unsigned long hist_last;
d730bc58 26 struct flist_head list;
1e613c9c
KC
27};
28
0e14633c
AK
29enum {
30 IO_LOG_SAMPLE_AVG = 0,
31 IO_LOG_SAMPLE_MAX,
32 IO_LOG_SAMPLE_BOTH,
33};
34
35struct io_sample_value {
36 uint64_t val0;
37 uint64_t val1;
38};
af2fde19
SW
39
40union io_sample_data {
0e14633c 41 struct io_sample_value val;
af2fde19
SW
42 struct io_u_plat_entry *plat_entry;
43};
44
0e14633c 45#define sample_val(value) ((union io_sample_data) { .val.val0 = value })
af2fde19
SW
46#define sample_plat(plat) ((union io_sample_data) { .plat_entry = plat })
47
5995a6a4
JA
48/*
49 * A single data sample
50 */
51struct io_sample {
1b42725f 52 uint64_t time;
af2fde19 53 union io_sample_data data;
b26317c9 54 uint32_t __ddir;
03ec570f 55 uint16_t priority;
5fff9543 56 uint64_t bs;
5995a6a4
JA
57};
58
ae588852
JA
59struct io_sample_offset {
60 struct io_sample s;
61 uint64_t offset;
62};
63
ea51b956
JA
64enum {
65 IO_LOG_TYPE_LAT = 1,
66 IO_LOG_TYPE_CLAT,
67 IO_LOG_TYPE_SLAT,
68 IO_LOG_TYPE_BW,
69 IO_LOG_TYPE_IOPS,
1e613c9c 70 IO_LOG_TYPE_HIST,
ea51b956
JA
71};
72
6d37f67f 73#define DEF_LOG_ENTRIES 1024
7e419452
JA
74#define MAX_LOG_ENTRIES (1024 * DEF_LOG_ENTRIES)
75
7e419452
JA
76struct io_logs {
77 struct flist_head list;
78 uint64_t nr_samples;
79 uint64_t max_samples;
80 void *log;
81};
6d37f67f 82
5995a6a4
JA
83/*
84 * Dynamically growing data sample log
85 */
86struct io_log {
b8bc8cba
JA
87 /*
88 * Entries already logged
89 */
7e419452
JA
90 struct flist_head io_logs;
91 uint32_t cur_log_max;
b8bc8cba 92
1fed2080
JA
93 /*
94 * When the current log runs out of space, store events here until
95 * we have a chance to regrow
96 */
97 struct io_logs *pending;
98
b26317c9
JA
99 unsigned int log_ddir_mask;
100
cb7e0ace
JA
101 char *filename;
102
aee2ab67
JA
103 struct thread_data *td;
104
1b42725f 105 unsigned int log_type;
ea51b956 106
3c568239
JA
107 /*
108 * If we fail extending the log, stop collecting more entries.
109 */
7e419452 110 bool disabled;
3c568239 111
ae588852
JA
112 /*
113 * Log offsets
114 */
115 unsigned int log_offset;
116
03ec570f
DLM
117 /*
118 * Log I/O priorities
119 */
120 unsigned int log_prio;
121
aee2ab67
JA
122 /*
123 * Max size of log entries before a chunk is compressed
124 */
125 unsigned int log_gz;
126
b26317c9
JA
127 /*
128 * Don't deflate for storing, just store the compressed bits
129 */
130 unsigned int log_gz_store;
131
b8bc8cba
JA
132 /*
133 * Windowed average, for logging single entries average over some
134 * period of time.
135 */
6eaf09d6 136 struct io_stat avg_window[DDIR_RWDIR_CNT];
b8bc8cba 137 unsigned long avg_msec;
8355119b 138 unsigned long avg_last[DDIR_RWDIR_CNT];
aee2ab67 139
8aa89d70
JA
140 /*
141 * Windowed latency histograms, for keeping track of when we need to
142 * save a copy of the histogram every approximately hist_msec
143 * milliseconds.
144 */
1e613c9c
KC
145 struct io_hist hist_window[DDIR_RWDIR_CNT];
146 unsigned long hist_msec;
868f6f03 147 unsigned int hist_coarseness;
1e613c9c 148
aee2ab67
JA
149 pthread_mutex_t chunk_lock;
150 unsigned int chunk_seq;
151 struct flist_head chunk_list;
858bce70
JA
152
153 pthread_mutex_t deferred_free_lock;
154#define IOLOG_MAX_DEFER 8
155 void *deferred_items[IOLOG_MAX_DEFER];
156 unsigned int deferred;
5995a6a4
JA
157};
158
49e98daa
JA
159/*
160 * If the upper bit is set, then we have the offset as well
161 */
162#define LOG_OFFSET_SAMPLE_BIT 0x80000000U
03ec570f
DLM
163/*
164 * If the bit following the upper bit is set, then we have the priority
165 */
166#define LOG_PRIO_SAMPLE_BIT 0x40000000U
0e14633c
AK
167/*
168 * If the bit following prioity sample vit is set, we report both avg and max
169 */
170#define LOG_AVG_MAX_SAMPLE_BIT 0x20000000U
03ec570f 171
0e14633c
AK
172#define LOG_SAMPLE_BITS (LOG_OFFSET_SAMPLE_BIT | LOG_PRIO_SAMPLE_BIT |\
173 LOG_AVG_MAX_SAMPLE_BIT)
03ec570f 174#define io_sample_ddir(io) ((io)->__ddir & ~LOG_SAMPLE_BITS)
b26317c9
JA
175
176static inline void io_sample_set_ddir(struct io_log *log,
177 struct io_sample *io,
178 enum fio_ddir ddir)
179{
180 io->__ddir = ddir | log->log_ddir_mask;
181}
182
ae588852
JA
183static inline size_t __log_entry_sz(int log_offset)
184{
185 if (log_offset)
186 return sizeof(struct io_sample_offset);
187 else
188 return sizeof(struct io_sample);
189}
190
191static inline size_t log_entry_sz(struct io_log *log)
192{
193 return __log_entry_sz(log->log_offset);
194}
195
868f6f03
KC
196static inline size_t log_sample_sz(struct io_log *log, struct io_logs *cur_log)
197{
198 return cur_log->nr_samples * log_entry_sz(log);
199}
200
ae588852
JA
201static inline struct io_sample *__get_sample(void *samples, int log_offset,
202 uint64_t sample)
203{
6f9bbb55
CB
204 uint64_t sample_offset = sample * __log_entry_sz(log_offset);
205 return (struct io_sample *) ((char *) samples + sample_offset);
ae588852
JA
206}
207
7e419452
JA
208struct io_logs *iolog_cur_log(struct io_log *);
209uint64_t iolog_nr_samples(struct io_log *);
1fed2080 210void regrow_logs(struct thread_data *);
76204de3 211void regrow_agg_logs(void);
7e419452 212
ae588852 213static inline struct io_sample *get_sample(struct io_log *iolog,
7e419452 214 struct io_logs *cur_log,
ae588852
JA
215 uint64_t sample)
216{
7e419452 217 return __get_sample(cur_log->log, iolog->log_offset, sample);
ae588852
JA
218}
219
0d29de83
JA
220enum {
221 IP_F_ONRB = 1,
222 IP_F_ONLIST = 2,
223 IP_F_TRIMMED = 4,
f9401285 224 IP_F_IN_FLIGHT = 8,
0d29de83
JA
225};
226
5995a6a4
JA
227/*
228 * When logging io actions, this matches a single sent io_u
229 */
230struct io_piece {
231 union {
e96c0125 232 struct fio_rb_node rb_node;
5995a6a4
JA
233 struct flist_head list;
234 };
0d29de83 235 struct flist_head trim_list;
5995a6a4
JA
236 union {
237 int fileno;
238 struct fio_file *file;
239 };
240 unsigned long long offset;
da0a7bd2 241 unsigned short numberio;
5995a6a4 242 unsigned long len;
a917a8b3 243 unsigned int flags;
5995a6a4 244 enum fio_ddir ddir;
315bbf01
MG
245 unsigned long delay;
246 unsigned int file_action;
5995a6a4
JA
247};
248
249/*
250 * Log exports
251 */
252enum file_log_act {
253 FIO_LOG_ADD_FILE,
254 FIO_LOG_OPEN_FILE,
255 FIO_LOG_CLOSE_FILE,
256 FIO_LOG_UNLINK_FILE,
257};
258
8062f527 259struct io_u;
5995a6a4 260extern int __must_check read_iolog_get(struct thread_data *, struct io_u *);
1f440ece 261extern void log_io_u(const struct thread_data *, const struct io_u *);
5995a6a4 262extern void log_file(struct thread_data *, struct fio_file *, enum file_log_act);
b153f94a 263extern bool __must_check init_iolog(struct thread_data *td);
5995a6a4 264extern void log_io_piece(struct thread_data *, struct io_u *);
890b6656 265extern void unlog_io_piece(struct thread_data *, struct io_u *);
94a78d52 266extern void trim_io_piece(const struct io_u *);
5995a6a4
JA
267extern void queue_io_piece(struct thread_data *, struct io_piece *);
268extern void prune_io_piece_log(struct thread_data *);
269extern void write_iolog_close(struct thread_data *);
a21ed2b5 270int64_t iolog_items_to_fetch(struct thread_data *td);
24660963 271extern int iolog_compress_init(struct thread_data *, struct sk_out *);
155f2f02 272extern void iolog_compress_exit(struct thread_data *);
0cba0f91 273extern size_t log_chunk_sizes(struct io_log *);
71e6e5a2 274extern int init_io_u_buffers(struct thread_data *);
315bbf01
MG
275extern unsigned long long delay_since_ttime(const struct thread_data *,
276 unsigned long long);
5995a6a4 277
b26317c9
JA
278#ifdef CONFIG_ZLIB
279extern int iolog_file_inflate(const char *);
280#endif
281
5995a6a4
JA
282/*
283 * Logging
284 */
aee2ab67
JA
285struct log_params {
286 struct thread_data *td;
287 unsigned long avg_msec;
1e613c9c
KC
288 unsigned long hist_msec;
289 int hist_coarseness;
aee2ab67
JA
290 int log_type;
291 int log_offset;
03ec570f 292 int log_prio;
aee2ab67 293 int log_gz;
b26317c9 294 int log_gz_store;
aee2ab67
JA
295 int log_compress;
296};
297
a47591e4
JA
298static inline bool per_unit_log(struct io_log *log)
299{
83636545 300 return log && (!log->avg_msec || log->log_gz || log->log_gz_store);
a47591e4
JA
301}
302
b392f36d
JA
303static inline bool inline_log(struct io_log *log)
304{
305 return log->log_type == IO_LOG_TYPE_LAT ||
306 log->log_type == IO_LOG_TYPE_CLAT ||
307 log->log_type == IO_LOG_TYPE_SLAT;
308}
309
a79f17bf
SW
310static inline void ipo_bytes_align(unsigned int replay_align, struct io_piece *ipo)
311{
3dd2e8aa 312 if (!replay_align)
a79f17bf
SW
313 return;
314
315 ipo->offset &= ~(replay_align - (uint64_t)1);
316}
317
a47591e4 318extern void finalize_logs(struct thread_data *td, bool);
aee2ab67 319extern void setup_log(struct io_log **, struct log_params *, const char *);
60a25727 320extern void flush_log(struct io_log *, bool);
bead01d7 321extern void flush_samples(FILE *, void *, uint64_t);
6cc0e5aa 322extern uint64_t hist_sum(int, int, uint64_t *, uint64_t *);
518dac09 323extern void free_log(struct io_log *);
a47591e4
JA
324extern void fio_writeout_logs(bool);
325extern void td_writeout_logs(struct thread_data *, bool);
7e419452 326extern int iolog_cur_flush(struct io_log *, struct io_logs *);
5995a6a4 327
0d29de83
JA
328static inline void init_ipo(struct io_piece *ipo)
329{
8812d7f2 330 INIT_FLIST_HEAD(&ipo->list);
0d29de83
JA
331 INIT_FLIST_HEAD(&ipo->trim_list);
332}
333
0cba0f91
JA
334struct iolog_compress {
335 struct flist_head list;
336 void *buf;
337 size_t len;
338 unsigned int seq;
339};
340
5995a6a4 341#endif