Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

f2fs: trace elapsed time for gc_lock lock

Use f2fs_{down,up}_write_trace for gc_lock to trace lock elapsed time.

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Chao Yu and committed by
Jaegeuk Kim
e605302c bb28b668

+54 -42
+6 -4
fs/f2fs/checkpoint.c
··· 1930 1930 static int __write_checkpoint_sync(struct f2fs_sb_info *sbi) 1931 1931 { 1932 1932 struct cp_control cpc = { .reason = CP_SYNC, }; 1933 + struct f2fs_lock_context lc; 1933 1934 int err; 1934 1935 1935 - f2fs_down_write(&sbi->gc_lock); 1936 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 1936 1937 err = f2fs_write_checkpoint(sbi, &cpc); 1937 - f2fs_up_write(&sbi->gc_lock); 1938 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 1938 1939 1939 1940 return err; 1940 1941 } ··· 2023 2022 cpc.reason = __get_cp_reason(sbi); 2024 2023 if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC || 2025 2024 sbi->umount_lock_holder == current) { 2025 + struct f2fs_lock_context lc; 2026 2026 int ret; 2027 2027 2028 - f2fs_down_write(&sbi->gc_lock); 2028 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 2029 2029 ret = f2fs_write_checkpoint(sbi, &cpc); 2030 - f2fs_up_write(&sbi->gc_lock); 2030 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 2031 2031 2032 2032 return ret; 2033 2033 }
+12 -10
fs/f2fs/f2fs.h
··· 178 178 LOCK_NAME_CP_RWSEM, 179 179 LOCK_NAME_NODE_CHANGE, 180 180 LOCK_NAME_NODE_WRITE, 181 + LOCK_NAME_GC_LOCK, 181 182 }; 182 183 183 184 /* ··· 1409 1408 unsigned long long age_threshold; /* age threshold */ 1410 1409 }; 1411 1410 1412 - struct f2fs_gc_control { 1413 - unsigned int victim_segno; /* target victim segment number */ 1414 - int init_gc_type; /* FG_GC or BG_GC */ 1415 - bool no_bg_gc; /* check the space and stop bg_gc */ 1416 - bool should_migrate_blocks; /* should migrate blocks */ 1417 - bool err_gc_skipped; /* return EAGAIN if GC skipped */ 1418 - bool one_time; /* require one time GC in one migration unit */ 1419 - unsigned int nr_free_secs; /* # of free sections to do GC */ 1420 - }; 1421 - 1422 1411 struct f2fs_time_stat { 1423 1412 unsigned long long total_time; /* total wall clock time */ 1424 1413 #ifdef CONFIG_64BIT ··· 1425 1434 struct f2fs_lock_context { 1426 1435 struct f2fs_time_stat ts; 1427 1436 bool lock_trace; 1437 + }; 1438 + 1439 + struct f2fs_gc_control { 1440 + unsigned int victim_segno; /* target victim segment number */ 1441 + int init_gc_type; /* FG_GC or BG_GC */ 1442 + bool no_bg_gc; /* check the space and stop bg_gc */ 1443 + bool should_migrate_blocks; /* should migrate blocks */ 1444 + bool err_gc_skipped; /* return EAGAIN if GC skipped */ 1445 + bool one_time; /* require one time GC in one migration unit */ 1446 + unsigned int nr_free_secs; /* # of free sections to do GC */ 1447 + struct f2fs_lock_context lc; /* lock context for gc_lock */ 1428 1448 }; 1429 1449 1430 1450 /*
+7 -6
fs/f2fs/file.c
··· 1928 1928 1929 1929 if (has_not_enough_free_secs(sbi, 0, 1930 1930 sbi->reserved_pin_section)) { 1931 - f2fs_down_write(&sbi->gc_lock); 1931 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 1932 1932 stat_inc_gc_call_count(sbi, FOREGROUND); 1933 1933 err = f2fs_gc(sbi, &gc_control); 1934 1934 if (err && err != -ENODATA) { ··· 2779 2779 return ret; 2780 2780 2781 2781 if (!sync) { 2782 - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { 2782 + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, 2783 + &gc_control.lc)) { 2783 2784 ret = -EBUSY; 2784 2785 goto out; 2785 2786 } 2786 2787 } else { 2787 - f2fs_down_write(&sbi->gc_lock); 2788 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 2788 2789 } 2789 2790 2790 2791 gc_control.init_gc_type = sync ? FG_GC : BG_GC; ··· 2825 2824 2826 2825 do_more: 2827 2826 if (!range->sync) { 2828 - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { 2827 + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &gc_control.lc)) { 2829 2828 ret = -EBUSY; 2830 2829 goto out; 2831 2830 } 2832 2831 } else { 2833 - f2fs_down_write(&sbi->gc_lock); 2832 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 2834 2833 } 2835 2834 2836 2835 gc_control.victim_segno = GET_SEGNO(sbi, range->start); ··· 3321 3320 end_segno = min(start_segno + range.segments, dev_end_segno); 3322 3321 3323 3322 while (start_segno < end_segno) { 3324 - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { 3323 + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &gc_control.lc)) { 3325 3324 ret = -EBUSY; 3326 3325 goto out; 3327 3326 }
+13 -10
fs/f2fs/gc.c
··· 102 102 if (sbi->gc_mode == GC_URGENT_HIGH || 103 103 sbi->gc_mode == GC_URGENT_MID) { 104 104 wait_ms = gc_th->urgent_sleep_time; 105 - f2fs_down_write(&sbi->gc_lock); 105 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 106 106 goto do_gc; 107 107 } 108 108 109 109 if (foreground) { 110 - f2fs_down_write(&sbi->gc_lock); 110 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 111 111 goto do_gc; 112 - } else if (!f2fs_down_write_trylock(&sbi->gc_lock)) { 112 + } else if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, 113 + &gc_control.lc)) { 113 114 stat_other_skip_bggc_count(sbi); 114 115 goto next; 115 116 } 116 117 117 118 if (!is_idle(sbi, GC_TIME)) { 118 119 increase_sleep_time(gc_th, &wait_ms); 119 - f2fs_up_write(&sbi->gc_lock); 120 + f2fs_up_write_trace(&sbi->gc_lock, &gc_control.lc); 120 121 stat_io_skip_bggc_count(sbi); 121 122 goto next; 122 123 } ··· 126 125 if (has_enough_free_blocks(sbi, 127 126 gc_th->no_zoned_gc_percent)) { 128 127 wait_ms = gc_th->no_gc_sleep_time; 129 - f2fs_up_write(&sbi->gc_lock); 128 + f2fs_up_write_trace(&sbi->gc_lock, 129 + &gc_control.lc); 130 130 goto next; 131 131 } 132 132 if (wait_ms == gc_th->no_gc_sleep_time) ··· 2048 2046 reserved_segments(sbi), 2049 2047 prefree_segments(sbi)); 2050 2048 2051 - f2fs_up_write(&sbi->gc_lock); 2049 + f2fs_up_write_trace(&sbi->gc_lock, &gc_control->lc); 2052 2050 2053 2051 put_gc_inode(&gc_list); 2054 2052 ··· 2266 2264 __u64 old_block_count, shrunk_blocks; 2267 2265 struct cp_control cpc = { CP_RESIZE, 0, 0, 0 }; 2268 2266 struct f2fs_lock_context lc; 2267 + struct f2fs_lock_context glc; 2269 2268 unsigned int secs; 2270 2269 int err = 0; 2271 2270 __u32 rem; ··· 2310 2307 secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi)); 2311 2308 2312 2309 /* stop other GC */ 2313 - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { 2310 + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &glc)) { 2314 2311 err = -EAGAIN; 2315 2312 goto out_drop_write; 2316 2313 } ··· 2332 2329 2333 2330 out_unlock: 2334 2331 f2fs_unlock_op(sbi, &lc); 2335 - f2fs_up_write(&sbi->gc_lock); 2332 + f2fs_up_write_trace(&sbi->gc_lock, &glc); 2336 2333 out_drop_write: 2337 2334 mnt_drop_write_file(filp); 2338 2335 if (err) ··· 2349 2346 return -EROFS; 2350 2347 } 2351 2348 2352 - f2fs_down_write(&sbi->gc_lock); 2349 + f2fs_down_write_trace(&sbi->gc_lock, &glc); 2353 2350 f2fs_down_write(&sbi->cp_global_sem); 2354 2351 2355 2352 spin_lock(&sbi->stat_lock); ··· 2399 2396 } 2400 2397 out_err: 2401 2398 f2fs_up_write(&sbi->cp_global_sem); 2402 - f2fs_up_write(&sbi->gc_lock); 2399 + f2fs_up_write_trace(&sbi->gc_lock, &glc); 2403 2400 thaw_super(sbi->sb, FREEZE_HOLDER_KERNEL, NULL); 2404 2401 return err; 2405 2402 }
+6 -5
fs/f2fs/segment.c
··· 462 462 .should_migrate_blocks = false, 463 463 .err_gc_skipped = false, 464 464 .nr_free_secs = 1 }; 465 - f2fs_down_write(&sbi->gc_lock); 465 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 466 466 stat_inc_gc_call_count(sbi, FOREGROUND); 467 467 f2fs_gc(sbi, &gc_control); 468 468 } ··· 3373 3373 f2fs_unlock_op(sbi, &lc); 3374 3374 3375 3375 if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) { 3376 - f2fs_down_write(&sbi->gc_lock); 3376 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 3377 3377 err = f2fs_gc_range(sbi, 0, sbi->first_seq_zone_segno - 1, 3378 3378 true, ZONED_PIN_SEC_REQUIRED_COUNT); 3379 - f2fs_up_write(&sbi->gc_lock); 3379 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 3380 3380 3381 3381 gc_required = false; 3382 3382 if (!err) ··· 3496 3496 block_t start_block, end_block; 3497 3497 struct cp_control cpc; 3498 3498 struct discard_policy dpolicy; 3499 + struct f2fs_lock_context lc; 3499 3500 unsigned long long trimmed = 0; 3500 3501 int err = 0; 3501 3502 bool need_align = f2fs_lfs_mode(sbi) && __is_large_section(sbi); ··· 3529 3528 if (sbi->discard_blks == 0) 3530 3529 goto out; 3531 3530 3532 - f2fs_down_write(&sbi->gc_lock); 3531 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 3533 3532 stat_inc_cp_call_count(sbi, TOTAL_CALL); 3534 3533 err = f2fs_write_checkpoint(sbi, &cpc); 3535 - f2fs_up_write(&sbi->gc_lock); 3534 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 3536 3535 if (err) 3537 3536 goto out; 3538 3537
+8 -6
fs/f2fs/super.c
··· 2559 2559 { 2560 2560 unsigned int s_flags = sbi->sb->s_flags; 2561 2561 struct cp_control cpc; 2562 + struct f2fs_lock_context lc; 2562 2563 unsigned int gc_mode = sbi->gc_mode; 2563 2564 int err = 0; 2564 2565 int ret; ··· 2589 2588 .no_bg_gc = true, 2590 2589 .nr_free_secs = 1 }; 2591 2590 2592 - f2fs_down_write(&sbi->gc_lock); 2591 + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); 2593 2592 stat_inc_gc_call_count(sbi, FOREGROUND); 2594 2593 err = f2fs_gc(sbi, &gc_control); 2595 2594 if (err == -ENODATA) { ··· 2613 2612 } 2614 2613 2615 2614 skip_gc: 2616 - f2fs_down_write(&sbi->gc_lock); 2615 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 2617 2616 cpc.reason = CP_PAUSE; 2618 2617 set_sbi_flag(sbi, SBI_CP_DISABLED); 2619 2618 stat_inc_cp_call_count(sbi, TOTAL_CALL); ··· 2626 2625 spin_unlock(&sbi->stat_lock); 2627 2626 2628 2627 out_unlock: 2629 - f2fs_up_write(&sbi->gc_lock); 2628 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 2630 2629 restore_flag: 2631 2630 sbi->gc_mode = gc_mode; 2632 2631 sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ ··· 2639 2638 unsigned int nr_pages = get_pages(sbi, F2FS_DIRTY_DATA) / 16; 2640 2639 long long start, writeback, lock, sync_inode, end; 2641 2640 int ret; 2641 + struct f2fs_lock_context lc; 2642 2642 2643 2643 f2fs_info(sbi, "%s start, meta: %lld, node: %lld, data: %lld", 2644 2644 __func__, ··· 2674 2672 2675 2673 sync_inode = ktime_get(); 2676 2674 2677 - f2fs_down_write(&sbi->gc_lock); 2675 + f2fs_down_write_trace(&sbi->gc_lock, &lc); 2678 2676 f2fs_dirty_to_prefree(sbi); 2679 2677 2680 2678 clear_sbi_flag(sbi, SBI_CP_DISABLED); 2681 2679 set_sbi_flag(sbi, SBI_IS_DIRTY); 2682 - f2fs_up_write(&sbi->gc_lock); 2680 + f2fs_up_write_trace(&sbi->gc_lock, &lc); 2683 2681 2684 2682 f2fs_info(sbi, "%s sync_fs, meta: %lld, imeta: %lld, node: %lld, dents: %lld, qdata: %lld", 2685 2683 __func__, ··· 4895 4893 sbi->sb = sb; 4896 4894 4897 4895 /* initialize locks within allocated memory */ 4898 - init_f2fs_rwsem(&sbi->gc_lock); 4896 + init_f2fs_rwsem_trace(&sbi->gc_lock, sbi, LOCK_NAME_GC_LOCK); 4899 4897 mutex_init(&sbi->writepages); 4900 4898 init_f2fs_rwsem(&sbi->cp_global_sem); 4901 4899 init_f2fs_rwsem_trace(&sbi->node_write, sbi, LOCK_NAME_NODE_WRITE);
+2 -1
include/trace/events/f2fs.h
··· 188 188 __print_symbolic(lock, \ 189 189 { LOCK_NAME_CP_RWSEM, "cp_rwsem" }, \ 190 190 { LOCK_NAME_NODE_CHANGE, "node_change" }, \ 191 - { LOCK_NAME_NODE_WRITE, "node_write" }) 191 + { LOCK_NAME_NODE_WRITE, "node_write" }, \ 192 + { LOCK_NAME_GC_LOCK, "gc_lock" }) 192 193 193 194 struct f2fs_sb_info; 194 195 struct f2fs_io_info;