提交 368e2d09 编写于 作者: D Dave Chinner

xfs: rework the perag trace points to be perag centric

So that they all output the same information in the traces to make
debugging refcount issues easier.

This means that all the lookup/drop functions no longer need to use
the full memory barrier atomic operations (atomic*_return()) so
will have less overhead when tracing is off. The set/clear tag
tracepoints no longer abuse the reference count to pass the tag -
the tag being cleared is obvious from the _RET_IP_ that is recorded
in the trace point.
Signed-off-by: NDave Chinner <dchinner@redhat.com>
Reviewed-by: NAllison Henderson <allison.henderson@oracle.com>
Reviewed-by: NDarrick J. Wong <djwong@kernel.org>
上级 c4d5660a
...@@ -44,16 +44,15 @@ xfs_perag_get( ...@@ -44,16 +44,15 @@ xfs_perag_get(
xfs_agnumber_t agno) xfs_agnumber_t agno)
{ {
struct xfs_perag *pag; struct xfs_perag *pag;
int ref = 0;
rcu_read_lock(); rcu_read_lock();
pag = radix_tree_lookup(&mp->m_perag_tree, agno); pag = radix_tree_lookup(&mp->m_perag_tree, agno);
if (pag) { if (pag) {
trace_xfs_perag_get(pag, _RET_IP_);
ASSERT(atomic_read(&pag->pag_ref) >= 0); ASSERT(atomic_read(&pag->pag_ref) >= 0);
ref = atomic_inc_return(&pag->pag_ref); atomic_inc(&pag->pag_ref);
} }
rcu_read_unlock(); rcu_read_unlock();
trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
return pag; return pag;
} }
...@@ -68,7 +67,6 @@ xfs_perag_get_tag( ...@@ -68,7 +67,6 @@ xfs_perag_get_tag(
{ {
struct xfs_perag *pag; struct xfs_perag *pag;
int found; int found;
int ref;
rcu_read_lock(); rcu_read_lock();
found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
...@@ -77,9 +75,9 @@ xfs_perag_get_tag( ...@@ -77,9 +75,9 @@ xfs_perag_get_tag(
rcu_read_unlock(); rcu_read_unlock();
return NULL; return NULL;
} }
ref = atomic_inc_return(&pag->pag_ref); trace_xfs_perag_get_tag(pag, _RET_IP_);
atomic_inc(&pag->pag_ref);
rcu_read_unlock(); rcu_read_unlock();
trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_);
return pag; return pag;
} }
...@@ -87,11 +85,9 @@ void ...@@ -87,11 +85,9 @@ void
xfs_perag_put( xfs_perag_put(
struct xfs_perag *pag) struct xfs_perag *pag)
{ {
int ref; trace_xfs_perag_put(pag, _RET_IP_);
ASSERT(atomic_read(&pag->pag_ref) > 0); ASSERT(atomic_read(&pag->pag_ref) > 0);
ref = atomic_dec_return(&pag->pag_ref); atomic_dec(&pag->pag_ref);
trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
} }
/* /*
...@@ -110,8 +106,7 @@ xfs_perag_grab( ...@@ -110,8 +106,7 @@ xfs_perag_grab(
rcu_read_lock(); rcu_read_lock();
pag = radix_tree_lookup(&mp->m_perag_tree, agno); pag = radix_tree_lookup(&mp->m_perag_tree, agno);
if (pag) { if (pag) {
trace_xfs_perag_grab(mp, pag->pag_agno, trace_xfs_perag_grab(pag, _RET_IP_);
atomic_read(&pag->pag_active_ref), _RET_IP_);
if (!atomic_inc_not_zero(&pag->pag_active_ref)) if (!atomic_inc_not_zero(&pag->pag_active_ref))
pag = NULL; pag = NULL;
} }
...@@ -138,8 +133,7 @@ xfs_perag_grab_tag( ...@@ -138,8 +133,7 @@ xfs_perag_grab_tag(
rcu_read_unlock(); rcu_read_unlock();
return NULL; return NULL;
} }
trace_xfs_perag_grab_tag(mp, pag->pag_agno, trace_xfs_perag_grab_tag(pag, _RET_IP_);
atomic_read(&pag->pag_active_ref), _RET_IP_);
if (!atomic_inc_not_zero(&pag->pag_active_ref)) if (!atomic_inc_not_zero(&pag->pag_active_ref))
pag = NULL; pag = NULL;
rcu_read_unlock(); rcu_read_unlock();
...@@ -150,8 +144,7 @@ void ...@@ -150,8 +144,7 @@ void
xfs_perag_rele( xfs_perag_rele(
struct xfs_perag *pag) struct xfs_perag *pag)
{ {
trace_xfs_perag_rele(pag->pag_mount, pag->pag_agno, trace_xfs_perag_rele(pag, _RET_IP_);
atomic_read(&pag->pag_active_ref), _RET_IP_);
if (atomic_dec_and_test(&pag->pag_active_ref)) if (atomic_dec_and_test(&pag->pag_active_ref))
wake_up(&pag->pag_active_wq); wake_up(&pag->pag_active_wq);
} }
......
...@@ -255,7 +255,7 @@ xfs_perag_set_inode_tag( ...@@ -255,7 +255,7 @@ xfs_perag_set_inode_tag(
break; break;
} }
trace_xfs_perag_set_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); trace_xfs_perag_set_inode_tag(pag, _RET_IP_);
} }
/* Clear a tag on both the AG incore inode tree and the AG radix tree. */ /* Clear a tag on both the AG incore inode tree and the AG radix tree. */
...@@ -289,7 +289,7 @@ xfs_perag_clear_inode_tag( ...@@ -289,7 +289,7 @@ xfs_perag_clear_inode_tag(
radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno, tag); radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno, tag);
spin_unlock(&mp->m_perag_lock); spin_unlock(&mp->m_perag_lock);
trace_xfs_perag_clear_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); trace_xfs_perag_clear_inode_tag(pag, _RET_IP_);
} }
/* /*
......
...@@ -159,33 +159,34 @@ TRACE_EVENT(xlog_intent_recovery_failed, ...@@ -159,33 +159,34 @@ TRACE_EVENT(xlog_intent_recovery_failed,
); );
DECLARE_EVENT_CLASS(xfs_perag_class, DECLARE_EVENT_CLASS(xfs_perag_class,
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip),
unsigned long caller_ip), TP_ARGS(pag, caller_ip),
TP_ARGS(mp, agno, refcount, caller_ip),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(dev_t, dev) __field(dev_t, dev)
__field(xfs_agnumber_t, agno) __field(xfs_agnumber_t, agno)
__field(int, refcount) __field(int, refcount)
__field(int, active_refcount)
__field(unsigned long, caller_ip) __field(unsigned long, caller_ip)
), ),
TP_fast_assign( TP_fast_assign(
__entry->dev = mp->m_super->s_dev; __entry->dev = pag->pag_mount->m_super->s_dev;
__entry->agno = agno; __entry->agno = pag->pag_agno;
__entry->refcount = refcount; __entry->refcount = atomic_read(&pag->pag_ref);
__entry->active_refcount = atomic_read(&pag->pag_active_ref);
__entry->caller_ip = caller_ip; __entry->caller_ip = caller_ip;
), ),
TP_printk("dev %d:%d agno 0x%x refcount %d caller %pS", TP_printk("dev %d:%d agno 0x%x passive refs %d active refs %d caller %pS",
MAJOR(__entry->dev), MINOR(__entry->dev), MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->agno, __entry->agno,
__entry->refcount, __entry->refcount,
__entry->active_refcount,
(char *)__entry->caller_ip) (char *)__entry->caller_ip)
); );
#define DEFINE_PERAG_REF_EVENT(name) \ #define DEFINE_PERAG_REF_EVENT(name) \
DEFINE_EVENT(xfs_perag_class, name, \ DEFINE_EVENT(xfs_perag_class, name, \
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), \
unsigned long caller_ip), \ TP_ARGS(pag, caller_ip))
TP_ARGS(mp, agno, refcount, caller_ip))
DEFINE_PERAG_REF_EVENT(xfs_perag_get); DEFINE_PERAG_REF_EVENT(xfs_perag_get);
DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag);
DEFINE_PERAG_REF_EVENT(xfs_perag_put); DEFINE_PERAG_REF_EVENT(xfs_perag_put);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册