Skip to content

Commit 2839653

Browse files
Jaegeuk KimJaegeuk Kim
authored andcommitted
FROMGIT: f2fs: add a sysfs entry to reclaim POSIX_FADV_NOREUSE pages
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. Bug: 390229090 Reviewed-by: Chao Yu <[email protected]> Change-Id: I58f09afe4533a1814f3646dd21f883048f891f86 Signed-off-by: Jaegeuk Kim <[email protected]> (cherry picked from commit a907f3a68ee26ba493a08a958809208d17f3347e https: //git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/ dev)
1 parent 05cd503 commit 2839653

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" <[email protected]>
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" <[email protected]>
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
@@ -4250,6 +4250,8 @@ unsigned long f2fs_shrink_count(struct shrinker *shrink,
42504250
struct shrink_control *sc);
42514251
unsigned long f2fs_shrink_scan(struct shrinker *shrink,
42524252
struct shrink_control *sc);
4253+
unsigned int f2fs_donate_files(void);
4254+
void f2fs_reclaim_caches(unsigned int reclaim_caches_kb);
42534255
void f2fs_join_shrinker(struct f2fs_sb_info *sbi);
42544256
void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
42554257

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
@@ -916,6 +916,39 @@ static struct f2fs_base_attr f2fs_base_attr_##_name = { \
916916
.show = f2fs_feature_show, \
917917
}
918918

919+
static ssize_t f2fs_tune_show(struct f2fs_base_attr *a, char *buf)
920+
{
921+
unsigned int res = 0;
922+
923+
if (!strcmp(a->attr.name, "reclaim_caches_kb"))
924+
res = f2fs_donate_files();
925+
926+
return sysfs_emit(buf, "%u\n", res);
927+
}
928+
929+
static ssize_t f2fs_tune_store(struct f2fs_base_attr *a,
930+
const char *buf, size_t count)
931+
{
932+
unsigned long t;
933+
int ret;
934+
935+
ret = kstrtoul(skip_spaces(buf), 0, &t);
936+
if (ret)
937+
return ret;
938+
939+
if (!strcmp(a->attr.name, "reclaim_caches_kb"))
940+
f2fs_reclaim_caches(t);
941+
942+
return count;
943+
}
944+
945+
#define F2FS_TUNE_RW_ATTR(_name) \
946+
static struct f2fs_base_attr f2fs_base_attr_##_name = { \
947+
.attr = {.name = __stringify(_name), .mode = 0644 }, \
948+
.show = f2fs_tune_show, \
949+
.store = f2fs_tune_store, \
950+
}
951+
919952
static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
920953
struct f2fs_sb_info *sbi, char *buf)
921954
{
@@ -1368,6 +1401,14 @@ static struct attribute *f2fs_sb_feat_attrs[] = {
13681401
};
13691402
ATTRIBUTE_GROUPS(f2fs_sb_feat);
13701403

1404+
F2FS_TUNE_RW_ATTR(reclaim_caches_kb);
1405+
1406+
static struct attribute *f2fs_tune_attrs[] = {
1407+
BASE_ATTR_LIST(reclaim_caches_kb),
1408+
NULL,
1409+
};
1410+
ATTRIBUTE_GROUPS(f2fs_tune);
1411+
13711412
static const struct sysfs_ops f2fs_attr_ops = {
13721413
.show = f2fs_attr_show,
13731414
.store = f2fs_attr_store,
@@ -1401,6 +1442,20 @@ static struct kobject f2fs_feat = {
14011442
.kset = &f2fs_kset,
14021443
};
14031444

1445+
static const struct sysfs_ops f2fs_tune_attr_ops = {
1446+
.show = f2fs_base_attr_show,
1447+
.store = f2fs_base_attr_store,
1448+
};
1449+
1450+
static const struct kobj_type f2fs_tune_ktype = {
1451+
.default_groups = f2fs_tune_groups,
1452+
.sysfs_ops = &f2fs_tune_attr_ops,
1453+
};
1454+
1455+
static struct kobject f2fs_tune = {
1456+
.kset = &f2fs_kset,
1457+
};
1458+
14041459
static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
14051460
struct attribute *attr, char *buf)
14061461
{
@@ -1637,21 +1692,29 @@ int __init f2fs_init_sysfs(void)
16371692
if (ret)
16381693
goto put_kobject;
16391694

1695+
ret = kobject_init_and_add(&f2fs_tune, &f2fs_tune_ktype,
1696+
NULL, "tuning");
1697+
if (ret)
1698+
goto put_kobject;
1699+
16401700
f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
16411701
if (!f2fs_proc_root) {
16421702
ret = -ENOMEM;
16431703
goto put_kobject;
16441704
}
16451705

16461706
return 0;
1707+
16471708
put_kobject:
1709+
kobject_put(&f2fs_tune);
16481710
kobject_put(&f2fs_feat);
16491711
kset_unregister(&f2fs_kset);
16501712
return ret;
16511713
}
16521714

16531715
void f2fs_exit_sysfs(void)
16541716
{
1717+
kobject_put(&f2fs_tune);
16551718
kobject_put(&f2fs_feat);
16561719
kset_unregister(&f2fs_kset);
16571720
remove_proc_entry("fs/f2fs", NULL);

0 commit comments

Comments
 (0)