Received: by 2002:a5d:9c59:0:0:0:0:0 with SMTP id 25csp2212455iof; Tue, 7 Jun 2022 23:22:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyym06zRmAZh5EicoD5FrKtQDNlHSeUWridn8J1DjsJa0cp9XxOlS04QkHc6OLfwEK/hYu3 X-Received: by 2002:a17:902:74c8:b0:167:93c0:c30d with SMTP id f8-20020a17090274c800b0016793c0c30dmr6960141plt.109.1654669332818; Tue, 07 Jun 2022 23:22:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654669332; cv=none; d=google.com; s=arc-20160816; b=kta6YWo9/nUW9LBq4D1k3/e/MfngLJR6O70hxT67p6RUQ9jf5YvMGThJWbJcoCi8fO BLB5DlO8Xd5UyrUEyIHc8CTJXEvVsK+/l94AqsGAscmr5Xa0rGu/naAMteyvF/LDoo5+ ZOieySCImJ/hfwo6W4o0zPFjWG4G9+I0Tn4f5+2rEAlNP8f3rswWoBvBO5G8+buDygp2 dNG/05NKLV9m21w7GbeaVkAEh67yfGEdB9XB7koWxHba+w8SFZC583F3RmlmNZJFncGs oPbYYOYzqBjYgzLEoH+KsCZl1mkAOlGkxnk1+EovYwlh7E6rMdkEoMmySFPKGKrT8s18 VJ8A== 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=g756FwNhxCuJ499wXpOogMIGulwujcoF9C2z8RMzwA0=; b=QYa7h7E7dwSip0q9Zt6AhN9doOaQmncIkYmuoPseMQ7Nj9oKmwwbwBmBjJTWoDE+cF Otpx8eMKcIlsMAyiIZSbuJqbucs6SCR+CiZWEOB0+IvqUYhuY5lOfI7Hl7PPn1cti9+L bJ4rOB0bl6B2xosCRhliQB4BhBEcA1W0YiWtxhjXm3XkaluFRqJ1942lg1TfPRHKfFz3 XWyhvzjbfQfx5m14UNLLU7EbAEThJz74Md4VqFgaIGIt7ffvAdiuLUAFMQsNTTbxEIiC 8YD5GiPs69CrZPuL4XJ1OIBlybMMOeQ6rCSwG6hh9dix1wtPqBYdRRN9KdqATUdgOPpf iV4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=b6vvhIwy; 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 t20-20020a170902dcd400b0015ee6096fadsi23325634pll.69.2022.06.07.23.22.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jun 2022 23:22:12 -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=b6vvhIwy; 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 D1D98263DE5; Tue, 7 Jun 2022 22:42:51 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443457AbiFHCCb (ORCPT + 99 others); Tue, 7 Jun 2022 22:02:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1841758AbiFHAIO (ORCPT ); Tue, 7 Jun 2022 20:08:14 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D28C2534CD; Tue, 7 Jun 2022 12:18:19 -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 E21C2B823DC; Tue, 7 Jun 2022 19:18:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 571C6C36B0B; Tue, 7 Jun 2022 19:18:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654629496; bh=ibFWBZNYf96bTV+pa3KOvrMz/s+3mgQ+XsQOvLGXtoY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b6vvhIwyUI45QjjsH5EVcvWXUGIWuCcUOk2fyD+7XgOIL/DFj58/UjE0Nw1dVTgnB 06AZA1iRsPc2RHFFAOwG4ZKpx9QLjNQ1zMkR4jtoi008MQ51nytFwNqacrjB7Nfe2c zlpZyBrVX+KjIMad9lpAdjRM0TS50J2fp4twPxhY= 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.18 711/879] f2fs: fix deadloop in foreground GC Date: Tue, 7 Jun 2022 19:03:49 +0200 Message-Id: <20220607165023.491299256@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220607165002.659942637@linuxfoundation.org> References: <20220607165002.659942637@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 @@ -572,11 +572,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; @@ -602,19 +601,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)