Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/writeback
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/writeback: (27 commits) mm: properly reflect task dirty limits in dirty_exceeded logic writeback: don't busy retry writeback on new/freeing inodes writeback: scale IO chunk size up to half device bandwidth writeback: trace global_dirty_state writeback: introduce max-pause and pass-good dirty limits writeback: introduce smoothed global dirty limit writeback: consolidate variable names in balance_dirty_pages() writeback: show bdi write bandwidth in debugfs writeback: bdi write bandwidth estimation writeback: account per-bdi accumulated written pages writeback: make writeback_control.nr_to_write straight writeback: skip tmpfs early in balance_dirty_pages_ratelimited_nr() writeback: trace event writeback_queue_io writeback: trace event writeback_single_inode writeback: remove .nonblocking and .encountered_congestion writeback: remove writeback_control.more_io writeback: skip balance_dirty_pages() for in-memory fs writeback: add bdi_dirty_limit() kernel-doc writeback: avoid extra sync work at enqueue time writeback: elevate queue_io() into wb_writeback() ... Fix up trivial conflicts in fs/fs-writeback.c and mm/filemap.c
This commit is contained in:
@@ -45,6 +45,17 @@ static struct timer_list sync_supers_timer;
|
||||
static int bdi_sync_supers(void *);
|
||||
static void sync_supers_timer_fn(unsigned long);
|
||||
|
||||
void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
|
||||
{
|
||||
if (wb1 < wb2) {
|
||||
spin_lock(&wb1->list_lock);
|
||||
spin_lock_nested(&wb2->list_lock, 1);
|
||||
} else {
|
||||
spin_lock(&wb2->list_lock);
|
||||
spin_lock_nested(&wb1->list_lock, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
@@ -67,34 +78,42 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
|
||||
struct inode *inode;
|
||||
|
||||
nr_dirty = nr_io = nr_more_io = 0;
|
||||
spin_lock(&inode_wb_list_lock);
|
||||
spin_lock(&wb->list_lock);
|
||||
list_for_each_entry(inode, &wb->b_dirty, i_wb_list)
|
||||
nr_dirty++;
|
||||
list_for_each_entry(inode, &wb->b_io, i_wb_list)
|
||||
nr_io++;
|
||||
list_for_each_entry(inode, &wb->b_more_io, i_wb_list)
|
||||
nr_more_io++;
|
||||
spin_unlock(&inode_wb_list_lock);
|
||||
spin_unlock(&wb->list_lock);
|
||||
|
||||
global_dirty_limits(&background_thresh, &dirty_thresh);
|
||||
bdi_thresh = bdi_dirty_limit(bdi, dirty_thresh);
|
||||
|
||||
#define K(x) ((x) << (PAGE_SHIFT - 10))
|
||||
seq_printf(m,
|
||||
"BdiWriteback: %8lu kB\n"
|
||||
"BdiReclaimable: %8lu kB\n"
|
||||
"BdiDirtyThresh: %8lu kB\n"
|
||||
"DirtyThresh: %8lu kB\n"
|
||||
"BackgroundThresh: %8lu kB\n"
|
||||
"b_dirty: %8lu\n"
|
||||
"b_io: %8lu\n"
|
||||
"b_more_io: %8lu\n"
|
||||
"bdi_list: %8u\n"
|
||||
"state: %8lx\n",
|
||||
"BdiWriteback: %10lu kB\n"
|
||||
"BdiReclaimable: %10lu kB\n"
|
||||
"BdiDirtyThresh: %10lu kB\n"
|
||||
"DirtyThresh: %10lu kB\n"
|
||||
"BackgroundThresh: %10lu kB\n"
|
||||
"BdiWritten: %10lu kB\n"
|
||||
"BdiWriteBandwidth: %10lu kBps\n"
|
||||
"b_dirty: %10lu\n"
|
||||
"b_io: %10lu\n"
|
||||
"b_more_io: %10lu\n"
|
||||
"bdi_list: %10u\n"
|
||||
"state: %10lx\n",
|
||||
(unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)),
|
||||
(unsigned long) K(bdi_stat(bdi, BDI_RECLAIMABLE)),
|
||||
K(bdi_thresh), K(dirty_thresh),
|
||||
K(background_thresh), nr_dirty, nr_io, nr_more_io,
|
||||
K(bdi_thresh),
|
||||
K(dirty_thresh),
|
||||
K(background_thresh),
|
||||
(unsigned long) K(bdi_stat(bdi, BDI_WRITTEN)),
|
||||
(unsigned long) K(bdi->write_bandwidth),
|
||||
nr_dirty,
|
||||
nr_io,
|
||||
nr_more_io,
|
||||
!list_empty(&bdi->bdi_list), bdi->state);
|
||||
#undef K
|
||||
|
||||
@@ -249,18 +268,6 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
|
||||
return wb_has_dirty_io(&bdi->wb);
|
||||
}
|
||||
|
||||
static void bdi_flush_io(struct backing_dev_info *bdi)
|
||||
{
|
||||
struct writeback_control wbc = {
|
||||
.sync_mode = WB_SYNC_NONE,
|
||||
.older_than_this = NULL,
|
||||
.range_cyclic = 1,
|
||||
.nr_to_write = 1024,
|
||||
};
|
||||
|
||||
writeback_inodes_wb(&bdi->wb, &wbc);
|
||||
}
|
||||
|
||||
/*
|
||||
* kupdated() used to do this. We cannot do it from the bdi_forker_thread()
|
||||
* or we risk deadlocking on ->s_umount. The longer term solution would be
|
||||
@@ -446,9 +453,10 @@ static int bdi_forker_thread(void *ptr)
|
||||
if (IS_ERR(task)) {
|
||||
/*
|
||||
* If thread creation fails, force writeout of
|
||||
* the bdi from the thread.
|
||||
* the bdi from the thread. Hopefully 1024 is
|
||||
* large enough for efficient IO.
|
||||
*/
|
||||
bdi_flush_io(bdi);
|
||||
writeback_inodes_wb(&bdi->wb, 1024);
|
||||
} else {
|
||||
/*
|
||||
* The spinlock makes sure we do not lose
|
||||
@@ -629,9 +637,15 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi)
|
||||
INIT_LIST_HEAD(&wb->b_dirty);
|
||||
INIT_LIST_HEAD(&wb->b_io);
|
||||
INIT_LIST_HEAD(&wb->b_more_io);
|
||||
spin_lock_init(&wb->list_lock);
|
||||
setup_timer(&wb->wakeup_timer, wakeup_timer_fn, (unsigned long)bdi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial write bandwidth: 100 MB/s
|
||||
*/
|
||||
#define INIT_BW (100 << (20 - PAGE_SHIFT))
|
||||
|
||||
int bdi_init(struct backing_dev_info *bdi)
|
||||
{
|
||||
int i, err;
|
||||
@@ -654,6 +668,13 @@ int bdi_init(struct backing_dev_info *bdi)
|
||||
}
|
||||
|
||||
bdi->dirty_exceeded = 0;
|
||||
|
||||
bdi->bw_time_stamp = jiffies;
|
||||
bdi->written_stamp = 0;
|
||||
|
||||
bdi->write_bandwidth = INIT_BW;
|
||||
bdi->avg_write_bandwidth = INIT_BW;
|
||||
|
||||
err = prop_local_init_percpu(&bdi->completions);
|
||||
|
||||
if (err) {
|
||||
@@ -677,11 +698,12 @@ void bdi_destroy(struct backing_dev_info *bdi)
|
||||
if (bdi_has_dirty_io(bdi)) {
|
||||
struct bdi_writeback *dst = &default_backing_dev_info.wb;
|
||||
|
||||
spin_lock(&inode_wb_list_lock);
|
||||
bdi_lock_two(&bdi->wb, dst);
|
||||
list_splice(&bdi->wb.b_dirty, &dst->b_dirty);
|
||||
list_splice(&bdi->wb.b_io, &dst->b_io);
|
||||
list_splice(&bdi->wb.b_more_io, &dst->b_more_io);
|
||||
spin_unlock(&inode_wb_list_lock);
|
||||
spin_unlock(&bdi->wb.list_lock);
|
||||
spin_unlock(&dst->list_lock);
|
||||
}
|
||||
|
||||
bdi_unregister(bdi);
|
||||
|
Reference in New Issue
Block a user