| .. | .. |
|---|
| 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); |
|---|