8064 need a static DTrace probe in VN_HOLD

illumos/illumos-gate@ade42b557a
ade42b557a

https://www.illumos.org/issues/8064
  It's currently nearly impossible to trace what process places a hold on
  a vnode, as the only ways holds are place is via the `VN_HOLD()` and
  `VN_HOLD_CALLER()` macros, which inline the bumping of `v_count`. Adding
  static DTrace probes to these macros would enable tracing of where
  specific vnode references come from.
  For completeness and symmetry, a similar static probe should be added to
  `vn_rele()` and `vn_rele_dnlc()`.

Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Prashanth Sreenivasa <pks@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Author: Sebastien Roy <seb@delphix.com>
This commit is contained in:
avg 2017-05-26 11:39:34 +00:00
parent b339a8eba3
commit dd7589a8b7
6 changed files with 54 additions and 20 deletions

View File

@ -23,8 +23,9 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 2017 by Delphix. All rights reserved.
*/
#include <sys/types.h>
#include <sys/cmn_err.h>
@ -671,7 +672,7 @@ found:
}
vn_free(vp);
} else {
vp->v_count--;
VN_RELE_LOCKED(vp);
data = NULL;
mutex_exit(&vp->v_lock);
if (vp->v_flag & V_XATTRDIR) {

View File

@ -22,6 +22,8 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@ -836,7 +838,7 @@ vn_rele(vnode_t *vp)
VOP_INACTIVE(vp, CRED(), NULL);
return;
}
vp->v_count--;
VN_RELE_LOCKED(vp);
mutex_exit(&vp->v_lock);
}
@ -857,15 +859,15 @@ vn_rele_dnlc(vnode_t *vp)
VOP_INACTIVE(vp, CRED(), NULL);
return;
}
vp->v_count--;
VN_RELE_LOCKED(vp);
}
mutex_exit(&vp->v_lock);
}
/*
* Like vn_rele() except that it clears v_stream under v_lock.
* This is used by sockfs when it dismantels the association between
* the sockfs node and the vnode in the underlaying file system.
* This is used by sockfs when it dismantles the association between
* the sockfs node and the vnode in the underlying file system.
* v_lock has to be held to prevent a thread coming through the lookupname
* path from accessing a stream head that is going away.
*/
@ -880,7 +882,7 @@ vn_rele_stream(vnode_t *vp)
VOP_INACTIVE(vp, CRED(), NULL);
return;
}
vp->v_count--;
VN_RELE_LOCKED(vp);
mutex_exit(&vp->v_lock);
}
@ -911,7 +913,7 @@ vn_rele_async(vnode_t *vp, taskq_t *taskq)
vp, TQ_SLEEP) != NULL);
return;
}
vp->v_count--;
VN_RELE_LOCKED(vp);
mutex_exit(&vp->v_lock);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
*/
@ -1210,7 +1210,7 @@ zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
mutex_enter(&vp->v_lock);
if (vp->v_count > 1) {
vp->v_count--;
VN_RELE_LOCKED(vp);
mutex_exit(&vp->v_lock);
mutex_exit(&sdp->sd_lock);
VN_RELE(dvp);

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2015 Joyent, Inc.
* Copyright 2017 Nexenta Systems, Inc.
@ -1819,7 +1819,7 @@ top:
ASSERT0(error);
}
mutex_enter(&vp->v_lock);
vp->v_count--;
VN_RELE_LOCKED(vp);
ASSERT0(vp->v_count);
mutex_exit(&vp->v_lock);
mutex_exit(&zp->z_lock);
@ -4411,7 +4411,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
mutex_enter(&zp->z_lock);
mutex_enter(&vp->v_lock);
ASSERT(vp->v_count == 1);
vp->v_count = 0;
VN_RELE_LOCKED(vp);
mutex_exit(&vp->v_lock);
mutex_exit(&zp->z_lock);
rw_exit(&zfsvfs->z_teardown_inactive_lock);

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
@ -1293,7 +1293,7 @@ zfs_zinactive(znode_t *zp)
mutex_enter(&zp->z_lock);
mutex_enter(&vp->v_lock);
vp->v_count--;
VN_RELE_LOCKED(vp);
if (vp->v_count > 0 || vn_has_cached_data(vp)) {
/*
* If the hold count is greater than zero, somebody has

View File

@ -22,6 +22,7 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@ -53,6 +54,7 @@
#include <sys/list.h>
#ifdef _KERNEL
#include <sys/buf.h>
#include <sys/sdt.h>
#endif /* _KERNEL */
#ifdef __cplusplus
@ -1342,10 +1344,32 @@ int vn_vmpss_usepageio(vnode_t *);
*/
extern uint_t pvn_vmodsort_supported;
#define VN_HOLD(vp) { \
mutex_enter(&(vp)->v_lock); \
(vp)->v_count++; \
mutex_exit(&(vp)->v_lock); \
/*
* All changes to v_count should be done through VN_HOLD() or VN_RELE(), or
* one of their variants. This makes it possible to ensure proper locking,
* and to guarantee that all modifications are accompanied by a firing of
* the vn-hold or vn-rele SDT DTrace probe.
*
* Example DTrace command for tracing vnode references using these probes:
*
* dtrace -q -n 'sdt:::vn-hold,sdt:::vn-rele
* {
* this->vp = (vnode_t *)arg0;
* printf("%s %s(%p[%s]) %d\n", execname, probename, this->vp,
* this->vp->v_path == NULL ? "NULL" : stringof(this->vp->v_path),
* this->vp->v_count)
* }'
*/
#define VN_HOLD_LOCKED(vp) { \
ASSERT(mutex_owned(&(vp)->v_lock)); \
(vp)->v_count++; \
DTRACE_PROBE1(vn__hold, vnode_t *, vp); \
}
#define VN_HOLD(vp) { \
mutex_enter(&(vp)->v_lock); \
VN_HOLD_LOCKED(vp); \
mutex_exit(&(vp)->v_lock); \
}
#define VN_RELE(vp) { \
@ -1356,6 +1380,13 @@ extern uint_t pvn_vmodsort_supported;
vn_rele_async(vp, taskq); \
}
#define VN_RELE_LOCKED(vp) { \
ASSERT(mutex_owned(&(vp)->v_lock)); \
ASSERT((vp)->v_count >= 1); \
(vp)->v_count--; \
DTRACE_PROBE1(vn__rele, vnode_t *, vp); \
}
#define VN_SET_VFS_TYPE_DEV(vp, vfsp, type, dev) { \
(vp)->v_vfsp = (vfsp); \
(vp)->v_type = (type); \