| .. | .. | 
|---|
| 11 | 11 | #include <linux/flex_proportions.h> | 
|---|
| 12 | 12 | #include <linux/backing-dev-defs.h> | 
|---|
| 13 | 13 | #include <linux/blk_types.h> | 
|---|
|  | 14 | +#include <linux/blk-cgroup.h> | 
|---|
| 14 | 15 |  | 
|---|
| 15 | 16 | struct bio; | 
|---|
| 16 | 17 |  | 
|---|
| .. | .. | 
|---|
| 68 | 69 | unsigned for_reclaim:1;		/* Invoked from the page allocator */ | 
|---|
| 69 | 70 | unsigned range_cyclic:1;	/* range_start is cyclic */ | 
|---|
| 70 | 71 | unsigned for_sync:1;		/* sync(2) WB_SYNC_ALL writeback */ | 
|---|
|  | 72 | + | 
|---|
|  | 73 | +	/* | 
|---|
|  | 74 | +	 * When writeback IOs are bounced through async layers, only the | 
|---|
|  | 75 | +	 * initial synchronous phase should be accounted towards inode | 
|---|
|  | 76 | +	 * cgroup ownership arbitration to avoid confusion.  Later stages | 
|---|
|  | 77 | +	 * can set the following flag to disable the accounting. | 
|---|
|  | 78 | +	 */ | 
|---|
|  | 79 | +	unsigned no_cgroup_owner:1; | 
|---|
|  | 80 | + | 
|---|
|  | 81 | +	unsigned punt_to_cgroup:1;	/* cgrp punting, see __REQ_CGROUP_PUNT */ | 
|---|
|  | 82 | + | 
|---|
| 71 | 83 | #ifdef CONFIG_CGROUP_WRITEBACK | 
|---|
| 72 | 84 | struct bdi_writeback *wb;	/* wb this writeback is issued under */ | 
|---|
| 73 | 85 | struct inode *inode;		/* inode being written out */ | 
|---|
| .. | .. | 
|---|
| 84 | 96 |  | 
|---|
| 85 | 97 | static inline int wbc_to_write_flags(struct writeback_control *wbc) | 
|---|
| 86 | 98 | { | 
|---|
| 87 |  | -	if (wbc->sync_mode == WB_SYNC_ALL) | 
|---|
| 88 |  | -		return REQ_SYNC; | 
|---|
| 89 |  | -	else if (wbc->for_kupdate || wbc->for_background) | 
|---|
| 90 |  | -		return REQ_BACKGROUND; | 
|---|
|  | 99 | +	int flags = 0; | 
|---|
| 91 | 100 |  | 
|---|
| 92 |  | -	return 0; | 
|---|
|  | 101 | +	if (wbc->punt_to_cgroup) | 
|---|
|  | 102 | +		flags = REQ_CGROUP_PUNT; | 
|---|
|  | 103 | + | 
|---|
|  | 104 | +	if (wbc->sync_mode == WB_SYNC_ALL) | 
|---|
|  | 105 | +		flags |= REQ_SYNC; | 
|---|
|  | 106 | +	else if (wbc->for_kupdate || wbc->for_background) | 
|---|
|  | 107 | +		flags |= REQ_BACKGROUND; | 
|---|
|  | 108 | + | 
|---|
|  | 109 | +	return flags; | 
|---|
|  | 110 | +} | 
|---|
|  | 111 | + | 
|---|
|  | 112 | +static inline struct cgroup_subsys_state * | 
|---|
|  | 113 | +wbc_blkcg_css(struct writeback_control *wbc) | 
|---|
|  | 114 | +{ | 
|---|
|  | 115 | +#ifdef CONFIG_CGROUP_WRITEBACK | 
|---|
|  | 116 | +	if (wbc->wb) | 
|---|
|  | 117 | +		return wbc->wb->blkcg_css; | 
|---|
|  | 118 | +#endif | 
|---|
|  | 119 | +	return blkcg_root_css; | 
|---|
| 93 | 120 | } | 
|---|
| 94 | 121 |  | 
|---|
| 95 | 122 | /* | 
|---|
| .. | .. | 
|---|
| 170 | 197 | void wakeup_flusher_threads_bdi(struct backing_dev_info *bdi, | 
|---|
| 171 | 198 | enum wb_reason reason); | 
|---|
| 172 | 199 | void inode_wait_for_writeback(struct inode *inode); | 
|---|
|  | 200 | +void inode_io_list_del(struct inode *inode); | 
|---|
| 173 | 201 |  | 
|---|
| 174 | 202 | /* writeback.h requires fs.h; it, too, is not included from here. */ | 
|---|
| 175 | 203 | static inline void wait_on_inode(struct inode *inode) | 
|---|
| .. | .. | 
|---|
| 188 | 216 | struct inode *inode) | 
|---|
| 189 | 217 | __releases(&inode->i_lock); | 
|---|
| 190 | 218 | void wbc_detach_inode(struct writeback_control *wbc); | 
|---|
| 191 |  | -void wbc_account_io(struct writeback_control *wbc, struct page *page, | 
|---|
| 192 |  | -		    size_t bytes); | 
|---|
|  | 219 | +void wbc_account_cgroup_owner(struct writeback_control *wbc, struct page *page, | 
|---|
|  | 220 | +			      size_t bytes); | 
|---|
|  | 221 | +int cgroup_writeback_by_id(u64 bdi_id, int memcg_id, unsigned long nr_pages, | 
|---|
|  | 222 | +			   enum wb_reason reason, struct wb_completion *done); | 
|---|
| 193 | 223 | void cgroup_writeback_umount(void); | 
|---|
| 194 | 224 |  | 
|---|
| 195 | 225 | /** | 
|---|
| .. | .. | 
|---|
| 246 | 276 | * | 
|---|
| 247 | 277 | * @bio is a part of the writeback in progress controlled by @wbc.  Perform | 
|---|
| 248 | 278 | * writeback specific initialization.  This is used to apply the cgroup | 
|---|
| 249 |  | - * writeback context. | 
|---|
|  | 279 | + * writeback context.  Must be called after the bio has been associated with | 
|---|
|  | 280 | + * a device. | 
|---|
| 250 | 281 | */ | 
|---|
| 251 | 282 | static inline void wbc_init_bio(struct writeback_control *wbc, struct bio *bio) | 
|---|
| 252 | 283 | { | 
|---|
| .. | .. | 
|---|
| 257 | 288 | * regular writeback instead of writing things out itself. | 
|---|
| 258 | 289 | */ | 
|---|
| 259 | 290 | if (wbc->wb) | 
|---|
| 260 |  | -		bio_associate_blkcg(bio, wbc->wb->blkcg_css); | 
|---|
|  | 291 | +		bio_associate_blkg_from_css(bio, wbc->wb->blkcg_css); | 
|---|
| 261 | 292 | } | 
|---|
| 262 | 293 |  | 
|---|
| 263 | 294 | #else	/* CONFIG_CGROUP_WRITEBACK */ | 
|---|
| .. | .. | 
|---|
| 290 | 321 | { | 
|---|
| 291 | 322 | } | 
|---|
| 292 | 323 |  | 
|---|
| 293 |  | -static inline void wbc_account_io(struct writeback_control *wbc, | 
|---|
| 294 |  | -				  struct page *page, size_t bytes) | 
|---|
|  | 324 | +static inline void wbc_account_cgroup_owner(struct writeback_control *wbc, | 
|---|
|  | 325 | +					    struct page *page, size_t bytes) | 
|---|
| 295 | 326 | { | 
|---|
| 296 | 327 | } | 
|---|
| 297 | 328 |  | 
|---|
| .. | .. | 
|---|
| 332 | 363 | extern int block_dump; | 
|---|
| 333 | 364 | extern int laptop_mode; | 
|---|
| 334 | 365 |  | 
|---|
| 335 |  | -extern int dirty_background_ratio_handler(struct ctl_table *table, int write, | 
|---|
| 336 |  | -		void __user *buffer, size_t *lenp, | 
|---|
| 337 |  | -		loff_t *ppos); | 
|---|
| 338 |  | -extern int dirty_background_bytes_handler(struct ctl_table *table, int write, | 
|---|
| 339 |  | -		void __user *buffer, size_t *lenp, | 
|---|
| 340 |  | -		loff_t *ppos); | 
|---|
| 341 |  | -extern int dirty_ratio_handler(struct ctl_table *table, int write, | 
|---|
| 342 |  | -		void __user *buffer, size_t *lenp, | 
|---|
| 343 |  | -		loff_t *ppos); | 
|---|
| 344 |  | -extern int dirty_bytes_handler(struct ctl_table *table, int write, | 
|---|
| 345 |  | -		void __user *buffer, size_t *lenp, | 
|---|
| 346 |  | -		loff_t *ppos); | 
|---|
|  | 366 | +int dirty_background_ratio_handler(struct ctl_table *table, int write, | 
|---|
|  | 367 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
|  | 368 | +int dirty_background_bytes_handler(struct ctl_table *table, int write, | 
|---|
|  | 369 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
|  | 370 | +int dirty_ratio_handler(struct ctl_table *table, int write, | 
|---|
|  | 371 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
|  | 372 | +int dirty_bytes_handler(struct ctl_table *table, int write, | 
|---|
|  | 373 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
| 347 | 374 | int dirtytime_interval_handler(struct ctl_table *table, int write, | 
|---|
| 348 |  | -			       void __user *buffer, size_t *lenp, loff_t *ppos); | 
|---|
| 349 |  | - | 
|---|
| 350 |  | -struct ctl_table; | 
|---|
| 351 |  | -int dirty_writeback_centisecs_handler(struct ctl_table *, int, | 
|---|
| 352 |  | -				      void __user *, size_t *, loff_t *); | 
|---|
|  | 375 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
|  | 376 | +int dirty_writeback_centisecs_handler(struct ctl_table *table, int write, | 
|---|
|  | 377 | +		void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
| 353 | 378 |  | 
|---|
| 354 | 379 | void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty); | 
|---|
| 355 | 380 | unsigned long wb_calc_thresh(struct bdi_writeback *wb, unsigned long thresh); | 
|---|