Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/log.c | 13 +++++++--- fs/gfs2/log.h | 2 +- fs/gfs2/lops.c | 6 ++--- fs/gfs2/trace_gfs2.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ fs/gfs2/trans.c | 4 ++- 5 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 636c82dda68b..28699a1e5fbd 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -75,6 +75,7 @@ static void gfs2_remove_from_ail(struct gfs2_bufdata *bd) list_del_init(&bd->bd_ail_st_list); list_del_init(&bd->bd_ail_gl_list); atomic_dec(&bd->bd_gl->gl_ail_count); + trace_gfs2_glock_ail(bd, 3); brelse(bd->bd_bh); } @@ -675,21 +676,25 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) bd->bd_blkno = bh->b_blocknr; gfs2_remove_from_ail(bd); /* drops ref on bh */ bd->bd_bh = NULL; + trace_gfs2_glock_ail(bd, 5); set_bit(GLF_LFLUSH, &gl->gl_flags); + trace_gfs2_glock_ail(bd, 6); list_add(&bd->bd_list, &sdp->sd_log_revokes); } -void gfs2_glock_remove_revoke(struct gfs2_glock *gl) +void gfs2_glock_remove_revoke(struct gfs2_bufdata *bd) { int revokes; smp_mb__before_atomic(); - revokes = atomic_dec_return(&gl->gl_revokes); + revokes = atomic_dec_return(&bd->bd_gl->gl_revokes); smp_mb__after_atomic(); if (revokes == 0) { - clear_bit(GLF_LFLUSH, &gl->gl_flags); - gfs2_glock_queue_put(gl); + clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + trace_gfs2_glock_ail(bd, 7); + gfs2_glock_queue_put(bd->bd_gl); } + trace_gfs2_glock_ail(bd, 8); } /** diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index c1cd6ae17659..5fbfc0dc4b7a 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h @@ -77,7 +77,7 @@ extern void log_flush_wait(struct gfs2_sbd *sdp); extern int gfs2_logd(void *data); extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); -extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl); +extern void gfs2_glock_remove_revoke(struct gfs2_bufdata *bd); extern void gfs2_write_revokes(struct gfs2_sbd *sdp); #endif /* __LOG_DOT_H__ */ diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 48b54ec1c793..c9b430295506 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -118,12 +118,14 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, struct gfs2_glock *gl = bd->bd_gl; list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list); atomic_inc(&gl->gl_ail_count); + trace_gfs2_glock_ail(bd, 4); } bd->bd_tr = tr; list_add(&bd->bd_ail_st_list, &tr->tr_ail1_list); spin_unlock(&sdp->sd_ail_lock); clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + trace_gfs2_glock_ail(bd, 2); trace_gfs2_pin(bd, 0); unlock_buffer(bh); atomic_dec(&sdp->sd_log_pinned); @@ -906,13 +908,11 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { struct list_head *head = &sdp->sd_log_revokes; struct gfs2_bufdata *bd; - struct gfs2_glock *gl; while (!list_empty(head)) { bd = list_first_entry(head, struct gfs2_bufdata, bd_list); list_del_init(&bd->bd_list); - gl = bd->bd_gl; - gfs2_glock_remove_revoke(gl); + gfs2_glock_remove_revoke(bd); kmem_cache_free(gfs2_bufdata_cachep, bd); } } diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index e0025258107a..7cc090eb4fad 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h @@ -34,6 +34,16 @@ { GFS2_BLKST_DINODE, "dinode" }, \ { GFS2_BLKST_UNLINKED, "unlinked" }) +#define ail_caller(x) __print_symbolic(x, \ + {1, "gfs2_trans_add_meta lflush++"}, \ + {2, "gfs2_unpin lflush--"}, \ + {3, "gfs2_remove_from_ail gl_ail_count--"}, \ + {4, "gfs2_unpin gl_ail_count++"}, \ + {5, "gfs2_add_revoke gl_revokes++"}, \ + {6, "gfs2_add_revoke lflush++"}, \ + {7, "glock_remove_revoke lflush--"}, \ + {8, "glock_remove_revoke gl_revokes--"}) + #define TRACE_RS_DELETE 0 #define TRACE_RS_TREEDEL 1 #define TRACE_RS_INSERT 2 @@ -158,6 +168,57 @@ TRACE_EVENT(gfs2_glock_put, ); +/* ail list management for a glock */ +TRACE_EVENT(gfs2_glock_ail, + + TP_PROTO(const struct gfs2_bufdata *bd, int caller), + + TP_ARGS(bd, caller), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( u64, glnum ) + __field( u32, gltype ) + __field( u64, blk ) + __field( int, caller ) + __field( int, lflush ) + __field( int, ail_count ) + __field( int, revokes ) + __field( int, bd_list_q ) + __field( int, bd_ail_st_list_q ) + __field( int, bd_ail_gl_list_q ) + __field( int, gl_refs ) + ), + + TP_fast_assign( + __entry->dev = bd->bd_gl->gl_name.ln_sbd->sd_vfs->s_dev; + __entry->gltype = bd->bd_gl->gl_name.ln_type; + __entry->glnum = bd->bd_gl->gl_name.ln_number; + __entry->blk = bd->bd_bh ? bd->bd_bh->b_blocknr : + bd->bd_blkno; + __entry->caller = caller; + __entry->lflush = test_bit(GLF_LFLUSH, + &bd->bd_gl->gl_flags); + __entry->ail_count = atomic_read(&bd->bd_gl->gl_ail_count); + __entry->revokes = atomic_read(&bd->bd_gl->gl_revokes); + __entry->bd_list_q = !list_empty(&bd->bd_list); + __entry->bd_ail_st_list_q = !list_empty(&bd->bd_ail_st_list); + __entry->bd_ail_gl_list_q = !list_empty(&bd->bd_ail_gl_list); + __entry->gl_refs = bd->bd_gl->gl_lockref.count; + ), + + TP_printk("%u,%u glock %d:%lld blk %lld c:%d lflush:%d ail:%d " + "revokes:%d q:%d/%d/%d ref:%d %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->gltype, (unsigned long long)__entry->glnum, + (unsigned long long)__entry->blk, __entry->caller, + __entry->lflush, __entry->ail_count, __entry->revokes, + __entry->bd_list_q, __entry->bd_ail_st_list_q, + __entry->bd_ail_gl_list_q, __entry->gl_refs, + ail_caller(__entry->caller)) + +); + /* Callback (local or remote) requesting lock demotion */ TRACE_EVENT(gfs2_demote_rq, diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index ffe840505082..9aed58f7368d 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -173,6 +173,7 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh) set_bit(TR_TOUCHED, &tr->tr_flags); if (list_empty(&bd->bd_list)) { set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + trace_gfs2_glock_ail(bd, 1); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); gfs2_pin(sdp, bd->bd_bh); tr->tr_num_databuf_new++; @@ -216,6 +217,7 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh) if (!list_empty(&bd->bd_list)) goto out_unlock; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + trace_gfs2_glock_ail(bd, 1); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) { @@ -266,7 +268,7 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); sdp->sd_log_num_revoke--; if (bd->bd_gl) - gfs2_glock_remove_revoke(bd->bd_gl); + gfs2_glock_remove_revoke(bd); kmem_cache_free(gfs2_bufdata_cachep, bd); tr->tr_num_revoke_rm++; if (--n == 0) -- 2.26.2