Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  *
0003  * Legacy blkg rwstat helpers enabled by CONFIG_BLK_CGROUP_RWSTAT.
0004  * Do not use in new code.
0005  */
0006 #include "blk-cgroup-rwstat.h"
0007 
0008 int blkg_rwstat_init(struct blkg_rwstat *rwstat, gfp_t gfp)
0009 {
0010     int i, ret;
0011 
0012     for (i = 0; i < BLKG_RWSTAT_NR; i++) {
0013         ret = percpu_counter_init(&rwstat->cpu_cnt[i], 0, gfp);
0014         if (ret) {
0015             while (--i >= 0)
0016                 percpu_counter_destroy(&rwstat->cpu_cnt[i]);
0017             return ret;
0018         }
0019         atomic64_set(&rwstat->aux_cnt[i], 0);
0020     }
0021     return 0;
0022 }
0023 EXPORT_SYMBOL_GPL(blkg_rwstat_init);
0024 
0025 void blkg_rwstat_exit(struct blkg_rwstat *rwstat)
0026 {
0027     int i;
0028 
0029     for (i = 0; i < BLKG_RWSTAT_NR; i++)
0030         percpu_counter_destroy(&rwstat->cpu_cnt[i]);
0031 }
0032 EXPORT_SYMBOL_GPL(blkg_rwstat_exit);
0033 
0034 /**
0035  * __blkg_prfill_rwstat - prfill helper for a blkg_rwstat
0036  * @sf: seq_file to print to
0037  * @pd: policy private data of interest
0038  * @rwstat: rwstat to print
0039  *
0040  * Print @rwstat to @sf for the device assocaited with @pd.
0041  */
0042 u64 __blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
0043              const struct blkg_rwstat_sample *rwstat)
0044 {
0045     static const char *rwstr[] = {
0046         [BLKG_RWSTAT_READ]  = "Read",
0047         [BLKG_RWSTAT_WRITE] = "Write",
0048         [BLKG_RWSTAT_SYNC]  = "Sync",
0049         [BLKG_RWSTAT_ASYNC] = "Async",
0050         [BLKG_RWSTAT_DISCARD]   = "Discard",
0051     };
0052     const char *dname = blkg_dev_name(pd->blkg);
0053     u64 v;
0054     int i;
0055 
0056     if (!dname)
0057         return 0;
0058 
0059     for (i = 0; i < BLKG_RWSTAT_NR; i++)
0060         seq_printf(sf, "%s %s %llu\n", dname, rwstr[i],
0061                rwstat->cnt[i]);
0062 
0063     v = rwstat->cnt[BLKG_RWSTAT_READ] +
0064         rwstat->cnt[BLKG_RWSTAT_WRITE] +
0065         rwstat->cnt[BLKG_RWSTAT_DISCARD];
0066     seq_printf(sf, "%s Total %llu\n", dname, v);
0067     return v;
0068 }
0069 EXPORT_SYMBOL_GPL(__blkg_prfill_rwstat);
0070 
0071 /**
0072  * blkg_prfill_rwstat - prfill callback for blkg_rwstat
0073  * @sf: seq_file to print to
0074  * @pd: policy private data of interest
0075  * @off: offset to the blkg_rwstat in @pd
0076  *
0077  * prfill callback for printing a blkg_rwstat.
0078  */
0079 u64 blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
0080                int off)
0081 {
0082     struct blkg_rwstat_sample rwstat = { };
0083 
0084     blkg_rwstat_read((void *)pd + off, &rwstat);
0085     return __blkg_prfill_rwstat(sf, pd, &rwstat);
0086 }
0087 EXPORT_SYMBOL_GPL(blkg_prfill_rwstat);
0088 
0089 /**
0090  * blkg_rwstat_recursive_sum - collect hierarchical blkg_rwstat
0091  * @blkg: blkg of interest
0092  * @pol: blkcg_policy which contains the blkg_rwstat
0093  * @off: offset to the blkg_rwstat in blkg_policy_data or @blkg
0094  * @sum: blkg_rwstat_sample structure containing the results
0095  *
0096  * Collect the blkg_rwstat specified by @blkg, @pol and @off and all its
0097  * online descendants and their aux counts.  The caller must be holding the
0098  * queue lock for online tests.
0099  *
0100  * If @pol is NULL, blkg_rwstat is at @off bytes into @blkg; otherwise, it
0101  * is at @off bytes into @blkg's blkg_policy_data of the policy.
0102  */
0103 void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol,
0104         int off, struct blkg_rwstat_sample *sum)
0105 {
0106     struct blkcg_gq *pos_blkg;
0107     struct cgroup_subsys_state *pos_css;
0108     unsigned int i;
0109 
0110     lockdep_assert_held(&blkg->q->queue_lock);
0111 
0112     memset(sum, 0, sizeof(*sum));
0113     rcu_read_lock();
0114     blkg_for_each_descendant_pre(pos_blkg, pos_css, blkg) {
0115         struct blkg_rwstat *rwstat;
0116 
0117         if (!pos_blkg->online)
0118             continue;
0119 
0120         if (pol)
0121             rwstat = (void *)blkg_to_pd(pos_blkg, pol) + off;
0122         else
0123             rwstat = (void *)pos_blkg + off;
0124 
0125         for (i = 0; i < BLKG_RWSTAT_NR; i++)
0126             sum->cnt[i] += blkg_rwstat_read_counter(rwstat, i);
0127     }
0128     rcu_read_unlock();
0129 }
0130 EXPORT_SYMBOL_GPL(blkg_rwstat_recursive_sum);