Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp160194pxb; Tue, 12 Apr 2022 20:06:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz7VV4dYl9xlK1PjQ8D+ZJu6vMO2EVQ74tk96y2I0J6zqVO5KwhslnC24EgoAjNUkgrb44J X-Received: by 2002:a17:907:6d91:b0:6e8:9b49:436a with SMTP id sb17-20020a1709076d9100b006e89b49436amr9624958ejc.464.1649819162690; Tue, 12 Apr 2022 20:06:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649819162; cv=none; d=google.com; s=arc-20160816; b=LQz1gEWL0rtMZLO8r0kFFgSh/JT6PJTbptk6k6TukhQGgprMihRmSGdB45adpl8tvs TZHMpXhZGK9mKLilGsNdDcUZOoXYFDf9jhJ6btvDrB6sPIGtn3u00dnaC/AUkyqxWtUu nkmpR8+UTfps+30Vwv3UWGZFArYf9N2eq6733ApDEIRHo+pNYbrhonBK0TEJBEhT84mT NdfR03irmHUw8Jgvb7/Zfcp4VmErSPZnYPjJXXLWZosZdPWsKz6cRyaRqCwiqshpdx9R okJrWjn4IWIcmHOOO7ucNCN0HZGKNAsavo968Xe82CyH2iNMKm+0O30p7+8m0YrYG0Bo qopg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id:dkim-signature; bh=/AR3emCo7ow3RxbhzPIAuD7+rMFDRiQzbJCgE8E3NoQ=; b=iRhBMNDMs+CVhYhGTZKFV8NaZvZ1CTv+kmCj2SGfQ08hd9c8+6GjCDOUoI0YXiXexN IZaZlQA1BgJ3tyuqd4yu+kelXc7sMLuQjQVPp32RbZwDz9jh1ugyYJCjVHBOM3fZSPCG DMu4SFrVGGoUtGZCT3r2iShq/kSAjxLAcXEpdIQ8BZLw9hEEimvtNG1gXHfM4rKveZQm HLROO5adGY+K65MPYf+bOOggIUP+d36Usip1QHAvbm9DHrCjp7tjXN8ZlG9zu/BV4OlX JEk2t6s9vru+Iyke8HW9xAybJZ5vBHOk4fxiZKqdjnokboSEHxB2Mi6cYYE/kqyO9kkx skyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=uA2wcTDt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b15-20020a50e38f000000b0041d8bccdb47si803961edm.599.2022.04.12.20.05.36; Tue, 12 Apr 2022 20:06:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=uA2wcTDt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229604AbiDMB2l (ORCPT + 99 others); Tue, 12 Apr 2022 21:28:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229522AbiDMB2k (ORCPT ); Tue, 12 Apr 2022 21:28:40 -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 61BE9377DE for ; Tue, 12 Apr 2022 18:26:20 -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 dfw.source.kernel.org (Postfix) with ESMTPS id E1FEB618F6 for ; Wed, 13 Apr 2022 01:26:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25586C385A1; Wed, 13 Apr 2022 01:26:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1649813179; bh=K/6FWbMzAcuGO4JVBgyhM+eY72etwU8K3Ish3/dDSw4=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=uA2wcTDtwy9I2/T2l50iLlV/osO3WccoJjVBjKKEBckBCVyS87eRmxGGhuo3X/yKr RPPdRCN6xbgLxbWcdo9bPTtaj40bCNZKaAthNLUeWd6nl3vQ2q0Ccq0pHj2zYKIrYF 7ryeU7B3bRPYgLIGmW5eAHO9MeNy4LYxo2n2dtKkMNcpJo9VfMsUCFhzIRQ35ky2tp AtxictKm2qyeAUvVGppDT/0CG53O6DfXGHIka8wgqV9yzpuB1JGHinHl5Dxy293PD+ b6s9NMNrd4CH9gHACxVODq0c16MsfQbfdlmS5VTeq5ucRluvT56s9Y1b9NEIYBCduS RokYke61AGiuQ== Message-ID: Date: Wed, 13 Apr 2022 09:26:15 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: [PATCH v3] f2fs: give priority to select unpinned section for foreground GC Content-Language: en-US To: Jaegeuk Kim Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, Chao Yu References: <20220406152651.5142-1-chao@kernel.org> <1eee9abe-f468-ce32-cdb9-3a706404de2f@kernel.org> From: Chao Yu In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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 On 2022/4/13 0:21, Jaegeuk Kim wrote: > On 04/12, Chao Yu wrote: >> On 2022/4/12 4:20, Jaegeuk Kim wrote: >>> On 04/06, Chao Yu wrote: >>>> Previously, during foreground GC, if victims contain data of pinned file, >>>> it will fail migration of the data, and meanwhile i_gc_failures of that >>>> pinned file may increase, and when it exceeds threshold, GC will unpin >>>> the file, result in breaking pinfile's semantics. >>>> >>>> In order to mitigate such condition, let's record and skip section which >>>> has pinned file's data and give priority to select unpinned one. >>>> >>>> Signed-off-by: Chao Yu >>>> --- >>>> v3: >>>> - check pin status before pinning section in pin_section(). >>>> fs/f2fs/gc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- >>>> fs/f2fs/segment.c | 7 ++++++ >>>> fs/f2fs/segment.h | 2 ++ >>>> 3 files changed, 62 insertions(+), 3 deletions(-) >>>> >>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>>> index 6a7e4148ff9d..df23824ae3c2 100644 >>>> --- a/fs/f2fs/gc.c >>>> +++ b/fs/f2fs/gc.c >>>> @@ -646,6 +646,37 @@ static void release_victim_entry(struct f2fs_sb_info *sbi) >>>> f2fs_bug_on(sbi, !list_empty(&am->victim_list)); >>>> } >>>> +static void pin_section(struct f2fs_sb_info *sbi, unsigned int segno) >>> >>> Need f2fs_...? >> >> Sure, I can add prefix... >> >> It's a local function, it won't pollute global namespace w/o f2fs_ prefix >> though. >> >>> >>>> +{ >>>> + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); >>>> + unsigned int secno = GET_SEC_FROM_SEG(sbi, segno); >>>> + >>>> + if (test_bit(secno, dirty_i->pinned_secmap)) >>>> + return; >>>> + set_bit(secno, dirty_i->pinned_secmap); >>>> + dirty_i->pinned_secmap_cnt++; >>>> +} >>>> + >>>> +static bool pinned_section_exists(struct dirty_seglist_info *dirty_i) >>>> +{ >>>> + return dirty_i->pinned_secmap_cnt; >>>> +} >>>> + >>>> +static bool section_is_pinned(struct dirty_seglist_info *dirty_i, >>>> + unsigned int secno) >>>> +{ >>>> + return pinned_section_exists(dirty_i) && >>>> + test_bit(secno, dirty_i->pinned_secmap); >>>> +} >>>> + >>>> +static void unpin_all_sections(struct f2fs_sb_info *sbi) >>>> +{ >>>> + unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); >>>> + >>>> + memset(DIRTY_I(sbi)->pinned_secmap, 0, bitmap_size); >>>> + DIRTY_I(sbi)->pinned_secmap_cnt = 0; >>>> +} >>>> + >>>> /* >>>> * This function is called from two paths. >>>> * One is garbage collection and the other is SSR segment selection. >>>> @@ -787,6 +818,9 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, >>>> if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap)) >>>> goto next; >>>> + if (gc_type == FG_GC && section_is_pinned(dirty_i, secno)) >>>> + goto next; >>>> + >>>> if (is_atgc) { >>>> add_victim_entry(sbi, &p, segno); >>>> goto next; >>>> @@ -1202,8 +1236,10 @@ static int move_data_block(struct inode *inode, block_t bidx, >>>> } >>>> if (f2fs_is_pinned_file(inode)) { >>>> - if (gc_type == FG_GC) >>>> + if (gc_type == FG_GC) { >>>> f2fs_pin_file_control(inode, true); >>>> + pin_section(F2FS_I_SB(inode), segno); >>> >>> Do we need to check unpinning the inode? >>> if (!f2fs_pin_file_control()) >>> f2fs_set_pin_section(); >> >> I'm thinking that it needs to avoid increasing GC_FAILURE_PIN AMAP, >> so could you please check below logic: >> >> From 7cb1ee0df32ede44b17c503b81930dae25d287eb Mon Sep 17 00:00:00 2001 >> From: Chao Yu >> Date: Wed, 6 Apr 2022 23:26:51 +0800 >> Subject: [PATCH v4] f2fs: give priority to select unpinned section for >> foreground GC >> >> Previously, during foreground GC, if victims contain data of pinned file, >> it will fail migration of the data, and meanwhile i_gc_failures of that >> pinned file may increase, and when it exceeds threshold, GC will unpin >> the file, result in breaking pinfile's semantics. >> >> In order to mitigate such condition, let's record and skip section which >> has pinned file's data and give priority to select unpinned one. >> >> Signed-off-by: Chao Yu >> --- >> v4: >> - add f2fs_ prefix for newly introduced functions >> - add bool type variable for functionality switch >> - increase GC_FAILURE_PIN only if it disable pinning section >> fs/f2fs/gc.c | 66 ++++++++++++++++++++++++++++++++++++++++++----- >> fs/f2fs/segment.c | 8 ++++++ >> fs/f2fs/segment.h | 3 +++ >> 3 files changed, 71 insertions(+), 6 deletions(-) >> >> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >> index 6a7e4148ff9d..296b31e28d3d 100644 >> --- a/fs/f2fs/gc.c >> +++ b/fs/f2fs/gc.c >> @@ -646,6 +646,41 @@ static void release_victim_entry(struct f2fs_sb_info *sbi) >> f2fs_bug_on(sbi, !list_empty(&am->victim_list)); >> } >> >> +static bool f2fs_pin_section(struct f2fs_sb_info *sbi, unsigned int segno) >> +{ >> + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); >> + unsigned int secno = GET_SEC_FROM_SEG(sbi, segno); >> + >> + if (!dirty_i->enable_pin_section) >> + return false; >> + if (test_bit(secno, dirty_i->pinned_secmap)) >> + return true; >> + set_bit(secno, dirty_i->pinned_secmap); >> + dirty_i->pinned_secmap_cnt++; > > if (!test_and_set_bit()) > dirty_i->pinned_secmap_cnt++; More clean. > >> + return true; >> +} >> + >> +static bool f2fs_pinned_section_exists(struct dirty_seglist_info *dirty_i) >> +{ >> + return dirty_i->enable_pin_section && dirty_i->pinned_secmap_cnt; >> +} >> + >> +static bool f2fs_section_is_pinned(struct dirty_seglist_info *dirty_i, >> + unsigned int secno) >> +{ >> + return f2fs_pinned_section_exists(dirty_i) && >> + test_bit(secno, dirty_i->pinned_secmap); >> +} >> + >> +static void f2fs_unpin_all_sections(struct f2fs_sb_info *sbi, bool enable) >> +{ >> + unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); >> + >> + memset(DIRTY_I(sbi)->pinned_secmap, 0, bitmap_size); >> + DIRTY_I(sbi)->pinned_secmap_cnt = 0; >> + DIRTY_I(sbi)->enable_pin_section = enable; >> +} >> + >> /* >> * This function is called from two paths. >> * One is garbage collection and the other is SSR segment selection. >> @@ -787,6 +822,9 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, >> if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap)) >> goto next; >> >> + if (gc_type == FG_GC && f2fs_section_is_pinned(dirty_i, secno)) >> + goto next; >> + >> if (is_atgc) { >> add_victim_entry(sbi, &p, segno); >> goto next; >> @@ -1202,8 +1240,10 @@ static int move_data_block(struct inode *inode, block_t bidx, >> } >> > > Can we make a generic function? > > f2fs_gc_pinned_control() > { > if (!f2fs_is_pinned_file(inode)) > return 0; > if (gc_type != FG_GC) > return 0; > if (!f2fs_pin_section()) > f2fs_pin_file_control(); > return -EAGAIN; > } Better. :) Thanks, > >> if (f2fs_is_pinned_file(inode)) { >> - if (gc_type == FG_GC) >> - f2fs_pin_file_control(inode, true); >> + if (gc_type == FG_GC) { >> + if (!f2fs_pin_section(F2FS_I_SB(inode), segno)) > >> + f2fs_pin_file_control(inode, true); >> + } >> err = -EAGAIN; >> goto out; >> } >> @@ -1352,8 +1392,10 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type, >> goto out; >> } >> if (f2fs_is_pinned_file(inode)) { >> - if (gc_type == FG_GC) >> - f2fs_pin_file_control(inode, true); >> + if (gc_type == FG_GC) { >> + if (!f2fs_pin_section(F2FS_I_SB(inode), segno)) >> + f2fs_pin_file_control(inode, true); >> + } >> err = -EAGAIN; >> goto out; >> } >> @@ -1483,7 +1525,8 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, >> >> if (is_inode_flag_set(inode, FI_PIN_FILE) && >> gc_type == FG_GC) { >> - f2fs_pin_file_control(inode, true); >> + if (!f2fs_pin_section(sbi, segno)) >> + f2fs_pin_file_control(inode, true); >> iput(inode); >> return submitted; >> } >> @@ -1766,9 +1809,17 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, >> ret = -EINVAL; >> goto stop; >> } >> +retry: >> ret = __get_victim(sbi, &segno, gc_type); >> - if (ret) >> + if (ret) { >> + /* allow to search victim from sections has pinned data */ >> + if (ret == -ENODATA && gc_type == FG_GC && >> + f2fs_pinned_section_exists(DIRTY_I(sbi))) { >> + f2fs_unpin_all_sections(sbi, false); >> + goto retry; >> + } >> goto stop; >> + } >> >> seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type, force); >> if (gc_type == FG_GC && >> @@ -1811,6 +1862,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, >> SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0; >> SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno; >> >> + if (gc_type == FG_GC && f2fs_pinned_section_exists(DIRTY_I(sbi))) >> + f2fs_unpin_all_sections(sbi, true); >> + >> trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed, >> get_pages(sbi, F2FS_DIRTY_NODES), >> get_pages(sbi, F2FS_DIRTY_DENTS), >> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c >> index 22dfeb991529..93c7bae57a25 100644 >> --- a/fs/f2fs/segment.c >> +++ b/fs/f2fs/segment.c >> @@ -4734,6 +4734,13 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi) >> dirty_i->victim_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); >> if (!dirty_i->victim_secmap) >> return -ENOMEM; >> + >> + dirty_i->pinned_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); >> + if (!dirty_i->pinned_secmap) >> + return -ENOMEM; >> + >> + dirty_i->pinned_secmap_cnt = 0; >> + dirty_i->enable_pin_section = true; >> return 0; >> } >> >> @@ -5322,6 +5329,7 @@ static void destroy_victim_secmap(struct f2fs_sb_info *sbi) >> { >> struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); >> >> + kvfree(dirty_i->pinned_secmap); >> kvfree(dirty_i->victim_secmap); >> } >> >> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h >> index 5c94caf0c0a1..8a591455d796 100644 >> --- a/fs/f2fs/segment.h >> +++ b/fs/f2fs/segment.h >> @@ -294,6 +294,9 @@ struct dirty_seglist_info { >> struct mutex seglist_lock; /* lock for segment bitmaps */ >> int nr_dirty[NR_DIRTY_TYPE]; /* # of dirty segments */ >> unsigned long *victim_secmap; /* background GC victims */ >> + unsigned long *pinned_secmap; /* pinned victims from foreground GC */ >> + unsigned int pinned_secmap_cnt; /* count of victims which has pinned data */ >> + bool enable_pin_section; /* enable pinning section */ >> }; >> >> /* victim selection function for cleaning and SSR */ >> -- >> 2.25.1 >> >> Thanks, >> >>> >>>> + } >>>> err = -EAGAIN; >>>> goto out; >>>> } >>>> @@ -1352,8 +1388,10 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type, >>>> goto out; >>>> } >>>> if (f2fs_is_pinned_file(inode)) { >>>> - if (gc_type == FG_GC) >>>> + if (gc_type == FG_GC) { >>>> f2fs_pin_file_control(inode, true); >>>> + pin_section(F2FS_I_SB(inode), segno); >>>> + } >>>> err = -EAGAIN; >>>> goto out; >>>> } >>>> @@ -1485,6 +1523,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, >>>> gc_type == FG_GC) { >>>> f2fs_pin_file_control(inode, true); >>>> iput(inode); >>>> + pin_section(sbi, segno); >>> >>> We don't have this code. >>> >>>> return submitted; >>>> } >>>> @@ -1766,9 +1805,17 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, >>>> ret = -EINVAL; >>>> goto stop; >>>> } >>>> +retry: >>>> ret = __get_victim(sbi, &segno, gc_type); >>>> - if (ret) >>>> + if (ret) { >>>> + /* allow to search victim from sections has pinned data */ >>>> + if (ret == -ENODATA && gc_type == FG_GC && >>>> + pinned_section_exists(DIRTY_I(sbi))) { >>>> + unpin_all_sections(sbi); >>>> + goto retry; >>>> + } >>>> goto stop; >>>> + } >>>> seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type, force); >>>> if (gc_type == FG_GC && >>>> @@ -1811,6 +1858,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, >>>> SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0; >>>> SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno; >>>> + if (gc_type == FG_GC && pinned_section_exists(DIRTY_I(sbi))) >>>> + unpin_all_sections(sbi); >>>> + >>>> trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed, >>>> get_pages(sbi, F2FS_DIRTY_NODES), >>>> get_pages(sbi, F2FS_DIRTY_DENTS), >>>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c >>>> index 012524db7437..1c20d7c9eca3 100644 >>>> --- a/fs/f2fs/segment.c >>>> +++ b/fs/f2fs/segment.c >>>> @@ -4736,6 +4736,12 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi) >>>> dirty_i->victim_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); >>>> if (!dirty_i->victim_secmap) >>>> return -ENOMEM; >>>> + >>>> + dirty_i->pinned_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); >>>> + if (!dirty_i->pinned_secmap) >>>> + return -ENOMEM; >>>> + >>>> + dirty_i->pinned_secmap_cnt = 0; >>>> return 0; >>>> } >>>> @@ -5324,6 +5330,7 @@ static void destroy_victim_secmap(struct f2fs_sb_info *sbi) >>>> { >>>> struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); >>>> + kvfree(dirty_i->pinned_secmap); >>>> kvfree(dirty_i->victim_secmap); >>>> } >>>> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h >>>> index 5c94caf0c0a1..fd6f246e649c 100644 >>>> --- a/fs/f2fs/segment.h >>>> +++ b/fs/f2fs/segment.h >>>> @@ -294,6 +294,8 @@ struct dirty_seglist_info { >>>> struct mutex seglist_lock; /* lock for segment bitmaps */ >>>> int nr_dirty[NR_DIRTY_TYPE]; /* # of dirty segments */ >>>> unsigned long *victim_secmap; /* background GC victims */ >>>> + unsigned long *pinned_secmap; /* pinned victims from foreground GC */ >>>> + unsigned int pinned_secmap_cnt; /* count of victims which has pinned data */ >>>> }; >>>> /* victim selection function for cleaning and SSR */ >>>> -- >>>> 2.32.0