linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jens Axboe <jens.axboe@oracle.com>
To: Theodore Tso <tytso@mit.edu>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Linux Kernel Developers List <linux-kernel@vger.kernel.org>,
	Ext4 Developers List <linux-ext4@vger.kernel.org>,
	jack@suse.cz
Subject: Re: [PATCH 1/3] block_write_full_page: Use synchronous writes for WBC_SYNC_ALL writebacks
Date: Tue, 7 Apr 2009 21:32:39 +0200	[thread overview]
Message-ID: <20090407193239.GE5178@kernel.dk> (raw)
In-Reply-To: <20090407190913.GA31723@mit.edu>

On Tue, Apr 07 2009, Theodore Tso wrote:
> On Tue, Apr 07, 2009 at 09:57:32AM +0200, Jens Axboe wrote:
> > > > It looks like a good candidate for WRITE_SYNC_PLUG instead,
> > > 
> 
> So is this patch sane?  (Compile-tested only, since I'm at a
> conference at the moment).  Am I using the proper abstraction to
> unplug the block device?  If not, it might be nice to document the
> preferred for callers into the block layer.
> 
> (BTW, I was looking at Documentation/biodoc.txt, and I found some
> clearly old documentation bits: "This is just the same as in 2.4 so
> far, though per-device unplugging support is anticipated for 2.5."  :-)

Woops, something to update :-)

> [RFQ] Smart unplugging for page writeback
> 
> Now that we have a distinction between WRITE_SYNC and WRITE_SYNC_PLUG,
> use WRITE_SYNC_PLUG in block_write_full_page(), and then before we
> wait for page writebacks to complete in jbd, jbd2, and filemap, call
> blk_unplug() to make sure the writes are on the way to the disk.
> 
> diff --git a/fs/buffer.c b/fs/buffer.c
> index 977e12a..95b5390 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -1646,7 +1646,8 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
>  	struct buffer_head *bh, *head;
>  	const unsigned blocksize = 1 << inode->i_blkbits;
>  	int nr_underway = 0;
> -	int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
> +	int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
> +			WRITE_SYNC_PLUG : WRITE);
>  
>  	BUG_ON(!PageLocked(page));

This should be all you need, forget the below. The manual unplugging
only really makes sense for very select situations, since it'll be done
when someone waits on the buffer anyway. And the block layer will unplug
implicitly if 3ms has passed or 4 requests are pending, if someone
hasn't done a wait for a page/bh in flight for that device anyway.

So at least with the current setup, it'll only really make a difference
if you end up waiting on the buffer 1-2ms after submission and you
haven't submitted enough IO to kick off the unplugging. If you wait
immediately, the time period between your blk_unplug() call and the one
that wait_on_bit() would do is so short that it will not make a
difference. And if you don't wait on the IO, you just want to let it hit
the disk eventually.


> diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
> index a8e8513..3e6726f 100644
> --- a/fs/jbd/commit.c
> +++ b/fs/jbd/commit.c
> @@ -21,6 +21,7 @@
>  #include <linux/mm.h>
>  #include <linux/pagemap.h>
>  #include <linux/bio.h>
> +#include <linux/blkdev.h>
>  
>  /*
>   * Default IO end handler for temporary BJ_IO buffer_heads.
> @@ -196,6 +197,7 @@ static int journal_submit_data_buffers(journal_t *journal,
>  	int locked;
>  	int bufs = 0;
>  	struct buffer_head **wbuf = journal->j_wbuf;
> +	struct block_device *fs_bdev = 0;
>  	int err = 0;
>  
>  	/*
> @@ -213,6 +215,7 @@ write_out_data:
>  	while (commit_transaction->t_sync_datalist) {
>  		jh = commit_transaction->t_sync_datalist;
>  		bh = jh2bh(jh);
> +		fs_bdev = bh->b_bdev;
>  		locked = 0;
>  
>  		/* Get reference just to make sure buffer does not disappear
> @@ -290,6 +293,8 @@ write_out_data:
>  	}
>  	spin_unlock(&journal->j_list_lock);
>  	journal_do_submit_data(wbuf, bufs, write_op);
> +	if (fs_bdev)
> +		blk_unplug(bdev_get_queue(fs_bdev));
>  
>  	return err;
>  }
> diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
> index 282750c..b5448dd 100644
> --- a/fs/jbd2/commit.c
> +++ b/fs/jbd2/commit.c
> @@ -26,6 +26,7 @@
>  #include <linux/writeback.h>
>  #include <linux/backing-dev.h>
>  #include <linux/bio.h>
> +#include <linux/blkdev.h>
>  
>  /*
>   * Default IO end handler for temporary BJ_IO buffer_heads.
> @@ -176,6 +177,7 @@ static int journal_wait_on_commit_record(journal_t *journal,
>  
>  retry:
>  	clear_buffer_dirty(bh);
> +	blk_unplug(bdev_get_queue(bh->b_bdev));
>  	wait_on_buffer(bh);

There's really not a lot of point to doing it this way, since
wait_on_buffer() will immediately do an unplug of the device anyway.

So it's quite on purpose that I didn't do a lot of tracking for this and
manual unplugging, we simply don't need it.

>  	if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) {
>  		printk(KERN_WARNING
> @@ -241,10 +243,12 @@ static int journal_submit_data_buffers(journal_t *journal,
>  	struct jbd2_inode *jinode;
>  	int err, ret = 0;
>  	struct address_space *mapping;
> +	struct block_device *fs_bdev = 0;
>  
>  	spin_lock(&journal->j_list_lock);
>  	list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
>  		mapping = jinode->i_vfs_inode->i_mapping;
> +		fs_bdev = jinode->i_vfs_inode->i_sb->s_bdev;
>  		jinode->i_flags |= JI_COMMIT_RUNNING;
>  		spin_unlock(&journal->j_list_lock);
>  		/*
> @@ -262,6 +266,8 @@ static int journal_submit_data_buffers(journal_t *journal,
>  		wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
>  	}
>  	spin_unlock(&journal->j_list_lock);
> +	if (fs_bdev)
> +		blk_unplug(bdev_get_queue(fs_bdev));
>  	return ret;
>  }
>  
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 2e2d38e..eff2ed9 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -274,6 +274,10 @@ int wait_on_page_writeback_range(struct address_space *mapping,
>  	if (end < start)
>  		return 0;
>  
> +	if (mapping->host && mapping->host->i_sb && mapping->host->i_sb &&
> +	    mapping->host->i_sb->s_bdev)
> +		blk_unplug(bdev_get_queue(mapping->host->i_sb->s_bdev));
> +

Ugh, this one is nasty!

        blk_run_address_space(mapping);

would be a lot cleaner.

-- 
Jens Axboe

  reply	other threads:[~2009-04-07 19:32 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-27 20:24 [PATCH 0/3] Ext3 latency improvement patches Theodore Ts'o
2009-03-27 20:24 ` [PATCH 1/3] block_write_full_page: Use synchronous writes for WBC_SYNC_ALL writebacks Theodore Ts'o
2009-03-27 20:24   ` [PATCH 2/3] ext3: Use WRITE_SYNC for commits which are caused by fsync() Theodore Ts'o
2009-03-27 20:24     ` [PATCH 3/3] ext3: Avoid starting a transaction in writepage when not necessary Theodore Ts'o
2009-03-27 22:23       ` Jan Kara
2009-03-27 23:03         ` Theodore Tso
2009-03-30 13:22           ` Jan Kara
2009-03-27 22:20     ` [PATCH 2/3] ext3: Use WRITE_SYNC for commits which are caused by fsync() Jan Kara
2009-03-27 20:55   ` [PATCH 1/3] block_write_full_page: Use synchronous writes for WBC_SYNC_ALL writebacks Jan Kara
2009-04-07  6:21   ` Andrew Morton
2009-04-07  6:50     ` Andrew Morton
2009-04-07  7:08       ` Jens Axboe
2009-04-07  7:17         ` Jens Axboe
2009-04-07  8:16           ` Jens Axboe
2009-04-07  7:23         ` Andrew Morton
2009-04-07  7:57           ` Jens Axboe
2009-04-07 19:09             ` Theodore Tso
2009-04-07 19:32               ` Jens Axboe [this message]
2009-04-07 21:44                 ` Theodore Tso
2009-04-07 22:19                   ` [PATCH] block_write_full_page: switch synchronous writes to use WRITE_SYNC_PLUG Theodore Tso
2009-04-07 23:09                     ` Andrew Morton
2009-04-07 23:46                       ` Theodore Tso
2009-04-08  8:08                       ` Jens Axboe
2009-04-08 22:34                         ` Andrew Morton
2009-04-09 17:59                           ` Jens Axboe
2009-04-08  6:00                     ` Jens Axboe
2009-04-08 15:26                       ` Theodore Tso
2009-04-08  5:58                   ` [PATCH 1/3] block_write_full_page: Use synchronous writes for WBC_SYNC_ALL writebacks Jens Axboe
2009-04-08 15:25                     ` Theodore Tso
2009-04-07 14:19           ` Theodore Tso
2009-03-27 20:50 ` [PATCH 0/3] Ext3 latency improvement patches Chris Mason
2009-03-27 21:03   ` Chris Mason
2009-03-27 21:19     ` Jan Kara
2009-03-27 21:30     ` Theodore Tso
2009-03-27 21:54       ` Jan Kara
2009-03-27 23:09         ` Theodore Tso
2009-03-28  0:14           ` Jeff Garzik
2009-03-28  0:24             ` David Rees
2009-03-30 14:16               ` Ric Wheeler
2009-03-30 11:23       ` Aneesh Kumar K.V
     [not found]       ` <20090330112330.GA11357@skywalker>
2009-03-30 11:44         ` Chris Mason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090407193239.GE5178@kernel.dk \
    --to=jens.axboe@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=jack@suse.cz \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).