ocfs2: Avoid livelock in ocfs2_readpage()
When someone writes to an inode, readers accessing the same inode via ocfs2_readpage() just busyloop trying to get ip_alloc_sem because do_generic_file_read() looks up the page again and retries ->readpage() when previous attempt failed with AOP_TRUNCATED_PAGE. When there are enough readers, they can occupy all CPUs and in non-preempt kernel the system is deadlocked because writer holding ip_alloc_sem is never run to release the semaphore. Fix the problem by making reader block on ip_alloc_sem to break the busy loop. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Joel Becker <jlbec@evilplan.org>
This commit is contained in:
parent
a11f7e63c5
commit
c7e25e6e0b
|
@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
|
|||
}
|
||||
|
||||
if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
|
||||
/*
|
||||
* Unlock the page and cycle ip_alloc_sem so that we don't
|
||||
* busyloop waiting for ip_alloc_sem to unlock
|
||||
*/
|
||||
ret = AOP_TRUNCATED_PAGE;
|
||||
unlock_page(page);
|
||||
unlock = 0;
|
||||
down_read(&oi->ip_alloc_sem);
|
||||
up_read(&oi->ip_alloc_sem);
|
||||
goto out_inode_unlock;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue