xfs: add iclog state trace events
authorDave Chinner <dchinner@redhat.com>
Fri, 18 Jun 2021 18:57:05 +0000 (11:57 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 21 Jun 2021 17:12:38 +0000 (10:12 -0700)
For the DEBUGS!

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_log.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_trace.h

index 6f9cafd..596cd16 100644 (file)
@@ -502,6 +502,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;
        }
 
@@ -520,6 +521,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;
 
@@ -781,6 +783,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) {
@@ -1754,6 +1757,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
@@ -1899,6 +1903,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);
 
@@ -2535,6 +2540,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
@@ -2624,6 +2630,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);
@@ -2683,6 +2691,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),
@@ -2764,6 +2773,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)) {
@@ -2783,6 +2793,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
@@ -2874,6 +2885,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
@@ -2947,6 +2959,8 @@ restart:
        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
@@ -3112,6 +3126,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;
@@ -3194,6 +3209,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)) {
@@ -3267,6 +3284,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;
index 2d7e7cb..293d82b 100644 (file)
@@ -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
  */
index 71dca77..28d5707 100644 (file)
@@ -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