From patchwork Mon Jun 18 14:52:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Foster X-Patchwork-Id: 10471795 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B4EA56029B for ; Mon, 18 Jun 2018 14:52:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A528A28A70 for ; Mon, 18 Jun 2018 14:52:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99D4028ABC; Mon, 18 Jun 2018 14:52:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AF6F28A70 for ; Mon, 18 Jun 2018 14:52:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934674AbeFROwq (ORCPT ); Mon, 18 Jun 2018 10:52:46 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50854 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S934773AbeFROwp (ORCPT ); Mon, 18 Jun 2018 10:52:45 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 259CA401DEB9; Mon, 18 Jun 2018 14:52:45 +0000 (UTC) Received: from bfoster.bos.redhat.com (dhcp-41-2.bos.redhat.com [10.18.41.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 068452156700; Mon, 18 Jun 2018 14:52:45 +0000 (UTC) From: Brian Foster To: linux-xfs@vger.kernel.org Cc: Christoph Hellwig Subject: [PATCH 1/2] xfs: combine [a]sync buffer submission apis Date: Mon, 18 Jun 2018 10:52:43 -0400 Message-Id: <20180618145244.30393-2-bfoster@redhat.com> In-Reply-To: <20180618145244.30393-1-bfoster@redhat.com> References: <20180618145244.30393-1-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Mon, 18 Jun 2018 14:52:45 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Mon, 18 Jun 2018 14:52:45 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'bfoster@redhat.com' RCPT:'' Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The buffer I/O submission path consists of separate function calls per type. The buffer I/O type is already controlled via buffer state (XBF_ASYNC), however, so there is no real need for separate submission functions. Combine the buffer submission functions into a single function that processes the buffer appropriately based on XBF_ASYNC. Retain an internal helper with a conditional wait parameter to continue to support batched !XBF_ASYNC submission/completion required by delwri queues. Suggested-by: Christoph Hellwig Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_buf.c | 72 +++++++++++++--------------------------- fs/xfs/xfs_buf.h | 10 ++++-- fs/xfs/xfs_log_recover.c | 4 +-- 3 files changed, 33 insertions(+), 53 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index b5c0f6949b30..64a9a09013e3 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -757,11 +757,7 @@ _xfs_buf_read( bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); - if (flags & XBF_ASYNC) { - xfs_buf_submit(bp); - return 0; - } - return xfs_buf_submit_wait(bp); + return xfs_buf_submit(bp); } xfs_buf_t * @@ -846,7 +842,7 @@ xfs_buf_read_uncached( bp->b_flags |= XBF_READ; bp->b_ops = ops; - xfs_buf_submit_wait(bp); + xfs_buf_submit(bp); if (bp->b_error) { int error = bp->b_error; xfs_buf_relse(bp); @@ -1249,7 +1245,7 @@ xfs_bwrite( bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL | XBF_DONE); - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error) { xfs_force_shutdown(bp->b_target->bt_mount, SHUTDOWN_META_IO_ERROR); @@ -1459,7 +1455,7 @@ _xfs_buf_ioapply( * itself. */ static int -__xfs_buf_submit( +__xfs_buf_submit_common( struct xfs_buf *bp) { trace_xfs_buf_submit(bp, _RET_IP_); @@ -1505,32 +1501,6 @@ __xfs_buf_submit( return 0; } -void -xfs_buf_submit( - struct xfs_buf *bp) -{ - int error; - - ASSERT(bp->b_flags & XBF_ASYNC); - - /* - * The caller's reference is released during I/O completion. - * This occurs some time after the last b_io_remaining reference is - * released, so after we drop our Io reference we have to have some - * other reference to ensure the buffer doesn't go away from underneath - * us. Take a direct reference to ensure we have safe access to the - * buffer until we are finished with it. - */ - xfs_buf_hold(bp); - - error = __xfs_buf_submit(bp); - if (error) - xfs_buf_ioend(bp); - - /* Note: it is not safe to reference bp now we've dropped our ref */ - xfs_buf_rele(bp); -} - /* * Wait for I/O completion of a sync buffer and return the I/O error code. */ @@ -1538,6 +1508,8 @@ static int xfs_buf_iowait( struct xfs_buf *bp) { + ASSERT(!(bp->b_flags & XBF_ASYNC)); + trace_xfs_buf_iowait(bp, _RET_IP_); wait_for_completion(&bp->b_iowait); trace_xfs_buf_iowait_done(bp, _RET_IP_); @@ -1549,30 +1521,33 @@ xfs_buf_iowait( * Synchronous buffer IO submission path, read or write. */ int -xfs_buf_submit_wait( - struct xfs_buf *bp) +__xfs_buf_submit( + struct xfs_buf *bp, + bool wait) { int error; - ASSERT(!(bp->b_flags & XBF_ASYNC)); - /* - * For synchronous IO, the IO does not inherit the submitters reference - * count, nor the buffer lock. Hence we cannot release the reference we - * are about to take until we've waited for all IO completion to occur, - * including any xfs_buf_ioend_async() work that may be pending. + * Grab a reference so the buffer does not go away underneath us. For + * async buffers, I/O completion drops the callers reference, which + * could occur before submission returns. */ xfs_buf_hold(bp); - error = __xfs_buf_submit(bp); - if (error) + error = __xfs_buf_submit_common(bp); + if (error) { + if (bp->b_flags & XBF_ASYNC) + xfs_buf_ioend(bp); goto out; - error = xfs_buf_iowait(bp); + } + if (wait) + error = xfs_buf_iowait(bp); out: /* - * all done now, we can release the hold that keeps the buffer - * referenced for the entire IO. + * Release the hold that keeps the buffer referenced for the entire + * I/O. Note that if the buffer is async, it is not safe to reference + * after this release. */ xfs_buf_rele(bp); return error; @@ -2026,12 +2001,11 @@ xfs_buf_delwri_submit_buffers( if (wait_list) { bp->b_flags &= ~XBF_ASYNC; list_move_tail(&bp->b_list, wait_list); - __xfs_buf_submit(bp); } else { bp->b_flags |= XBF_ASYNC; list_del_init(&bp->b_list); - xfs_buf_submit(bp); } + __xfs_buf_submit(bp, false); } blk_finish_plug(&plug); diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index d24dbd4dac39..a57693a5cdd7 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -298,8 +298,14 @@ extern void __xfs_buf_ioerror(struct xfs_buf *bp, int error, xfs_failaddr_t failaddr); #define xfs_buf_ioerror(bp, err) __xfs_buf_ioerror((bp), (err), __this_address) extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); -extern void xfs_buf_submit(struct xfs_buf *bp); -extern int xfs_buf_submit_wait(struct xfs_buf *bp); + +extern int __xfs_buf_submit(struct xfs_buf *bp, bool); +static inline int xfs_buf_submit(struct xfs_buf *bp) +{ + bool wait = bp->b_flags & XBF_ASYNC ? false : true; + return __xfs_buf_submit(bp, wait); +} + extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, xfs_buf_rw_t); #define xfs_buf_zero(bp, off, len) \ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b181b5f57a19..724a76d87564 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -196,7 +196,7 @@ xlog_bread_noalign( bp->b_io_length = nbblks; bp->b_error = 0; - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error && !XFS_FORCED_SHUTDOWN(log->l_mp)) xfs_buf_ioerror_alert(bp, __func__); return error; @@ -5707,7 +5707,7 @@ xlog_do_recover( bp->b_flags |= XBF_READ; bp->b_ops = &xfs_sb_buf_ops; - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error) { if (!XFS_FORCED_SHUTDOWN(mp)) { xfs_buf_ioerror_alert(bp, __func__);