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:
parent
b339a8eba3
commit
dd7589a8b7
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user