diff mbox series

[ipsec-next,v5,17/17] xfrm: iptfs: add tracepoint functionality

Message ID 20240714202246.1573817-18-chopps@chopps.org (mailing list archive)
State Awaiting Upstream
Delegated to: Netdev Maintainers
Headers show
Series Add IP-TFS mode to xfrm | expand

Checks

Context Check Description
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Christian Hopps July 14, 2024, 8:22 p.m. UTC
From: Christian Hopps <chopps@labn.net>

Add tracepoints to the IP-TFS code.

Signed-off-by: Christian Hopps <chopps@labn.net>
---
 net/xfrm/trace_iptfs.h | 218 +++++++++++++++++++++++++++++++++++++++++
 net/xfrm/xfrm_iptfs.c  |  60 ++++++++++++
 2 files changed, 278 insertions(+)
 create mode 100644 net/xfrm/trace_iptfs.h

Comments

kernel test robot July 15, 2024, 11:53 a.m. UTC | #1
Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on klassert-ipsec-next/master]
[also build test ERROR on next-20240715]
[cannot apply to klassert-ipsec/master netfilter-nf/main linus/master nf-next/master v6.10]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Hopps/xfrm-config-add-CONFIG_XFRM_IPTFS/20240715-042948
base:   https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
patch link:    https://lore.kernel.org/r/20240714202246.1573817-18-chopps%40chopps.org
patch subject: [PATCH ipsec-next v5 17/17] xfrm: iptfs: add tracepoint functionality
config: sh-allyesconfig (https://download.01.org/0day-ci/archive/20240715/202407151936.lWZK9Xnp-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240715/202407151936.lWZK9Xnp-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407151936.lWZK9Xnp-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/trace/define_trace.h:102,
                    from net/xfrm/trace_iptfs.h:218,
                    from net/xfrm/xfrm_iptfs.c:445:
   include/trace/../../net/xfrm/trace_iptfs.h: In function 'trace_event_raw_event_iptfs_egress_recv':
>> include/trace/../../net/xfrm/trace_iptfs.h:46:42: error: assignment to 'u32' {aka 'unsigned int'} from 'sk_buff_data_t' {aka 'unsigned char *'} makes integer from pointer without a cast [-Wint-conversion]
      46 |                            __entry->tail = skb->tail;
         |                                          ^
   include/trace/trace_events.h:402:11: note: in definition of macro 'DECLARE_EVENT_CLASS'
     402 |         { assign; }                                                     \
         |           ^~~~~~
   include/trace/trace_events.h:44:30: note: in expansion of macro 'PARAMS'
      44 |                              PARAMS(assign),                   \
         |                              ^~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: note: in expansion of macro 'TRACE_EVENT'
      22 | TRACE_EVENT(iptfs_egress_recv,
         | ^~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:40:13: note: in expansion of macro 'TP_fast_assign'
      40 |             TP_fast_assign(__entry->skb = skb;
         |             ^~~~~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:47:41: error: assignment to 'u32' {aka 'unsigned int'} from 'sk_buff_data_t' {aka 'unsigned char *'} makes integer from pointer without a cast [-Wint-conversion]
      47 |                            __entry->end = skb->end;
         |                                         ^
   include/trace/trace_events.h:402:11: note: in definition of macro 'DECLARE_EVENT_CLASS'
     402 |         { assign; }                                                     \
         |           ^~~~~~
   include/trace/trace_events.h:44:30: note: in expansion of macro 'PARAMS'
      44 |                              PARAMS(assign),                   \
         |                              ^~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: note: in expansion of macro 'TRACE_EVENT'
      22 | TRACE_EVENT(iptfs_egress_recv,
         | ^~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:40:13: note: in expansion of macro 'TP_fast_assign'
      40 |             TP_fast_assign(__entry->skb = skb;
         |             ^~~~~~~~~~~~~~
   In file included from include/trace/define_trace.h:103:
   include/trace/../../net/xfrm/trace_iptfs.h: In function 'perf_trace_iptfs_egress_recv':
>> include/trace/../../net/xfrm/trace_iptfs.h:46:42: error: assignment to 'u32' {aka 'unsigned int'} from 'sk_buff_data_t' {aka 'unsigned char *'} makes integer from pointer without a cast [-Wint-conversion]
      46 |                            __entry->tail = skb->tail;
         |                                          ^
   include/trace/perf.h:51:11: note: in definition of macro 'DECLARE_EVENT_CLASS'
      51 |         { assign; }                                                     \
         |           ^~~~~~
   include/trace/trace_events.h:44:30: note: in expansion of macro 'PARAMS'
      44 |                              PARAMS(assign),                   \
         |                              ^~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: note: in expansion of macro 'TRACE_EVENT'
      22 | TRACE_EVENT(iptfs_egress_recv,
         | ^~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:40:13: note: in expansion of macro 'TP_fast_assign'
      40 |             TP_fast_assign(__entry->skb = skb;
         |             ^~~~~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:47:41: error: assignment to 'u32' {aka 'unsigned int'} from 'sk_buff_data_t' {aka 'unsigned char *'} makes integer from pointer without a cast [-Wint-conversion]
      47 |                            __entry->end = skb->end;
         |                                         ^
   include/trace/perf.h:51:11: note: in definition of macro 'DECLARE_EVENT_CLASS'
      51 |         { assign; }                                                     \
         |           ^~~~~~
   include/trace/trace_events.h:44:30: note: in expansion of macro 'PARAMS'
      44 |                              PARAMS(assign),                   \
         |                              ^~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: note: in expansion of macro 'TRACE_EVENT'
      22 | TRACE_EVENT(iptfs_egress_recv,
         | ^~~~~~~~~~~
   include/trace/../../net/xfrm/trace_iptfs.h:40:13: note: in expansion of macro 'TP_fast_assign'
      40 |             TP_fast_assign(__entry->skb = skb;
         |             ^~~~~~~~~~~~~~


vim +46 include/trace/../../net/xfrm/trace_iptfs.h

    21	
    22	TRACE_EVENT(iptfs_egress_recv,
    23		    TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u16 blkoff),
    24		    TP_ARGS(skb, xtfs, blkoff),
    25		    TP_STRUCT__entry(__field(struct sk_buff *, skb)
    26				     __field(void *, head)
    27				     __field(void *, head_pg_addr)
    28				     __field(void *, pg0addr)
    29				     __field(u32, skb_len)
    30				     __field(u32, data_len)
    31				     __field(u32, headroom)
    32				     __field(u32, tailroom)
    33				     __field(u32, tail)
    34				     __field(u32, end)
    35				     __field(u32, pg0off)
    36				     __field(u8, head_frag)
    37				     __field(u8, frag_list)
    38				     __field(u8, nr_frags)
    39				     __field(u16, blkoff)),
    40		    TP_fast_assign(__entry->skb = skb;
    41				   __entry->head = skb->head;
    42				   __entry->skb_len = skb->len;
    43				   __entry->data_len = skb->data_len;
    44				   __entry->headroom = skb_headroom(skb);
    45				   __entry->tailroom = skb_tailroom(skb);
  > 46				   __entry->tail = skb->tail;
    47				   __entry->end = skb->end;
    48				   __entry->head_frag = skb->head_frag;
    49				   __entry->frag_list = (bool)skb_shinfo(skb)->frag_list;
    50				   __entry->nr_frags = skb_shinfo(skb)->nr_frags;
    51				   __entry->blkoff = blkoff;
    52				   __entry->head_pg_addr = page_address(virt_to_head_page(skb->head));
    53				   __entry->pg0addr = (__entry->nr_frags
    54						       ? page_address(netmem_to_page(skb_shinfo(skb)->frags[0].netmem))
    55						       : NULL);
    56				   __entry->pg0off = (__entry->nr_frags
    57						      ? skb_shinfo(skb)->frags[0].offset
    58						      : 0);
    59			    ),
    60		    TP_printk("EGRESS: skb=%p len=%u data_len=%u headroom=%u head_frag=%u frag_list=%u nr_frags=%u blkoff=%u\n\t\ttailroom=%u tail=%u end=%u head=%p hdpgaddr=%p pg0->addr=%p pg0->data=%p pg0->off=%u",
    61			      __entry->skb, __entry->skb_len, __entry->data_len, __entry->headroom,
    62			      __entry->head_frag, __entry->frag_list, __entry->nr_frags, __entry->blkoff,
    63			      __entry->tailroom, __entry->tail, __entry->end, __entry->head,
    64			      __entry->head_pg_addr, __entry->pg0addr, __entry->pg0addr + __entry->pg0off,
    65			      __entry->pg0off)
    66		)
    67
kernel test robot July 17, 2024, 5:21 a.m. UTC | #2
Hi Christian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on klassert-ipsec-next/master]
[also build test WARNING on next-20240716]
[cannot apply to klassert-ipsec/master netfilter-nf/main linus/master nf-next/master v6.10]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Hopps/xfrm-config-add-CONFIG_XFRM_IPTFS/20240715-042948
base:   https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
patch link:    https://lore.kernel.org/r/20240714202246.1573817-18-chopps%40chopps.org
patch subject: [PATCH ipsec-next v5 17/17] xfrm: iptfs: add tracepoint functionality
config: i386-randconfig-061-20240716 (https://download.01.org/0day-ci/archive/20240717/202407171316.DNF21j3K-lkp@intel.com/config)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240717/202407171316.DNF21j3K-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407171316.DNF21j3K-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   net/xfrm/xfrm_iptfs.c: note: in included file (through include/trace/trace_events.h, include/trace/define_trace.h, net/xfrm/trace_iptfs.h):
>> include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] tail @@     got unsigned char *[usertype] tail @@
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     expected unsigned int [usertype] tail
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     got unsigned char *[usertype] tail
>> include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] end @@     got unsigned char *[usertype] end @@
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     expected unsigned int [usertype] end
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     got unsigned char *[usertype] end
   net/xfrm/xfrm_iptfs.c: note: in included file (through include/trace/perf.h, include/trace/define_trace.h, net/xfrm/trace_iptfs.h):
>> include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] tail @@     got unsigned char *[usertype] tail @@
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     expected unsigned int [usertype] tail
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     got unsigned char *[usertype] tail
>> include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] end @@     got unsigned char *[usertype] end @@
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     expected unsigned int [usertype] end
   include/trace/../../net/xfrm/trace_iptfs.h:22:1: sparse:     got unsigned char *[usertype] end

vim +22 include/trace/../../net/xfrm/trace_iptfs.h

    21	
  > 22	TRACE_EVENT(iptfs_egress_recv,
    23		    TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u16 blkoff),
    24		    TP_ARGS(skb, xtfs, blkoff),
    25		    TP_STRUCT__entry(__field(struct sk_buff *, skb)
    26				     __field(void *, head)
    27				     __field(void *, head_pg_addr)
    28				     __field(void *, pg0addr)
    29				     __field(u32, skb_len)
    30				     __field(u32, data_len)
    31				     __field(u32, headroom)
    32				     __field(u32, tailroom)
    33				     __field(u32, tail)
    34				     __field(u32, end)
    35				     __field(u32, pg0off)
    36				     __field(u8, head_frag)
    37				     __field(u8, frag_list)
    38				     __field(u8, nr_frags)
    39				     __field(u16, blkoff)),
    40		    TP_fast_assign(__entry->skb = skb;
    41				   __entry->head = skb->head;
    42				   __entry->skb_len = skb->len;
    43				   __entry->data_len = skb->data_len;
    44				   __entry->headroom = skb_headroom(skb);
    45				   __entry->tailroom = skb_tailroom(skb);
    46				   __entry->tail = skb->tail;
    47				   __entry->end = skb->end;
    48				   __entry->head_frag = skb->head_frag;
    49				   __entry->frag_list = (bool)skb_shinfo(skb)->frag_list;
    50				   __entry->nr_frags = skb_shinfo(skb)->nr_frags;
    51				   __entry->blkoff = blkoff;
    52				   __entry->head_pg_addr = page_address(virt_to_head_page(skb->head));
    53				   __entry->pg0addr = (__entry->nr_frags
    54						       ? page_address(netmem_to_page(skb_shinfo(skb)->frags[0].netmem))
    55						       : NULL);
    56				   __entry->pg0off = (__entry->nr_frags
    57						      ? skb_shinfo(skb)->frags[0].offset
    58						      : 0);
    59			    ),
    60		    TP_printk("EGRESS: skb=%p len=%u data_len=%u headroom=%u head_frag=%u frag_list=%u nr_frags=%u blkoff=%u\n\t\ttailroom=%u tail=%u end=%u head=%p hdpgaddr=%p pg0->addr=%p pg0->data=%p pg0->off=%u",
    61			      __entry->skb, __entry->skb_len, __entry->data_len, __entry->headroom,
    62			      __entry->head_frag, __entry->frag_list, __entry->nr_frags, __entry->blkoff,
    63			      __entry->tailroom, __entry->tail, __entry->end, __entry->head,
    64			      __entry->head_pg_addr, __entry->pg0addr, __entry->pg0addr + __entry->pg0off,
    65			      __entry->pg0off)
    66		)
    67
diff mbox series

Patch

diff --git a/net/xfrm/trace_iptfs.h b/net/xfrm/trace_iptfs.h
new file mode 100644
index 000000000000..0425f051572f
--- /dev/null
+++ b/net/xfrm/trace_iptfs.h
@@ -0,0 +1,218 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/* xfrm_trace_iptfs.h
+ *
+ * August 12 2023, Christian Hopps <chopps@labn.net>
+ *
+ * Copyright (c) 2023, LabN Consulting, L.L.C.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM iptfs
+
+#if !defined(_TRACE_IPTFS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IPTFS_H
+
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/tracepoint.h>
+#include <net/ip.h>
+
+struct xfrm_iptfs_data;
+
+TRACE_EVENT(iptfs_egress_recv,
+	    TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u16 blkoff),
+	    TP_ARGS(skb, xtfs, blkoff),
+	    TP_STRUCT__entry(__field(struct sk_buff *, skb)
+			     __field(void *, head)
+			     __field(void *, head_pg_addr)
+			     __field(void *, pg0addr)
+			     __field(u32, skb_len)
+			     __field(u32, data_len)
+			     __field(u32, headroom)
+			     __field(u32, tailroom)
+			     __field(u32, tail)
+			     __field(u32, end)
+			     __field(u32, pg0off)
+			     __field(u8, head_frag)
+			     __field(u8, frag_list)
+			     __field(u8, nr_frags)
+			     __field(u16, blkoff)),
+	    TP_fast_assign(__entry->skb = skb;
+			   __entry->head = skb->head;
+			   __entry->skb_len = skb->len;
+			   __entry->data_len = skb->data_len;
+			   __entry->headroom = skb_headroom(skb);
+			   __entry->tailroom = skb_tailroom(skb);
+			   __entry->tail = skb->tail;
+			   __entry->end = skb->end;
+			   __entry->head_frag = skb->head_frag;
+			   __entry->frag_list = (bool)skb_shinfo(skb)->frag_list;
+			   __entry->nr_frags = skb_shinfo(skb)->nr_frags;
+			   __entry->blkoff = blkoff;
+			   __entry->head_pg_addr = page_address(virt_to_head_page(skb->head));
+			   __entry->pg0addr = (__entry->nr_frags
+					       ? page_address(netmem_to_page(skb_shinfo(skb)->frags[0].netmem))
+					       : NULL);
+			   __entry->pg0off = (__entry->nr_frags
+					      ? skb_shinfo(skb)->frags[0].offset
+					      : 0);
+		    ),
+	    TP_printk("EGRESS: skb=%p len=%u data_len=%u headroom=%u head_frag=%u frag_list=%u nr_frags=%u blkoff=%u\n\t\ttailroom=%u tail=%u end=%u head=%p hdpgaddr=%p pg0->addr=%p pg0->data=%p pg0->off=%u",
+		      __entry->skb, __entry->skb_len, __entry->data_len, __entry->headroom,
+		      __entry->head_frag, __entry->frag_list, __entry->nr_frags, __entry->blkoff,
+		      __entry->tailroom, __entry->tail, __entry->end, __entry->head,
+		      __entry->head_pg_addr, __entry->pg0addr, __entry->pg0addr + __entry->pg0off,
+		      __entry->pg0off)
+	)
+
+DECLARE_EVENT_CLASS(iptfs_ingress_preq_event,
+		    TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs,
+			     u32 pmtu, u8 was_gso),
+		    TP_ARGS(skb, xtfs, pmtu, was_gso),
+		    TP_STRUCT__entry(__field(struct sk_buff *, skb)
+				     __field(u32, skb_len)
+				     __field(u32, data_len)
+				     __field(u32, pmtu)
+				     __field(u32, queue_size)
+				     __field(u32, proto_seq)
+				     __field(u8, proto)
+				     __field(u8, was_gso)
+			    ),
+		    TP_fast_assign(__entry->skb = skb;
+				   __entry->skb_len = skb->len;
+				   __entry->data_len = skb->data_len;
+				   __entry->queue_size =
+					xtfs->cfg.max_queue_size - xtfs->queue_size;
+				   __entry->proto = __trace_ip_proto(ip_hdr(skb));
+				   __entry->proto_seq = __trace_ip_proto_seq(ip_hdr(skb));
+				   __entry->pmtu = pmtu;
+				   __entry->was_gso = was_gso;
+			    ),
+		    TP_printk("INGRPREQ: skb=%p len=%u data_len=%u qsize=%u proto=%u proto_seq=%u pmtu=%u was_gso=%u",
+			      __entry->skb, __entry->skb_len, __entry->data_len,
+			      __entry->queue_size, __entry->proto, __entry->proto_seq,
+			      __entry->pmtu, __entry->was_gso));
+
+DEFINE_EVENT(iptfs_ingress_preq_event, iptfs_enqueue,
+	     TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u32 pmtu, u8 was_gso),
+	     TP_ARGS(skb, xtfs, pmtu, was_gso));
+
+DEFINE_EVENT(iptfs_ingress_preq_event, iptfs_no_queue_space,
+	     TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u32 pmtu, u8 was_gso),
+	     TP_ARGS(skb, xtfs, pmtu, was_gso));
+
+DEFINE_EVENT(iptfs_ingress_preq_event, iptfs_too_big,
+	     TP_PROTO(struct sk_buff *skb, struct xfrm_iptfs_data *xtfs, u32 pmtu, u8 was_gso),
+	     TP_ARGS(skb, xtfs, pmtu, was_gso));
+
+DECLARE_EVENT_CLASS(iptfs_ingress_postq_event,
+		    TP_PROTO(struct sk_buff *skb, u32 mtu, u16 blkoff, struct iphdr *iph),
+		    TP_ARGS(skb, mtu, blkoff, iph),
+		    TP_STRUCT__entry(__field(struct sk_buff *, skb)
+				     __field(u32, skb_len)
+				     __field(u32, data_len)
+				     __field(u32, mtu)
+				     __field(u32, proto_seq)
+				     __field(u16, blkoff)
+				     __field(u8, proto)),
+		    TP_fast_assign(__entry->skb = skb;
+				   __entry->skb_len = skb->len;
+				   __entry->data_len = skb->data_len;
+				   __entry->mtu = mtu;
+				   __entry->blkoff = blkoff;
+				   __entry->proto = iph ? __trace_ip_proto(iph) : 0;
+				   __entry->proto_seq = iph ? __trace_ip_proto_seq(iph) : 0;
+			    ),
+		    TP_printk("INGRPSTQ: skb=%p len=%u data_len=%u mtu=%u blkoff=%u proto=%u proto_seq=%u",
+			      __entry->skb, __entry->skb_len, __entry->data_len, __entry->mtu,
+			      __entry->blkoff, __entry->proto, __entry->proto_seq));
+
+DEFINE_EVENT(iptfs_ingress_postq_event, iptfs_first_dequeue,
+	     TP_PROTO(struct sk_buff *skb, u32 mtu, u16 blkoff,
+		      struct iphdr *iph),
+	     TP_ARGS(skb, mtu, blkoff, iph));
+
+DEFINE_EVENT(iptfs_ingress_postq_event, iptfs_first_fragmenting,
+	     TP_PROTO(struct sk_buff *skb, u32 mtu, u16 blkoff,
+		      struct iphdr *iph),
+	     TP_ARGS(skb, mtu, blkoff, iph));
+
+DEFINE_EVENT(iptfs_ingress_postq_event, iptfs_first_final_fragment,
+	     TP_PROTO(struct sk_buff *skb, u32 mtu, u16 blkoff,
+		      struct iphdr *iph),
+	     TP_ARGS(skb, mtu, blkoff, iph));
+
+DEFINE_EVENT(iptfs_ingress_postq_event, iptfs_first_toobig,
+	     TP_PROTO(struct sk_buff *skb, u32 mtu, u16 blkoff,
+		      struct iphdr *iph),
+	     TP_ARGS(skb, mtu, blkoff, iph));
+
+TRACE_EVENT(iptfs_ingress_nth_peek,
+	    TP_PROTO(struct sk_buff *skb, u32 remaining),
+	    TP_ARGS(skb, remaining),
+	    TP_STRUCT__entry(__field(struct sk_buff *, skb)
+			     __field(u32, skb_len)
+			     __field(u32, remaining)),
+	    TP_fast_assign(__entry->skb = skb;
+			   __entry->skb_len = skb->len;
+			   __entry->remaining = remaining;
+		    ),
+	    TP_printk("INGRPSTQ: NTHPEEK: skb=%p len=%u remaining=%u",
+		      __entry->skb, __entry->skb_len, __entry->remaining));
+
+TRACE_EVENT(iptfs_ingress_nth_add, TP_PROTO(struct sk_buff *skb, u8 share_ok),
+	    TP_ARGS(skb, share_ok),
+	    TP_STRUCT__entry(__field(struct sk_buff *, skb)
+			     __field(u32, skb_len)
+			     __field(u32, data_len)
+			     __field(u8, share_ok)
+			     __field(u8, head_frag)
+			     __field(u8, pp_recycle)
+			     __field(u8, cloned)
+			     __field(u8, shared)
+			     __field(u8, nr_frags)
+			     __field(u8, frag_list)
+		    ),
+	    TP_fast_assign(__entry->skb = skb;
+			   __entry->skb_len = skb->len;
+			   __entry->data_len = skb->data_len;
+			   __entry->share_ok = share_ok;
+			   __entry->head_frag = skb->head_frag;
+			   __entry->pp_recycle = skb->pp_recycle;
+			   __entry->cloned = skb_cloned(skb);
+			   __entry->shared = skb_shared(skb);
+			   __entry->nr_frags = skb_shinfo(skb)->nr_frags;
+			   __entry->frag_list = (bool)skb_shinfo(skb)->frag_list;
+		    ),
+	    TP_printk("INGRPSTQ: NTHADD: skb=%p len=%u data_len=%u share_ok=%u head_frag=%u pp_recycle=%u cloned=%u shared=%u nr_frags=%u frag_list=%u",
+		      __entry->skb, __entry->skb_len, __entry->data_len, __entry->share_ok,
+		      __entry->head_frag, __entry->pp_recycle, __entry->cloned, __entry->shared,
+		      __entry->nr_frags, __entry->frag_list));
+
+DECLARE_EVENT_CLASS(iptfs_timer_event,
+		    TP_PROTO(struct xfrm_iptfs_data *xtfs, u64 time_val),
+		    TP_ARGS(xtfs, time_val),
+		    TP_STRUCT__entry(__field(u64, time_val)
+				     __field(u64, set_time)),
+		    TP_fast_assign(__entry->time_val = time_val;
+				   __entry->set_time = xtfs->iptfs_settime;
+			    ),
+		    TP_printk("TIMER: set_time=%llu time_val=%llu",
+			      __entry->set_time, __entry->time_val));
+
+DEFINE_EVENT(iptfs_timer_event, iptfs_timer_start,
+	     TP_PROTO(struct xfrm_iptfs_data *xtfs, u64 time_val),
+	     TP_ARGS(xtfs, time_val));
+
+DEFINE_EVENT(iptfs_timer_event, iptfs_timer_expire,
+	     TP_PROTO(struct xfrm_iptfs_data *xtfs, u64 time_val),
+	     TP_ARGS(xtfs, time_val));
+
+#endif /* _TRACE_IPTFS_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../net/xfrm
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace_iptfs
+#include <trace/define_trace.h>
diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c
index b6e3c1a1c71c..060361479410 100644
--- a/net/xfrm/xfrm_iptfs.c
+++ b/net/xfrm/xfrm_iptfs.c
@@ -19,6 +19,7 @@ 
 #include <crypto/aead.h>
 
 #include "xfrm_inout.h"
+#include "trace_iptfs.h"
 
 /* IPTFS encap (header) values. */
 #define IPTFS_SUBTYPE_BASIC 0
@@ -88,6 +89,39 @@  static enum hrtimer_restart iptfs_drop_timer(struct hrtimer *me);
 /* Utility Functions */
 /* ================= */
 
+static u32 __trace_ip_proto(struct iphdr *iph)
+{
+	if (iph->version == 4)
+		return iph->protocol;
+	return ((struct ipv6hdr *)iph)->nexthdr;
+}
+
+static u32 __trace_ip_proto_seq(struct iphdr *iph)
+{
+	void *nexthdr;
+	u32 protocol = 0;
+
+	if (iph->version == 4) {
+		nexthdr = (void *)(iph + 1);
+		protocol = iph->protocol;
+	} else if (iph->version == 6) {
+		nexthdr = (void *)(((struct ipv6hdr *)(iph)) + 1);
+		protocol = ((struct ipv6hdr *)(iph))->nexthdr;
+	}
+	switch (protocol) {
+	case IPPROTO_ICMP:
+		return ntohs(((struct icmphdr *)nexthdr)->un.echo.sequence);
+	case IPPROTO_ICMPV6:
+		return ntohs(((struct icmp6hdr *)nexthdr)->icmp6_sequence);
+	case IPPROTO_TCP:
+		return ntohl(((struct tcphdr *)nexthdr)->seq);
+	case IPPROTO_UDP:
+		return ntohs(((struct udphdr *)nexthdr)->source);
+	default:
+		return 0;
+	}
+}
+
 static u64 __esp_seq(struct sk_buff *skb)
 {
 	u64 seq = ntohl(XFRM_SKB_CB(skb)->seq.input.low);
@@ -403,6 +437,13 @@  static int skb_copy_bits_seq(struct skb_seq_state *st, int offset, void *to,
 	}
 }
 
+/* ================================== */
+/* IPTFS Trace Event Definitions      */
+/* ================================== */
+
+#define CREATE_TRACE_POINTS
+#include "trace_iptfs.h"
+
 /* ================================== */
 /* IPTFS Receiving (egress) Functions */
 /* ================================== */
@@ -892,6 +933,8 @@  static int iptfs_input_ordered(struct xfrm_state *x, struct sk_buff *skb)
 	}
 	data = sizeof(*ipth);
 
+	trace_iptfs_egress_recv(skb, xtfs, be16_to_cpu(ipth->block_offset));
+
 	/* Set data past the basic header */
 	if (ipth->subtype == IPTFS_SUBTYPE_CC) {
 		/* Copy the rest of the CC header */
@@ -1787,6 +1830,7 @@  static int iptfs_output_collect(struct net *net, struct sock *sk,
 		 */
 		if (!ok) {
 nospace:
+			trace_iptfs_no_queue_space(skb, xtfs, pmtu, was_gso);
 			if (skb->dev)
 				XFRM_INC_STATS(dev_net(skb->dev),
 					       LINUX_MIB_XFRMOUTNOQSPACE);
@@ -1798,6 +1842,7 @@  static int iptfs_output_collect(struct net *net, struct sock *sk,
 		 * enqueue.
 		 */
 		if (xtfs->cfg.dont_frag && iptfs_is_too_big(sk, skb, pmtu)) {
+			trace_iptfs_too_big(skb, xtfs, pmtu, was_gso);
 			kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
 			continue;
 		}
@@ -1806,6 +1851,8 @@  static int iptfs_output_collect(struct net *net, struct sock *sk,
 		ok = iptfs_enqueue(xtfs, skb);
 		if (!ok)
 			goto nospace;
+
+		trace_iptfs_enqueue(skb, xtfs, pmtu, was_gso);
 	}
 
 	/* Start a delay timer if we don't have one yet */
@@ -1813,6 +1860,7 @@  static int iptfs_output_collect(struct net *net, struct sock *sk,
 		hrtimer_start(&xtfs->iptfs_timer, xtfs->init_delay_ns,
 			      IPTFS_HRTIMER_MODE);
 		xtfs->iptfs_settime = ktime_get_raw_fast_ns();
+		trace_iptfs_timer_start(xtfs, xtfs->init_delay_ns);
 	}
 
 	spin_unlock_bh(&x->lock);
@@ -1910,6 +1958,7 @@  static int iptfs_copy_create_frags(struct sk_buff **skbp,
 	to_copy = skb->len - offset;
 	while (to_copy) {
 		/* Send all but last fragment to allow agg. append */
+		trace_iptfs_first_fragmenting(nskb, mtu, to_copy, NULL);
 		list_add_tail(&nskb->list, &sublist);
 
 		/* FUTURE: if the packet has an odd/non-aligning length we could
@@ -1935,6 +1984,8 @@  static int iptfs_copy_create_frags(struct sk_buff **skbp,
 
 	/* return last fragment that will be unsent (or NULL) */
 	*skbp = nskb;
+	if (nskb)
+		trace_iptfs_first_final_fragment(nskb, mtu, blkoff, NULL);
 
 	/* trim the original skb to MTU */
 	if (!err)
@@ -2039,6 +2090,8 @@  static int iptfs_first_skb(struct sk_buff **skbp, struct xfrm_iptfs_data *xtfs,
 	/* We've split these up before queuing */
 	BUG_ON(skb_is_gso(skb));
 
+	trace_iptfs_first_dequeue(skb, mtu, 0, ip_hdr(skb));
+
 	/* Simple case -- it fits. `mtu` accounted for all the overhead
 	 * including the basic IPTFS header.
 	 */
@@ -2141,6 +2194,7 @@  static void iptfs_output_queued(struct xfrm_state *x, struct sk_buff_head *list)
 				XFRM_INC_STATS(dev_net(skb->dev),
 					       LINUX_MIB_XFRMOUTERROR);
 
+			trace_iptfs_first_toobig(skb, mtu, 0, ip_hdr(skb));
 			kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
 			continue;
 		}
@@ -2188,6 +2242,7 @@  static void iptfs_output_queued(struct xfrm_state *x, struct sk_buff_head *list)
 		 * case.
 		 */
 		while ((skb2 = skb_peek(list))) {
+			trace_iptfs_ingress_nth_peek(skb2, remaining);
 			if (skb2->len > remaining)
 				break;
 
@@ -2225,6 +2280,8 @@  static void iptfs_output_queued(struct xfrm_state *x, struct sk_buff_head *list)
 			skb->len += skb2->len;
 			remaining -= skb2->len;
 
+			trace_iptfs_ingress_nth_add(skb2, share_ok);
+
 			if (share_ok) {
 				iptfs_consume_frags(skb, skb2);
 			} else {
@@ -2274,6 +2331,9 @@  static enum hrtimer_restart iptfs_delay_timer(struct hrtimer *me)
 	 * already).
 	 */
 
+	trace_iptfs_timer_expire(
+		xtfs, (unsigned long long)(ktime_get_raw_fast_ns() - settime));
+
 	iptfs_output_queued(x, &list);
 
 	return HRTIMER_NORESTART;