--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mctp
+
+#if !defined(_TRACE_MCTP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MCTP_H
+
+#include <linux/tracepoint.h>
+
+#ifndef __TRACE_MCTP_ENUMS
+#define __TRACE_MCTP_ENUMS
+enum {
+       MCTP_TRACE_KEY_TIMEOUT,
+       MCTP_TRACE_KEY_REPLIED,
+       MCTP_TRACE_KEY_INVALIDATED,
+       MCTP_TRACE_KEY_CLOSED,
+};
+#endif /* __TRACE_MCTP_ENUMS */
+
+TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_TIMEOUT);
+TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_REPLIED);
+TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_INVALIDATED);
+TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_CLOSED);
+
+TRACE_EVENT(mctp_key_acquire,
+       TP_PROTO(const struct mctp_sk_key *key),
+       TP_ARGS(key),
+       TP_STRUCT__entry(
+               __field(__u8,   paddr)
+               __field(__u8,   laddr)
+               __field(__u8,   tag)
+       ),
+       TP_fast_assign(
+               __entry->paddr = key->peer_addr;
+               __entry->laddr = key->local_addr;
+               __entry->tag = key->tag;
+       ),
+       TP_printk("local %d, peer %d, tag %1x",
+               __entry->laddr,
+               __entry->paddr,
+               __entry->tag
+       )
+);
+
+TRACE_EVENT(mctp_key_release,
+       TP_PROTO(const struct mctp_sk_key *key, int reason),
+       TP_ARGS(key, reason),
+       TP_STRUCT__entry(
+               __field(__u8,   paddr)
+               __field(__u8,   laddr)
+               __field(__u8,   tag)
+               __field(int,    reason)
+       ),
+       TP_fast_assign(
+               __entry->paddr = key->peer_addr;
+               __entry->laddr = key->local_addr;
+               __entry->tag = key->tag;
+               __entry->reason = reason;
+       ),
+       TP_printk("local %d, peer %d, tag %1x %s",
+               __entry->laddr,
+               __entry->paddr,
+               __entry->tag,
+               __print_symbolic(__entry->reason,
+                                { MCTP_TRACE_KEY_TIMEOUT, "timeout" },
+                                { MCTP_TRACE_KEY_REPLIED, "replied" },
+                                { MCTP_TRACE_KEY_INVALIDATED, "invalidated" },
+                                { MCTP_TRACE_KEY_CLOSED, "closed" })
+       )
+);
+
+#endif
+
+#include <trace/define_trace.h>
 
 #include <net/mctpdevice.h>
 #include <net/sock.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/mctp.h>
+
 /* socket implementation */
 
 static int mctp_release(struct socket *sock)
                spin_lock(&key->lock);
 
                if (!time_after_eq(key->expiry, jiffies)) {
+                       trace_mctp_key_release(key, MCTP_TRACE_KEY_TIMEOUT);
                        key->valid = false;
                        hlist_del_rcu(&key->hlist);
                        hlist_del_rcu(&key->sklist);
                hlist_del(&key->sklist);
                hlist_del(&key->hlist);
 
+               trace_mctp_key_release(key, MCTP_TRACE_KEY_CLOSED);
+
                spin_lock(&key->lock);
                if (key->reasm_head)
                        kfree_skb(key->reasm_head);
 
 #include <net/netlink.h>
 #include <net/sock.h>
 
+#include <trace/events/mctp.h>
+
 static const unsigned int mctp_message_maxlen = 64 * 1024;
 static const unsigned long mctp_key_lifetime = 6 * CONFIG_HZ;
 
-
 /* route output callbacks */
 static int mctp_route_discard(struct mctp_route *route, struct sk_buff *skb)
 {
                                /* we've hit a pending reassembly; not much we
                                 * can do but drop it
                                 */
+                               trace_mctp_key_release(key,
+                                                      MCTP_TRACE_KEY_REPLIED);
                                __mctp_key_unlock_drop(key, net, f);
                                key = NULL;
                        }
                        if (rc)
                                kfree(key);
 
+                       trace_mctp_key_acquire(key);
+
                        /* we don't need to release key->lock on exit */
                        key = NULL;
 
                } else {
                        if (key->reasm_head || key->reasm_dead) {
                                /* duplicate start? drop everything */
+                               trace_mctp_key_release(key,
+                                                      MCTP_TRACE_KEY_INVALIDATED);
                                __mctp_key_unlock_drop(key, net, f);
                                rc = -EEXIST;
                                key = NULL;
                if (!rc && flags & MCTP_HDR_FLAG_EOM) {
                        sock_queue_rcv_skb(key->sk, key->reasm_head);
                        key->reasm_head = NULL;
+                       trace_mctp_key_release(key, MCTP_TRACE_KEY_REPLIED);
                        __mctp_key_unlock_drop(key, net, f);
                        key = NULL;
                }
        if (tagbits) {
                key->tag = __ffs(tagbits);
                mctp_reserve_tag(net, key, msk);
+               trace_mctp_key_acquire(key);
+
                *tagp = key->tag;
                rc = 0;
        }