On Thu, Jun 17, 2021 at 06:26:10PM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > For the DEBUGS! > > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> Still looks fine to me. Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> --D > --- > fs/xfs/xfs_log.c | 18 +++++++++++++ > fs/xfs/xfs_log_priv.h | 10 ++++++++ > fs/xfs/xfs_trace.h | 60 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 88 insertions(+) > > diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c > index e921b554b683..54fd6a695bb5 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -524,6 +524,7 @@ __xlog_state_release_iclog( > iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); > xlog_verify_tail_lsn(log, iclog, tail_lsn); > /* cycle incremented when incrementing curr_block */ > + trace_xlog_iclog_syncing(iclog, _RET_IP_); > return true; > } > > @@ -543,6 +544,7 @@ xlog_state_release_iclog( > { > lockdep_assert_held(&log->l_icloglock); > > + trace_xlog_iclog_release(iclog, _RET_IP_); > if (iclog->ic_state == XLOG_STATE_IOERROR) > return -EIO; > > @@ -804,6 +806,7 @@ xlog_wait_on_iclog( > { > struct xlog *log = iclog->ic_log; > > + trace_xlog_iclog_wait_on(iclog, _RET_IP_); > if (!XLOG_FORCED_SHUTDOWN(log) && > iclog->ic_state != XLOG_STATE_ACTIVE && > iclog->ic_state != XLOG_STATE_DIRTY) { > @@ -1804,6 +1807,7 @@ xlog_write_iclog( > unsigned int count) > { > ASSERT(bno < log->l_logBBsize); > + trace_xlog_iclog_write(iclog, _RET_IP_); > > /* > * We lock the iclogbufs here so that we can serialise against I/O > @@ -1950,6 +1954,7 @@ xlog_sync( > unsigned int size; > > ASSERT(atomic_read(&iclog->ic_refcnt) == 0); > + trace_xlog_iclog_sync(iclog, _RET_IP_); > > count = xlog_calc_iclog_size(log, iclog, &roundoff); > > @@ -2488,6 +2493,7 @@ xlog_state_activate_iclog( > int *iclogs_changed) > { > ASSERT(list_empty_careful(&iclog->ic_callbacks)); > + trace_xlog_iclog_activate(iclog, _RET_IP_); > > /* > * If the number of ops in this iclog indicate it just contains the > @@ -2577,6 +2583,8 @@ xlog_state_clean_iclog( > { > int iclogs_changed = 0; > > + trace_xlog_iclog_clean(dirty_iclog, _RET_IP_); > + > dirty_iclog->ic_state = XLOG_STATE_DIRTY; > > xlog_state_activate_iclogs(log, &iclogs_changed); > @@ -2636,6 +2644,7 @@ xlog_state_set_callback( > struct xlog_in_core *iclog, > xfs_lsn_t header_lsn) > { > + trace_xlog_iclog_callback(iclog, _RET_IP_); > iclog->ic_state = XLOG_STATE_CALLBACK; > > ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), > @@ -2717,6 +2726,7 @@ xlog_state_do_iclog_callbacks( > __releases(&log->l_icloglock) > __acquires(&log->l_icloglock) > { > + trace_xlog_iclog_callbacks_start(iclog, _RET_IP_); > spin_unlock(&log->l_icloglock); > spin_lock(&iclog->ic_callback_lock); > while (!list_empty(&iclog->ic_callbacks)) { > @@ -2736,6 +2746,7 @@ xlog_state_do_iclog_callbacks( > */ > spin_lock(&log->l_icloglock); > spin_unlock(&iclog->ic_callback_lock); > + trace_xlog_iclog_callbacks_done(iclog, _RET_IP_); > } > > STATIC void > @@ -2827,6 +2838,7 @@ xlog_state_done_syncing( > > spin_lock(&log->l_icloglock); > ASSERT(atomic_read(&iclog->ic_refcnt) == 0); > + trace_xlog_iclog_sync_done(iclog, _RET_IP_); > > /* > * If we got an error, either on the first buffer, or in the case of > @@ -2899,6 +2911,8 @@ xlog_state_get_iclog_space( > atomic_inc(&iclog->ic_refcnt); /* prevents sync */ > log_offset = iclog->ic_offset; > > + trace_xlog_iclog_get_space(iclog, _RET_IP_); > + > /* On the 1st write to an iclog, figure out lsn. This works > * if iclogs marked XLOG_STATE_WANT_SYNC always write out what they are > * committing to. If the offset is set, that's how many blocks > @@ -3056,6 +3070,7 @@ xlog_state_switch_iclogs( > { > ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); > assert_spin_locked(&log->l_icloglock); > + trace_xlog_iclog_switch(iclog, _RET_IP_); > > if (!eventual_size) > eventual_size = iclog->ic_offset; > @@ -3138,6 +3153,8 @@ xfs_log_force( > if (iclog->ic_state == XLOG_STATE_IOERROR) > goto out_error; > > + trace_xlog_iclog_force(iclog, _RET_IP_); > + > if (iclog->ic_state == XLOG_STATE_DIRTY || > (iclog->ic_state == XLOG_STATE_ACTIVE && > atomic_read(&iclog->ic_refcnt) == 0 && iclog->ic_offset == 0)) { > @@ -3225,6 +3242,7 @@ xlog_force_lsn( > goto out_error; > > while (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) { > + trace_xlog_iclog_force_lsn(iclog, _RET_IP_); > iclog = iclog->ic_next; > if (iclog == log->l_iclog) > goto out_unlock; > diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h > index e4e421a70335..330befd9f6be 100644 > --- a/fs/xfs/xfs_log_priv.h > +++ b/fs/xfs/xfs_log_priv.h > @@ -50,6 +50,16 @@ enum xlog_iclog_state { > XLOG_STATE_IOERROR, /* IO error happened in sync'ing log */ > }; > > +#define XLOG_STATE_STRINGS \ > + { XLOG_STATE_ACTIVE, "XLOG_STATE_ACTIVE" }, \ > + { XLOG_STATE_WANT_SYNC, "XLOG_STATE_WANT_SYNC" }, \ > + { XLOG_STATE_SYNCING, "XLOG_STATE_SYNCING" }, \ > + { XLOG_STATE_DONE_SYNC, "XLOG_STATE_DONE_SYNC" }, \ > + { XLOG_STATE_CALLBACK, "XLOG_STATE_CALLBACK" }, \ > + { XLOG_STATE_DIRTY, "XLOG_STATE_DIRTY" }, \ > + { XLOG_STATE_IOERROR, "XLOG_STATE_IOERROR" } > + > + > /* > * Log ticket flags > */ > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 71dca776c110..28d570742000 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -24,6 +24,7 @@ struct xlog_ticket; > struct xlog_recover; > struct xlog_recover_item; > struct xlog_rec_header; > +struct xlog_in_core; > struct xfs_buf_log_format; > struct xfs_inode_log_format; > struct xfs_bmbt_irec; > @@ -3927,6 +3928,65 @@ DEFINE_EVENT(xfs_icwalk_class, name, \ > DEFINE_ICWALK_EVENT(xfs_ioc_free_eofblocks); > DEFINE_ICWALK_EVENT(xfs_blockgc_free_space); > > +TRACE_DEFINE_ENUM(XLOG_STATE_ACTIVE); > +TRACE_DEFINE_ENUM(XLOG_STATE_WANT_SYNC); > +TRACE_DEFINE_ENUM(XLOG_STATE_SYNCING); > +TRACE_DEFINE_ENUM(XLOG_STATE_DONE_SYNC); > +TRACE_DEFINE_ENUM(XLOG_STATE_CALLBACK); > +TRACE_DEFINE_ENUM(XLOG_STATE_DIRTY); > +TRACE_DEFINE_ENUM(XLOG_STATE_IOERROR); > + > +DECLARE_EVENT_CLASS(xlog_iclog_class, > + TP_PROTO(struct xlog_in_core *iclog, unsigned long caller_ip), > + TP_ARGS(iclog, caller_ip), > + TP_STRUCT__entry( > + __field(dev_t, dev) > + __field(uint32_t, state) > + __field(int32_t, refcount) > + __field(uint32_t, offset) > + __field(unsigned long long, lsn) > + __field(unsigned long, caller_ip) > + ), > + TP_fast_assign( > + __entry->dev = iclog->ic_log->l_mp->m_super->s_dev; > + __entry->state = iclog->ic_state; > + __entry->refcount = atomic_read(&iclog->ic_refcnt); > + __entry->offset = iclog->ic_offset; > + __entry->lsn = be64_to_cpu(iclog->ic_header.h_lsn); > + __entry->caller_ip = caller_ip; > + ), > + TP_printk("dev %d:%d state %s refcnt %d offset %u lsn 0x%llx caller %pS", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __print_symbolic(__entry->state, XLOG_STATE_STRINGS), > + __entry->refcount, > + __entry->offset, > + __entry->lsn, > + (char *)__entry->caller_ip) > + > +); > + > +#define DEFINE_ICLOG_EVENT(name) \ > +DEFINE_EVENT(xlog_iclog_class, name, \ > + TP_PROTO(struct xlog_in_core *iclog, unsigned long caller_ip), \ > + TP_ARGS(iclog, caller_ip)) > + > +DEFINE_ICLOG_EVENT(xlog_iclog_activate); > +DEFINE_ICLOG_EVENT(xlog_iclog_clean); > +DEFINE_ICLOG_EVENT(xlog_iclog_callback); > +DEFINE_ICLOG_EVENT(xlog_iclog_callbacks_start); > +DEFINE_ICLOG_EVENT(xlog_iclog_callbacks_done); > +DEFINE_ICLOG_EVENT(xlog_iclog_force); > +DEFINE_ICLOG_EVENT(xlog_iclog_force_lsn); > +DEFINE_ICLOG_EVENT(xlog_iclog_get_space); > +DEFINE_ICLOG_EVENT(xlog_iclog_release); > +DEFINE_ICLOG_EVENT(xlog_iclog_switch); > +DEFINE_ICLOG_EVENT(xlog_iclog_sync); > +DEFINE_ICLOG_EVENT(xlog_iclog_syncing); > +DEFINE_ICLOG_EVENT(xlog_iclog_sync_done); > +DEFINE_ICLOG_EVENT(xlog_iclog_want_sync); > +DEFINE_ICLOG_EVENT(xlog_iclog_wait_on); > +DEFINE_ICLOG_EVENT(xlog_iclog_write); > + > #endif /* _TRACE_XFS_H */ > > #undef TRACE_INCLUDE_PATH > -- > 2.31.1 >