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 X-Spam-Level: X-Spam-Status: No, score=-9.4 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26E3EC43387 for ; Sat, 5 Jan 2019 17:16:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DECE32085A for ; Sat, 5 Jan 2019 17:16:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546708568; bh=djpL9INx5ST2e41QWrUST8LJ172MaoUCIMZBbWY8vfs=; h=Subject:To:Cc:From:Date:List-ID:From; b=TtE1HFiyScXceuoUclaYFeSn/gvAjfubdY+uXLUnbRbaMtLcLxOd9akI8ELXy93mk SvWrJFNgDncGJAPr+6LL24JtYJ9wI//1nWFJX4G+if4XzPWCd1XInP7dQVeHIwJzVj jv/0YJcng0VUDWGssO9qBtT3x3gNjDxOlJSAwls0= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726349AbfAERQH (ORCPT ); Sat, 5 Jan 2019 12:16:07 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:57609 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726252AbfAERQH (ORCPT ); Sat, 5 Jan 2019 12:16:07 -0500 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 04B1721E32; Sat, 5 Jan 2019 12:16:06 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Sat, 05 Jan 2019 12:16:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=3dPhA/ 1XUeGO9gAIg2CLxdnZvPnJcweQ2wPA5r8/O4I=; b=gbkhXIr8m/2Pf+IEFojVME fDNGCIo+6oH4Z4BKJ429sVixfQUYgc+clNbOs1RU73TLE0rH/O1LAc92YHMlvlj5 /9sIZek5bs7IxTErbresLhxdM3WrH8DBDg5LHs1sfFMOw0fOVsb7OWcTqxt3Y5fp P342lqxnNlNHMkVt9rqgie8E0TriY7qX4GHA5arTJ+THAHln5IJ4e8ThqY/7Mxkl eBwfmxLrcJ6sHLEnSyBOnkLnlK3R5jzQ/O9jOIoEBgGfMfvU/VUQHTl3QvNZZGHs I95TDRKsVocO1r0s+HJrCJgpW/Y4WPkKqfj2EiTUB78kd30DHPahJS9pA4rMProA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtledrvdefgddutdduucdltddurdegtdekrddttd dmucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhht necuuegrihhlohhuthemuceftddtnecunecujfgurhepuffvhfffkfggtgfgsehtkeertd dttdflnecuhfhrohhmpeeoghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdho rhhgqeenucfkphepiedvrdduudelrdduieeirdelnecurfgrrhgrmhepmhgrihhlfhhroh hmpehgrhgvgheskhhrohgrhhdrtghomhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from localhost (unknown [62.119.166.9]) by mail.messagingengine.com (Postfix) with ESMTPA id AC372100B8; Sat, 5 Jan 2019 12:16:03 -0500 (EST) Subject: FAILED: patch "[PATCH] Btrfs: fix deadlock with memory reclaim during scrub" failed to apply to 4.19-stable tree To: fdmanana@suse.com, dsterba@suse.com, nborisov@suse.com Cc: From: Date: Sat, 05 Jan 2019 18:15:47 +0100 Message-ID: <154670854719086@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org The patch below does not apply to the 4.19-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . thanks, greg k-h ------------------ original commit in Linus's tree ------------------ >From a5fb11429167ee6ddeeacc554efaf5776b36433a Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 26 Nov 2018 20:07:17 +0000 Subject: [PATCH] Btrfs: fix deadlock with memory reclaim during scrub When a transaction commit starts, it attempts to pause scrub and it blocks until the scrub is paused. So while the transaction is blocked waiting for scrub to pause, we can not do memory allocation with GFP_KERNEL from scrub, otherwise we risk getting into a deadlock with reclaim. Checking for scrub pause requests is done early at the beginning of the while loop of scrub_stripe() and later in the loop, scrub_extent() and scrub_raid56_parity() are called, which in turn call scrub_pages() and scrub_pages_for_parity() respectively. These last two functions do memory allocations using GFP_KERNEL. Same problem could happen while scrubbing the super blocks, since it calls scrub_pages(). We also can not have any of the worker tasks, created by the scrub task, doing GFP_KERNEL allocations, because before pausing, the scrub task waits for all the worker tasks to complete (also done at scrub_stripe()). So make sure GFP_NOFS is used for the memory allocations because at any time a scrub pause request can happen from another task that started to commit a transaction. Fixes: 58c4e173847a ("btrfs: scrub: use GFP_KERNEL on the submission path") CC: stable@vger.kernel.org # 4.6+ Reviewed-by: Nikolay Borisov Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 902819d3cf41..bbd1b36f4918 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -322,6 +322,7 @@ static struct full_stripe_lock *insert_full_stripe_lock( struct rb_node *parent = NULL; struct full_stripe_lock *entry; struct full_stripe_lock *ret; + unsigned int nofs_flag; lockdep_assert_held(&locks_root->lock); @@ -339,8 +340,17 @@ static struct full_stripe_lock *insert_full_stripe_lock( } } - /* Insert new lock */ + /* + * Insert new lock. + * + * We must use GFP_NOFS because the scrub task might be waiting for a + * worker task executing this function and in turn a transaction commit + * might be waiting the scrub task to pause (which needs to wait for all + * the worker tasks to complete before pausing). + */ + nofs_flag = memalloc_nofs_save(); ret = kmalloc(sizeof(*ret), GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); if (!ret) return ERR_PTR(-ENOMEM); ret->logical = fstripe_logical; @@ -1620,8 +1630,19 @@ static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx, mutex_lock(&sctx->wr_lock); again: if (!sctx->wr_curr_bio) { + unsigned int nofs_flag; + + /* + * We must use GFP_NOFS because the scrub task might be waiting + * for a worker task executing this function and in turn a + * transaction commit might be waiting the scrub task to pause + * (which needs to wait for all the worker tasks to complete + * before pausing). + */ + nofs_flag = memalloc_nofs_save(); sctx->wr_curr_bio = kzalloc(sizeof(*sctx->wr_curr_bio), GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); if (!sctx->wr_curr_bio) { mutex_unlock(&sctx->wr_lock); return -ENOMEM; @@ -3772,6 +3793,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, struct scrub_ctx *sctx; int ret; struct btrfs_device *dev; + unsigned int nofs_flag; if (btrfs_fs_closing(fs_info)) return -EINVAL; @@ -3875,6 +3897,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, atomic_inc(&fs_info->scrubs_running); mutex_unlock(&fs_info->scrub_lock); + /* + * In order to avoid deadlock with reclaim when there is a transaction + * trying to pause scrub, make sure we use GFP_NOFS for all the + * allocations done at btrfs_scrub_pages() and scrub_pages_for_parity() + * invoked by our callees. The pausing request is done when the + * transaction commit starts, and it blocks the transaction until scrub + * is paused (done at specific points at scrub_stripe() or right above + * before incrementing fs_info->scrubs_running). + */ + nofs_flag = memalloc_nofs_save(); if (!is_dev_replace) { /* * by holding device list mutex, we can @@ -3887,6 +3919,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, if (!ret) ret = scrub_enumerate_chunks(sctx, dev, start, end); + memalloc_nofs_restore(nofs_flag); wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); atomic_dec(&fs_info->scrubs_running);