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