]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/commit
MFC: r227059
authorrmacklem <rmacklem@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Thu, 17 Nov 2011 16:38:22 +0000 (16:38 +0000)
committerrmacklem <rmacklem@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Thu, 17 Nov 2011 16:38:22 +0000 (16:38 +0000)
commit1fc21665b85bd6ea9fa192837602c83a61a47191
tree98423cc9e01e9b38bed2368ed3561d6831b1d0ec
parent9d03d9b77c49fb492399b587cc44b5b3db56d459
MFC: r227059
Both a crash reported on freebsd-current on Oct. 18 under the
subject heading "mtx_lock() of destroyed mutex on NFS" and
PR# 156168 appear to be caused by clnt_dg_destroy() closing
down the socket prematurely. When to close down the socket
is controlled by a reference count (cs_refs), but clnt_dg_create()
checks for sb_upcall being non-NULL to decide if a new socket
is needed. I believe the crashes were caused by the following race:
  clnt_dg_destroy() finds cs_refs == 0 and decides to delete socket
  clnt_dg_destroy() then loses race with clnt_dg_create() for
    acquisition of the SOCKBUF_LOCK()
  clnt_dg_create() finds sb_upcall != NULL and increments cs_refs to 1
  clnt_dg_destroy() then acquires SOCKBUF_LOCK(), sets sb_upcall to
    NULL and destroys socket

This patch fixes the above race by changing clnt_dg_destroy() so
that it acquires SOCKBUF_LOCK() before testing cs_refs.

Tested by: bz
Reviewed by: dfr
Approved by: re (kib)

git-svn-id: svn://svn.freebsd.org/base/releng/9.0@227631 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/rpc/clnt_dg.c