anolis: mm: kidled: Add a new *KIDLED_YOUNG flag to replace *REFERENCED checking

ANBZ: #9779

Now kidled will skip the dentry/inode with *REFERENCED set, which means
the age of these entries is always 0. To reclaim these entries and avoid
pollution of the *REFERENCED flag, introduce a new *KIDLED_YOUNG flag for
kidled to indicate the entry has been referenced since the last kidled
scanning.

*KIDLED_YOUNG should be set at the same time as the *REFERENCED. More
specifically, it will be set in retain_dentry() and inode_lru_list_add()
for now.

Besides, kidled and coldpgs modules are modified to check *KIDELD_YOUNG
instead of *REFERENCED:

When kidled scans an entry with *KIDLED_YOUNG set, it clears this flag
and set the age of this entry to 0.

When coldpgs scans an entry with *KIDLED_YOUNG set, it just ignores this
entry.

Signed-off-by: Shawn Wang <shawnwang@linux.alibaba.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Xu Yu <xuyu@linux.alibaba.com>
Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/3720
This commit is contained in:
Shawn Wang 2024-08-16 14:24:48 +08:00 committed by 小龙
parent b1184e6c25
commit fa73812bca
4 changed files with 38 additions and 7 deletions

View File

@ -654,10 +654,18 @@ static inline bool retain_dentry(struct dentry *dentry)
/* retain; LRU fodder */
dentry->d_lockref.count--;
if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST)))
if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST))) {
d_lru_add(dentry);
else if (unlikely(!(dentry->d_flags & DCACHE_REFERENCED)))
return true;
}
if (unlikely(!(dentry->d_flags & DCACHE_REFERENCED)))
dentry->d_flags |= DCACHE_REFERENCED;
#ifdef CONFIG_KIDLED
/* Keep KIDLED_YOUNG and REFERENCED set synchronously */
if (unlikely(!(dentry->d_flags & DCACHE_KIDLED_YOUNG)))
dentry->d_flags |= DCACHE_KIDLED_YOUNG;
#endif
return true;
}
@ -1252,7 +1260,8 @@ static enum lru_status dentry_lru_cold_count(struct list_head *item,
goto out;
if (READ_ONCE(dentry->d_lockref.count) ||
(dentry->d_flags & DCACHE_REFERENCED)) {
(dentry->d_flags & DCACHE_KIDLED_YOUNG)) {
dentry->d_flags &= ~DCACHE_KIDLED_YOUNG;
if (dentry_age)
kidled_set_slab_age(dentry, 0);
goto out;
@ -1284,7 +1293,11 @@ static inline bool valid_cold_dentry_check(struct dentry *dentry)
assert_spin_locked(&dentry->d_lock);
if (dentry->d_lockref.count)
return false;
if (dentry->d_flags & DCACHE_REFERENCED)
/*
* Since RECLAIM_COLDPGS depends on KIDLED, check
* DCACHE_KIDLED_YOUNG instead of DCACHE_REFERENCED.
*/
if (dentry->d_flags & DCACHE_KIDLED_YOUNG)
return false;
return true;

View File

@ -432,8 +432,13 @@ static void inode_lru_list_add(struct inode *inode)
{
if (list_lru_add(&inode->i_sb->s_inode_lru, &inode->i_lru))
this_cpu_inc(nr_unused);
else
else {
inode->i_state |= I_REFERENCED;
#ifdef CONFIG_KIDLED
/* Keep KIDLED_YOUNG and REFERENCED set synchronously */
inode->i_state |= I_KIDLED_YOUNG;
#endif
}
}
/*
@ -830,7 +835,8 @@ static enum lru_status inode_lru_cold_count(struct list_head *item,
goto out;
if (atomic_read(&inode->i_count) ||
(inode->i_state & I_REFERENCED)) {
(inode->i_state & I_KIDLED_YOUNG)) {
inode->i_state &= ~I_KIDLED_YOUNG;
if (unlikely(inode_age))
kidled_set_slab_age(inode, 0);
goto out;
@ -870,7 +876,11 @@ static inline bool valid_cold_inode_check(struct inode *inode)
assert_spin_locked(&inode->i_lock);
if (atomic_read(&inode->i_count))
return false;
if (inode->i_state & I_REFERENCED)
/*
* Since RECLAIM_COLDPGS depends on KIDLED, check
* I_KIDLED_YOUNG instead of I_REFERENCED.
*/
if (inode->i_state & I_KIDLED_YOUNG)
return false;
if (inode_has_buffers(inode))
return false;

View File

@ -229,6 +229,10 @@ struct dentry_operations {
#define DCACHE_DENTRY_CURSOR 0x20000000
#define DCACHE_NORCU 0x40000000 /* No RCU delay for freeing */
#ifdef CONFIG_KIDLED
#define DCACHE_KIDLED_YOUNG 0x80000000 /* Mark the dentry is young for kidled */
#endif
extern seqlock_t rename_lock;
/*

View File

@ -2306,6 +2306,10 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
#define I_DONTCACHE (1 << 16)
#define I_SYNC_QUEUED (1 << 17)
#ifdef CONFIG_KIDLED
#define I_KIDLED_YOUNG (1 << 31)
#endif
#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
#define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)