[ovs-dev] [PATCH v3] packets: Reorganize the pkt_metadata structure.

Bhanuprakash Bodireddy bhanuprakash.bodireddy at intel.com
Tue Jul 25 04:14:44 UTC 2017


pkt_metadata_init() is called for every packet in userspace datapath and
initializes few members in pkt_metadata. Before this the members that
needs to be initialized are prefetched using pkt_metadata_prefetch_init().

The above functions are critical to the userspace datapath performance
and should be in sync. Any changes to the pkt_metadata should also include
changes to metadata_init() and prefetch_init() if necessary.

This commit slightly refactors the pkt_metadata structure and introduces
cache line markers to catch any violations to the structure. Also only
prefetch the cachelines having the members that needs to be zeroed out.

Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy at intel.com>
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
v2->v3: Use PADDED_MEMBERS_CACHELINE_MARKER.
v1->v2: Use PADDED_MEMBERS.

 lib/packets.h | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/lib/packets.h b/lib/packets.h
index 8c9c741..5314362 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -92,6 +92,7 @@ flow_tnl_equal(const struct flow_tnl *a, const struct flow_tnl *b)
 
 /* Datapath packet metadata */
 struct pkt_metadata {
+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0,
     uint32_t recirc_id;         /* Recirculation id carried with the
                                    recirculating packets. 0 for packets
                                    received from the wire. */
@@ -104,16 +105,29 @@ struct pkt_metadata {
     uint16_t ct_zone;           /* Connection zone. */
     uint32_t ct_mark;           /* Connection mark. */
     ovs_u128 ct_label;          /* Connection label. */
+    union flow_in_port in_port; /* Input port. */
+);
+
+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1,
     union {                     /* Populated only for non-zero 'ct_state'. */
         struct ovs_key_ct_tuple_ipv4 ipv4;
         struct ovs_key_ct_tuple_ipv6 ipv6;   /* Used only if                */
     } ct_orig_tuple;                         /* 'ct_orig_tuple_ipv6' is set */
-    union flow_in_port in_port; /* Input port. */
+);
+
+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline2,
     struct flow_tnl tunnel;     /* Encapsulating tunnel parameters. Note that
                                  * if 'ip_dst' == 0, the rest of the fields may
                                  * be uninitialized. */
+);
 };
 
+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline0) == 0);
+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline1) == \
+                           CACHE_LINE_SIZE);
+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline2) == \
+                           2 * CACHE_LINE_SIZE);
+
 static inline void
 pkt_metadata_init_tnl(struct pkt_metadata *md)
 {
@@ -148,7 +162,12 @@ pkt_metadata_init(struct pkt_metadata *md, odp_port_t port)
 static inline void
 pkt_metadata_prefetch_init(struct pkt_metadata *md)
 {
-    ovs_prefetch_range(md, offsetof(struct pkt_metadata, tunnel.ip_src));
+    /* Prefetch cacheline0 as members till ct_state and odp_port will
+     * be initialized later in pkt_metadata_init(). */
+    OVS_PREFETCH(md->cacheline0);
+
+    /* Prefetch cachline2 as ip_dst & ipv6_dst fields will be initialized. */
+    OVS_PREFETCH(md->cacheline2);
 }
 
 bool dpid_from_string(const char *s, uint64_t *dpidp);
-- 
2.4.11



More information about the dev mailing list