diff options
author | udpa <none@none> | 2008-01-28 11:18:07 -0800 |
---|---|---|
committer | udpa <none@none> | 2008-01-28 11:18:07 -0800 |
commit | 6ede7bac3e9a6dfa53f3115dca1cf401bfa21a36 (patch) | |
tree | 0f81b0381c4626fd44b9e2c65904febbb5051563 /usr/src/uts/common/inet/tcp/tcp_fusion.c | |
parent | 69c33a7b46881d33b972b85db0dca57ce983f016 (diff) | |
download | illumos-joyent-6ede7bac3e9a6dfa53f3115dca1cf401bfa21a36.tar.gz |
6602033 "mutex_exit: not owner" panic occurs in ip:tcp_fuse_rrw().
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp_fusion.c')
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_fusion.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp_fusion.c b/usr/src/uts/common/inet/tcp/tcp_fusion.c index c22868be52..2503a13e29 100644 --- a/usr/src/uts/common/inet/tcp/tcp_fusion.c +++ b/usr/src/uts/common/inet/tcp/tcp_fusion.c @@ -948,12 +948,26 @@ plugged: mutex_exit(&tcp->tcp_non_sq_lock); mutex_enter(&peer_tcp->tcp_non_sq_lock); mutex_enter(&tcp->tcp_non_sq_lock); - CONN_DEC_REF(peer_tcp->tcp_connp); - /* This might have changed in the interim */ + /* + * This might have changed in the interim + * Once read-side tcp_non_sq_lock is dropped above + * anything can happen, we need to check all + * known conditions again once we reaquire + * read-side tcp_non_sq_lock. + */ if (tcp->tcp_fuse_syncstr_plugged) { mutex_exit(&peer_tcp->tcp_non_sq_lock); + CONN_DEC_REF(peer_tcp->tcp_connp); goto plugged; } + if (!tcp->tcp_direct_sockfs || tcp->tcp_fuse_syncstr_stopped) { + mutex_exit(&tcp->tcp_non_sq_lock); + mutex_exit(&peer_tcp->tcp_non_sq_lock); + CONN_DEC_REF(peer_tcp->tcp_connp); + TCP_STAT(tcps, tcp_fusion_rrw_busy); + return (EBUSY); + } + CONN_DEC_REF(peer_tcp->tcp_connp); } else { mutex_enter(&peer_tcp->tcp_non_sq_lock); } |