As a preparation for tracking inner checksums, separate Rx checksum
status from the DPDK ol_flags field.
To minimize the cost of translating from DPDK API to OVS API, simply map
OVS flags to DPDK Rx mbuf flags.

Signed-off-by: David Marchand <david.march...@redhat.com>
---
Changes since v1:
- fixed patch reordering issue: introduce offloads field in this patch,

---
 lib/dp-packet-gso.c |   3 ++
 lib/dp-packet.c     |   2 +-
 lib/dp-packet.h     | 128 ++++++++++++++++++++++----------------------
 lib/netdev-dpdk.c   |  22 +++++++-
 lib/netdev-dummy.c  |  16 +++---
 5 files changed, 95 insertions(+), 76 deletions(-)

diff --git a/lib/dp-packet-gso.c b/lib/dp-packet-gso.c
index 80652ba9f9..a109631d2c 100644
--- a/lib/dp-packet-gso.c
+++ b/lib/dp-packet-gso.c
@@ -51,7 +51,9 @@ dp_packet_gso_seg_new(const struct dp_packet *p, size_t 
hdr_len,
     seg->inner_l4_ofs = p->inner_l4_ofs;
 
     /* The protocol headers remain the same, so preserve hash and mark. */
+    seg->has_hash = p->has_hash;
     *dp_packet_rss_ptr(seg) = *dp_packet_rss_ptr(p);
+    seg->has_mark = p->has_mark;
     *dp_packet_flow_mark_ptr(seg) = *dp_packet_flow_mark_ptr(p);
 
     /* The segment should inherit all the offloading flags from the
@@ -59,6 +61,7 @@ dp_packet_gso_seg_new(const struct dp_packet *p, size_t 
hdr_len,
      * buffer and indirect buffer flags. */
     *dp_packet_ol_flags_ptr(seg) = *dp_packet_ol_flags_ptr(p)
         & DP_PACKET_OL_SUPPORTED_MASK;
+    seg->offloads = p->offloads;
 
     dp_packet_hwol_reset_tcp_seg(seg);
 
diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 6a9bfd63ba..313f783224 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -193,7 +193,7 @@ dp_packet_clone_with_headroom(const struct dp_packet 
*buffer, size_t headroom)
                                                     dp_packet_size(buffer),
                                                     headroom);
     /* Copy the following fields into the returned buffer: l2_pad_size,
-     * l2_5_ofs, l3_ofs, l4_ofs, cutlen, packet_type and md. */
+     * l2_5_ofs, l3_ofs, l4_ofs, cutlen, packet_type, offloads and md. */
     memcpy(&new_buffer->l2_pad_size, &buffer->l2_pad_size,
             sizeof(struct dp_packet) -
             offsetof(struct dp_packet, l2_pad_size));
diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index cf33aa83e0..345a690242 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -56,22 +56,8 @@ enum OVS_PACKED_ENUM dp_packet_source {
 #endif
 
 /* Bit masks for the 'ol_flags' member of the 'dp_packet' structure. */
-enum dp_packet_offload_mask {
+enum {
     /* Value 0 is not used. */
-    /* Is the 'rss_hash' valid? */
-    DEF_OL_FLAG(DP_PACKET_OL_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, 0x1),
-    /* Is the 'flow_mark' valid? */
-    DEF_OL_FLAG(DP_PACKET_OL_FLOW_MARK, RTE_MBUF_F_RX_FDIR_ID, 0x2),
-    /* Bad L4 checksum in the packet. */
-    DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_BAD, RTE_MBUF_F_RX_L4_CKSUM_BAD, 0x4),
-    /* Bad IP checksum in the packet. */
-    DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_BAD, RTE_MBUF_F_RX_IP_CKSUM_BAD, 0x8),
-    /* Valid L4 checksum in the packet. */
-    DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_GOOD,
-                0x10),
-    /* Valid IP checksum in the packet. */
-    DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_GOOD,
-                0x20),
     /* TCP Segmentation Offload. */
     DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, RTE_MBUF_F_TX_TCP_SEG, 0x40),
     /* Offload TCP checksum. */
@@ -101,13 +87,7 @@ enum dp_packet_offload_mask {
     /* Adding new field requires adding to DP_PACKET_OL_SUPPORTED_MASK. */
 };
 
-#define DP_PACKET_OL_SUPPORTED_MASK (DP_PACKET_OL_RSS_HASH           | \
-                                     DP_PACKET_OL_FLOW_MARK          | \
-                                     DP_PACKET_OL_RX_L4_CKSUM_BAD    | \
-                                     DP_PACKET_OL_RX_IP_CKSUM_BAD    | \
-                                     DP_PACKET_OL_RX_L4_CKSUM_GOOD   | \
-                                     DP_PACKET_OL_RX_IP_CKSUM_GOOD   | \
-                                     DP_PACKET_OL_TX_TCP_SEG         | \
+#define DP_PACKET_OL_SUPPORTED_MASK (DP_PACKET_OL_TX_TCP_SEG         | \
                                      DP_PACKET_OL_TX_TCP_CKSUM       | \
                                      DP_PACKET_OL_TX_UDP_CKSUM       | \
                                      DP_PACKET_OL_TX_SCTP_CKSUM      | \
@@ -125,10 +105,31 @@ enum dp_packet_offload_mask {
                                    DP_PACKET_OL_TX_IP_CKSUM | \
                                    DP_PACKET_OL_TX_OUTER_IP_CKSUM | \
                                    DP_PACKET_OL_TX_OUTER_UDP_CKSUM)
-#define DP_PACKET_OL_RX_IP_CKSUM_MASK (DP_PACKET_OL_RX_IP_CKSUM_GOOD | \
-                                       DP_PACKET_OL_RX_IP_CKSUM_BAD)
-#define DP_PACKET_OL_RX_L4_CKSUM_MASK (DP_PACKET_OL_RX_L4_CKSUM_GOOD | \
-                                       DP_PACKET_OL_RX_L4_CKSUM_BAD)
+
+/* Bit masks for the 'offloads' member of the 'dp_packet' structure. */
+enum OVS_PACKED_ENUM dp_packet_offload_mask {
+    /* Bad IP checksum in the packet. */
+    DP_PACKET_OL_IP_CKSUM_BAD = UINT16_C(1) << 4,
+    /* Valid IP checksum in the packet. */
+    DP_PACKET_OL_IP_CKSUM_GOOD = UINT16_C(1) << 7,
+
+    /* Bad L4 checksum in the packet. */
+    DP_PACKET_OL_L4_CKSUM_BAD = UINT16_C(1) << 3,
+    /* Valid L4 checksum in the packet. */
+    DP_PACKET_OL_L4_CKSUM_GOOD = UINT16_C(1) << 8,
+};
+
+#ifdef DPDK_NETDEV
+BUILD_ASSERT_DECL(DP_PACKET_OL_IP_CKSUM_BAD == RTE_MBUF_F_RX_IP_CKSUM_BAD);
+BUILD_ASSERT_DECL(DP_PACKET_OL_IP_CKSUM_GOOD == RTE_MBUF_F_RX_IP_CKSUM_GOOD);
+BUILD_ASSERT_DECL(DP_PACKET_OL_L4_CKSUM_BAD == RTE_MBUF_F_RX_L4_CKSUM_BAD);
+BUILD_ASSERT_DECL(DP_PACKET_OL_L4_CKSUM_GOOD == RTE_MBUF_F_RX_L4_CKSUM_GOOD);
+#endif
+
+#define DP_PACKET_OL_IP_CKSUM_MASK (DP_PACKET_OL_IP_CKSUM_GOOD | \
+                                    DP_PACKET_OL_IP_CKSUM_BAD)
+#define DP_PACKET_OL_L4_CKSUM_MASK (DP_PACKET_OL_L4_CKSUM_GOOD | \
+                                    DP_PACKET_OL_L4_CKSUM_BAD)
 
 /* Buffer for holding packet data.  A dp_packet is automatically reallocated
  * as necessary if it grows too large for the available memory.
@@ -148,6 +149,8 @@ struct dp_packet {
     uint16_t tso_segsz;         /* TCP segment size. */
 #endif
     enum dp_packet_source source;  /* Source of memory allocated as 'base'. */
+    bool has_hash;                 /* Is the 'rss_hash' valid? */
+    bool has_mark;                 /* Is the 'flow_mark' valid? */
 
     /* All the following elements of this struct are copied in a single call
      * of memcpy in dp_packet_clone_with_headroom. */
@@ -164,12 +167,17 @@ struct dp_packet {
                                       or UINT16_MAX. */
     uint32_t cutlen;               /* length in bytes to cut from the end. */
     ovs_be32 packet_type;          /* Packet type as defined in OpenFlow */
+    enum OVS_PACKED_ENUM dp_packet_offload_mask offloads;
+                                   /* Checksums status and offloads. */
     union {
         struct pkt_metadata md;
         uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
     };
 };
 
+BUILD_ASSERT_DECL(MEMBER_SIZEOF(struct dp_packet, offloads)
+                  <= sizeof(uint32_t));
+
 #if HAVE_AF_XDP
 struct dp_packet_afxdp {
     struct umem_pool *mpool;
@@ -995,17 +1003,6 @@ dp_packet_delete_batch(struct dp_packet_batch *batch, 
bool should_steal)
     }
 }
 
-static inline void
-dp_packet_batch_init_packet_fields(struct dp_packet_batch *batch)
-{
-    struct dp_packet *packet;
-
-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
-        dp_packet_reset_cutlen(packet);
-        packet->packet_type = htonl(PT_ETH);
-    }
-}
-
 static inline void
 dp_packet_batch_apply_cutlen(struct dp_packet_batch *batch)
 {
@@ -1045,25 +1042,27 @@ static inline void
 dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
 {
     *dp_packet_rss_ptr(p) = hash;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RSS_HASH;
+    p->has_hash = true;
 }
 
 static inline bool
 dp_packet_rss_valid(const struct dp_packet *p)
 {
-    return *dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RSS_HASH;
+    return p->has_hash;
 }
 
 static inline void
 dp_packet_reset_offload(struct dp_packet *p)
 {
     *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_SUPPORTED_MASK;
+    p->has_hash = p->has_mark = false;
+    p->offloads = 0;
 }
 
 static inline bool
 dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark)
 {
-    if (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_FLOW_MARK) {
+    if (p->has_mark) {
         *mark = *dp_packet_flow_mark_ptr(p);
         return true;
     }
@@ -1075,7 +1074,7 @@ static inline void
 dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark)
 {
     *dp_packet_flow_mark_ptr(p) = mark;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_FLOW_MARK;
+    p->has_mark = true;
 }
 
 /* Returns the L4 cksum offload bitmask. */
@@ -1291,9 +1290,8 @@ dp_packet_hwol_reset_tcp_seg(struct dp_packet *p)
                         | DP_PACKET_OL_TX_TCP_CKSUM;
     const struct ip_header *ip_hdr;
 
-    ol_flags = ol_flags & ~(DP_PACKET_OL_TX_TCP_SEG
-                            | DP_PACKET_OL_RX_L4_CKSUM_GOOD
-                            | DP_PACKET_OL_RX_IP_CKSUM_GOOD);
+    ol_flags &= ~DP_PACKET_OL_TX_TCP_SEG;
+    p->offloads &= ~(DP_PACKET_OL_L4_CKSUM_GOOD | DP_PACKET_OL_IP_CKSUM_GOOD);
 
     if (dp_packet_hwol_is_tunnel(p)) {
         ip_hdr = dp_packet_inner_l3(p);
@@ -1324,37 +1322,37 @@ dp_packet_hwol_reset_tcp_seg(struct dp_packet *p)
 static inline bool
 dp_packet_ip_checksum_good(const struct dp_packet *p)
 {
-    return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) ==
-            DP_PACKET_OL_RX_IP_CKSUM_GOOD;
+    return (p->offloads & DP_PACKET_OL_IP_CKSUM_MASK)
+            == DP_PACKET_OL_IP_CKSUM_GOOD;
 }
 
 /* Marks packet 'p' with good IPv4 checksum. */
 static inline void
 dp_packet_ol_set_ip_csum_good(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_IP_CKSUM_BAD;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_IP_CKSUM_GOOD;
+    p->offloads &= ~DP_PACKET_OL_IP_CKSUM_BAD;
+    p->offloads |= DP_PACKET_OL_IP_CKSUM_GOOD;
 }
 
 /* Resets IP good checksum flag in packet 'p'. */
 static inline void
 dp_packet_ol_reset_ip_csum_good(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_IP_CKSUM_GOOD;
+    p->offloads &= ~DP_PACKET_OL_IP_CKSUM_GOOD;
 }
 
 static inline bool
 dp_packet_ip_checksum_bad(const struct dp_packet *p)
 {
-    return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) ==
-            DP_PACKET_OL_RX_IP_CKSUM_BAD;
+    return (p->offloads & DP_PACKET_OL_IP_CKSUM_MASK)
+            == DP_PACKET_OL_IP_CKSUM_BAD;
 }
 
 static inline void
 dp_packet_ol_set_ip_csum_bad(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_IP_CKSUM_GOOD;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_IP_CKSUM_BAD;
+    p->offloads &= ~DP_PACKET_OL_IP_CKSUM_GOOD;
+    p->offloads |= DP_PACKET_OL_IP_CKSUM_BAD;
 }
 
 /* Return 'true' is packet 'b' is not encapsulated and is marked for IPv4
@@ -1427,15 +1425,15 @@ dp_packet_ip_set_header_csum(struct dp_packet *p, bool 
inner)
 static inline bool
 dp_packet_l4_checksum_good(const struct dp_packet *p)
 {
-    return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) ==
-            DP_PACKET_OL_RX_L4_CKSUM_GOOD;
+    return (p->offloads & DP_PACKET_OL_L4_CKSUM_MASK)
+            == DP_PACKET_OL_L4_CKSUM_GOOD;
 }
 
 static inline bool
 dp_packet_l4_checksum_bad(const struct dp_packet *p)
 {
-    return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) ==
-            DP_PACKET_OL_RX_L4_CKSUM_BAD;
+    return (p->offloads & DP_PACKET_OL_L4_CKSUM_MASK)
+            == DP_PACKET_OL_L4_CKSUM_BAD;
 }
 
 /* Returns 'true' if the packet has good integrity though the
@@ -1443,8 +1441,8 @@ dp_packet_l4_checksum_bad(const struct dp_packet *p)
 static inline bool
 dp_packet_ol_l4_csum_partial(const struct dp_packet *p)
 {
-    return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) ==
-            DP_PACKET_OL_RX_L4_CKSUM_MASK;
+    return (p->offloads & DP_PACKET_OL_L4_CKSUM_MASK)
+            == DP_PACKET_OL_L4_CKSUM_MASK;
 }
 
 /* Marks packet 'p' with good integrity though the checksum in the
@@ -1452,15 +1450,15 @@ dp_packet_ol_l4_csum_partial(const struct dp_packet *p)
 static inline void
 dp_packet_ol_set_l4_csum_partial(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_L4_CKSUM_MASK;
+    p->offloads |= DP_PACKET_OL_L4_CKSUM_MASK;
 }
 
 /* Marks packet 'p' with good L4 checksum. */
 static inline void
 dp_packet_ol_set_l4_csum_good(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_L4_CKSUM_BAD;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_L4_CKSUM_GOOD;
+    p->offloads &= ~DP_PACKET_OL_L4_CKSUM_BAD;
+    p->offloads |= DP_PACKET_OL_L4_CKSUM_GOOD;
 }
 
 /* Marks packet 'p' with good L4 checksum as modified. */
@@ -1468,15 +1466,15 @@ static inline void
 dp_packet_ol_reset_l4_csum_good(struct dp_packet *p)
 {
     if (!dp_packet_ol_l4_csum_partial(p)) {
-        *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_L4_CKSUM_GOOD;
+        p->offloads &= ~DP_PACKET_OL_L4_CKSUM_GOOD;
     }
 }
 
 static inline void
 dp_packet_ol_set_l4_csum_bad(struct dp_packet *p)
 {
-    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_L4_CKSUM_GOOD;
-    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_L4_CKSUM_BAD;
+    p->offloads &= ~DP_PACKET_OL_L4_CKSUM_GOOD;
+    p->offloads |= DP_PACKET_OL_L4_CKSUM_BAD;
 }
 
 static inline void
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 1ef8abc723..6172cbfec7 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -2623,6 +2623,24 @@ netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq)
     rte_free(rx);
 }
 
+static inline void
+netdev_dpdk_batch_init_packet_fields(struct dp_packet_batch *batch)
+{
+    struct dp_packet *packet;
+
+    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
+        dp_packet_reset_cutlen(packet);
+        packet->packet_type = htonl(PT_ETH);
+        packet->has_hash = !!(packet->mbuf.ol_flags & RTE_MBUF_F_RX_RSS_HASH);
+        packet->has_mark = !!(packet->mbuf.ol_flags & RTE_MBUF_F_RX_FDIR_ID);
+        packet->offloads =
+            packet->mbuf.ol_flags & (RTE_MBUF_F_RX_IP_CKSUM_BAD
+                                     | RTE_MBUF_F_RX_IP_CKSUM_GOOD
+                                     | RTE_MBUF_F_RX_L4_CKSUM_BAD
+                                     | RTE_MBUF_F_RX_L4_CKSUM_GOOD);
+    }
+}
+
 /* Prepare the packet for HWOL.
  * Return True if the packet is OK to continue. */
 static bool
@@ -2972,7 +2990,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
     }
 
     batch->count = nb_rx;
-    dp_packet_batch_init_packet_fields(batch);
+    netdev_dpdk_batch_init_packet_fields(batch);
 
     return 0;
 }
@@ -3023,7 +3041,7 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct 
dp_packet_batch *batch,
     }
 
     batch->count = nb_rx;
-    dp_packet_batch_init_packet_fields(batch);
+    netdev_dpdk_batch_init_packet_fields(batch);
 
     if (qfill) {
         if (nb_rx == NETDEV_MAX_BURST) {
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 6acf6b5986..f7a1988dea 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -1216,13 +1216,13 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct 
dp_packet_batch *batch,
         bool l4_csum_bad;
 
         ip_csum_good = !!(*dp_packet_ol_flags_ptr(packet)
-                          & DP_PACKET_OL_RX_IP_CKSUM_GOOD);
+                          & DP_PACKET_OL_IP_CKSUM_GOOD);
         ip_csum_bad = !!(*dp_packet_ol_flags_ptr(packet)
-                         & DP_PACKET_OL_RX_IP_CKSUM_BAD);
+                         & DP_PACKET_OL_IP_CKSUM_BAD);
         l4_csum_good = !!(*dp_packet_ol_flags_ptr(packet)
-                          & DP_PACKET_OL_RX_L4_CKSUM_GOOD);
+                          & DP_PACKET_OL_L4_CKSUM_GOOD);
         l4_csum_bad = !!(*dp_packet_ol_flags_ptr(packet)
-                         & DP_PACKET_OL_RX_L4_CKSUM_BAD);
+                         & DP_PACKET_OL_L4_CKSUM_BAD);
         VLOG_DBG("Rx: packet with csum IP %s, L4 %s, segsz %"PRIu16,
                  ip_csum_good ? (ip_csum_bad ? "good+bad" : "good")
                               : (ip_csum_bad ? "bad" : "unknown"),
@@ -1334,13 +1334,13 @@ netdev_dummy_send(struct netdev *netdev, int qid,
             bool l4_csum_bad;
 
             ip_csum_good = !!(*dp_packet_ol_flags_ptr(packet)
-                              & DP_PACKET_OL_RX_IP_CKSUM_GOOD);
+                              & DP_PACKET_OL_IP_CKSUM_GOOD);
             ip_csum_bad = !!(*dp_packet_ol_flags_ptr(packet)
-                             & DP_PACKET_OL_RX_IP_CKSUM_BAD);
+                             & DP_PACKET_OL_IP_CKSUM_BAD);
             l4_csum_good = !!(*dp_packet_ol_flags_ptr(packet)
-                              & DP_PACKET_OL_RX_L4_CKSUM_GOOD);
+                              & DP_PACKET_OL_L4_CKSUM_GOOD);
             l4_csum_bad = !!(*dp_packet_ol_flags_ptr(packet)
-                             & DP_PACKET_OL_RX_L4_CKSUM_BAD);
+                             & DP_PACKET_OL_L4_CKSUM_BAD);
             VLOG_DBG("Tx: packet with csum IP %s, L4 %s, segsz %"PRIu16
                      ", Tx flags %s, %s, %s",
                      ip_csum_good ? (ip_csum_bad ? "good+bad" : "good")
-- 
2.48.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to