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