cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gc.h (5042B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * fs/f2fs/gc.h
      4 *
      5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
      6 *             http://www.samsung.com/
      7 */
      8#define GC_THREAD_MIN_WB_PAGES		1	/*
      9						 * a threshold to determine
     10						 * whether IO subsystem is idle
     11						 * or not
     12						 */
     13#define DEF_GC_THREAD_URGENT_SLEEP_TIME	500	/* 500 ms */
     14#define DEF_GC_THREAD_MIN_SLEEP_TIME	30000	/* milliseconds */
     15#define DEF_GC_THREAD_MAX_SLEEP_TIME	60000
     16#define DEF_GC_THREAD_NOGC_SLEEP_TIME	300000	/* wait 5 min */
     17
     18/* choose candidates from sections which has age of more than 7 days */
     19#define DEF_GC_THREAD_AGE_THRESHOLD		(60 * 60 * 24 * 7)
     20#define DEF_GC_THREAD_CANDIDATE_RATIO		20	/* select 20% oldest sections as candidates */
     21#define DEF_GC_THREAD_MAX_CANDIDATE_COUNT	10	/* select at most 10 sections as candidates */
     22#define DEF_GC_THREAD_AGE_WEIGHT		60	/* age weight */
     23#define DEFAULT_ACCURACY_CLASS			10000	/* accuracy class */
     24
     25#define LIMIT_INVALID_BLOCK	40 /* percentage over total user space */
     26#define LIMIT_FREE_BLOCK	40 /* percentage over invalid + free space */
     27
     28#define DEF_GC_FAILED_PINNED_FILES	2048
     29
     30/* Search max. number of dirty segments to select a victim segment */
     31#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
     32
     33struct f2fs_gc_kthread {
     34	struct task_struct *f2fs_gc_task;
     35	wait_queue_head_t gc_wait_queue_head;
     36
     37	/* for gc sleep time */
     38	unsigned int urgent_sleep_time;
     39	unsigned int min_sleep_time;
     40	unsigned int max_sleep_time;
     41	unsigned int no_gc_sleep_time;
     42
     43	/* for changing gc mode */
     44	unsigned int gc_wake;
     45
     46	/* for GC_MERGE mount option */
     47	wait_queue_head_t fggc_wq;		/*
     48						 * caller of f2fs_balance_fs()
     49						 * will wait on this wait queue.
     50						 */
     51};
     52
     53struct gc_inode_list {
     54	struct list_head ilist;
     55	struct radix_tree_root iroot;
     56};
     57
     58struct victim_info {
     59	unsigned long long mtime;	/* mtime of section */
     60	unsigned int segno;		/* section No. */
     61};
     62
     63struct victim_entry {
     64	struct rb_node rb_node;		/* rb node located in rb-tree */
     65	union {
     66		struct {
     67			unsigned long long mtime;	/* mtime of section */
     68			unsigned int segno;		/* segment No. */
     69		};
     70		struct victim_info vi;	/* victim info */
     71	};
     72	struct list_head list;
     73};
     74
     75/*
     76 * inline functions
     77 */
     78
     79/*
     80 * On a Zoned device zone-capacity can be less than zone-size and if
     81 * zone-capacity is not aligned to f2fs segment size(2MB), then the segment
     82 * starting just before zone-capacity has some blocks spanning across the
     83 * zone-capacity, these blocks are not usable.
     84 * Such spanning segments can be in free list so calculate the sum of usable
     85 * blocks in currently free segments including normal and spanning segments.
     86 */
     87static inline block_t free_segs_blk_count_zoned(struct f2fs_sb_info *sbi)
     88{
     89	block_t free_seg_blks = 0;
     90	struct free_segmap_info *free_i = FREE_I(sbi);
     91	int j;
     92
     93	spin_lock(&free_i->segmap_lock);
     94	for (j = 0; j < MAIN_SEGS(sbi); j++)
     95		if (!test_bit(j, free_i->free_segmap))
     96			free_seg_blks += f2fs_usable_blks_in_seg(sbi, j);
     97	spin_unlock(&free_i->segmap_lock);
     98
     99	return free_seg_blks;
    100}
    101
    102static inline block_t free_segs_blk_count(struct f2fs_sb_info *sbi)
    103{
    104	if (f2fs_sb_has_blkzoned(sbi))
    105		return free_segs_blk_count_zoned(sbi);
    106
    107	return free_segments(sbi) << sbi->log_blocks_per_seg;
    108}
    109
    110static inline block_t free_user_blocks(struct f2fs_sb_info *sbi)
    111{
    112	block_t free_blks, ovp_blks;
    113
    114	free_blks = free_segs_blk_count(sbi);
    115	ovp_blks = overprovision_segments(sbi) << sbi->log_blocks_per_seg;
    116
    117	if (free_blks < ovp_blks)
    118		return 0;
    119
    120	return free_blks - ovp_blks;
    121}
    122
    123static inline block_t limit_invalid_user_blocks(struct f2fs_sb_info *sbi)
    124{
    125	return (long)(sbi->user_block_count * LIMIT_INVALID_BLOCK) / 100;
    126}
    127
    128static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi)
    129{
    130	block_t reclaimable_user_blocks = sbi->user_block_count -
    131		written_block_count(sbi);
    132	return (long)(reclaimable_user_blocks * LIMIT_FREE_BLOCK) / 100;
    133}
    134
    135static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th,
    136							unsigned int *wait)
    137{
    138	unsigned int min_time = gc_th->min_sleep_time;
    139	unsigned int max_time = gc_th->max_sleep_time;
    140
    141	if (*wait == gc_th->no_gc_sleep_time)
    142		return;
    143
    144	if ((long long)*wait + (long long)min_time > (long long)max_time)
    145		*wait = max_time;
    146	else
    147		*wait += min_time;
    148}
    149
    150static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th,
    151							unsigned int *wait)
    152{
    153	unsigned int min_time = gc_th->min_sleep_time;
    154
    155	if (*wait == gc_th->no_gc_sleep_time)
    156		*wait = gc_th->max_sleep_time;
    157
    158	if ((long long)*wait - (long long)min_time < (long long)min_time)
    159		*wait = min_time;
    160	else
    161		*wait -= min_time;
    162}
    163
    164static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
    165{
    166	block_t invalid_user_blocks = sbi->user_block_count -
    167					written_block_count(sbi);
    168	/*
    169	 * Background GC is triggered with the following conditions.
    170	 * 1. There are a number of invalid blocks.
    171	 * 2. There is not enough free space.
    172	 */
    173	if (invalid_user_blocks > limit_invalid_user_blocks(sbi) &&
    174			free_user_blocks(sbi) < limit_free_user_blocks(sbi))
    175		return true;
    176	return false;
    177}