Whamcloud - gitweb
LU-4540 llite: deadlock for page write 36/9036/2
authorJinshan Xiong <jinshan.xiong@intel.com>
Tue, 28 Jan 2014 22:31:36 +0000 (14:31 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 6 Feb 2014 07:05:56 +0000 (07:05 +0000)
Writing thread already locked page #1, and then wait for the
Writeback bit of page #2;

Ptlrpc thread is composing a write RPC, so it sets Writeback on
page #2 and tries to lock page #1 to make it ready.

Deadlocked.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I2da547b4c93c3464e520a1f593985adae9360bc9
Reviewed-on: http://review.whamcloud.com/9036
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: wangdi <di.wang@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/rw26.c

index 9365c74..447dc43 100644 (file)
@@ -546,7 +546,8 @@ static int ll_write_begin(struct file *file, struct address_space *mapping,
 
        /* To avoid deadlock, try to lock page first. */
        vmpage = grab_cache_page_nowait(mapping, index);
-       if (unlikely(vmpage == NULL || PageDirty(vmpage))) {
+       if (unlikely(vmpage == NULL ||
+                    PageDirty(vmpage) || PageWriteback(vmpage))) {
                struct ccc_io *cio = ccc_env_io(env);
                struct cl_page_list *plist = &cio->u.write.cui_queue;
 
@@ -555,7 +556,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping,
                 * because it holds page lock of a dirty page and request for
                 * more grants. It's okay for the dirty page to be the first
                 * one in commit page list, though. */
-               if (vmpage != NULL && PageDirty(vmpage) && plist->pl_nr > 0) {
+               if (vmpage != NULL && plist->pl_nr > 0) {
                        unlock_page(vmpage);
                        page_cache_release(vmpage);
                        vmpage = NULL;