Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[linux-2.6-microblaze.git] / include / linux / part_stat.h
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 /*
8  * Macros to operate on percpu disk statistics:
9  *
10  * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters
11  * and should be called between disk_stat_lock() and
12  * disk_stat_unlock().
13  *
14  * part_stat_read() can be called at any time.
15  *
16  * part_stat_{add|set_all}() and {init|free}_part_stats are for
17  * internal use only.
18  */
19 #ifdef  CONFIG_SMP
20 #define part_stat_lock()        ({ rcu_read_lock(); get_cpu(); })
21 #define part_stat_unlock()      do { put_cpu(); rcu_read_unlock(); } while (0)
22
23 #define part_stat_get_cpu(part, field, cpu)                             \
24         (per_cpu_ptr((part)->dkstats, (cpu))->field)
25
26 #define part_stat_get(part, field)                                      \
27         part_stat_get_cpu(part, field, smp_processor_id())
28
29 #define part_stat_read(part, field)                                     \
30 ({                                                                      \
31         typeof((part)->dkstats->field) res = 0;                         \
32         unsigned int _cpu;                                              \
33         for_each_possible_cpu(_cpu)                                     \
34                 res += per_cpu_ptr((part)->dkstats, _cpu)->field;       \
35         res;                                                            \
36 })
37
38 static inline void part_stat_set_all(struct hd_struct *part, int value)
39 {
40         int i;
41
42         for_each_possible_cpu(i)
43                 memset(per_cpu_ptr(part->dkstats, i), value,
44                                 sizeof(struct disk_stats));
45 }
46
47 static inline int init_part_stats(struct hd_struct *part)
48 {
49         part->dkstats = alloc_percpu(struct disk_stats);
50         if (!part->dkstats)
51                 return 0;
52         return 1;
53 }
54
55 static inline void free_part_stats(struct hd_struct *part)
56 {
57         free_percpu(part->dkstats);
58 }
59
60 #else /* !CONFIG_SMP */
61 #define part_stat_lock()        ({ rcu_read_lock(); 0; })
62 #define part_stat_unlock()      rcu_read_unlock()
63
64 #define part_stat_get(part, field)              ((part)->dkstats.field)
65 #define part_stat_get_cpu(part, field, cpu)     part_stat_get(part, field)
66 #define part_stat_read(part, field)             part_stat_get(part, field)
67
68 static inline void part_stat_set_all(struct hd_struct *part, int value)
69 {
70         memset(&part->dkstats, value, sizeof(struct disk_stats));
71 }
72
73 static inline int init_part_stats(struct hd_struct *part)
74 {
75         return 1;
76 }
77
78 static inline void free_part_stats(struct hd_struct *part)
79 {
80 }
81
82 #endif /* CONFIG_SMP */
83
84 #define part_stat_read_accum(part, field)                               \
85         (part_stat_read(part, field[STAT_READ]) +                       \
86          part_stat_read(part, field[STAT_WRITE]) +                      \
87          part_stat_read(part, field[STAT_DISCARD]))
88
89 #define __part_stat_add(part, field, addnd)                             \
90         (part_stat_get(part, field) += (addnd))
91
92 #define part_stat_add(part, field, addnd)       do {                    \
93         __part_stat_add((part), field, addnd);                          \
94         if ((part)->partno)                                             \
95                 __part_stat_add(&part_to_disk((part))->part0,           \
96                                 field, addnd);                          \
97 } while (0)
98
99 #define part_stat_dec(gendiskp, field)                                  \
100         part_stat_add(gendiskp, field, -1)
101 #define part_stat_inc(gendiskp, field)                                  \
102         part_stat_add(gendiskp, field, 1)
103 #define part_stat_sub(gendiskp, field, subnd)                           \
104         part_stat_add(gendiskp, field, -subnd)
105
106 #define part_stat_local_dec(gendiskp, field)                            \
107         local_dec(&(part_stat_get(gendiskp, field)))
108 #define part_stat_local_inc(gendiskp, field)                            \
109         local_inc(&(part_stat_get(gendiskp, field)))
110 #define part_stat_local_read(gendiskp, field)                           \
111         local_read(&(part_stat_get(gendiskp, field)))
112 #define part_stat_local_read_cpu(gendiskp, field, cpu)                  \
113         local_read(&(part_stat_get_cpu(gendiskp, field, cpu)))
114
115 #endif /* _LINUX_PART_STAT_H */