Skip to content

Commit 9933e05

Browse files
Jaegeuk Kimgregkh
authored andcommitted
f2fs: add a sysfs entry to reclaim POSIX_FADV_NOREUSE pages
[ Upstream commit a907f3a ] 1. fadvise(fd1, POSIX_FADV_NOREUSE, {0,3}); 2. fadvise(fd2, POSIX_FADV_NOREUSE, {1,2}); 3. fadvise(fd3, POSIX_FADV_NOREUSE, {3,1}); 4. echo 1024 > /sys/fs/f2fs/tuning/reclaim_caches_kb This gives a way to reclaim file-backed pages by iterating all f2fs mounts until reclaiming 1MB page cache ranges, registered by #1, #2, and #3. 5. cat /sys/fs/f2fs/tuning/reclaim_caches_kb -> gives total number of registered file ranges. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Stable-dep-of: e462fc4 ("f2fs: maintain one time GC mode is enabled during whole zoned GC cycle") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 58eceda commit 9933e05

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

Documentation/ABI/testing/sysfs-fs-f2fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,3 +828,10 @@ Date: November 2024
828828
Contact: "Chao Yu" <chao@kernel.org>
829829
Description: It controls max read extent count for per-inode, the value of threshold
830830
is 10240 by default.
831+
832+
What: /sys/fs/f2fs/tuning/reclaim_caches_kb
833+
Date: February 2025
834+
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
835+
Description: It reclaims the given KBs of file-backed pages registered by
836+
ioctl(F2FS_IOC_DONATE_RANGE).
837+
For example, writing N tries to drop N KBs spaces in LRU.

fs/f2fs/f2fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,6 +4271,8 @@ unsigned long f2fs_shrink_count(struct shrinker *shrink,
42714271
struct shrink_control *sc);
42724272
unsigned long f2fs_shrink_scan(struct shrinker *shrink,
42734273
struct shrink_control *sc);
4274+
unsigned int f2fs_donate_files(void);
4275+
void f2fs_reclaim_caches(unsigned int reclaim_caches_kb);
42744276
void f2fs_join_shrinker(struct f2fs_sb_info *sbi);
42754277
void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
42764278

fs/f2fs/shrinker.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,96 @@ unsigned long f2fs_shrink_scan(struct shrinker *shrink,
130130
return freed;
131131
}
132132

133+
unsigned int f2fs_donate_files(void)
134+
{
135+
struct f2fs_sb_info *sbi;
136+
struct list_head *p;
137+
unsigned int donate_files = 0;
138+
139+
spin_lock(&f2fs_list_lock);
140+
p = f2fs_list.next;
141+
while (p != &f2fs_list) {
142+
sbi = list_entry(p, struct f2fs_sb_info, s_list);
143+
144+
/* stop f2fs_put_super */
145+
if (!mutex_trylock(&sbi->umount_mutex)) {
146+
p = p->next;
147+
continue;
148+
}
149+
spin_unlock(&f2fs_list_lock);
150+
151+
donate_files += sbi->donate_files;
152+
153+
spin_lock(&f2fs_list_lock);
154+
p = p->next;
155+
mutex_unlock(&sbi->umount_mutex);
156+
}
157+
spin_unlock(&f2fs_list_lock);
158+
159+
return donate_files;
160+
}
161+
162+
static unsigned int do_reclaim_caches(struct f2fs_sb_info *sbi,
163+
unsigned int reclaim_caches_kb)
164+
{
165+
struct inode *inode;
166+
struct f2fs_inode_info *fi;
167+
unsigned int nfiles = sbi->donate_files;
168+
pgoff_t npages = reclaim_caches_kb >> (PAGE_SHIFT - 10);
169+
170+
while (npages && nfiles--) {
171+
pgoff_t len;
172+
173+
spin_lock(&sbi->inode_lock[DONATE_INODE]);
174+
if (list_empty(&sbi->inode_list[DONATE_INODE])) {
175+
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
176+
break;
177+
}
178+
fi = list_first_entry(&sbi->inode_list[DONATE_INODE],
179+
struct f2fs_inode_info, gdonate_list);
180+
list_move_tail(&fi->gdonate_list, &sbi->inode_list[DONATE_INODE]);
181+
inode = igrab(&fi->vfs_inode);
182+
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
183+
184+
if (!inode)
185+
continue;
186+
187+
len = fi->donate_end - fi->donate_start + 1;
188+
npages = npages < len ? 0 : npages - len;
189+
invalidate_inode_pages2_range(inode->i_mapping,
190+
fi->donate_start, fi->donate_end);
191+
iput(inode);
192+
cond_resched();
193+
}
194+
return npages << (PAGE_SHIFT - 10);
195+
}
196+
197+
void f2fs_reclaim_caches(unsigned int reclaim_caches_kb)
198+
{
199+
struct f2fs_sb_info *sbi;
200+
struct list_head *p;
201+
202+
spin_lock(&f2fs_list_lock);
203+
p = f2fs_list.next;
204+
while (p != &f2fs_list && reclaim_caches_kb) {
205+
sbi = list_entry(p, struct f2fs_sb_info, s_list);
206+
207+
/* stop f2fs_put_super */
208+
if (!mutex_trylock(&sbi->umount_mutex)) {
209+
p = p->next;
210+
continue;
211+
}
212+
spin_unlock(&f2fs_list_lock);
213+
214+
reclaim_caches_kb = do_reclaim_caches(sbi, reclaim_caches_kb);
215+
216+
spin_lock(&f2fs_list_lock);
217+
p = p->next;
218+
mutex_unlock(&sbi->umount_mutex);
219+
}
220+
spin_unlock(&f2fs_list_lock);
221+
}
222+
133223
void f2fs_join_shrinker(struct f2fs_sb_info *sbi)
134224
{
135225
spin_lock(&f2fs_list_lock);

fs/f2fs/sysfs.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,39 @@ static struct f2fs_base_attr f2fs_base_attr_##_name = { \
939939
.show = f2fs_feature_show, \
940940
}
941941

942+
static ssize_t f2fs_tune_show(struct f2fs_base_attr *a, char *buf)
943+
{
944+
unsigned int res = 0;
945+
946+
if (!strcmp(a->attr.name, "reclaim_caches_kb"))
947+
res = f2fs_donate_files();
948+
949+
return sysfs_emit(buf, "%u\n", res);
950+
}
951+
952+
static ssize_t f2fs_tune_store(struct f2fs_base_attr *a,
953+
const char *buf, size_t count)
954+
{
955+
unsigned long t;
956+
int ret;
957+
958+
ret = kstrtoul(skip_spaces(buf), 0, &t);
959+
if (ret)
960+
return ret;
961+
962+
if (!strcmp(a->attr.name, "reclaim_caches_kb"))
963+
f2fs_reclaim_caches(t);
964+
965+
return count;
966+
}
967+
968+
#define F2FS_TUNE_RW_ATTR(_name) \
969+
static struct f2fs_base_attr f2fs_base_attr_##_name = { \
970+
.attr = {.name = __stringify(_name), .mode = 0644 }, \
971+
.show = f2fs_tune_show, \
972+
.store = f2fs_tune_store, \
973+
}
974+
942975
static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
943976
struct f2fs_sb_info *sbi, char *buf)
944977
{
@@ -1389,6 +1422,14 @@ static struct attribute *f2fs_sb_feat_attrs[] = {
13891422
};
13901423
ATTRIBUTE_GROUPS(f2fs_sb_feat);
13911424

1425+
F2FS_TUNE_RW_ATTR(reclaim_caches_kb);
1426+
1427+
static struct attribute *f2fs_tune_attrs[] = {
1428+
BASE_ATTR_LIST(reclaim_caches_kb),
1429+
NULL,
1430+
};
1431+
ATTRIBUTE_GROUPS(f2fs_tune);
1432+
13921433
static const struct sysfs_ops f2fs_attr_ops = {
13931434
.show = f2fs_attr_show,
13941435
.store = f2fs_attr_store,
@@ -1422,6 +1463,20 @@ static struct kobject f2fs_feat = {
14221463
.kset = &f2fs_kset,
14231464
};
14241465

1466+
static const struct sysfs_ops f2fs_tune_attr_ops = {
1467+
.show = f2fs_base_attr_show,
1468+
.store = f2fs_base_attr_store,
1469+
};
1470+
1471+
static const struct kobj_type f2fs_tune_ktype = {
1472+
.default_groups = f2fs_tune_groups,
1473+
.sysfs_ops = &f2fs_tune_attr_ops,
1474+
};
1475+
1476+
static struct kobject f2fs_tune = {
1477+
.kset = &f2fs_kset,
1478+
};
1479+
14251480
static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
14261481
struct attribute *attr, char *buf)
14271482
{
@@ -1660,21 +1715,29 @@ int __init f2fs_init_sysfs(void)
16601715
if (ret)
16611716
goto put_kobject;
16621717

1718+
ret = kobject_init_and_add(&f2fs_tune, &f2fs_tune_ktype,
1719+
NULL, "tuning");
1720+
if (ret)
1721+
goto put_kobject;
1722+
16631723
f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
16641724
if (!f2fs_proc_root) {
16651725
ret = -ENOMEM;
16661726
goto put_kobject;
16671727
}
16681728

16691729
return 0;
1730+
16701731
put_kobject:
1732+
kobject_put(&f2fs_tune);
16711733
kobject_put(&f2fs_feat);
16721734
kset_unregister(&f2fs_kset);
16731735
return ret;
16741736
}
16751737

16761738
void f2fs_exit_sysfs(void)
16771739
{
1740+
kobject_put(&f2fs_tune);
16781741
kobject_put(&f2fs_feat);
16791742
kset_unregister(&f2fs_kset);
16801743
remove_proc_entry("fs/f2fs", NULL);

0 commit comments

Comments
 (0)