Skip to content

Commit

Permalink
ocfs2: Avoid livelock in ocfs2_readpage()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jan Kara authored and Joel Becker committed Jul 28, 2011
1 parent a11f7e6 commit c7e25e6
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit c7e25e6

Please sign in to comment.