[ovs-dev] [PATCH RFC v1] Tracing Packets Traveling the Slow Path

Mick Tarsel mtarsel at gmail.com
Thu Jan 28 22:11:52 UTC 2016


This patch will uniquely assign an ID number to packets traveling in the slow
path and utilize the TRACE_EVENT macro in order to compute a packet's round-trip
time (RTT). There are 2 trace events, upcall_start and upcall_end. The first
trace event records which sk_buffer it is probing as well as the unique ID
associated with each packet. The unique ID will continue to stay with the packet
throughout OVS and allow us to use another trace_event (upcall_end) at the end
of the packet's journey in order to compute RTT. We cannot probe the sk_buffer
address because this will change when entering user space. Using these trace
events, we can utilize such tools as perf(with python) or systemtap to generate
benchmarks - perhaps providing some benchmark standard of packets traveling the
slow path. If tracing is disabled (debug fs not mounted) impact should be
minimal (see /Documentation/trace/). I have a python script to gather stats from
perf output. Example output found here:
https://gist.github.com/mtarsel/908667c1d0a6373c694c Another example of possible
output was previously posted to ovs-discuss here:
http://openvswitch.org/pipermail/discuss/2015-September/018924.html Note:
TRACE_EVENT's struct syntax will not comply with checkpatch.pl

Signed-off-by: Mick Tarsel mtarsel at gmail.com
---
 datapath/Makefile.am |    3 +
 datapath/Modules.mk  |    1 +
 datapath/datapath.c  |   10 +++++
 datapath/trace.h     |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 0 deletions(-)
 create mode 100644 datapath/trace.h

diff --git a/datapath/Makefile.am b/datapath/Makefile.am
index 458fa5b..0451d93 100644
--- a/datapath/Makefile.am
+++ b/datapath/Makefile.am
@@ -11,6 +11,9 @@ AUTOMAKE_OPTIONS = -Wno-portability
 include Modules.mk
 include linux/Modules.mk
 
+#for trace_event macro
+CFLAGS_datapath.o = -I$(src)
+
 # The following is based on commands for the Automake "distdir" target.
 distfiles: Makefile
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
diff --git a/datapath/Modules.mk b/datapath/Modules.mk
index 3ffeee2..ea70c87 100644
--- a/datapath/Modules.mk
+++ b/datapath/Modules.mk
@@ -41,6 +41,7 @@ openvswitch_headers = \
 	flow.h \
 	flow_netlink.h \
 	flow_table.h \
+	trace.h \
 	vlan.h \
 	vport.h \
 	vport-internal_dev.h \
diff --git a/datapath/datapath.c b/datapath/datapath.c
index e3d3c8c..ef91b8f 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -62,6 +62,10 @@
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
 
+/*define this only once and before trace.h is included*/
+#define CREATE_TRACE_POINTS
+#define "trace.h"
+
 int ovs_net_id __read_mostly;
 EXPORT_SYMBOL_GPL(ovs_net_id);
 
@@ -316,6 +320,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
 		goto err;
 	}
 
+	if (trace_upcall_start_enabled())
+		trace_upcall_start(skb, tag_packet(skb));
+
 	if (!skb_is_gso(skb))
 		err = queue_userspace_packet(dp, skb, key, upcall_info);
 	else
@@ -606,6 +613,9 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
 	}
 	OVS_CB(packet)->mru = mru;
 
+	if (trace_upcall_end_enabled())
+		trace_upcall_end(packet, report_packet(packet));
+
 	/* Build an sw_flow for sending this packet. */
 	flow = ovs_flow_alloc();
 	err = PTR_ERR(flow);
diff --git a/datapath/trace.h b/datapath/trace.h
new file mode 100644
index 0000000..5c395d5
--- /dev/null
+++ b/datapath/trace.h
@@ -0,0 +1,106 @@
+/* Written by Mick Tarsel */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM openvswitch
+
+#if !defined(_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+
+#include <linux/tracepoint.h>
+
+#if !defined(_TRACE_H_)
+
+struct packet_tag {
+	char eyeCatch;
+	unsigned long reqid;
+};
+
+#define TAGGED 0x69
+
+static inline int tag_packet(struct sk_buff *skb)
+{
+	struct packet_tag pkt_id;
+	static unsigned int id;
+	unsigned char *temp_pkt;
+
+	pkt_id.eyeCatch = TAGGED;
+	pkt_id.reqid = ++id;
+
+	if (sizeof(struct packet_tag) <= skb_tailroom(skb)) {
+		temp_pkt = skb_put(skb, sizeof(pkt_id));
+		memcpy(temp_pkt, &pkt_id, sizeof(pkt_id));
+		pr_debug("%s:skb=%p reqid=%lu\n", __func__, skb, pkt_id.reqid);
+		return id;
+	}
+
+	if (net_ratelimit())
+		pr_debug("%s:Insufficient room to tag skb=%p\n", __func__, skb);
+
+	return 0;
+}
+
+static inline int report_packet(struct sk_buff *skb)
+{
+	struct packet_tag *pkt_id;
+	unsigned char *temp_pkt;
+
+	temp_pkt = (skb->data)+(skb->len) - sizeof(struct packet_tag);
+	pkt_id = (struct packet_tag *)temp_pkt;
+
+	if (pkt_id->eyeCatch == TAGGED) {
+		pr_debug("%s:skb=%p reqid=%lu\n", __func__, skb, pkt_id->reqid);
+		return pkt_id->reqid;
+	}
+
+	return 0;
+}
+
+#endif
+
+#define _TRACE_H_
+
+/* Tracepoint for OVS packets: traces packets travelling between kernel
+and userspace to compute RTT of a packet travelling in the slow path*/
+
+/* upcall_start is the trace event which is invoked after the packet has been
+tagged by tag_packet(). This newly tagged packet will exit kernel space
+and travel into user space to be assigned to a new flow.*/
+
+TRACE_EVENT(upcall_start,
+
+	TP_PROTO(struct sk_buff *skb, int id),
+
+	TP_ARGS(skb, id),
+
+	TP_STRUCT__entry(
+		__field(    const void *,     skbaddr     )
+		__field(    u16,     protocol     )
+		__field(    int,        id      )
+	),
+
+	TP_fast_assign(
+		__entry->skbaddr = skb;
+		__entry->protocol = ntohs(skb->protocol);
+		__entry->id = (const int) id;
+	),
+
+	TP_printk("skbaddr=%p proto=0x%04x id=%d\n",
+		  __entry->skbaddr, __entry->protocol, __entry->id)
+);
+
+/* define from upcall_start trace event a new event with the same proto,
+ and args instead named upcall_end */
+DEFINE_EVENT(upcall_start, upcall_end,
+	TP_PROTO(struct sk_buff *skb, int id),
+	TP_ARGS(skb, id)
+);
+
+#endif /*_TRACE_TRACE_H || TRACE_HEADER_MULTI_READ */
+
+/* our file is not located in include/trace/events - the default location*/
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
1.7.1




More information about the dev mailing list