Blame view

include/linux/backing-dev-defs.h 7.89 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
66114cad6   Tejun Heo   writeback: separa...
2
3
4
5
  #ifndef __LINUX_BACKING_DEV_DEFS_H
  #define __LINUX_BACKING_DEV_DEFS_H
  
  #include <linux/list.h>
52ebea749   Tejun Heo   writeback: make b...
6
7
  #include <linux/radix-tree.h>
  #include <linux/rbtree.h>
66114cad6   Tejun Heo   writeback: separa...
8
9
  #include <linux/spinlock.h>
  #include <linux/percpu_counter.h>
52ebea749   Tejun Heo   writeback: make b...
10
  #include <linux/percpu-refcount.h>
66114cad6   Tejun Heo   writeback: separa...
11
12
13
  #include <linux/flex_proportions.h>
  #include <linux/timer.h>
  #include <linux/workqueue.h>
d03f6cdc1   Jan Kara   block: Dynamicall...
14
  #include <linux/kref.h>
66114cad6   Tejun Heo   writeback: separa...
15
16
17
18
19
20
21
22
23
  
  struct page;
  struct device;
  struct dentry;
  
  /*
   * Bits in bdi_writeback.state
   */
  enum wb_state {
66114cad6   Tejun Heo   writeback: separa...
24
25
  	WB_registered,		/* bdi_register() was done */
  	WB_writeback_running,	/* Writeback is in progress */
d6c10f1fc   Tejun Heo   writeback: implem...
26
  	WB_has_dirty_io,	/* Dirty inodes on ->b_{dirty|io|more_io} */
66114cad6   Tejun Heo   writeback: separa...
27
  };
4aa9c692e   Tejun Heo   bdi: separate out...
28
29
30
31
  enum wb_congested_state {
  	WB_async_congested,	/* The async (write) queue is getting full */
  	WB_sync_congested,	/* The sync queue is getting full */
  };
66114cad6   Tejun Heo   writeback: separa...
32
33
34
35
36
37
38
39
40
41
42
  typedef int (congested_fn)(void *, int);
  
  enum wb_stat_item {
  	WB_RECLAIMABLE,
  	WB_WRITEBACK,
  	WB_DIRTIED,
  	WB_WRITTEN,
  	NR_WB_STAT_ITEMS
  };
  
  #define WB_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
52ebea749   Tejun Heo   writeback: make b...
43
44
45
46
47
48
49
  /*
   * For cgroup writeback, multiple wb's may map to the same blkcg.  Those
   * wb's can operate mostly independently but should share the congested
   * state.  To facilitate such sharing, the congested state is tracked using
   * the following struct which is created on demand, indexed by blkcg ID on
   * its bdi, and refcounted.
   */
4aa9c692e   Tejun Heo   bdi: separate out...
50
51
  struct bdi_writeback_congested {
  	unsigned long state;		/* WB_[a]sync_congested flags */
a13f35e87   Tejun Heo   writeback: don't ...
52
  	atomic_t refcnt;		/* nr of attached wb's and blkg */
52ebea749   Tejun Heo   writeback: make b...
53
54
  
  #ifdef CONFIG_CGROUP_WRITEBACK
b7d680d7b   Jan Kara   bdi: Mark congest...
55
56
57
  	struct backing_dev_info *__bdi;	/* the associated bdi, set to NULL
  					 * on bdi unregistration. For memcg-wb
  					 * internal use only! */
52ebea749   Tejun Heo   writeback: make b...
58
59
60
  	int blkcg_id;			/* ID of the associated blkcg */
  	struct rb_node rb_node;		/* on bdi->cgwb_congestion_tree */
  #endif
4aa9c692e   Tejun Heo   bdi: separate out...
61
  };
52ebea749   Tejun Heo   writeback: make b...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  /*
   * Each wb (bdi_writeback) can perform writeback operations, is measured
   * and throttled, independently.  Without cgroup writeback, each bdi
   * (bdi_writeback) is served by its embedded bdi->wb.
   *
   * On the default hierarchy, blkcg implicitly enables memcg.  This allows
   * using memcg's page ownership for attributing writeback IOs, and every
   * memcg - blkcg combination can be served by its own wb by assigning a
   * dedicated wb to each memcg, which enables isolation across different
   * cgroups and propagation of IO back pressure down from the IO layer upto
   * the tasks which are generating the dirty pages to be written back.
   *
   * A cgroup wb is indexed on its bdi by the ID of the associated memcg,
   * refcounted with the number of inodes attached to it, and pins the memcg
   * and the corresponding blkcg.  As the corresponding blkcg for a memcg may
   * change as blkcg is disabled and enabled higher up in the hierarchy, a wb
   * is tested for blkcg after lookup and removed from index on mismatch so
   * that a new wb for the combination can be created.
   */
66114cad6   Tejun Heo   writeback: separa...
81
82
83
84
85
86
87
88
89
90
91
92
93
  struct bdi_writeback {
  	struct backing_dev_info *bdi;	/* our parent bdi */
  
  	unsigned long state;		/* Always use atomic bitops on this */
  	unsigned long last_old_flush;	/* last old data flush */
  
  	struct list_head b_dirty;	/* dirty inodes */
  	struct list_head b_io;		/* parked for writeback */
  	struct list_head b_more_io;	/* parked for more writeback */
  	struct list_head b_dirty_time;	/* time stamps are dirty */
  	spinlock_t list_lock;		/* protects the b_* lists */
  
  	struct percpu_counter stat[NR_WB_STAT_ITEMS];
4aa9c692e   Tejun Heo   bdi: separate out...
94
  	struct bdi_writeback_congested *congested;
66114cad6   Tejun Heo   writeback: separa...
95
96
97
98
  	unsigned long bw_time_stamp;	/* last time write bw is updated */
  	unsigned long dirtied_stamp;
  	unsigned long written_stamp;	/* pages written at bw_time_stamp */
  	unsigned long write_bandwidth;	/* the estimated write bandwidth */
95a46c65e   Tejun Heo   writeback: make b...
99
  	unsigned long avg_write_bandwidth; /* further smoothed write bw, > 0 */
66114cad6   Tejun Heo   writeback: separa...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  
  	/*
  	 * The base dirty throttle rate, re-calculated on every 200ms.
  	 * All the bdi tasks' dirty rate will be curbed under it.
  	 * @dirty_ratelimit tracks the estimated @balanced_dirty_ratelimit
  	 * in small steps and is much more smooth/stable than the latter.
  	 */
  	unsigned long dirty_ratelimit;
  	unsigned long balanced_dirty_ratelimit;
  
  	struct fprop_local_percpu completions;
  	int dirty_exceeded;
  
  	spinlock_t work_lock;		/* protects work_list & dwork scheduling */
  	struct list_head work_list;
  	struct delayed_work dwork;	/* work item used for writeback */
52ebea749   Tejun Heo   writeback: make b...
116

b57d74aff   Jens Axboe   writeback: track ...
117
  	unsigned long dirty_sleep;	/* last wait */
b817525a4   Tejun Heo   writeback: bdi_wr...
118
  	struct list_head bdi_node;	/* anchored at bdi->wb_list */
52ebea749   Tejun Heo   writeback: make b...
119
120
  #ifdef CONFIG_CGROUP_WRITEBACK
  	struct percpu_ref refcnt;	/* used only for !root wb's */
841710aa6   Tejun Heo   writeback: implem...
121
  	struct fprop_local_percpu memcg_completions;
52ebea749   Tejun Heo   writeback: make b...
122
123
124
125
126
127
128
129
130
131
  	struct cgroup_subsys_state *memcg_css; /* the associated memcg */
  	struct cgroup_subsys_state *blkcg_css; /* and blkcg */
  	struct list_head memcg_node;	/* anchored at memcg->cgwb_list */
  	struct list_head blkcg_node;	/* anchored at blkcg->cgwb_list */
  
  	union {
  		struct work_struct release_work;
  		struct rcu_head rcu;
  	};
  #endif
66114cad6   Tejun Heo   writeback: separa...
132
133
134
135
  };
  
  struct backing_dev_info {
  	struct list_head bdi_list;
ea1754a08   Kirill A. Shutemov   mm, fs: remove re...
136
  	unsigned long ra_pages;	/* max readahead in PAGE_SIZE units */
9491ae4aa   Jens Axboe   mm: don't cap req...
137
  	unsigned long io_pages;	/* max allowed IO size */
66114cad6   Tejun Heo   writeback: separa...
138
139
  	congested_fn *congested_fn; /* Function pointer if device is md/dm */
  	void *congested_data;	/* Pointer to aux data for congested func */
fca39346a   Jan Kara   fs: Provide infra...
140
  	const char *name;
66114cad6   Tejun Heo   writeback: separa...
141

d03f6cdc1   Jan Kara   block: Dynamicall...
142
  	struct kref refcnt;	/* Reference counter for the structure */
8db378a57   Andrew Morton   include/linux/bac...
143
  	unsigned int capabilities; /* Device capabilities */
66114cad6   Tejun Heo   writeback: separa...
144
145
  	unsigned int min_ratio;
  	unsigned int max_ratio, max_prop_frac;
95a46c65e   Tejun Heo   writeback: make b...
146
147
148
149
150
  	/*
  	 * Sum of avg_write_bw of wbs with dirty inodes.  > 0 if there are
  	 * any dirty wbs, which is depended upon by bdi_has_dirty().
  	 */
  	atomic_long_t tot_write_bandwidth;
766a9d6e6   Tejun Heo   writeback: implem...
151

52ebea749   Tejun Heo   writeback: make b...
152
  	struct bdi_writeback wb;  /* the root writeback info for this bdi */
b817525a4   Tejun Heo   writeback: bdi_wr...
153
  	struct list_head wb_list; /* list of all wbs */
52ebea749   Tejun Heo   writeback: make b...
154
155
156
  #ifdef CONFIG_CGROUP_WRITEBACK
  	struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
  	struct rb_root cgwb_congested_tree; /* their congested states */
1bbe05e27   Jan Kara   bdi: Fix another ...
157
  	struct mutex cgwb_release_mutex;  /* protect shutdown of wb structs */
a13f35e87   Tejun Heo   writeback: don't ...
158
159
  #else
  	struct bdi_writeback_congested *wb_congested;
52ebea749   Tejun Heo   writeback: make b...
160
  #endif
cc395d7f1   Tejun Heo   writeback: implem...
161
  	wait_queue_head_t wb_waitq;
66114cad6   Tejun Heo   writeback: separa...
162
  	struct device *dev;
df08c32ce   Dan Williams   block: fix bdi vs...
163
  	struct device *owner;
66114cad6   Tejun Heo   writeback: separa...
164
165
166
167
168
169
170
171
172
173
174
175
176
  
  	struct timer_list laptop_mode_wb_timer;
  
  #ifdef CONFIG_DEBUG_FS
  	struct dentry *debug_dir;
  	struct dentry *debug_stats;
  #endif
  };
  
  enum {
  	BLK_RW_ASYNC	= 0,
  	BLK_RW_SYNC	= 1,
  };
ec8a6f264   Tejun Heo   writeback: make c...
177
178
179
180
181
182
183
184
185
186
187
188
  void clear_wb_congested(struct bdi_writeback_congested *congested, int sync);
  void set_wb_congested(struct bdi_writeback_congested *congested, int sync);
  
  static inline void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
  {
  	clear_wb_congested(bdi->wb.congested, sync);
  }
  
  static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync)
  {
  	set_wb_congested(bdi->wb.congested, sync);
  }
66114cad6   Tejun Heo   writeback: separa...
189

7c9b87a78   Greg Thelen   writeback: safer ...
190
191
192
193
  struct wb_lock_cookie {
  	bool locked;
  	unsigned long flags;
  };
21c6321fb   Tejun Heo   writeback: reloca...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  #ifdef CONFIG_CGROUP_WRITEBACK
  
  /**
   * wb_tryget - try to increment a wb's refcount
   * @wb: bdi_writeback to get
   */
  static inline bool wb_tryget(struct bdi_writeback *wb)
  {
  	if (wb != &wb->bdi->wb)
  		return percpu_ref_tryget(&wb->refcnt);
  	return true;
  }
  
  /**
   * wb_get - increment a wb's refcount
   * @wb: bdi_writeback to get
   */
  static inline void wb_get(struct bdi_writeback *wb)
  {
  	if (wb != &wb->bdi->wb)
  		percpu_ref_get(&wb->refcnt);
  }
  
  /**
   * wb_put - decrement a wb's refcount
   * @wb: bdi_writeback to put
   */
  static inline void wb_put(struct bdi_writeback *wb)
  {
b7bf54a9c   Anders Roxell   writeback: don't ...
223
224
225
226
227
228
229
  	if (WARN_ON_ONCE(!wb->bdi)) {
  		/*
  		 * A driver bug might cause a file to be removed before bdi was
  		 * initialized.
  		 */
  		return;
  	}
21c6321fb   Tejun Heo   writeback: reloca...
230
231
232
  	if (wb != &wb->bdi->wb)
  		percpu_ref_put(&wb->refcnt);
  }
e8a7abf5a   Tejun Heo   writeback: disass...
233
234
235
236
237
238
239
240
241
242
  /**
   * wb_dying - is a wb dying?
   * @wb: bdi_writeback of interest
   *
   * Returns whether @wb is unlinked and being drained.
   */
  static inline bool wb_dying(struct bdi_writeback *wb)
  {
  	return percpu_ref_is_dying(&wb->refcnt);
  }
21c6321fb   Tejun Heo   writeback: reloca...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  #else	/* CONFIG_CGROUP_WRITEBACK */
  
  static inline bool wb_tryget(struct bdi_writeback *wb)
  {
  	return true;
  }
  
  static inline void wb_get(struct bdi_writeback *wb)
  {
  }
  
  static inline void wb_put(struct bdi_writeback *wb)
  {
  }
e8a7abf5a   Tejun Heo   writeback: disass...
257
258
259
260
  static inline bool wb_dying(struct bdi_writeback *wb)
  {
  	return false;
  }
21c6321fb   Tejun Heo   writeback: reloca...
261
  #endif	/* CONFIG_CGROUP_WRITEBACK */
66114cad6   Tejun Heo   writeback: separa...
262
  #endif	/* __LINUX_BACKING_DEV_DEFS_H */