Print this page
8040 NFSv4 client: 3-way deadlock between nfs4_bio(), nfs4_do_delegreturn(), and nfs4_flush_pages()
Reviewed by: Arne Jansen <arne@die-jansens.de>
Reviewed by: Vitaliy Gusev <gusev.vitaliy@icloud.com>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>

*** 462,500 **** mutex_exit(&mi->mi_lock); rp = VTOR4(vp); mutex_enter(&rp->r_statelock); was_serial = (rp->r_serial == curthread); ! if (rp->r_serial && !was_serial) { ! klwp_t *lwp = ttolwp(curthread); ! /* ! * If we're the recovery thread, then purge current attrs ! * and bail out to avoid potential deadlock between another ! * thread caching attrs (r_serial thread), recov thread, ! * and an async writer thread. */ - if (recov) { PURGE_ATTRCACHE4_LOCKED(rp); mutex_exit(&rp->r_statelock); return; } - if (lwp != NULL) - lwp->lwp_nostop++; - while (rp->r_serial != NULL) { - if (!cv_wait_sig(&rp->r_cv, &rp->r_statelock)) { - mutex_exit(&rp->r_statelock); - if (lwp != NULL) - lwp->lwp_nostop--; - return; - } - } - if (lwp != NULL) - lwp->lwp_nostop--; - } - /* * If there is a page flush thread, the current thread needs to * bail out, to prevent a possible deadlock between the current * thread (which might be in a start_op/end_op region), the * recovery thread, and the page flush thread. Expire the --- 462,482 ---- mutex_exit(&mi->mi_lock); rp = VTOR4(vp); mutex_enter(&rp->r_statelock); was_serial = (rp->r_serial == curthread); ! if (rp->r_serial != NULL && !was_serial) { /* ! * Purge current attrs and bail out to avoid potential deadlock ! * between another thread caching attrs (r_serial thread), this ! * thread, and a thread trying to read or write pages. */ PURGE_ATTRCACHE4_LOCKED(rp); mutex_exit(&rp->r_statelock); return; } /* * If there is a page flush thread, the current thread needs to * bail out, to prevent a possible deadlock between the current * thread (which might be in a start_op/end_op region), the * recovery thread, and the page flush thread. Expire the