1#ifndef FIO_DISKUTIL_H 2#define FIO_DISKUTIL_H 3#include "json.h" 4#define FIO_DU_NAME_SZ 64 5 6#include "lib/output_buffer.h" 7#include "helper_thread.h" 8 9struct disk_util_stats { 10 uint64_t ios[2]; 11 uint64_t merges[2]; 12 uint64_t sectors[2]; 13 uint64_t ticks[2]; 14 uint64_t io_ticks; 15 uint64_t time_in_queue; 16 uint64_t msec; 17}; 18 19/* 20 * Disk utils as read in /sys/block/<dev>/stat 21 */ 22struct disk_util_stat { 23 uint8_t name[FIO_DU_NAME_SZ]; 24 struct disk_util_stats s; 25}; 26 27struct disk_util_agg { 28 uint64_t ios[2]; 29 uint64_t merges[2]; 30 uint64_t sectors[2]; 31 uint64_t ticks[2]; 32 uint64_t io_ticks; 33 uint64_t time_in_queue; 34 uint32_t slavecount; 35 uint32_t pad; 36 fio_fp64_t max_util; 37}; 38 39/* 40 * Per-device disk util management 41 */ 42struct disk_util { 43 struct flist_head list; 44 /* If this disk is a slave, hook it into the master's 45 * list using this head. 46 */ 47 struct flist_head slavelist; 48 49 char *sysfs_root; 50 char path[PATH_MAX]; 51 int major, minor; 52 53 struct disk_util_stat dus; 54 struct disk_util_stat last_dus; 55 56 struct disk_util_agg agg; 57 58 /* For software raids, this entry maintains pointers to the 59 * entries for the slave devices. The disk_util entries for 60 * the slaves devices should primarily be maintained through 61 * the disk_list list, i.e. for memory allocation and 62 * de-allocation, etc. Whereas this list should be used only 63 * for aggregating a software RAID's disk util figures. 64 */ 65 struct flist_head slaves; 66 67 struct timeval time; 68 69 struct fio_mutex *lock; 70 unsigned long users; 71}; 72 73static inline void disk_util_mod(struct disk_util *du, int val) 74{ 75 if (du) { 76 struct flist_head *n; 77 78 fio_mutex_down(du->lock); 79 du->users += val; 80 81 flist_for_each(n, &du->slavelist) { 82 struct disk_util *slave; 83 84 slave = flist_entry(n, struct disk_util, slavelist); 85 slave->users += val; 86 } 87 fio_mutex_up(du->lock); 88 } 89} 90static inline void disk_util_inc(struct disk_util *du) 91{ 92 disk_util_mod(du, 1); 93} 94 95static inline void disk_util_dec(struct disk_util *du) 96{ 97 disk_util_mod(du, -1); 98} 99 100#define DISK_UTIL_MSEC (250) 101 102extern struct flist_head disk_list; 103 104/* 105 * disk util stuff 106 */ 107#ifdef FIO_HAVE_DISK_UTIL 108extern void print_disk_util(struct disk_util_stat *, struct disk_util_agg *, int terse, struct buf_output *); 109extern void show_disk_util(int terse, struct json_object *parent, struct buf_output *); 110extern void json_array_add_disk_util(struct disk_util_stat *dus, 111 struct disk_util_agg *agg, struct json_array *parent); 112extern void init_disk_util(struct thread_data *); 113extern int update_io_ticks(void); 114extern void setup_disk_util(void); 115extern void disk_util_prune_entries(void); 116#else 117/* keep this as a function to avoid a warning in handle_du() */ 118static inline void print_disk_util(struct disk_util_stat *du, 119 struct disk_util_agg *agg, int terse, 120 struct buf_output *out) 121{ 122} 123#define show_disk_util(terse, parent, out) 124#define disk_util_prune_entries() 125#define init_disk_util(td) 126#define setup_disk_util() 127#define json_array_add_disk_util(dus, agg, parent) 128 129static inline int update_io_ticks(void) 130{ 131 return helper_should_exit(); 132} 133#endif 134 135#endif 136