18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _BLK_CGROUP_H
38c2ecf20Sopenharmony_ci#define _BLK_CGROUP_H
48c2ecf20Sopenharmony_ci/*
58c2ecf20Sopenharmony_ci * Common Block IO controller cgroup interface
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Based on ideas and code from CFQ, CFS and BFQ:
88c2ecf20Sopenharmony_ci * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
118c2ecf20Sopenharmony_ci *		      Paolo Valente <paolo.valente@unimore.it>
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
148c2ecf20Sopenharmony_ci * 	              Nauman Rafique <nauman@google.com>
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/cgroup.h>
188c2ecf20Sopenharmony_ci#include <linux/percpu.h>
198c2ecf20Sopenharmony_ci#include <linux/percpu_counter.h>
208c2ecf20Sopenharmony_ci#include <linux/u64_stats_sync.h>
218c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
228c2ecf20Sopenharmony_ci#include <linux/radix-tree.h>
238c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
248c2ecf20Sopenharmony_ci#include <linux/atomic.h>
258c2ecf20Sopenharmony_ci#include <linux/kthread.h>
268c2ecf20Sopenharmony_ci#include <linux/fs.h>
278c2ecf20Sopenharmony_ci#include <linux/blk-mq.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
308c2ecf20Sopenharmony_ci#define BLKG_STAT_CPU_BATCH	(INT_MAX / 2)
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/* Max limits for throttle policy */
338c2ecf20Sopenharmony_ci#define THROTL_IOPS_MAX		UINT_MAX
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_CGROUP
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cienum blkg_iostat_type {
388c2ecf20Sopenharmony_ci	BLKG_IOSTAT_READ,
398c2ecf20Sopenharmony_ci	BLKG_IOSTAT_WRITE,
408c2ecf20Sopenharmony_ci	BLKG_IOSTAT_DISCARD,
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	BLKG_IOSTAT_NR,
438c2ecf20Sopenharmony_ci};
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistruct blkcg_gq;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistruct blkcg {
488c2ecf20Sopenharmony_ci	struct cgroup_subsys_state	css;
498c2ecf20Sopenharmony_ci	spinlock_t			lock;
508c2ecf20Sopenharmony_ci	refcount_t			online_pin;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	struct radix_tree_root		blkg_tree;
538c2ecf20Sopenharmony_ci	struct blkcg_gq	__rcu		*blkg_hint;
548c2ecf20Sopenharmony_ci	struct hlist_head		blkg_list;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	struct blkcg_policy_data	*cpd[BLKCG_MAX_POLS];
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	struct list_head		all_blkcgs_node;
598c2ecf20Sopenharmony_ci#ifdef CONFIG_CGROUP_WRITEBACK
608c2ecf20Sopenharmony_ci	struct list_head		cgwb_list;
618c2ecf20Sopenharmony_ci#endif
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistruct blkg_iostat {
658c2ecf20Sopenharmony_ci	u64				bytes[BLKG_IOSTAT_NR];
668c2ecf20Sopenharmony_ci	u64				ios[BLKG_IOSTAT_NR];
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct blkg_iostat_set {
708c2ecf20Sopenharmony_ci	struct u64_stats_sync		sync;
718c2ecf20Sopenharmony_ci	struct blkg_iostat		cur;
728c2ecf20Sopenharmony_ci	struct blkg_iostat		last;
738c2ecf20Sopenharmony_ci};
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/*
768c2ecf20Sopenharmony_ci * A blkcg_gq (blkg) is association between a block cgroup (blkcg) and a
778c2ecf20Sopenharmony_ci * request_queue (q).  This is used by blkcg policies which need to track
788c2ecf20Sopenharmony_ci * information per blkcg - q pair.
798c2ecf20Sopenharmony_ci *
808c2ecf20Sopenharmony_ci * There can be multiple active blkcg policies and each blkg:policy pair is
818c2ecf20Sopenharmony_ci * represented by a blkg_policy_data which is allocated and freed by each
828c2ecf20Sopenharmony_ci * policy's pd_alloc/free_fn() methods.  A policy can allocate private data
838c2ecf20Sopenharmony_ci * area by allocating larger data structure which embeds blkg_policy_data
848c2ecf20Sopenharmony_ci * at the beginning.
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_cistruct blkg_policy_data {
878c2ecf20Sopenharmony_ci	/* the blkg and policy id this per-policy data belongs to */
888c2ecf20Sopenharmony_ci	struct blkcg_gq			*blkg;
898c2ecf20Sopenharmony_ci	int				plid;
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/*
938c2ecf20Sopenharmony_ci * Policies that need to keep per-blkcg data which is independent from any
948c2ecf20Sopenharmony_ci * request_queue associated to it should implement cpd_alloc/free_fn()
958c2ecf20Sopenharmony_ci * methods.  A policy can allocate private data area by allocating larger
968c2ecf20Sopenharmony_ci * data structure which embeds blkcg_policy_data at the beginning.
978c2ecf20Sopenharmony_ci * cpd_init() is invoked to let each policy handle per-blkcg data.
988c2ecf20Sopenharmony_ci */
998c2ecf20Sopenharmony_cistruct blkcg_policy_data {
1008c2ecf20Sopenharmony_ci	/* the blkcg and policy id this per-policy data belongs to */
1018c2ecf20Sopenharmony_ci	struct blkcg			*blkcg;
1028c2ecf20Sopenharmony_ci	int				plid;
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/* association between a blk cgroup and a request queue */
1068c2ecf20Sopenharmony_cistruct blkcg_gq {
1078c2ecf20Sopenharmony_ci	/* Pointer to the associated request_queue */
1088c2ecf20Sopenharmony_ci	struct request_queue		*q;
1098c2ecf20Sopenharmony_ci	struct list_head		q_node;
1108c2ecf20Sopenharmony_ci	struct hlist_node		blkcg_node;
1118c2ecf20Sopenharmony_ci	struct blkcg			*blkcg;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	/* all non-root blkcg_gq's are guaranteed to have access to parent */
1148c2ecf20Sopenharmony_ci	struct blkcg_gq			*parent;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	/* reference count */
1178c2ecf20Sopenharmony_ci	struct percpu_ref		refcnt;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	/* is this blkg online? protected by both blkcg and q locks */
1208c2ecf20Sopenharmony_ci	bool				online;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	struct blkg_iostat_set __percpu	*iostat_cpu;
1238c2ecf20Sopenharmony_ci	struct blkg_iostat_set		iostat;
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	struct blkg_policy_data		*pd[BLKCG_MAX_POLS];
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	spinlock_t			async_bio_lock;
1288c2ecf20Sopenharmony_ci	struct bio_list			async_bios;
1298c2ecf20Sopenharmony_ci	struct work_struct		async_bio_work;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	atomic_t			use_delay;
1328c2ecf20Sopenharmony_ci	atomic64_t			delay_nsec;
1338c2ecf20Sopenharmony_ci	atomic64_t			delay_start;
1348c2ecf20Sopenharmony_ci	u64				last_delay;
1358c2ecf20Sopenharmony_ci	int				last_use;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	struct rcu_head			rcu_head;
1388c2ecf20Sopenharmony_ci};
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_citypedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
1418c2ecf20Sopenharmony_citypedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
1428c2ecf20Sopenharmony_citypedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
1438c2ecf20Sopenharmony_citypedef void (blkcg_pol_bind_cpd_fn)(struct blkcg_policy_data *cpd);
1448c2ecf20Sopenharmony_citypedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp,
1458c2ecf20Sopenharmony_ci				struct request_queue *q, struct blkcg *blkcg);
1468c2ecf20Sopenharmony_citypedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
1478c2ecf20Sopenharmony_citypedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd);
1488c2ecf20Sopenharmony_citypedef void (blkcg_pol_offline_pd_fn)(struct blkg_policy_data *pd);
1498c2ecf20Sopenharmony_citypedef void (blkcg_pol_free_pd_fn)(struct blkg_policy_data *pd);
1508c2ecf20Sopenharmony_citypedef void (blkcg_pol_reset_pd_stats_fn)(struct blkg_policy_data *pd);
1518c2ecf20Sopenharmony_citypedef size_t (blkcg_pol_stat_pd_fn)(struct blkg_policy_data *pd, char *buf,
1528c2ecf20Sopenharmony_ci				      size_t size);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistruct blkcg_policy {
1558c2ecf20Sopenharmony_ci	int				plid;
1568c2ecf20Sopenharmony_ci	/* cgroup files for the policy */
1578c2ecf20Sopenharmony_ci	struct cftype			*dfl_cftypes;
1588c2ecf20Sopenharmony_ci	struct cftype			*legacy_cftypes;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* operations */
1618c2ecf20Sopenharmony_ci	blkcg_pol_alloc_cpd_fn		*cpd_alloc_fn;
1628c2ecf20Sopenharmony_ci	blkcg_pol_init_cpd_fn		*cpd_init_fn;
1638c2ecf20Sopenharmony_ci	blkcg_pol_free_cpd_fn		*cpd_free_fn;
1648c2ecf20Sopenharmony_ci	blkcg_pol_bind_cpd_fn		*cpd_bind_fn;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	blkcg_pol_alloc_pd_fn		*pd_alloc_fn;
1678c2ecf20Sopenharmony_ci	blkcg_pol_init_pd_fn		*pd_init_fn;
1688c2ecf20Sopenharmony_ci	blkcg_pol_online_pd_fn		*pd_online_fn;
1698c2ecf20Sopenharmony_ci	blkcg_pol_offline_pd_fn		*pd_offline_fn;
1708c2ecf20Sopenharmony_ci	blkcg_pol_free_pd_fn		*pd_free_fn;
1718c2ecf20Sopenharmony_ci	blkcg_pol_reset_pd_stats_fn	*pd_reset_stats_fn;
1728c2ecf20Sopenharmony_ci	blkcg_pol_stat_pd_fn		*pd_stat_fn;
1738c2ecf20Sopenharmony_ci};
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciextern struct blkcg blkcg_root;
1768c2ecf20Sopenharmony_ciextern struct cgroup_subsys_state * const blkcg_root_css;
1778c2ecf20Sopenharmony_ciextern bool blkcg_debug_stats;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_cistruct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
1808c2ecf20Sopenharmony_ci				      struct request_queue *q, bool update_hint);
1818c2ecf20Sopenharmony_ciint blkcg_init_queue(struct request_queue *q);
1828c2ecf20Sopenharmony_civoid blkcg_exit_queue(struct request_queue *q);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/* Blkio controller policy registration */
1858c2ecf20Sopenharmony_ciint blkcg_policy_register(struct blkcg_policy *pol);
1868c2ecf20Sopenharmony_civoid blkcg_policy_unregister(struct blkcg_policy *pol);
1878c2ecf20Sopenharmony_ciint blkcg_activate_policy(struct request_queue *q,
1888c2ecf20Sopenharmony_ci			  const struct blkcg_policy *pol);
1898c2ecf20Sopenharmony_civoid blkcg_deactivate_policy(struct request_queue *q,
1908c2ecf20Sopenharmony_ci			     const struct blkcg_policy *pol);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ciconst char *blkg_dev_name(struct blkcg_gq *blkg);
1938c2ecf20Sopenharmony_civoid blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg,
1948c2ecf20Sopenharmony_ci		       u64 (*prfill)(struct seq_file *,
1958c2ecf20Sopenharmony_ci				     struct blkg_policy_data *, int),
1968c2ecf20Sopenharmony_ci		       const struct blkcg_policy *pol, int data,
1978c2ecf20Sopenharmony_ci		       bool show_total);
1988c2ecf20Sopenharmony_ciu64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistruct blkg_conf_ctx {
2018c2ecf20Sopenharmony_ci	struct gendisk			*disk;
2028c2ecf20Sopenharmony_ci	struct blkcg_gq			*blkg;
2038c2ecf20Sopenharmony_ci	char				*body;
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistruct gendisk *blkcg_conf_get_disk(char **inputp);
2078c2ecf20Sopenharmony_ciint blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
2088c2ecf20Sopenharmony_ci		   char *input, struct blkg_conf_ctx *ctx);
2098c2ecf20Sopenharmony_civoid blkg_conf_finish(struct blkg_conf_ctx *ctx);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci/**
2128c2ecf20Sopenharmony_ci * blkcg_css - find the current css
2138c2ecf20Sopenharmony_ci *
2148c2ecf20Sopenharmony_ci * Find the css associated with either the kthread or the current task.
2158c2ecf20Sopenharmony_ci * This may return a dying css, so it is up to the caller to use tryget logic
2168c2ecf20Sopenharmony_ci * to confirm it is alive and well.
2178c2ecf20Sopenharmony_ci */
2188c2ecf20Sopenharmony_cistatic inline struct cgroup_subsys_state *blkcg_css(void)
2198c2ecf20Sopenharmony_ci{
2208c2ecf20Sopenharmony_ci	struct cgroup_subsys_state *css;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	css = kthread_blkcg();
2238c2ecf20Sopenharmony_ci	if (css)
2248c2ecf20Sopenharmony_ci		return css;
2258c2ecf20Sopenharmony_ci	return task_css(current, io_cgrp_id);
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	return css ? container_of(css, struct blkcg, css) : NULL;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci/**
2348c2ecf20Sopenharmony_ci * __bio_blkcg - internal, inconsistent version to get blkcg
2358c2ecf20Sopenharmony_ci *
2368c2ecf20Sopenharmony_ci * DO NOT USE.
2378c2ecf20Sopenharmony_ci * This function is inconsistent and consequently is dangerous to use.  The
2388c2ecf20Sopenharmony_ci * first part of the function returns a blkcg where a reference is owned by the
2398c2ecf20Sopenharmony_ci * bio.  This means it does not need to be rcu protected as it cannot go away
2408c2ecf20Sopenharmony_ci * with the bio owning a reference to it.  However, the latter potentially gets
2418c2ecf20Sopenharmony_ci * it from task_css().  This can race against task migration and the cgroup
2428c2ecf20Sopenharmony_ci * dying.  It is also semantically different as it must be called rcu protected
2438c2ecf20Sopenharmony_ci * and is susceptible to failure when trying to get a reference to it.
2448c2ecf20Sopenharmony_ci * Therefore, it is not ok to assume that *_get() will always succeed on the
2458c2ecf20Sopenharmony_ci * blkcg returned here.
2468c2ecf20Sopenharmony_ci */
2478c2ecf20Sopenharmony_cistatic inline struct blkcg *__bio_blkcg(struct bio *bio)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	if (bio && bio->bi_blkg)
2508c2ecf20Sopenharmony_ci		return bio->bi_blkg->blkcg;
2518c2ecf20Sopenharmony_ci	return css_to_blkcg(blkcg_css());
2528c2ecf20Sopenharmony_ci}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci/**
2558c2ecf20Sopenharmony_ci * bio_blkcg - grab the blkcg associated with a bio
2568c2ecf20Sopenharmony_ci * @bio: target bio
2578c2ecf20Sopenharmony_ci *
2588c2ecf20Sopenharmony_ci * This returns the blkcg associated with a bio, %NULL if not associated.
2598c2ecf20Sopenharmony_ci * Callers are expected to either handle %NULL or know association has been
2608c2ecf20Sopenharmony_ci * done prior to calling this.
2618c2ecf20Sopenharmony_ci */
2628c2ecf20Sopenharmony_cistatic inline struct blkcg *bio_blkcg(struct bio *bio)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	if (bio && bio->bi_blkg)
2658c2ecf20Sopenharmony_ci		return bio->bi_blkg->blkcg;
2668c2ecf20Sopenharmony_ci	return NULL;
2678c2ecf20Sopenharmony_ci}
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_cistatic inline bool blk_cgroup_congested(void)
2708c2ecf20Sopenharmony_ci{
2718c2ecf20Sopenharmony_ci	struct cgroup_subsys_state *css;
2728c2ecf20Sopenharmony_ci	bool ret = false;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	rcu_read_lock();
2758c2ecf20Sopenharmony_ci	css = kthread_blkcg();
2768c2ecf20Sopenharmony_ci	if (!css)
2778c2ecf20Sopenharmony_ci		css = task_css(current, io_cgrp_id);
2788c2ecf20Sopenharmony_ci	while (css) {
2798c2ecf20Sopenharmony_ci		if (atomic_read(&css->cgroup->congestion_count)) {
2808c2ecf20Sopenharmony_ci			ret = true;
2818c2ecf20Sopenharmony_ci			break;
2828c2ecf20Sopenharmony_ci		}
2838c2ecf20Sopenharmony_ci		css = css->parent;
2848c2ecf20Sopenharmony_ci	}
2858c2ecf20Sopenharmony_ci	rcu_read_unlock();
2868c2ecf20Sopenharmony_ci	return ret;
2878c2ecf20Sopenharmony_ci}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci/**
2908c2ecf20Sopenharmony_ci * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
2918c2ecf20Sopenharmony_ci * @return: true if this bio needs to be submitted with the root blkg context.
2928c2ecf20Sopenharmony_ci *
2938c2ecf20Sopenharmony_ci * In order to avoid priority inversions we sometimes need to issue a bio as if
2948c2ecf20Sopenharmony_ci * it were attached to the root blkg, and then backcharge to the actual owning
2958c2ecf20Sopenharmony_ci * blkg.  The idea is we do bio_blkcg() to look up the actual context for the
2968c2ecf20Sopenharmony_ci * bio and attach the appropriate blkg to the bio.  Then we call this helper and
2978c2ecf20Sopenharmony_ci * if it is true run with the root blkg for that queue and then do any
2988c2ecf20Sopenharmony_ci * backcharging to the originating cgroup once the io is complete.
2998c2ecf20Sopenharmony_ci */
3008c2ecf20Sopenharmony_cistatic inline bool bio_issue_as_root_blkg(struct bio *bio)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	return (bio->bi_opf & (REQ_META | REQ_SWAP)) != 0;
3038c2ecf20Sopenharmony_ci}
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci/**
3068c2ecf20Sopenharmony_ci * blkcg_parent - get the parent of a blkcg
3078c2ecf20Sopenharmony_ci * @blkcg: blkcg of interest
3088c2ecf20Sopenharmony_ci *
3098c2ecf20Sopenharmony_ci * Return the parent blkcg of @blkcg.  Can be called anytime.
3108c2ecf20Sopenharmony_ci */
3118c2ecf20Sopenharmony_cistatic inline struct blkcg *blkcg_parent(struct blkcg *blkcg)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	return css_to_blkcg(blkcg->css.parent);
3148c2ecf20Sopenharmony_ci}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci/**
3178c2ecf20Sopenharmony_ci * __blkg_lookup - internal version of blkg_lookup()
3188c2ecf20Sopenharmony_ci * @blkcg: blkcg of interest
3198c2ecf20Sopenharmony_ci * @q: request_queue of interest
3208c2ecf20Sopenharmony_ci * @update_hint: whether to update lookup hint with the result or not
3218c2ecf20Sopenharmony_ci *
3228c2ecf20Sopenharmony_ci * This is internal version and shouldn't be used by policy
3238c2ecf20Sopenharmony_ci * implementations.  Looks up blkgs for the @blkcg - @q pair regardless of
3248c2ecf20Sopenharmony_ci * @q's bypass state.  If @update_hint is %true, the caller should be
3258c2ecf20Sopenharmony_ci * holding @q->queue_lock and lookup hint is updated on success.
3268c2ecf20Sopenharmony_ci */
3278c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
3288c2ecf20Sopenharmony_ci					     struct request_queue *q,
3298c2ecf20Sopenharmony_ci					     bool update_hint)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	struct blkcg_gq *blkg;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	if (blkcg == &blkcg_root)
3348c2ecf20Sopenharmony_ci		return q->root_blkg;
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	blkg = rcu_dereference(blkcg->blkg_hint);
3378c2ecf20Sopenharmony_ci	if (blkg && blkg->q == q)
3388c2ecf20Sopenharmony_ci		return blkg;
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	return blkg_lookup_slowpath(blkcg, q, update_hint);
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci/**
3448c2ecf20Sopenharmony_ci * blkg_lookup - lookup blkg for the specified blkcg - q pair
3458c2ecf20Sopenharmony_ci * @blkcg: blkcg of interest
3468c2ecf20Sopenharmony_ci * @q: request_queue of interest
3478c2ecf20Sopenharmony_ci *
3488c2ecf20Sopenharmony_ci * Lookup blkg for the @blkcg - @q pair.  This function should be called
3498c2ecf20Sopenharmony_ci * under RCU read lock.
3508c2ecf20Sopenharmony_ci */
3518c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
3528c2ecf20Sopenharmony_ci					   struct request_queue *q)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	WARN_ON_ONCE(!rcu_read_lock_held());
3558c2ecf20Sopenharmony_ci	return __blkg_lookup(blkcg, q, false);
3568c2ecf20Sopenharmony_ci}
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci/**
3598c2ecf20Sopenharmony_ci * blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair
3608c2ecf20Sopenharmony_ci * @q: request_queue of interest
3618c2ecf20Sopenharmony_ci *
3628c2ecf20Sopenharmony_ci * Lookup blkg for @q at the root level. See also blkg_lookup().
3638c2ecf20Sopenharmony_ci */
3648c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
3658c2ecf20Sopenharmony_ci{
3668c2ecf20Sopenharmony_ci	return q->root_blkg;
3678c2ecf20Sopenharmony_ci}
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci/**
3708c2ecf20Sopenharmony_ci * blkg_to_pdata - get policy private data
3718c2ecf20Sopenharmony_ci * @blkg: blkg of interest
3728c2ecf20Sopenharmony_ci * @pol: policy of interest
3738c2ecf20Sopenharmony_ci *
3748c2ecf20Sopenharmony_ci * Return pointer to private data associated with the @blkg-@pol pair.
3758c2ecf20Sopenharmony_ci */
3768c2ecf20Sopenharmony_cistatic inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
3778c2ecf20Sopenharmony_ci						  struct blkcg_policy *pol)
3788c2ecf20Sopenharmony_ci{
3798c2ecf20Sopenharmony_ci	return blkg ? blkg->pd[pol->plid] : NULL;
3808c2ecf20Sopenharmony_ci}
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_cistatic inline struct blkcg_policy_data *blkcg_to_cpd(struct blkcg *blkcg,
3838c2ecf20Sopenharmony_ci						     struct blkcg_policy *pol)
3848c2ecf20Sopenharmony_ci{
3858c2ecf20Sopenharmony_ci	return blkcg ? blkcg->cpd[pol->plid] : NULL;
3868c2ecf20Sopenharmony_ci}
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci/**
3898c2ecf20Sopenharmony_ci * pdata_to_blkg - get blkg associated with policy private data
3908c2ecf20Sopenharmony_ci * @pd: policy private data of interest
3918c2ecf20Sopenharmony_ci *
3928c2ecf20Sopenharmony_ci * @pd is policy private data.  Determine the blkg it's associated with.
3938c2ecf20Sopenharmony_ci */
3948c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd)
3958c2ecf20Sopenharmony_ci{
3968c2ecf20Sopenharmony_ci	return pd ? pd->blkg : NULL;
3978c2ecf20Sopenharmony_ci}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_cistatic inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)
4008c2ecf20Sopenharmony_ci{
4018c2ecf20Sopenharmony_ci	return cpd ? cpd->blkcg : NULL;
4028c2ecf20Sopenharmony_ci}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ciextern void blkcg_destroy_blkgs(struct blkcg *blkcg);
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci/**
4078c2ecf20Sopenharmony_ci * blkcg_pin_online - pin online state
4088c2ecf20Sopenharmony_ci * @blkcg: blkcg of interest
4098c2ecf20Sopenharmony_ci *
4108c2ecf20Sopenharmony_ci * While pinned, a blkcg is kept online.  This is primarily used to
4118c2ecf20Sopenharmony_ci * impedance-match blkg and cgwb lifetimes so that blkg doesn't go offline
4128c2ecf20Sopenharmony_ci * while an associated cgwb is still active.
4138c2ecf20Sopenharmony_ci */
4148c2ecf20Sopenharmony_cistatic inline void blkcg_pin_online(struct blkcg *blkcg)
4158c2ecf20Sopenharmony_ci{
4168c2ecf20Sopenharmony_ci	refcount_inc(&blkcg->online_pin);
4178c2ecf20Sopenharmony_ci}
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci/**
4208c2ecf20Sopenharmony_ci * blkcg_unpin_online - unpin online state
4218c2ecf20Sopenharmony_ci * @blkcg: blkcg of interest
4228c2ecf20Sopenharmony_ci *
4238c2ecf20Sopenharmony_ci * This is primarily used to impedance-match blkg and cgwb lifetimes so
4248c2ecf20Sopenharmony_ci * that blkg doesn't go offline while an associated cgwb is still active.
4258c2ecf20Sopenharmony_ci * When this count goes to zero, all active cgwbs have finished so the
4268c2ecf20Sopenharmony_ci * blkcg can continue destruction by calling blkcg_destroy_blkgs().
4278c2ecf20Sopenharmony_ci */
4288c2ecf20Sopenharmony_cistatic inline void blkcg_unpin_online(struct blkcg *blkcg)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	do {
4318c2ecf20Sopenharmony_ci		if (!refcount_dec_and_test(&blkcg->online_pin))
4328c2ecf20Sopenharmony_ci			break;
4338c2ecf20Sopenharmony_ci		blkcg_destroy_blkgs(blkcg);
4348c2ecf20Sopenharmony_ci		blkcg = blkcg_parent(blkcg);
4358c2ecf20Sopenharmony_ci	} while (blkcg);
4368c2ecf20Sopenharmony_ci}
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci/**
4398c2ecf20Sopenharmony_ci * blkg_path - format cgroup path of blkg
4408c2ecf20Sopenharmony_ci * @blkg: blkg of interest
4418c2ecf20Sopenharmony_ci * @buf: target buffer
4428c2ecf20Sopenharmony_ci * @buflen: target buffer length
4438c2ecf20Sopenharmony_ci *
4448c2ecf20Sopenharmony_ci * Format the path of the cgroup of @blkg into @buf.
4458c2ecf20Sopenharmony_ci */
4468c2ecf20Sopenharmony_cistatic inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
4478c2ecf20Sopenharmony_ci{
4488c2ecf20Sopenharmony_ci	return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
4498c2ecf20Sopenharmony_ci}
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci/**
4528c2ecf20Sopenharmony_ci * blkg_get - get a blkg reference
4538c2ecf20Sopenharmony_ci * @blkg: blkg to get
4548c2ecf20Sopenharmony_ci *
4558c2ecf20Sopenharmony_ci * The caller should be holding an existing reference.
4568c2ecf20Sopenharmony_ci */
4578c2ecf20Sopenharmony_cistatic inline void blkg_get(struct blkcg_gq *blkg)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	percpu_ref_get(&blkg->refcnt);
4608c2ecf20Sopenharmony_ci}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci/**
4638c2ecf20Sopenharmony_ci * blkg_tryget - try and get a blkg reference
4648c2ecf20Sopenharmony_ci * @blkg: blkg to get
4658c2ecf20Sopenharmony_ci *
4668c2ecf20Sopenharmony_ci * This is for use when doing an RCU lookup of the blkg.  We may be in the midst
4678c2ecf20Sopenharmony_ci * of freeing this blkg, so we can only use it if the refcnt is not zero.
4688c2ecf20Sopenharmony_ci */
4698c2ecf20Sopenharmony_cistatic inline bool blkg_tryget(struct blkcg_gq *blkg)
4708c2ecf20Sopenharmony_ci{
4718c2ecf20Sopenharmony_ci	return blkg && percpu_ref_tryget(&blkg->refcnt);
4728c2ecf20Sopenharmony_ci}
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci/**
4758c2ecf20Sopenharmony_ci * blkg_put - put a blkg reference
4768c2ecf20Sopenharmony_ci * @blkg: blkg to put
4778c2ecf20Sopenharmony_ci */
4788c2ecf20Sopenharmony_cistatic inline void blkg_put(struct blkcg_gq *blkg)
4798c2ecf20Sopenharmony_ci{
4808c2ecf20Sopenharmony_ci	percpu_ref_put(&blkg->refcnt);
4818c2ecf20Sopenharmony_ci}
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci/**
4848c2ecf20Sopenharmony_ci * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
4858c2ecf20Sopenharmony_ci * @d_blkg: loop cursor pointing to the current descendant
4868c2ecf20Sopenharmony_ci * @pos_css: used for iteration
4878c2ecf20Sopenharmony_ci * @p_blkg: target blkg to walk descendants of
4888c2ecf20Sopenharmony_ci *
4898c2ecf20Sopenharmony_ci * Walk @c_blkg through the descendants of @p_blkg.  Must be used with RCU
4908c2ecf20Sopenharmony_ci * read locked.  If called under either blkcg or queue lock, the iteration
4918c2ecf20Sopenharmony_ci * is guaranteed to include all and only online blkgs.  The caller may
4928c2ecf20Sopenharmony_ci * update @pos_css by calling css_rightmost_descendant() to skip subtree.
4938c2ecf20Sopenharmony_ci * @p_blkg is included in the iteration and the first node to be visited.
4948c2ecf20Sopenharmony_ci */
4958c2ecf20Sopenharmony_ci#define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg)		\
4968c2ecf20Sopenharmony_ci	css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css)	\
4978c2ecf20Sopenharmony_ci		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
4988c2ecf20Sopenharmony_ci					      (p_blkg)->q, false)))
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci/**
5018c2ecf20Sopenharmony_ci * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
5028c2ecf20Sopenharmony_ci * @d_blkg: loop cursor pointing to the current descendant
5038c2ecf20Sopenharmony_ci * @pos_css: used for iteration
5048c2ecf20Sopenharmony_ci * @p_blkg: target blkg to walk descendants of
5058c2ecf20Sopenharmony_ci *
5068c2ecf20Sopenharmony_ci * Similar to blkg_for_each_descendant_pre() but performs post-order
5078c2ecf20Sopenharmony_ci * traversal instead.  Synchronization rules are the same.  @p_blkg is
5088c2ecf20Sopenharmony_ci * included in the iteration and the last node to be visited.
5098c2ecf20Sopenharmony_ci */
5108c2ecf20Sopenharmony_ci#define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg)		\
5118c2ecf20Sopenharmony_ci	css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css)	\
5128c2ecf20Sopenharmony_ci		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
5138c2ecf20Sopenharmony_ci					      (p_blkg)->q, false)))
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_cibool __blkcg_punt_bio_submit(struct bio *bio);
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_cistatic inline bool blkcg_punt_bio_submit(struct bio *bio)
5188c2ecf20Sopenharmony_ci{
5198c2ecf20Sopenharmony_ci	if (bio->bi_opf & REQ_CGROUP_PUNT)
5208c2ecf20Sopenharmony_ci		return __blkcg_punt_bio_submit(bio);
5218c2ecf20Sopenharmony_ci	else
5228c2ecf20Sopenharmony_ci		return false;
5238c2ecf20Sopenharmony_ci}
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_cistatic inline void blkcg_bio_issue_init(struct bio *bio)
5268c2ecf20Sopenharmony_ci{
5278c2ecf20Sopenharmony_ci	bio_issue_init(&bio->bi_issue, bio_sectors(bio));
5288c2ecf20Sopenharmony_ci}
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_cistatic inline void blkcg_use_delay(struct blkcg_gq *blkg)
5318c2ecf20Sopenharmony_ci{
5328c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(atomic_read(&blkg->use_delay) < 0))
5338c2ecf20Sopenharmony_ci		return;
5348c2ecf20Sopenharmony_ci	if (atomic_add_return(1, &blkg->use_delay) == 1)
5358c2ecf20Sopenharmony_ci		atomic_inc(&blkg->blkcg->css.cgroup->congestion_count);
5368c2ecf20Sopenharmony_ci}
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_cistatic inline int blkcg_unuse_delay(struct blkcg_gq *blkg)
5398c2ecf20Sopenharmony_ci{
5408c2ecf20Sopenharmony_ci	int old = atomic_read(&blkg->use_delay);
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(old < 0))
5438c2ecf20Sopenharmony_ci		return 0;
5448c2ecf20Sopenharmony_ci	if (old == 0)
5458c2ecf20Sopenharmony_ci		return 0;
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	/*
5488c2ecf20Sopenharmony_ci	 * We do this song and dance because we can race with somebody else
5498c2ecf20Sopenharmony_ci	 * adding or removing delay.  If we just did an atomic_dec we'd end up
5508c2ecf20Sopenharmony_ci	 * negative and we'd already be in trouble.  We need to subtract 1 and
5518c2ecf20Sopenharmony_ci	 * then check to see if we were the last delay so we can drop the
5528c2ecf20Sopenharmony_ci	 * congestion count on the cgroup.
5538c2ecf20Sopenharmony_ci	 */
5548c2ecf20Sopenharmony_ci	while (old) {
5558c2ecf20Sopenharmony_ci		int cur = atomic_cmpxchg(&blkg->use_delay, old, old - 1);
5568c2ecf20Sopenharmony_ci		if (cur == old)
5578c2ecf20Sopenharmony_ci			break;
5588c2ecf20Sopenharmony_ci		old = cur;
5598c2ecf20Sopenharmony_ci	}
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci	if (old == 0)
5628c2ecf20Sopenharmony_ci		return 0;
5638c2ecf20Sopenharmony_ci	if (old == 1)
5648c2ecf20Sopenharmony_ci		atomic_dec(&blkg->blkcg->css.cgroup->congestion_count);
5658c2ecf20Sopenharmony_ci	return 1;
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci/**
5698c2ecf20Sopenharmony_ci * blkcg_set_delay - Enable allocator delay mechanism with the specified delay amount
5708c2ecf20Sopenharmony_ci * @blkg: target blkg
5718c2ecf20Sopenharmony_ci * @delay: delay duration in nsecs
5728c2ecf20Sopenharmony_ci *
5738c2ecf20Sopenharmony_ci * When enabled with this function, the delay is not decayed and must be
5748c2ecf20Sopenharmony_ci * explicitly cleared with blkcg_clear_delay(). Must not be mixed with
5758c2ecf20Sopenharmony_ci * blkcg_[un]use_delay() and blkcg_add_delay() usages.
5768c2ecf20Sopenharmony_ci */
5778c2ecf20Sopenharmony_cistatic inline void blkcg_set_delay(struct blkcg_gq *blkg, u64 delay)
5788c2ecf20Sopenharmony_ci{
5798c2ecf20Sopenharmony_ci	int old = atomic_read(&blkg->use_delay);
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	/* We only want 1 person setting the congestion count for this blkg. */
5828c2ecf20Sopenharmony_ci	if (!old && atomic_cmpxchg(&blkg->use_delay, old, -1) == old)
5838c2ecf20Sopenharmony_ci		atomic_inc(&blkg->blkcg->css.cgroup->congestion_count);
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci	atomic64_set(&blkg->delay_nsec, delay);
5868c2ecf20Sopenharmony_ci}
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci/**
5898c2ecf20Sopenharmony_ci * blkcg_clear_delay - Disable allocator delay mechanism
5908c2ecf20Sopenharmony_ci * @blkg: target blkg
5918c2ecf20Sopenharmony_ci *
5928c2ecf20Sopenharmony_ci * Disable use_delay mechanism. See blkcg_set_delay().
5938c2ecf20Sopenharmony_ci */
5948c2ecf20Sopenharmony_cistatic inline void blkcg_clear_delay(struct blkcg_gq *blkg)
5958c2ecf20Sopenharmony_ci{
5968c2ecf20Sopenharmony_ci	int old = atomic_read(&blkg->use_delay);
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci	/* We only want 1 person clearing the congestion count for this blkg. */
5998c2ecf20Sopenharmony_ci	if (old && atomic_cmpxchg(&blkg->use_delay, old, 0) == old)
6008c2ecf20Sopenharmony_ci		atomic_dec(&blkg->blkcg->css.cgroup->congestion_count);
6018c2ecf20Sopenharmony_ci}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci/**
6048c2ecf20Sopenharmony_ci * blk_cgroup_mergeable - Determine whether to allow or disallow merges
6058c2ecf20Sopenharmony_ci * @rq: request to merge into
6068c2ecf20Sopenharmony_ci * @bio: bio to merge
6078c2ecf20Sopenharmony_ci *
6088c2ecf20Sopenharmony_ci * @bio and @rq should belong to the same cgroup and their issue_as_root should
6098c2ecf20Sopenharmony_ci * match. The latter is necessary as we don't want to throttle e.g. a metadata
6108c2ecf20Sopenharmony_ci * update because it happens to be next to a regular IO.
6118c2ecf20Sopenharmony_ci */
6128c2ecf20Sopenharmony_cistatic inline bool blk_cgroup_mergeable(struct request *rq, struct bio *bio)
6138c2ecf20Sopenharmony_ci{
6148c2ecf20Sopenharmony_ci	return rq->bio->bi_blkg == bio->bi_blkg &&
6158c2ecf20Sopenharmony_ci		bio_issue_as_root_blkg(rq->bio) == bio_issue_as_root_blkg(bio);
6168c2ecf20Sopenharmony_ci}
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_civoid blk_cgroup_bio_start(struct bio *bio);
6198c2ecf20Sopenharmony_civoid blkcg_add_delay(struct blkcg_gq *blkg, u64 now, u64 delta);
6208c2ecf20Sopenharmony_civoid blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay);
6218c2ecf20Sopenharmony_civoid blkcg_maybe_throttle_current(void);
6228c2ecf20Sopenharmony_ci#else	/* CONFIG_BLK_CGROUP */
6238c2ecf20Sopenharmony_ci
6248c2ecf20Sopenharmony_cistruct blkcg {
6258c2ecf20Sopenharmony_ci};
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_cistruct blkg_policy_data {
6288c2ecf20Sopenharmony_ci};
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_cistruct blkcg_policy_data {
6318c2ecf20Sopenharmony_ci};
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_cistruct blkcg_gq {
6348c2ecf20Sopenharmony_ci};
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_cistruct blkcg_policy {
6378c2ecf20Sopenharmony_ci};
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci#define blkcg_root_css	((struct cgroup_subsys_state *)ERR_PTR(-EINVAL))
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_cistatic inline void blkcg_maybe_throttle_current(void) { }
6428c2ecf20Sopenharmony_cistatic inline bool blk_cgroup_congested(void) { return false; }
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci#ifdef CONFIG_BLOCK
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_cistatic inline void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay) { }
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
6498c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
6508c2ecf20Sopenharmony_ci{ return NULL; }
6518c2ecf20Sopenharmony_cistatic inline int blkcg_init_queue(struct request_queue *q) { return 0; }
6528c2ecf20Sopenharmony_cistatic inline void blkcg_exit_queue(struct request_queue *q) { }
6538c2ecf20Sopenharmony_cistatic inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
6548c2ecf20Sopenharmony_cistatic inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
6558c2ecf20Sopenharmony_cistatic inline int blkcg_activate_policy(struct request_queue *q,
6568c2ecf20Sopenharmony_ci					const struct blkcg_policy *pol) { return 0; }
6578c2ecf20Sopenharmony_cistatic inline void blkcg_deactivate_policy(struct request_queue *q,
6588c2ecf20Sopenharmony_ci					   const struct blkcg_policy *pol) { }
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_cistatic inline struct blkcg *__bio_blkcg(struct bio *bio) { return NULL; }
6618c2ecf20Sopenharmony_cistatic inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; }
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_cistatic inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
6648c2ecf20Sopenharmony_ci						  struct blkcg_policy *pol) { return NULL; }
6658c2ecf20Sopenharmony_cistatic inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) { return NULL; }
6668c2ecf20Sopenharmony_cistatic inline char *blkg_path(struct blkcg_gq *blkg) { return NULL; }
6678c2ecf20Sopenharmony_cistatic inline void blkg_get(struct blkcg_gq *blkg) { }
6688c2ecf20Sopenharmony_cistatic inline void blkg_put(struct blkcg_gq *blkg) { }
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_cistatic inline bool blkcg_punt_bio_submit(struct bio *bio) { return false; }
6718c2ecf20Sopenharmony_cistatic inline void blkcg_bio_issue_init(struct bio *bio) { }
6728c2ecf20Sopenharmony_cistatic inline void blk_cgroup_bio_start(struct bio *bio) { }
6738c2ecf20Sopenharmony_cistatic inline bool blk_cgroup_mergeable(struct request *rq, struct bio *bio) { return true; }
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci#define blk_queue_for_each_rl(rl, q)	\
6768c2ecf20Sopenharmony_ci	for ((rl) = &(q)->root_rl; (rl); (rl) = NULL)
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci#endif	/* CONFIG_BLOCK */
6798c2ecf20Sopenharmony_ci#endif	/* CONFIG_BLK_CGROUP */
6808c2ecf20Sopenharmony_ci#endif	/* _BLK_CGROUP_H */
681