bcachefs: Add actual tracepoints for transaction restarts
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 23 Apr 2019 04:10:08 +0000 (00:10 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:21 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_cache.c
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/trace.h

index 55aaa3e4aa844cb27186ae4e3ed2abd5dea07e46..bb88ce1415c829d619ea1d859f52015598864990 100644 (file)
@@ -734,6 +734,8 @@ retry:
                                goto retry;
 
                        trans_restart();
+                       trace_trans_restart_btree_node_reused(c,
+                                               iter->trans->ip);
                        return ERR_PTR(-EINTR);
                }
        }
index 6b9af53a3e775faecf6ebfcb3fdbfe33499e6947..4bdbdd22b437ddb72f03dbcb9c5daaf53e36db3b 100644 (file)
@@ -252,12 +252,15 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
                }
        }
 
-       if (ret)
-               __btree_node_lock_type(iter->trans->c, b, type);
-       else
+       if (unlikely(!ret)) {
                trans_restart();
+               trace_trans_restart_would_deadlock(iter->trans->c,
+                                                  iter->trans->ip);
+               return false;
+       }
 
-       return ret;
+       __btree_node_lock_type(iter->trans->c, b, type);
+       return true;
 }
 
 /* Btree iterator locking: */
@@ -1695,6 +1698,7 @@ success:
 
        if (trans->iters_live) {
                trans_restart();
+               trace_trans_restart_iters_realloced(trans->c, trans->ip);
                return -EINTR;
        }
 
@@ -1863,6 +1867,7 @@ void *bch2_trans_kmalloc(struct btree_trans *trans,
 
                if (old_bytes) {
                        trans_restart();
+                       trace_trans_restart_mem_realloced(trans->c, trans->ip);
                        return ERR_PTR(-EINTR);
                }
        }
@@ -1939,6 +1944,7 @@ void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c)
        memset(trans, 0, offsetof(struct btree_trans, iters_onstack));
 
        trans->c                = c;
+       trans->ip               = _RET_IP_;
        trans->size             = ARRAY_SIZE(trans->iters_onstack);
        trans->iters            = trans->iters_onstack;
        trans->updates          = trans->updates_onstack;
index 8c6f5fe6998e834356d02b77fec3a300259faec7..dd4fa2f595ec96098a65cc8a63553ca61a6b35b3 100644 (file)
@@ -267,6 +267,7 @@ struct btree_insert_entry {
 
 struct btree_trans {
        struct bch_fs           *c;
+       unsigned long           ip;
        size_t                  nr_restarts;
        u64                     commit_start;
 
index 2633a5452b13637a818a32b6030799b3c8719f87..a9d7905f33738aa92bbfb6d132abfb5c67df8573 100644 (file)
@@ -440,6 +440,7 @@ static int bch2_trans_journal_preres_get(struct btree_trans *trans)
 
        if (!bch2_btree_trans_relock(trans)) {
                trans_restart(" (iter relock after journal preres get blocked)");
+               trace_trans_restart_journal_preres_get(c, trans->ip);
                return -EINTR;
        }
 
@@ -564,6 +565,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
        if (race_fault()) {
                ret = -EINTR;
                trans_restart(" (race)");
+               trace_trans_restart_fault_inject(c, trans->ip);
                goto out;
        }
 
@@ -680,6 +682,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
                 */
                if (!ret || (flags & BTREE_INSERT_NOUNLOCK)) {
                        trans_restart(" (split)");
+                       trace_trans_restart_btree_node_split(c, trans->ip);
                        ret = -EINTR;
                }
                break;
@@ -699,6 +702,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
                        return 0;
 
                trans_restart(" (iter relock after marking replicas)");
+               trace_trans_restart_mark_replicas(c, trans->ip);
                ret = -EINTR;
                break;
        case BTREE_INSERT_NEED_JOURNAL_RES:
@@ -712,6 +716,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
                        return 0;
 
                trans_restart(" (iter relock after journal res get blocked)");
+               trace_trans_restart_journal_res_get(c, trans->ip);
                ret = -EINTR;
                break;
        default:
@@ -724,6 +729,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
 
                if (ret2) {
                        trans_restart(" (traverse)");
+                       trace_trans_restart_traverse(c, trans->ip);
                        return ret2;
                }
 
@@ -735,6 +741,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
                        return 0;
 
                trans_restart(" (atomic)");
+               trace_trans_restart_atomic(c, trans->ip);
        }
 
        return ret;
index 1aa6ac05d50eabc5563288ca2f4338e1a4848962..2864a72938ce7eaffe30f945bd47e76858adf312 100644 (file)
@@ -499,6 +499,78 @@ TRACE_EVENT(copygc,
                __entry->buckets_moved, __entry->buckets_not_moved)
 );
 
+DECLARE_EVENT_CLASS(transaction_restart,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip),
+
+       TP_STRUCT__entry(
+               __array(char,                   name,   16)
+               __field(unsigned long,          ip      )
+       ),
+
+       TP_fast_assign(
+               memcpy(__entry->name, c->name, 16);
+               __entry->ip = ip;
+       ),
+
+       TP_printk("%pS", (void *) __entry->ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_btree_node_reused,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_would_deadlock,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_iters_realloced,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_mem_realloced,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_journal_res_get,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_journal_preres_get,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_mark_replicas,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_fault_inject,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_btree_node_split,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_traverse,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
+DEFINE_EVENT(transaction_restart,      trans_restart_atomic,
+       TP_PROTO(struct bch_fs *c, unsigned long ip),
+       TP_ARGS(c, ip)
+);
+
 #endif /* _TRACE_BCACHEFS_H */
 
 /* This part must be outside protection */