[PATCH v5 11/18] fs: Move call_rcu() to call_rcu_lazy() in some paths

From: Joel Fernandes (Google)
Date: Thu Sep 01 2022 - 18:19:35 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 c5dc32a59c76..28a159a7e460 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 8b56b94e2f56..530e62538d3d 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -728,7 +728,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 99c6796c9f28..36b3de669771 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_rcuhead, file_free_rcu);
+ call_rcu_lazy(&f->f_rcuhead, file_free_rcu);
}

/*
diff --git a/fs/inode.c b/fs/inode.c
index 6462276dfdf0..7d1573cf3a97 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.789.g6183377224-goog