cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

blk-cgroup-rwstat.c (3485B)


      1/* SPDX-License-Identifier: GPL-2.0
      2 *
      3 * Legacy blkg rwstat helpers enabled by CONFIG_BLK_CGROUP_RWSTAT.
      4 * Do not use in new code.
      5 */
      6#include "blk-cgroup-rwstat.h"
      7
      8int blkg_rwstat_init(struct blkg_rwstat *rwstat, gfp_t gfp)
      9{
     10	int i, ret;
     11
     12	for (i = 0; i < BLKG_RWSTAT_NR; i++) {
     13		ret = percpu_counter_init(&rwstat->cpu_cnt[i], 0, gfp);
     14		if (ret) {
     15			while (--i >= 0)
     16				percpu_counter_destroy(&rwstat->cpu_cnt[i]);
     17			return ret;
     18		}
     19		atomic64_set(&rwstat->aux_cnt[i], 0);
     20	}
     21	return 0;
     22}
     23EXPORT_SYMBOL_GPL(blkg_rwstat_init);
     24
     25void blkg_rwstat_exit(struct blkg_rwstat *rwstat)
     26{
     27	int i;
     28
     29	for (i = 0; i < BLKG_RWSTAT_NR; i++)
     30		percpu_counter_destroy(&rwstat->cpu_cnt[i]);
     31}
     32EXPORT_SYMBOL_GPL(blkg_rwstat_exit);
     33
     34/**
     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
     39 *
     40 * Print @rwstat to @sf for the device assocaited with @pd.
     41 */
     42u64 __blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
     43			 const struct blkg_rwstat_sample *rwstat)
     44{
     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",
     51	};
     52	const char *dname = blkg_dev_name(pd->blkg);
     53	u64 v;
     54	int i;
     55
     56	if (!dname)
     57		return 0;
     58
     59	for (i = 0; i < BLKG_RWSTAT_NR; i++)
     60		seq_printf(sf, "%s %s %llu\n", dname, rwstr[i],
     61			   rwstat->cnt[i]);
     62
     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);
     67	return v;
     68}
     69EXPORT_SYMBOL_GPL(__blkg_prfill_rwstat);
     70
     71/**
     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
     76 *
     77 * prfill callback for printing a blkg_rwstat.
     78 */
     79u64 blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
     80		       int off)
     81{
     82	struct blkg_rwstat_sample rwstat = { };
     83
     84	blkg_rwstat_read((void *)pd + off, &rwstat);
     85	return __blkg_prfill_rwstat(sf, pd, &rwstat);
     86}
     87EXPORT_SYMBOL_GPL(blkg_prfill_rwstat);
     88
     89/**
     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
     95 *
     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.
     99 *
    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.
    102 */
    103void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol,
    104		int off, struct blkg_rwstat_sample *sum)
    105{
    106	struct blkcg_gq *pos_blkg;
    107	struct cgroup_subsys_state *pos_css;
    108	unsigned int i;
    109
    110	lockdep_assert_held(&blkg->q->queue_lock);
    111
    112	memset(sum, 0, sizeof(*sum));
    113	rcu_read_lock();
    114	blkg_for_each_descendant_pre(pos_blkg, pos_css, blkg) {
    115		struct blkg_rwstat *rwstat;
    116
    117		if (!pos_blkg->online)
    118			continue;
    119
    120		if (pol)
    121			rwstat = (void *)blkg_to_pd(pos_blkg, pol) + off;
    122		else
    123			rwstat = (void *)pos_blkg + off;
    124
    125		for (i = 0; i < BLKG_RWSTAT_NR; i++)
    126			sum->cnt[i] += blkg_rwstat_read_counter(rwstat, i);
    127	}
    128	rcu_read_unlock();
    129}
    130EXPORT_SYMBOL_GPL(blkg_rwstat_recursive_sum);