From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: Re: [Regression 3.16-rc kernel] -55% reduction in throughput for OLTP benchmark Date: Tue, 29 Jul 2014 07:19:08 -0700 Message-ID: <20140729141908.GA4464@infradead.org> References: <1406584299.2970.924.camel@schen9-DESK> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Al Viro , suruchi , ak , Dave Hansen , Matthew Wilcox , "hubert.nueckel" , beth.marsh-prime@intel.com, "doug.nelson" , linux-kernel , linux-fsdevel To: Tim Chen Return-path: Content-Disposition: inline In-Reply-To: <1406584299.2970.924.camel@schen9-DESK> Sender: linux-kernel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org Hi Tim, I think the problem is that sdio.size doesn't get set set with the new dio code. Please try the patch below to fix this by not relying on that field: diff --git a/fs/direct-io.c b/fs/direct-io.c index 194d0d1..adbb847 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -71,7 +71,6 @@ struct dio_submit { been performed at the start of a write */ int pages_in_io; /* approximate total IO pages */ - size_t size; /* total request size (doesn't change)*/ sector_t block_in_file; /* Current offset into the underlying file in dio_block units. */ unsigned blocks_available; /* At block_in_file. changes */ @@ -1104,7 +1103,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, unsigned blkbits = i_blkbits; unsigned blocksize_mask = (1 << blkbits) - 1; ssize_t retval = -EINVAL; - loff_t end = offset + iov_iter_count(iter); + size_t count = iov_iter_count(iter); + loff_t end = offset + count; struct dio *dio; struct dio_submit sdio = { 0, }; struct buffer_head map_bh = { 0, }; @@ -1286,16 +1286,14 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * This had *better* be the only place that raises -EIOCBQUEUED. */ BUG_ON(retval == -EIOCBQUEUED); - if (dio->is_async && retval == 0 && dio->result && - ((rw == READ) || (dio->result == sdio.size))) + if (dio->is_async && rw == READ && retval == 0 && dio->result == count) retval = -EIOCBQUEUED; - - if (retval != -EIOCBQUEUED) + else dio_await_completion(dio); - if (drop_refcount(dio) == 0) { + if (drop_refcount(dio) == 0) retval = dio_complete(dio, offset, retval, false); - } else + else BUG_ON(retval != -EIOCBQUEUED); out: