Add tracepoints for Realtek r8169
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 549be1c..a448482 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -32,6 +32,9 @@
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/net_rtl8169.h>
+
#define MODULENAME "r8169"
#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
@@ -5997,6 +6000,28 @@
return slots_avail > nr_frags;
}
+static void dhowells_trace_xmit(struct rtl8169_private *tp)
+{
+ unsigned int dirty_tx, cursor, n = 0;
+
+ dirty_tx = tp->dirty_tx;
+ smp_rmb();
+
+ for (cursor = dirty_tx; cursor != tp->cur_tx; cursor++) {
+ unsigned int entry = cursor % NUM_TX_DESC;
+ u32 status;
+
+ status = le32_to_cpu(tp->TxDescArray[entry].opts1);
+ if (status & DescOwn)
+ break;
+ n++;
+ if (n >= 32)
+ break;
+ }
+
+ trace_net_rtl8169_tx(tp->dev, dirty_tx, tp->cur_tx, n);
+}
+
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -6058,6 +6083,7 @@
/* Force all memory writes to complete before notifying device */
wmb();
+ dhowells_trace_xmit(tp);
tp->cur_tx += frags + 1;
@@ -6197,6 +6223,8 @@
if (tp->cur_tx != dirty_tx)
RTL_W8(tp, TxPoll, NPQ);
}
+
+ trace_net_rtl8169_napi_tx(dev, tx_left);
}
static inline int rtl8169_fragmented_frame(u32 status)
@@ -6327,6 +6355,7 @@
count = cur_rx - tp->cur_rx;
tp->cur_rx = cur_rx;
+ trace_net_rtl8169_napi_rx(dev, count, budget);
return count;
}
@@ -6338,6 +6367,9 @@
if (!tp->irq_enabled || status == 0xffff || !(status & tp->irq_mask))
return IRQ_NONE;
+ if (status && status != 0xffff)
+ trace_net_rtl8169_interrupt(tp->napi.dev, status);
+
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(tp->dev);
goto out;
@@ -6399,6 +6431,7 @@
int work_done;
work_done = rtl_rx(dev, tp, (u32) budget);
+ trace_net_rtl8169_poll(dev, work_done);
rtl_tx(dev, tp, budget);
diff --git a/include/trace/events/net_rtl8169.h b/include/trace/events/net_rtl8169.h
new file mode 100644
index 0000000..8cc911b
--- /dev/null
+++ b/include/trace/events/net_rtl8169.h
@@ -0,0 +1,125 @@
+/* Realtek RTL8169 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 net_rtl8169
+
+#if !defined(_TRACE_NET_RTL8169_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_NET_RTL8169_H
+
+#include <linux/tracepoint.h>
+#include <linux/errqueue.h>
+
+
+TRACE_EVENT(net_rtl8169_interrupt,
+ TP_PROTO(struct net_device *netdev, u16 status),
+
+ TP_ARGS(netdev, status),
+
+ TP_STRUCT__entry(
+ __field(u16, status )
+ __array(char, name, IFNAMSIZ )
+ ),
+
+ TP_fast_assign(
+ __entry->status = status;
+ memcpy(__entry->name, netdev->name, IFNAMSIZ);
+ ),
+
+ TP_printk("%s st=%x", __entry->name, __entry->status)
+ );
+
+TRACE_EVENT(net_rtl8169_poll,
+ TP_PROTO(struct net_device *netdev, int work_done),
+
+ TP_ARGS(netdev, work_done),
+
+ TP_STRUCT__entry(
+ __field(int, work_done )
+ __array(char, name, IFNAMSIZ )
+ ),
+
+ TP_fast_assign(
+ __entry->work_done = work_done;
+ memcpy(__entry->name, netdev->name, IFNAMSIZ);
+ ),
+
+ TP_printk("%s wd=%d", __entry->name, __entry->work_done)
+ );
+
+TRACE_EVENT(net_rtl8169_napi_rx,
+ TP_PROTO(struct net_device *netdev, unsigned int count, u32 budget),
+
+ TP_ARGS(netdev, count, budget),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, count )
+ __field(u32, budget )
+ __array(char, name, IFNAMSIZ )
+ ),
+
+ TP_fast_assign(
+ __entry->count = count;
+ __entry->budget = budget;
+ memcpy(__entry->name, netdev->name, IFNAMSIZ);
+ ),
+
+ TP_printk("%s count=%d/%d",
+ __entry->name, __entry->count, __entry->budget)
+ );
+
+TRACE_EVENT(net_rtl8169_napi_tx,
+ TP_PROTO(struct net_device *netdev, unsigned int tx_left),
+
+ TP_ARGS(netdev, tx_left),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, tx_left )
+ __array(char, name, IFNAMSIZ )
+ ),
+
+ TP_fast_assign(
+ __entry->tx_left = tx_left;
+ memcpy(__entry->name, netdev->name, IFNAMSIZ);
+ ),
+
+ TP_printk("%s l=%u",
+ __entry->name, __entry->tx_left)
+ );
+
+TRACE_EVENT(net_rtl8169_tx,
+ TP_PROTO(struct net_device *netdev, unsigned int dirty_tx,
+ unsigned int cur_tx, unsigned int n),
+
+ TP_ARGS(netdev, dirty_tx, cur_tx, n),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, dirty_tx )
+ __field(unsigned int, cur_tx )
+ __field(unsigned int, n )
+ __array(char, name, IFNAMSIZ )
+ ),
+
+ TP_fast_assign(
+ __entry->dirty_tx = dirty_tx;
+ __entry->cur_tx = cur_tx;
+ __entry->n = n;
+ memcpy(__entry->name, netdev->name, IFNAMSIZ);
+ ),
+
+ TP_printk("%s p=%u/%u n=%u",
+ __entry->name, __entry->dirty_tx, __entry->cur_tx,
+ __entry->n)
+ );
+
+#endif /* _TRACE_NET_RTL8169_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>