ixgbe: Trace Rx and Tx events
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a2b2ad1..a1c0fb8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -46,6 +46,9 @@
 #include "ixgbe_model.h"
 #include "ixgbe_txrx_common.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/ixgbe.h>
+
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
 			      "Intel(R) 10 Gigabit PCI Express Network Driver";
@@ -1202,6 +1205,9 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 		budget--;
 	} while (likely(budget));
 
+	if (total_packets)
+		trace_ixgbe_tx_done(adapter->netdev, total_packets);
+
 	i += tx_ring->count;
 	tx_ring->next_to_clean = i;
 	u64_stats_update_begin(&tx_ring->syncp);
@@ -2403,6 +2409,9 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 		total_rx_packets++;
 	}
 
+	if (total_rx_packets)
+		trace_ixgbe_rx(adapter->netdev, total_rx_packets, budget);
+
 	if (xdp_xmit & IXGBE_XDP_REDIR)
 		xdp_do_flush_map();
 
@@ -3167,6 +3176,8 @@ int ixgbe_poll(struct napi_struct *napi, int budget)
 		ixgbe_update_dca(q_vector);
 #endif
 
+	trace_ixgbe_poll(adapter->netdev, budget);
+
 	ixgbe_for_each_ring(ring, q_vector->tx) {
 		bool wd = ring->xsk_umem ?
 			  ixgbe_clean_xdp_tx_irq(q_vector, ring, budget) :
@@ -3319,6 +3330,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
 		return IRQ_NONE;	/* Not our interrupt */
 	}
 
+	trace_ixgbe_intr(adapter->netdev, eicr);
+
 	if (eicr & IXGBE_EICR_LSC)
 		ixgbe_check_lsc(adapter);
 
@@ -8217,7 +8230,7 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 	union ixgbe_adv_tx_desc *tx_desc;
 	skb_frag_t *frag;
 	dma_addr_t dma;
-	unsigned int data_len, size;
+	unsigned int data_len, size, count = 0;
 	u32 tx_flags = first->tx_flags;
 	u32 cmd_type = ixgbe_tx_cmd_type(skb, tx_flags);
 	u16 i = tx_ring->next_to_use;
@@ -8251,6 +8264,7 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 		/* record length, and DMA address */
 		dma_unmap_len_set(tx_buffer, len, size);
 		dma_unmap_addr_set(tx_buffer, dma, dma);
+		count++;
 
 		tx_desc->read.buffer_addr = cpu_to_le64(dma);
 
@@ -8334,6 +8348,7 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 		writel(i, tx_ring->tail);
 	}
 
+	trace_ixgbe_tx(tx_ring->netdev, count);
 	return 0;
 dma_error:
 	dev_err(tx_ring->dev, "TX DMA map failed\n");
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index b43be9f..961e91c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -4,6 +4,7 @@
 #include <linux/bpf_trace.h>
 #include <net/xdp_sock.h>
 #include <net/xdp.h>
+#include <trace/events/ixgbe.h>
 
 #include "ixgbe.h"
 #include "ixgbe_txrx_common.h"
@@ -539,6 +540,8 @@ int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
 		writel(ring->next_to_use, ring->tail);
 	}
 
+	trace_ixgbe_rx(adapter->netdev, total_rx_packets, budget);
+
 	u64_stats_update_begin(&rx_ring->syncp);
 	rx_ring->stats.packets += total_rx_packets;
 	rx_ring->stats.bytes += total_rx_bytes;
diff --git a/include/trace/events/ixgbe.h b/include/trace/events/ixgbe.h
new file mode 100644
index 0000000..6260151
--- /dev/null
+++ b/include/trace/events/ixgbe.h
@@ -0,0 +1,119 @@
+/* Realtek IXGBE tracepoints
+ *
+ * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ixgbe
+
+#if !defined(_TRACE_IXGBE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IXGBE_H
+
+#include <linux/tracepoint.h>
+#include <linux/errqueue.h>
+
+
+TRACE_EVENT(ixgbe_intr,
+	    TP_PROTO(struct net_device *netdev, u32 eicr),
+
+	    TP_ARGS(netdev, eicr),
+
+	    TP_STRUCT__entry(
+		    __field(u32,			eicr		)
+		    __array(char,			name, IFNAMSIZ	)
+			     ),
+
+	    TP_fast_assign(
+		    __entry->eicr = eicr;
+		    memcpy(__entry->name, netdev->name, IFNAMSIZ);
+			   ),
+
+	    TP_printk("%s eicr=%x", __entry->name, __entry->eicr)
+	    );
+
+TRACE_EVENT(ixgbe_poll,
+	    TP_PROTO(struct net_device *netdev, int budget),
+
+	    TP_ARGS(netdev, budget),
+
+	    TP_STRUCT__entry(
+		    __field(int,			budget		)
+		    __array(char,			name, IFNAMSIZ	)
+			     ),
+
+	    TP_fast_assign(
+		    __entry->budget = budget;
+		    memcpy(__entry->name, netdev->name, IFNAMSIZ);
+			   ),
+
+	    TP_printk("%s b=%d", __entry->name, __entry->budget)
+	    );
+
+TRACE_EVENT(ixgbe_rx,
+	    TP_PROTO(struct net_device *netdev, unsigned int count, int budget),
+
+	    TP_ARGS(netdev, count, budget),
+
+	    TP_STRUCT__entry(
+		    __field(unsigned int,		count		)
+		    __field(int,			budget		)
+		    __array(char,			name, IFNAMSIZ	)
+			     ),
+
+	    TP_fast_assign(
+		    __entry->count = count;
+		    __entry->budget = budget;
+		    memcpy(__entry->name, netdev->name, IFNAMSIZ);
+			   ),
+
+	    TP_printk("%s c=%u/%d",
+		      __entry->name, __entry->count, __entry->budget)
+	    );
+
+TRACE_EVENT(ixgbe_tx,
+	    TP_PROTO(struct net_device *netdev, unsigned int count),
+
+	    TP_ARGS(netdev, count),
+
+	    TP_STRUCT__entry(
+		    __field(unsigned int,		count		)
+		    __array(char,			name, IFNAMSIZ	)
+			     ),
+
+	    TP_fast_assign(
+		    __entry->count = count;
+		    memcpy(__entry->name, netdev->name, IFNAMSIZ);
+			   ),
+
+	    TP_printk("%s c=%u",
+		      __entry->name, __entry->count)
+	    );
+
+TRACE_EVENT(ixgbe_tx_done,
+	    TP_PROTO(struct net_device *netdev, unsigned int count),
+
+	    TP_ARGS(netdev, count),
+
+	    TP_STRUCT__entry(
+		    __field(unsigned int,		count		)
+		    __array(char,			name, IFNAMSIZ	)
+			     ),
+
+	    TP_fast_assign(
+		    __entry->count = count;
+		    memcpy(__entry->name, netdev->name, IFNAMSIZ);
+			   ),
+
+	    TP_printk("%s c=%u",
+		      __entry->name, __entry->count)
+	    );
+
+#endif /* _TRACE_IXGBE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>