dcache: Fix locking bugs in backported "deal with deadlock in d_walk()"
[firefly-linux-kernel-4.4.55.git] / fs / nfs / callback.c
index cff089a412c7f4bde3bd2f1d5138a4679535b772..e05c96ebb27da226ac74d80c39a6834fafa62843 100644 (file)
@@ -128,22 +128,24 @@ nfs41_callback_svc(void *vrqstp)
                if (try_to_freeze())
                        continue;
 
-               prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
+               prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_UNINTERRUPTIBLE);
                spin_lock_bh(&serv->sv_cb_lock);
                if (!list_empty(&serv->sv_cb_list)) {
                        req = list_first_entry(&serv->sv_cb_list,
                                        struct rpc_rqst, rq_bc_list);
                        list_del(&req->rq_bc_list);
                        spin_unlock_bh(&serv->sv_cb_lock);
+                       finish_wait(&serv->sv_cb_waitq, &wq);
                        dprintk("Invoking bc_svc_process()\n");
                        error = bc_svc_process(serv, req, rqstp);
                        dprintk("bc_svc_process() returned w/ error code= %d\n",
                                error);
                } else {
                        spin_unlock_bh(&serv->sv_cb_lock);
-                       schedule();
+                       /* schedule_timeout to game the hung task watchdog */
+                       schedule_timeout(60 * HZ);
+                       finish_wait(&serv->sv_cb_waitq, &wq);
                }
-               finish_wait(&serv->sv_cb_waitq, &wq);
        }
        return 0;
 }