[PATCH v4 04/14] fs: Move call_rcu() to call_rcu_lazy() in some paths

From: Joel Fernandes (Google)
Date: Fri Aug 19 2022 - 16:49:29 EST


This is required to prevent callbacks triggering RCU machinery too
quickly and too often, which adds more power to the system.

When testing, we found that these paths were invoked often when the
system is not doing anything (screen is ON but otherwise idle).

Signed-off-by: Joel Fernandes (Google) <joel@xxxxxxxxxxxxxxxxx>
---
fs/dcache.c | 4 ++--
fs/eventpoll.c | 2 +-
fs/file_table.c | 2 +-
fs/inode.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index 93f4f5ee07bf..7f51bac390c8 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -366,7 +366,7 @@ static void dentry_free(struct dentry *dentry)
if (unlikely(dname_external(dentry))) {
struct external_name *p = external_name(dentry);
if (likely(atomic_dec_and_test(&p->u.count))) {
- call_rcu(&dentry->d_u.d_rcu, __d_free_external);
+ call_rcu_lazy(&dentry->d_u.d_rcu, __d_free_external);
return;
}
}
@@ -374,7 +374,7 @@ static void dentry_free(struct dentry *dentry)
if (dentry->d_flags & DCACHE_NORCU)
__d_free(&dentry->d_u.d_rcu);
else
- call_rcu(&dentry->d_u.d_rcu, __d_free);
+ call_rcu_lazy(&dentry->d_u.d_rcu, __d_free);
}

/*
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 971f98af48ff..57b3f781760c 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -729,7 +729,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
* ep->mtx. The rcu read side, reverse_path_check_proc(), does not make
* use of the rbn field.
*/
- call_rcu(&epi->rcu, epi_rcu_free);
+ call_rcu_lazy(&epi->rcu, epi_rcu_free);

percpu_counter_dec(&ep->user->epoll_watches);

diff --git a/fs/file_table.c b/fs/file_table.c
index 5424e3a8df5f..417f57e9cb30 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -56,7 +56,7 @@ static inline void file_free(struct file *f)
security_file_free(f);
if (!(f->f_mode & FMODE_NOACCOUNT))
percpu_counter_dec(&nr_files);
- call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
+ call_rcu_lazy(&f->f_u.fu_rcuhead, file_free_rcu);
}

/*
diff --git a/fs/inode.c b/fs/inode.c
index bd4da9c5207e..38fe040ddbd6 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -312,7 +312,7 @@ static void destroy_inode(struct inode *inode)
return;
}
inode->free_inode = ops->free_inode;
- call_rcu(&inode->i_rcu, i_callback);
+ call_rcu_lazy(&inode->i_rcu, i_callback);
}

/**
--
2.37.2.609.g9ff673ca1a-goog