]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
f2fs: introduce sbi->gc_mode to determine the policy
authorJaegeuk Kim <jaegeuk@kernel.org>
Mon, 7 May 2018 21:22:40 +0000 (14:22 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 31 May 2018 18:31:51 +0000 (11:31 -0700)
This is to avoid sbi->gc_thread pointer access.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/f2fs.h
fs/f2fs/gc.c
fs/f2fs/gc.h
fs/f2fs/segment.c
fs/f2fs/sysfs.c

index 24eab9622ad1b083d362d8b69e516d9e7c05ddbd..72b9cd71d2fc0a0b19a2c65bdcf5b279a5116c8e 100644 (file)
@@ -1066,6 +1066,13 @@ enum {
        MAX_TIME,
 };
 
+enum {
+       GC_NORMAL,
+       GC_IDLE_CB,
+       GC_IDLE_GREEDY,
+       GC_URGENT,
+};
+
 enum {
        WHINT_MODE_OFF,         /* not pass down write hints */
        WHINT_MODE_USER,        /* try to pass down hints given by users */
@@ -1197,6 +1204,7 @@ struct f2fs_sb_info {
        struct mutex gc_mutex;                  /* mutex for GC */
        struct f2fs_gc_kthread  *gc_thread;     /* GC thread */
        unsigned int cur_victim_sec;            /* current victim section num */
+       unsigned int gc_mode;                   /* current GC state */
 
        /* threshold for gc trials on pinned files */
        u64 gc_pin_file_threshold;
index ec9b1579c5106b23539b1f2068a5c15a9c6824a9..f02a9fee4b4b32a629ce2da3d828bceed676d56c 100644 (file)
@@ -76,7 +76,7 @@ static int gc_thread_func(void *data)
                 * invalidated soon after by user update or deletion.
                 * So, I'd like to wait some time to collect dirty segments.
                 */
-               if (gc_th->gc_urgent) {
+               if (sbi->gc_mode == GC_URGENT) {
                        wait_ms = gc_th->urgent_sleep_time;
                        mutex_lock(&sbi->gc_mutex);
                        goto do_gc;
@@ -131,8 +131,6 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
        gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
        gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
 
-       gc_th->gc_idle = 0;
-       gc_th->gc_urgent = 0;
        gc_th->gc_wake= 0;
 
        sbi->gc_thread = gc_th;
@@ -158,21 +156,19 @@ void stop_gc_thread(struct f2fs_sb_info *sbi)
        sbi->gc_thread = NULL;
 }
 
-static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type)
+static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
 {
        int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY;
 
-       if (!gc_th)
-               return gc_mode;
-
-       if (gc_th->gc_idle) {
-               if (gc_th->gc_idle == 1)
-                       gc_mode = GC_CB;
-               else if (gc_th->gc_idle == 2)
-                       gc_mode = GC_GREEDY;
-       }
-       if (gc_th->gc_urgent)
+       switch (sbi->gc_mode) {
+       case GC_IDLE_CB:
+               gc_mode = GC_CB;
+               break;
+       case GC_IDLE_GREEDY:
+       case GC_URGENT:
                gc_mode = GC_GREEDY;
+               break;
+       }
        return gc_mode;
 }
 
@@ -187,7 +183,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
                p->max_search = dirty_i->nr_dirty[type];
                p->ofs_unit = 1;
        } else {
-               p->gc_mode = select_gc_type(sbi->gc_thread, gc_type);
+               p->gc_mode = select_gc_type(sbi, gc_type);
                p->dirty_segmap = dirty_i->dirty_segmap[DIRTY];
                p->max_search = dirty_i->nr_dirty[DIRTY];
                p->ofs_unit = sbi->segs_per_sec;
@@ -195,7 +191,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
 
        /* we need to check every dirty segments in the FG_GC case */
        if (gc_type != FG_GC &&
-                       (sbi->gc_thread && !sbi->gc_thread->gc_urgent) &&
+                       (sbi->gc_mode != GC_URGENT) &&
                        p->max_search > sbi->max_victim_search)
                p->max_search = sbi->max_victim_search;
 
index b0045d4c8d1e6f74f0da0e0ee1ef9376e0289f33..c8619e408009068c63ff37d35eecc84797eb8130 100644 (file)
@@ -36,8 +36,6 @@ struct f2fs_gc_kthread {
        unsigned int no_gc_sleep_time;
 
        /* for changing gc mode */
-       unsigned int gc_idle;
-       unsigned int gc_urgent;
        unsigned int gc_wake;
 };
 
index 9f27e9b64c1cdecb3ac83da86845d5822b6f4911..55cba4fc3a04788aaa1e6e9b242cd7706eaae13f 100644 (file)
@@ -177,7 +177,7 @@ bool need_SSR(struct f2fs_sb_info *sbi)
 
        if (test_opt(sbi, LFS))
                return false;
-       if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+       if (sbi->gc_mode == GC_URGENT)
                return true;
 
        return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs +
@@ -1405,7 +1405,7 @@ static int issue_discard_thread(void *data)
                if (dcc->discard_wake)
                        dcc->discard_wake = 0;
 
-               if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+               if (sbi->gc_mode == GC_URGENT)
                        __init_discard_policy(sbi, &dpolicy, DPOLICY_FORCE, 1);
 
                sb_start_intwrite(sbi->sb);
index 6d8d8f41e517d74416006826bd127c510d163b5d..dd940d156af62ee54c8c047a19a29aa7768497fb 100644 (file)
@@ -248,16 +248,33 @@ out:
        if (!strcmp(a->attr.name, "trim_sections"))
                return -EINVAL;
 
+       if (!strcmp(a->attr.name, "gc_urgent")) {
+               if (t >= 1) {
+                       sbi->gc_mode = GC_URGENT;
+                       if (sbi->gc_thread) {
+                               wake_up_interruptible_all(
+                                       &sbi->gc_thread->gc_wait_queue_head);
+                               wake_up_discard_thread(sbi, true);
+                       }
+               } else {
+                       sbi->gc_mode = GC_NORMAL;
+               }
+               return count;
+       }
+       if (!strcmp(a->attr.name, "gc_idle")) {
+               if (t == GC_IDLE_CB)
+                       sbi->gc_mode = GC_IDLE_CB;
+               else if (t == GC_IDLE_GREEDY)
+                       sbi->gc_mode = GC_IDLE_GREEDY;
+               else
+                       sbi->gc_mode = GC_NORMAL;
+               return count;
+       }
+
        *ui = t;
 
        if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
                f2fs_reset_iostat(sbi);
-       if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
-               sbi->gc_thread->gc_wake = 1;
-               wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
-               wake_up_discard_thread(sbi, true);
-       }
-
        return count;
 }
 
@@ -349,8 +366,8 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);