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 9 struct 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 */ 22 struct disk_util_stat { 23 uint8_t name[FIO_DU_NAME_SZ]; 24 struct disk_util_stats s; 25 }; 26 27 struct 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 */ 42 struct 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 73 static 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 } 90 static inline void disk_util_inc(struct disk_util *du) 91 { 92 disk_util_mod(du, 1); 93 } 94 95 static 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 102 extern struct flist_head disk_list; 103 104 /* 105 * disk util stuff 106 */ 107 #ifdef FIO_HAVE_DISK_UTIL 108 extern void print_disk_util(struct disk_util_stat *, struct disk_util_agg *, int terse, struct buf_output *); 109 extern void show_disk_util(int terse, struct json_object *parent, struct buf_output *); 110 extern void json_array_add_disk_util(struct disk_util_stat *dus, 111 struct disk_util_agg *agg, struct json_array *parent); 112 extern void init_disk_util(struct thread_data *); 113 extern int update_io_ticks(void); 114 extern void setup_disk_util(void); 115 extern void disk_util_prune_entries(void); 116 #else 117 /* keep this as a function to avoid a warning in handle_du() */ 118 static 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 129 static inline int update_io_ticks(void) 130 { 131 return helper_should_exit(); 132 } 133 #endif 134 135 #endif 136