mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
vfs: drop one lock trip in evict()
Most commonly neither I_LRU_ISOLATING nor I_SYNC are set, but the stock kernel takes a back-to-back relock trip to check for them. It probably can be avoided altogether, but for now massage things back to just one lock acquire. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://lore.kernel.org/r/20240813143626.1573445-1-mjguzik@gmail.com Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
3a987b88a4
commit
57510c58b5
@ -1510,13 +1510,12 @@ static int write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
* Wait for writeback on an inode to complete. Called with i_lock held.
|
||||
* Caller must make sure inode cannot go away when we drop i_lock.
|
||||
*/
|
||||
static void __inode_wait_for_writeback(struct inode *inode)
|
||||
__releases(inode->i_lock)
|
||||
__acquires(inode->i_lock)
|
||||
void inode_wait_for_writeback(struct inode *inode)
|
||||
{
|
||||
DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
|
||||
wait_queue_head_t *wqh;
|
||||
|
||||
lockdep_assert_held(&inode->i_lock);
|
||||
wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
|
||||
while (inode->i_state & I_SYNC) {
|
||||
spin_unlock(&inode->i_lock);
|
||||
@ -1526,16 +1525,6 @@ static void __inode_wait_for_writeback(struct inode *inode)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for writeback on an inode to complete. Caller must have inode pinned.
|
||||
*/
|
||||
void inode_wait_for_writeback(struct inode *inode)
|
||||
{
|
||||
spin_lock(&inode->i_lock);
|
||||
__inode_wait_for_writeback(inode);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sleep until I_SYNC is cleared. This function must be called with i_lock
|
||||
* held and drops it. It is aimed for callers not holding any inode reference
|
||||
@ -1757,7 +1746,7 @@ static int writeback_single_inode(struct inode *inode,
|
||||
*/
|
||||
if (wbc->sync_mode != WB_SYNC_ALL)
|
||||
goto out;
|
||||
__inode_wait_for_writeback(inode);
|
||||
inode_wait_for_writeback(inode);
|
||||
}
|
||||
WARN_ON(inode->i_state & I_SYNC);
|
||||
/*
|
||||
|
@ -507,7 +507,7 @@ static void inode_unpin_lru_isolating(struct inode *inode)
|
||||
|
||||
static void inode_wait_for_lru_isolating(struct inode *inode)
|
||||
{
|
||||
spin_lock(&inode->i_lock);
|
||||
lockdep_assert_held(&inode->i_lock);
|
||||
if (inode->i_state & I_LRU_ISOLATING) {
|
||||
DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LRU_ISOLATING);
|
||||
wait_queue_head_t *wqh;
|
||||
@ -518,7 +518,6 @@ static void inode_wait_for_lru_isolating(struct inode *inode)
|
||||
spin_lock(&inode->i_lock);
|
||||
WARN_ON(inode->i_state & I_LRU_ISOLATING);
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -690,6 +689,7 @@ static void evict(struct inode *inode)
|
||||
|
||||
inode_sb_list_del(inode);
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
inode_wait_for_lru_isolating(inode);
|
||||
|
||||
/*
|
||||
@ -699,6 +699,7 @@ static void evict(struct inode *inode)
|
||||
* the inode. We just have to wait for running writeback to finish.
|
||||
*/
|
||||
inode_wait_for_writeback(inode);
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
||||
if (op->evict_inode) {
|
||||
op->evict_inode(inode);
|
||||
|
Loading…
Reference in New Issue
Block a user