1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_PART_STAT_H 3 #define _LINUX_PART_STAT_H 4 5 #include <linux/genhd.h> 6 7 struct disk_stats { 8 u64 nsecs[NR_STAT_GROUPS]; 9 unsigned long sectors[NR_STAT_GROUPS]; 10 unsigned long ios[NR_STAT_GROUPS]; 11 unsigned long merges[NR_STAT_GROUPS]; 12 unsigned long io_ticks; 13 local_t in_flight[2]; 14 }; 15 16 /* 17 * Macros to operate on percpu disk statistics: 18 * 19 * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters and should 20 * be called between disk_stat_lock() and disk_stat_unlock(). 21 * 22 * part_stat_read() can be called at any time. 23 */ 24 #define part_stat_lock() preempt_disable() 25 #define part_stat_unlock() preempt_enable() 26 27 #define part_stat_get_cpu(part, field, cpu) \ 28 (per_cpu_ptr((part)->dkstats, (cpu))->field) 29 30 #define part_stat_get(part, field) \ 31 part_stat_get_cpu(part, field, smp_processor_id()) 32 33 #define part_stat_read(part, field) \ 34 ({ \ 35 typeof((part)->dkstats->field) res = 0; \ 36 unsigned int _cpu; \ 37 for_each_possible_cpu(_cpu) \ 38 res += per_cpu_ptr((part)->dkstats, _cpu)->field; \ 39 res; \ 40 }) 41 42 static inline void part_stat_set_all(struct hd_struct *part, int value) 43 { 44 int i; 45 46 for_each_possible_cpu(i) 47 memset(per_cpu_ptr(part->dkstats, i), value, 48 sizeof(struct disk_stats)); 49 } 50 51 #define part_stat_read_accum(part, field) \ 52 (part_stat_read(part, field[STAT_READ]) + \ 53 part_stat_read(part, field[STAT_WRITE]) + \ 54 part_stat_read(part, field[STAT_DISCARD])) 55 56 #define __part_stat_add(part, field, addnd) \ 57 __this_cpu_add((part)->dkstats->field, addnd) 58 59 #define part_stat_add(part, field, addnd) do { \ 60 __part_stat_add((part), field, addnd); \ 61 if ((part)->partno) \ 62 __part_stat_add(&part_to_disk((part))->part0, \ 63 field, addnd); \ 64 } while (0) 65 66 #define part_stat_dec(gendiskp, field) \ 67 part_stat_add(gendiskp, field, -1) 68 #define part_stat_inc(gendiskp, field) \ 69 part_stat_add(gendiskp, field, 1) 70 #define part_stat_sub(gendiskp, field, subnd) \ 71 part_stat_add(gendiskp, field, -subnd) 72 73 #define part_stat_local_dec(gendiskp, field) \ 74 local_dec(&(part_stat_get(gendiskp, field))) 75 #define part_stat_local_inc(gendiskp, field) \ 76 local_inc(&(part_stat_get(gendiskp, field))) 77 #define part_stat_local_read(gendiskp, field) \ 78 local_read(&(part_stat_get(gendiskp, field))) 79 #define part_stat_local_read_cpu(gendiskp, field, cpu) \ 80 local_read(&(part_stat_get_cpu(gendiskp, field, cpu))) 81 82 #endif /* _LINUX_PART_STAT_H */ 83