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