From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04F7BEB64D7 for ; Fri, 16 Jun 2023 10:27:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343760AbjFPK1J (ORCPT ); Fri, 16 Jun 2023 06:27:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344132AbjFPK0d (ORCPT ); Fri, 16 Jun 2023 06:26:33 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE7843AAE; Fri, 16 Jun 2023 03:25:50 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8F40B63591; Fri, 16 Jun 2023 10:25:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3A643C433CA; Fri, 16 Jun 2023 10:25:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686911148; bh=dQfhVRkBunwTxmNqhiny34v4o5uLsp3NaqxXhfPS/kI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nhL4AIzwco1rhdf3bKn8YblI9lfkZ84oQ1Zns3IHd1yPfI8ZTiK2Z/HhDtliBP6/k I2hfIFD8ywpUsGbpnjgrJLFF8I95GP5QwRCwrDvUgpe6HqSON8CLYdmH2trvXeILpp ptDnJrfLNrsRz8ZzpMoyi8bua+tMcNfTN8Yq44Qu9pc9o9yfP+pbhsk0UjvbY5Cz0q nzyBmDlrKju4r3oU3Zt4rvAo+Z0gzckg1vz5GDpzpg5urlshhG9BCp9rxAb+W6g7Rv MeVEmCXgvNRn1d8AI2b2i5eeVmHgXolNJIb1TfdPhq574SGKF6MHcDxBNdkqDAP/wN iwkcujyy9Bnmw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Andreas Gruenbacher , Jan Kara , Sasha Levin , rpeterso@redhat.com, cluster-devel@redhat.com Subject: [PATCH AUTOSEL 6.3 14/30] gfs2: Don't get stuck writing page onto itself under direct I/O Date: Fri, 16 Jun 2023 06:25:02 -0400 Message-Id: <20230616102521.673087-14-sashal@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230616102521.673087-1-sashal@kernel.org> References: <20230616102521.673087-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.3.8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andreas Gruenbacher [ Upstream commit fa58cc888d67e640e354d8b3ceef877ea167b0cf ] When a direct I/O write is performed, iomap_dio_rw() invalidates the part of the page cache which the write is going to before carrying out the write. In the odd case, the direct I/O write will be reading from the same page it is writing to. gfs2 carries out writes with page faults disabled, so it should have been obvious that this page invalidation can cause iomap_dio_rw() to never make any progress. Currently, gfs2 will end up in an endless retry loop in gfs2_file_direct_write() instead, though. Break this endless loop by limiting the number of retries and falling back to buffered I/O after that. Also simplify should_fault_in_pages() sightly and add a comment to make the above case easier to understand. Reported-by: Jan Kara Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/file.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 300844f50dcd2..cb62c8f07d1e7 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -784,9 +784,13 @@ static inline bool should_fault_in_pages(struct iov_iter *i, if (!user_backed_iter(i)) return false; + /* + * Try to fault in multiple pages initially. When that doesn't result + * in any progress, fall back to a single page. + */ size = PAGE_SIZE; offs = offset_in_page(iocb->ki_pos); - if (*prev_count != count || !*window_size) { + if (*prev_count != count) { size_t nr_dirtied; nr_dirtied = max(current->nr_dirtied_pause - @@ -870,6 +874,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from, struct gfs2_inode *ip = GFS2_I(inode); size_t prev_count = 0, window_size = 0; size_t written = 0; + bool enough_retries; ssize_t ret; /* @@ -913,11 +918,17 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from, if (ret > 0) written = ret; + enough_retries = prev_count == iov_iter_count(from) && + window_size <= PAGE_SIZE; if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) { gfs2_glock_dq(gh); window_size -= fault_in_iov_iter_readable(from, window_size); - if (window_size) - goto retry; + if (window_size) { + if (!enough_retries) + goto retry; + /* fall back to buffered I/O */ + ret = 0; + } } out_unlock: if (gfs2_holder_queued(gh)) -- 2.39.2