Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp3206537pxb; Mon, 9 Nov 2020 05:35:36 -0800 (PST) X-Google-Smtp-Source: ABdhPJx6TRhKtmY3PbagWdVZQgWtNJNiZ2J1wYOzUkyfGiuQBFdcsZPa36oRG+AmlPJirpMttbkg X-Received: by 2002:a50:ef03:: with SMTP id m3mr4960051eds.212.1604928935867; Mon, 09 Nov 2020 05:35:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604928935; cv=none; d=google.com; s=arc-20160816; b=ElJqfU7UH6snAPM0Jb8vvDS+bAPtTK/joATTGaPgc5JJNNgDKZ6pGVqGuqlrOanr4J 4Qw1sEq0JuR45HKcZZSiB4Q31d0aDlUbkUZUwElg4NLvCPGxYoDerei8RY4RvVIjszW5 2EFSue6kFbYmQK4ROfiCwEzLHrkzRql69vvkX/+cNlVaZp7TYCpNqC9hFKC/ZamiB3B3 NoRG9QblhNec2x8aThFFgSrRKJTyw/mW/T9GsoqWhWD1NbN9FOApd8fBnMc4cHAPAyyn NZ9LIRTTJkADVP8iNy/lWaeoFynSgxMslJPbps7Rr0gzuObpkKeeNcop8stdZgppUIBO rYTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=na3sCXM8nafGAahyri5YPOpH3r5Gsb8Ow2IQqpVmfcY=; b=Wx1n72zaPQVDkhUwngPyDFCaPtXfvaR9vv+WFdlthVqTMYM2OgO4dP5mA+pk2QtBha FFHcoaFKcLj0ExhHmI8BdmmcNgX9rl1qcURAaiBAWyBCxqILXifMnnfHuBY/79/ndc1W zQ2qxIQQPLJmF3Wl5jZ6afoz7gUnDYeHe7WpnbNckDLZamLFB78yxUquBWxpA+T0dOjS hgxIAllbaLbnFYImcMeY11eAMcpCgV6ICrkvPSDKDEsUhDzZ6DE38niLtrZQlz8v+EiZ q18cEnaK2lEWJTFa/0kxNCZJOXm8AYRl7WOCvididjh1BcjHAJBHEC7K8StJki75bKnU 02Iw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=tK0Xu3sf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gq17si6678991ejb.178.2020.11.09.05.35.12; Mon, 09 Nov 2020 05:35:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=tK0Xu3sf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731655AbgKINIa (ORCPT + 99 others); Mon, 9 Nov 2020 08:08:30 -0500 Received: from mail.kernel.org ([198.145.29.99]:33254 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731658AbgKINI3 (ORCPT ); Mon, 9 Nov 2020 08:08:29 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8032520731; Mon, 9 Nov 2020 13:08:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1604927308; bh=2h+ZNV3G4Q9jBLsnb1NkXvBXLZVyltoc1OW3nzC/sMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tK0Xu3sfn9vVBr9hdIukyMK0q+rHcdd+12WmI544SYbMDotr/oq3slMPyM/sjZIZq 91WImaIK4I4lwI4Y+wcngN+kQF/MK48zjurbyRcWKBroRJFeQ4bQV/CNLQwelCSrbi fc3H7LgaSyb5BgbxtiZcpMBZTSecjI9kChW17tuU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Filipe Manana , Josef Bacik , David Sterba , Ben Hutchings Subject: [PATCH 4.19 16/71] btrfs: flush write bio if we loop in extent_write_cache_pages Date: Mon, 9 Nov 2020 13:55:10 +0100 Message-Id: <20201109125020.675443697@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201109125019.906191744@linuxfoundation.org> References: <20201109125019.906191744@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Josef Bacik commit 42ffb0bf584ae5b6b38f72259af1e0ee417ac77f upstream. There exists a deadlock with range_cyclic that has existed forever. If we loop around with a bio already built we could deadlock with a writer who has the page locked that we're attempting to write but is waiting on a page in our bio to be written out. The task traces are as follows PID: 1329874 TASK: ffff889ebcdf3800 CPU: 33 COMMAND: "kworker/u113:5" #0 [ffffc900297bb658] __schedule at ffffffff81a4c33f #1 [ffffc900297bb6e0] schedule at ffffffff81a4c6e3 #2 [ffffc900297bb6f8] io_schedule at ffffffff81a4ca42 #3 [ffffc900297bb708] __lock_page at ffffffff811f145b #4 [ffffc900297bb798] __process_pages_contig at ffffffff814bc502 #5 [ffffc900297bb8c8] lock_delalloc_pages at ffffffff814bc684 #6 [ffffc900297bb900] find_lock_delalloc_range at ffffffff814be9ff #7 [ffffc900297bb9a0] writepage_delalloc at ffffffff814bebd0 #8 [ffffc900297bba18] __extent_writepage at ffffffff814bfbf2 #9 [ffffc900297bba98] extent_write_cache_pages at ffffffff814bffbd PID: 2167901 TASK: ffff889dc6a59c00 CPU: 14 COMMAND: "aio-dio-invalid" #0 [ffffc9003b50bb18] __schedule at ffffffff81a4c33f #1 [ffffc9003b50bba0] schedule at ffffffff81a4c6e3 #2 [ffffc9003b50bbb8] io_schedule at ffffffff81a4ca42 #3 [ffffc9003b50bbc8] wait_on_page_bit at ffffffff811f24d6 #4 [ffffc9003b50bc60] prepare_pages at ffffffff814b05a7 #5 [ffffc9003b50bcd8] btrfs_buffered_write at ffffffff814b1359 #6 [ffffc9003b50bdb0] btrfs_file_write_iter at ffffffff814b5933 #7 [ffffc9003b50be38] new_sync_write at ffffffff8128f6a8 #8 [ffffc9003b50bec8] vfs_write at ffffffff81292b9d #9 [ffffc9003b50bf00] ksys_pwrite64 at ffffffff81293032 I used drgn to find the respective pages we were stuck on page_entry.page 0xffffea00fbfc7500 index 8148 bit 15 pid 2167901 page_entry.page 0xffffea00f9bb7400 index 7680 bit 0 pid 1329874 As you can see the kworker is waiting for bit 0 (PG_locked) on index 7680, and aio-dio-invalid is waiting for bit 15 (PG_writeback) on index 8148. aio-dio-invalid has 7680, and the kworker epd looks like the following crash> struct extent_page_data ffffc900297bbbb0 struct extent_page_data { bio = 0xffff889f747ed830, tree = 0xffff889eed6ba448, extent_locked = 0, sync_io = 0 } Probably worth mentioning as well that it waits for writeback of the page to complete while holding a lock on it (at prepare_pages()). Using drgn I walked the bio pages looking for page 0xffffea00fbfc7500 which is the one we're waiting for writeback on bio = Object(prog, 'struct bio', address=0xffff889f747ed830) for i in range(0, bio.bi_vcnt.value_()): bv = bio.bi_io_vec[i] if bv.bv_page.value_() == 0xffffea00fbfc7500: print("FOUND IT") which validated what I suspected. The fix for this is simple, flush the epd before we loop back around to the beginning of the file during writeout. Fixes: b293f02e1423 ("Btrfs: Add writepages support") CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Filipe Manana Signed-off-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/extent_io.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4045,7 +4045,16 @@ retry: */ scanned = 1; index = 0; - goto retry; + + /* + * If we're looping we could run into a page that is locked by a + * writer and that writer could be waiting on writeback for a + * page in our current bio, and thus deadlock, so flush the + * write bio here. + */ + ret = flush_write_bio(epd); + if (!ret) + goto retry; } if (wbc->range_cyclic || (wbc->nr_to_write > 0 && range_whole))