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