Received: by 2002:a5d:9c59:0:0:0:0:0 with SMTP id 25csp2266422iof; Wed, 8 Jun 2022 00:54:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwzkTCV50FvLAuHt0N+j8n0ecra0R34t3hnFHxVPY04jwWqlyiJcjIKHXpkzyH+yni+JlaW X-Received: by 2002:a17:902:ea0f:b0:167:9a4d:bad0 with SMTP id s15-20020a170902ea0f00b001679a4dbad0mr5287699plg.68.1654674888367; Wed, 08 Jun 2022 00:54:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654674888; cv=none; d=google.com; s=arc-20160816; b=b+mY5E1Wxd1HPUwPpXG2Ic5mHZumUknpXQ9m0HjotAbnrt7XGii3DhjvvEDe/ui3/9 26byFDHPDkWq9oPIwtzhFUwhOuvR7It7LU2u9v9x1h7ebXZ/9rtr0MSwbJ/AKekXyU6p HHV9P/gUXHlQP9YnHBS3140SEvbN2PeRwSjiJzqNytoSH2Pth6EYCwGjwzTiXth4bTe2 VFMyc9AQPSTq+p6iyZYlbWdl/8ToYT6IvUW1zryc7i7P/p5MX3OTwJAY0LwbHeMP2q+b MB84Ges7BaUuMRWX4GqkLuDpY4pKvAWLPn9pe2hs05MIHoVqbNl+l7kV/laSqsUBSZMD 3/6A== 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=OTG8+VoDFQAaztKPQvH4Zt0DC1bsFuFF7XmvCLarBWo=; b=Og/RxehfS/tq9LpTplWYOX+fiC7z0JcnDiJwoRvDCQK2JQX1JP9CrGbRYDELjEqs/t 5qf76e2SANcrH0CgfomU6OMiPJsuMO1Cwvjq4eHt/UuQ2BXqs5BsnRWVSU4jSaDOghB/ q4ujjMDeWnZzq8dDn/JOsrGkEfuqbqsZrW6IOJlK7/vFN6eIMm5zqEm4r9j2/orHMmAl 0zBblMn99P4ZmWQIx3JbGDo9DE001lW0OYXGEvIXUBgCQr5a/0jQs0E/lNjSCZxW05f2 MeEzw8GHMBiW5H/z3hQxQ7tc8x074tvliWx1VUmk3mt/ZSpvlPMrjJ3ngmlOScxb1jp3 cOwQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="H/RojdmL"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id n7-20020a170902e54700b00153b2d1653asi32570224plf.322.2022.06.08.00.54.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jun 2022 00:54:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="H/RojdmL"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0FB9F1D786A; Wed, 8 Jun 2022 00:23:47 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357699AbiFGTqO (ORCPT + 99 others); Tue, 7 Jun 2022 15:46:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353476AbiFGSrj (ORCPT ); Tue, 7 Jun 2022 14:47:39 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DFDEEB6; Tue, 7 Jun 2022 11:02:58 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B25F2B82375; Tue, 7 Jun 2022 18:02:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD22BC341CF; Tue, 7 Jun 2022 18:02:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654624975; bh=YsbqfK4bDhrH0z3BIe/ryhtT8bg72/Iiz12ahGehA0s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H/RojdmLaxGdSdzAgxd9gm/e+2McS8G/2l6R+AKdFyYnhO9PkiERf1WO8tWgiiGh7 MfckLtNAgZ02cUplk+QJo6U3gv1rjCy9d6VBAuBVVsTKrgW2R5TS1bhok/ywPQpUER xjt+RIKwKHNwJe3nbHmaUDOGQFK+645MpLrCA0fY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ming Yan , Chao Yu , Jaegeuk Kim Subject: [PATCH 5.15 519/667] f2fs: fix deadloop in foreground GC Date: Tue, 7 Jun 2022 19:03:04 +0200 Message-Id: <20220607164950.269772700@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220607164934.766888869@linuxfoundation.org> References: <20220607164934.766888869@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chao Yu commit cfd66bb715fd11fde3338d0660cffa1396adc27d upstream. As Yanming reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215914 The root cause is: in a very small sized image, it's very easy to exceed threshold of foreground GC, if we calculate free space and dirty data based on section granularity, in corner case, has_not_enough_free_secs() will always return true, result in deadloop in f2fs_gc(). So this patch refactors has_not_enough_free_secs() as below to fix this issue: 1. calculate needed space based on block granularity, and separate all blocks to two parts, section part, and block part, comparing section part to free section, and comparing block part to free space in openned log. 2. account F2FS_DIRTY_NODES, F2FS_DIRTY_IMETA and F2FS_DIRTY_DENTS as node block consumer; 3. account F2FS_DIRTY_DENTS as data block consumer; Cc: stable@vger.kernel.org Reported-by: Ming Yan Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/segment.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -571,11 +571,10 @@ static inline int reserved_sections(stru return GET_SEC_FROM_SEG(sbi, reserved_segments(sbi)); } -static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi) +static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, + unsigned int node_blocks, unsigned int dent_blocks) { - unsigned int node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) + - get_pages(sbi, F2FS_DIRTY_DENTS); - unsigned int dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS); + unsigned int segno, left_blocks; int i; @@ -601,19 +600,28 @@ static inline bool has_curseg_enough_spa static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed, int needed) { - int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); - int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); - int imeta_secs = get_blocktype_secs(sbi, F2FS_DIRTY_IMETA); + unsigned int total_node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) + + get_pages(sbi, F2FS_DIRTY_DENTS) + + get_pages(sbi, F2FS_DIRTY_IMETA); + unsigned int total_dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS); + unsigned int node_secs = total_node_blocks / BLKS_PER_SEC(sbi); + unsigned int dent_secs = total_dent_blocks / BLKS_PER_SEC(sbi); + unsigned int node_blocks = total_node_blocks % BLKS_PER_SEC(sbi); + unsigned int dent_blocks = total_dent_blocks % BLKS_PER_SEC(sbi); + unsigned int free, need_lower, need_upper; if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) return false; - if (free_sections(sbi) + freed == reserved_sections(sbi) + needed && - has_curseg_enough_space(sbi)) + free = free_sections(sbi) + freed; + need_lower = node_secs + dent_secs + reserved_sections(sbi) + needed; + need_upper = need_lower + (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0); + + if (free > need_upper) return false; - return (free_sections(sbi) + freed) <= - (node_secs + 2 * dent_secs + imeta_secs + - reserved_sections(sbi) + needed); + else if (free <= need_lower) + return true; + return !has_curseg_enough_space(sbi, node_blocks, dent_blocks); } static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)