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: sysfs: introduce inject_lock_timeout

This patch adds a new sysfs node in /sys/fs/f2fs/<disk>/inject_lock_timeout,
it relies on CONFIG_F2FS_FAULT_INJECTION kernel config.

It can be used to simulate different type of timeout in lock duration.

========== ===============================
Flag_Value Flag_Description
========== ===============================
0x00000000 No timeout (default)
0x00000001 Simulate running time
0x00000002 Simulate IO type sleep time
0x00000003 Simulate Non-IO type sleep time
0x00000004 Simulate runnable 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
d36de29f c56254e2

+93 -5
+14
Documentation/ABI/testing/sysfs-fs-f2fs
··· 948 948 elapsed time exceeds this threshold, f2fs will print tracepoint to dump information 949 949 of related context. This sysfs entry can be used to control the value of threshold, 950 950 by default, the value is 500 ms. 951 + 952 + What: /sys/fs/f2fs/<disk>/inject_timeout_type 953 + Date: December 2025 954 + Contact: "Chao Yu" <chao@kernel.org> 955 + Description: This sysfs entry can be used to change type of injected timeout: 956 + ========== =============================== 957 + Flag_Value Flag_Description 958 + ========== =============================== 959 + 0x00000000 No timeout (default) 960 + 0x00000001 Simulate running time 961 + 0x00000002 Simulate IO type sleep time 962 + 0x00000003 Simulate Non-IO type sleep time 963 + 0x00000004 Simulate runnable time 964 + ========== ===============================
+1 -1
fs/f2fs/checkpoint.c
··· 64 64 return; 65 65 66 66 if (time_to_inject(sem->sbi, FAULT_LOCK_TIMEOUT)) 67 - f2fs_io_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT); 67 + f2fs_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT, true); 68 68 69 69 get_lock_elapsed_time(&tts); 70 70
+19 -3
fs/f2fs/f2fs.h
··· 73 73 enum fault_option { 74 74 FAULT_RATE = 1, /* only update fault rate */ 75 75 FAULT_TYPE = 2, /* only update fault type */ 76 - FAULT_ALL = 4, /* reset all fault injection options/stats */ 76 + FAULT_TIMEOUT = 4, /* only update fault timeout type */ 77 + FAULT_ALL = 8, /* reset all fault injection options/stats */ 77 78 }; 78 79 79 80 #ifdef CONFIG_F2FS_FAULT_INJECTION ··· 84 83 unsigned int inject_type; 85 84 /* Used to account total count of injection for each type */ 86 85 unsigned int inject_count[FAULT_MAX]; 86 + unsigned int inject_lock_timeout; /* inject lock timeout */ 87 87 }; 88 88 89 89 extern const char *f2fs_fault_name[FAULT_MAX]; ··· 184 182 LOCK_NAME_GC_LOCK, 185 183 LOCK_NAME_CP_GLOBAL, 186 184 LOCK_NAME_IO_RWSEM, 185 + }; 186 + 187 + enum f2fs_timeout_type { 188 + TIMEOUT_TYPE_NONE, 189 + TIMEOUT_TYPE_RUNNING, 190 + TIMEOUT_TYPE_IO_SLEEP, 191 + TIMEOUT_TYPE_NONIO_SLEEP, 192 + TIMEOUT_TYPE_RUNNABLE, 193 + TIMEOUT_TYPE_MAX, 187 194 }; 188 195 189 196 /* ··· 4938 4927 #ifdef CONFIG_F2FS_FAULT_INJECTION 4939 4928 extern int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate, 4940 4929 unsigned long type, enum fault_option fo); 4930 + extern void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi); 4941 4931 #else 4942 4932 static inline int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, 4943 4933 unsigned long rate, unsigned long type, 4944 4934 enum fault_option fo) 4945 4935 { 4946 4936 return 0; 4937 + } 4938 + static inline void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi) 4939 + { 4940 + return; 4947 4941 } 4948 4942 #endif 4949 4943 ··· 5000 4984 #define f2fs_schedule_timeout(timeout) \ 5001 4985 __f2fs_schedule_timeout(timeout, false) 5002 4986 5003 - static inline void f2fs_io_schedule_timeout_killable(long timeout) 4987 + static inline void f2fs_schedule_timeout_killable(long timeout, bool io) 5004 4988 { 5005 4989 unsigned long last_time = jiffies + timeout; 5006 4990 5007 4991 while (jiffies < last_time) { 5008 4992 if (fatal_signal_pending(current)) 5009 4993 return; 5010 - __f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT, true); 4994 + __f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT, io); 5011 4995 } 5012 4996 } 5013 4997
+1 -1
fs/f2fs/segment.c
··· 372 372 373 373 out: 374 374 if (time_to_inject(sbi, FAULT_ATOMIC_TIMEOUT)) 375 - f2fs_io_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT); 375 + f2fs_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT, true); 376 376 377 377 if (ret) { 378 378 sbi->revoked_atomic_block += fi->atomic_write_cnt;
+49
fs/f2fs/super.c
··· 97 97 f2fs_info(sbi, "build fault injection type: 0x%lx", type); 98 98 } 99 99 100 + if (fo & FAULT_TIMEOUT) { 101 + if (type >= TIMEOUT_TYPE_MAX) 102 + return -EINVAL; 103 + ffi->inject_lock_timeout = (unsigned int)type; 104 + f2fs_info(sbi, "build fault timeout injection type: 0x%lx", type); 105 + } 106 + 100 107 return 0; 108 + } 109 + 110 + static void inject_timeout(struct f2fs_sb_info *sbi) 111 + { 112 + struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info; 113 + enum f2fs_timeout_type type = ffi->inject_lock_timeout; 114 + unsigned long start_time = jiffies; 115 + unsigned long timeout = HZ; 116 + 117 + switch (type) { 118 + case TIMEOUT_TYPE_RUNNING: 119 + while (!time_after(jiffies, start_time + timeout)) { 120 + if (fatal_signal_pending(current)) 121 + return; 122 + ; 123 + } 124 + break; 125 + case TIMEOUT_TYPE_IO_SLEEP: 126 + f2fs_schedule_timeout_killable(timeout, true); 127 + break; 128 + case TIMEOUT_TYPE_NONIO_SLEEP: 129 + f2fs_schedule_timeout_killable(timeout, false); 130 + break; 131 + case TIMEOUT_TYPE_RUNNABLE: 132 + while (!time_after(jiffies, start_time + timeout)) { 133 + if (fatal_signal_pending(current)) 134 + return; 135 + schedule(); 136 + } 137 + break; 138 + default: 139 + return; 140 + } 141 + } 142 + 143 + void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi) 144 + { 145 + struct f2fs_lock_context lc; 146 + 147 + f2fs_lock_op(sbi, &lc); 148 + inject_timeout(sbi); 149 + f2fs_unlock_op(sbi, &lc); 101 150 } 102 151 #endif 103 152
+9
fs/f2fs/sysfs.c
··· 35 35 #ifdef CONFIG_F2FS_FAULT_INJECTION 36 36 FAULT_INFO_RATE, /* struct f2fs_fault_info */ 37 37 FAULT_INFO_TYPE, /* struct f2fs_fault_info */ 38 + FAULT_INFO_TIMEOUT, /* struct f2fs_fault_info */ 38 39 #endif 39 40 RESERVED_BLOCKS, /* struct f2fs_sb_info */ 40 41 CPRC_INFO, /* struct ckpt_req_control */ ··· 528 527 if (a->struct_type == FAULT_INFO_RATE) { 529 528 if (f2fs_build_fault_attr(sbi, t, 0, FAULT_RATE)) 530 529 return -EINVAL; 530 + return count; 531 + } 532 + if (a->struct_type == FAULT_INFO_TIMEOUT) { 533 + if (f2fs_build_fault_attr(sbi, 0, t, FAULT_TIMEOUT)) 534 + return -EINVAL; 535 + f2fs_simulate_lock_timeout(sbi); 531 536 return count; 532 537 } 533 538 #endif ··· 1240 1233 #ifdef CONFIG_F2FS_FAULT_INJECTION 1241 1234 FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_RATE, inject_rate); 1242 1235 FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TYPE, inject_type); 1236 + FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TIMEOUT, inject_lock_timeout); 1243 1237 #endif 1244 1238 1245 1239 /* RESERVED_BLOCKS ATTR */ ··· 1370 1362 #ifdef CONFIG_F2FS_FAULT_INJECTION 1371 1363 ATTR_LIST(inject_rate), 1372 1364 ATTR_LIST(inject_type), 1365 + ATTR_LIST(inject_lock_timeout), 1373 1366 #endif 1374 1367 ATTR_LIST(data_io_flag), 1375 1368 ATTR_LIST(node_io_flag),