xref: /linux-6.15/include/linux/part_stat.h (revision 8a3c3923)
1c6a564ffSChristoph Hellwig /* SPDX-License-Identifier: GPL-2.0 */
2c6a564ffSChristoph Hellwig #ifndef _LINUX_PART_STAT_H
3c6a564ffSChristoph Hellwig #define _LINUX_PART_STAT_H
4c6a564ffSChristoph Hellwig 
5322cbb50SChristoph Hellwig #include <linux/blkdev.h>
6b81e0c23SChristoph Hellwig #include <asm/local.h>
7c6a564ffSChristoph Hellwig 
858d4f14fSChristoph Hellwig struct disk_stats {
958d4f14fSChristoph Hellwig 	u64 nsecs[NR_STAT_GROUPS];
1058d4f14fSChristoph Hellwig 	unsigned long sectors[NR_STAT_GROUPS];
1158d4f14fSChristoph Hellwig 	unsigned long ios[NR_STAT_GROUPS];
1258d4f14fSChristoph Hellwig 	unsigned long merges[NR_STAT_GROUPS];
1358d4f14fSChristoph Hellwig 	unsigned long io_ticks;
1458d4f14fSChristoph Hellwig 	local_t in_flight[2];
1558d4f14fSChristoph Hellwig };
1658d4f14fSChristoph Hellwig 
17c6a564ffSChristoph Hellwig /*
18c6a564ffSChristoph Hellwig  * Macros to operate on percpu disk statistics:
19c6a564ffSChristoph Hellwig  *
2058d4f14fSChristoph Hellwig  * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters and should
2158d4f14fSChristoph Hellwig  * be called between disk_stat_lock() and disk_stat_unlock().
22c6a564ffSChristoph Hellwig  *
23c6a564ffSChristoph Hellwig  * part_stat_read() can be called at any time.
24c6a564ffSChristoph Hellwig  */
258ab1d40aSKonstantin Khlebnikov #define part_stat_lock()	preempt_disable()
268ab1d40aSKonstantin Khlebnikov #define part_stat_unlock()	preempt_enable()
27c6a564ffSChristoph Hellwig 
28c6a564ffSChristoph Hellwig #define part_stat_get_cpu(part, field, cpu)				\
298446fe92SChristoph Hellwig 	(per_cpu_ptr((part)->bd_stats, (cpu))->field)
30c6a564ffSChristoph Hellwig 
31c6a564ffSChristoph Hellwig #define part_stat_get(part, field)					\
32c6a564ffSChristoph Hellwig 	part_stat_get_cpu(part, field, smp_processor_id())
33c6a564ffSChristoph Hellwig 
34c6a564ffSChristoph Hellwig #define part_stat_read(part, field)					\
35c6a564ffSChristoph Hellwig ({									\
36*8a3c3923SUros Bizjak 	TYPEOF_UNQUAL((part)->bd_stats->field) res = 0;			\
37c6a564ffSChristoph Hellwig 	unsigned int _cpu;						\
38c6a564ffSChristoph Hellwig 	for_each_possible_cpu(_cpu)					\
398446fe92SChristoph Hellwig 		res += per_cpu_ptr((part)->bd_stats, _cpu)->field; \
40c6a564ffSChristoph Hellwig 	res;								\
41c6a564ffSChristoph Hellwig })
42c6a564ffSChristoph Hellwig 
part_stat_set_all(struct block_device * part,int value)438446fe92SChristoph Hellwig static inline void part_stat_set_all(struct block_device *part, int value)
44c6a564ffSChristoph Hellwig {
45c6a564ffSChristoph Hellwig 	int i;
46c6a564ffSChristoph Hellwig 
47c6a564ffSChristoph Hellwig 	for_each_possible_cpu(i)
488446fe92SChristoph Hellwig 		memset(per_cpu_ptr(part->bd_stats, i), value,
49c6a564ffSChristoph Hellwig 				sizeof(struct disk_stats));
50c6a564ffSChristoph Hellwig }
51c6a564ffSChristoph Hellwig 
52c6a564ffSChristoph Hellwig #define part_stat_read_accum(part, field)				\
53c6a564ffSChristoph Hellwig 	(part_stat_read(part, field[STAT_READ]) +			\
54c6a564ffSChristoph Hellwig 	 part_stat_read(part, field[STAT_WRITE]) +			\
55c6a564ffSChristoph Hellwig 	 part_stat_read(part, field[STAT_DISCARD]))
56c6a564ffSChristoph Hellwig 
57c6a564ffSChristoph Hellwig #define __part_stat_add(part, field, addnd)				\
588446fe92SChristoph Hellwig 	__this_cpu_add((part)->bd_stats->field, addnd)
59c6a564ffSChristoph Hellwig 
60c6a564ffSChristoph Hellwig #define part_stat_add(part, field, addnd)	do {			\
61c6a564ffSChristoph Hellwig 	__part_stat_add((part), field, addnd);				\
623f9b8fb4SAl Viro 	if (bdev_is_partition(part))					\
638446fe92SChristoph Hellwig 		__part_stat_add(bdev_whole(part), field, addnd);	\
64c6a564ffSChristoph Hellwig } while (0)
65c6a564ffSChristoph Hellwig 
6615e3d2c5SChristoph Hellwig #define part_stat_dec(part, field)					\
6715e3d2c5SChristoph Hellwig 	part_stat_add(part, field, -1)
6815e3d2c5SChristoph Hellwig #define part_stat_inc(part, field)					\
6915e3d2c5SChristoph Hellwig 	part_stat_add(part, field, 1)
7015e3d2c5SChristoph Hellwig #define part_stat_sub(part, field, subnd)				\
7115e3d2c5SChristoph Hellwig 	part_stat_add(part, field, -subnd)
72c6a564ffSChristoph Hellwig 
7315e3d2c5SChristoph Hellwig #define part_stat_local_dec(part, field)				\
7415e3d2c5SChristoph Hellwig 	local_dec(&(part_stat_get(part, field)))
7515e3d2c5SChristoph Hellwig #define part_stat_local_inc(part, field)				\
7615e3d2c5SChristoph Hellwig 	local_inc(&(part_stat_get(part, field)))
7715e3d2c5SChristoph Hellwig #define part_stat_local_read(part, field)				\
7815e3d2c5SChristoph Hellwig 	local_read(&(part_stat_get(part, field)))
7915e3d2c5SChristoph Hellwig #define part_stat_local_read_cpu(part, field, cpu)			\
8015e3d2c5SChristoph Hellwig 	local_read(&(part_stat_get_cpu(part, field, cpu)))
81c6a564ffSChristoph Hellwig 
82c6a564ffSChristoph Hellwig #endif /* _LINUX_PART_STAT_H */
83