1 /* SPDX-License-Identifier: GPL-2.0
3 * Legacy blkg rwstat helpers enabled by CONFIG_BLK_CGROUP_RWSTAT.
4 * Do not use in new code.
6 #include "blk-cgroup-rwstat.h"
8 int blkg_rwstat_init(struct blkg_rwstat
*rwstat
, gfp_t gfp
)
12 for (i
= 0; i
< BLKG_RWSTAT_NR
; i
++) {
13 ret
= percpu_counter_init(&rwstat
->cpu_cnt
[i
], 0, gfp
);
16 percpu_counter_destroy(&rwstat
->cpu_cnt
[i
]);
19 atomic64_set(&rwstat
->aux_cnt
[i
], 0);
23 EXPORT_SYMBOL_GPL(blkg_rwstat_init
);
25 void blkg_rwstat_exit(struct blkg_rwstat
*rwstat
)
29 for (i
= 0; i
< BLKG_RWSTAT_NR
; i
++)
30 percpu_counter_destroy(&rwstat
->cpu_cnt
[i
]);
32 EXPORT_SYMBOL_GPL(blkg_rwstat_exit
);
35 * __blkg_prfill_rwstat - prfill helper for a blkg_rwstat
36 * @sf: seq_file to print to
37 * @pd: policy private data of interest
38 * @rwstat: rwstat to print
40 * Print @rwstat to @sf for the device assocaited with @pd.
42 u64
__blkg_prfill_rwstat(struct seq_file
*sf
, struct blkg_policy_data
*pd
,
43 const struct blkg_rwstat_sample
*rwstat
)
45 static const char *rwstr
[] = {
46 [BLKG_RWSTAT_READ
] = "Read",
47 [BLKG_RWSTAT_WRITE
] = "Write",
48 [BLKG_RWSTAT_SYNC
] = "Sync",
49 [BLKG_RWSTAT_ASYNC
] = "Async",
50 [BLKG_RWSTAT_DISCARD
] = "Discard",
52 const char *dname
= blkg_dev_name(pd
->blkg
);
59 for (i
= 0; i
< BLKG_RWSTAT_NR
; i
++)
60 seq_printf(sf
, "%s %s %llu\n", dname
, rwstr
[i
],
63 v
= rwstat
->cnt
[BLKG_RWSTAT_READ
] +
64 rwstat
->cnt
[BLKG_RWSTAT_WRITE
] +
65 rwstat
->cnt
[BLKG_RWSTAT_DISCARD
];
66 seq_printf(sf
, "%s Total %llu\n", dname
, v
);
69 EXPORT_SYMBOL_GPL(__blkg_prfill_rwstat
);
72 * blkg_prfill_rwstat - prfill callback for blkg_rwstat
73 * @sf: seq_file to print to
74 * @pd: policy private data of interest
75 * @off: offset to the blkg_rwstat in @pd
77 * prfill callback for printing a blkg_rwstat.
79 u64
blkg_prfill_rwstat(struct seq_file
*sf
, struct blkg_policy_data
*pd
,
82 struct blkg_rwstat_sample rwstat
= { };
84 blkg_rwstat_read((void *)pd
+ off
, &rwstat
);
85 return __blkg_prfill_rwstat(sf
, pd
, &rwstat
);
87 EXPORT_SYMBOL_GPL(blkg_prfill_rwstat
);
90 * blkg_rwstat_recursive_sum - collect hierarchical blkg_rwstat
91 * @blkg: blkg of interest
92 * @pol: blkcg_policy which contains the blkg_rwstat
93 * @off: offset to the blkg_rwstat in blkg_policy_data or @blkg
94 * @sum: blkg_rwstat_sample structure containing the results
96 * Collect the blkg_rwstat specified by @blkg, @pol and @off and all its
97 * online descendants and their aux counts. The caller must be holding the
98 * queue lock for online tests.
100 * If @pol is NULL, blkg_rwstat is at @off bytes into @blkg; otherwise, it
101 * is at @off bytes into @blkg's blkg_policy_data of the policy.
103 void blkg_rwstat_recursive_sum(struct blkcg_gq
*blkg
, struct blkcg_policy
*pol
,
104 int off
, struct blkg_rwstat_sample
*sum
)
106 struct blkcg_gq
*pos_blkg
;
107 struct cgroup_subsys_state
*pos_css
;
110 lockdep_assert_held(&blkg
->q
->queue_lock
);
113 blkg_for_each_descendant_pre(pos_blkg
, pos_css
, blkg
) {
114 struct blkg_rwstat
*rwstat
;
116 if (!pos_blkg
->online
)
120 rwstat
= (void *)blkg_to_pd(pos_blkg
, pol
) + off
;
122 rwstat
= (void *)pos_blkg
+ off
;
124 for (i
= 0; i
< BLKG_RWSTAT_NR
; i
++)
125 sum
->cnt
[i
] = blkg_rwstat_read_counter(rwstat
, i
);
129 EXPORT_SYMBOL_GPL(blkg_rwstat_recursive_sum
);