lib: upgrade to DPDK v1.8.0
authorMark Kavanagh <mark.b.kavanagh@intel.com>
Tue, 17 Feb 2015 21:20:04 +0000 (13:20 -0800)
committerPravin B Shelar <pshelar@nicira.com>
Wed, 4 Mar 2015 18:05:39 +0000 (10:05 -0800)
DPDK v1.8.0 makes significant changes to struct rte_mbuf, including
removal of the 'pkt' and 'data' fields. The latter, formally a
pointer, is now calculated via an offset from the start of the
segment buffer.  So now dp_packet data is also stored as offset
from base pointer.

Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
Signed-off-by: Rory Sexton <rory.sexton@intel.com>
Signed-off-by: Kevin Traynor <kevin.traynor@intel.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
.travis/build.sh
INSTALL.DPDK.md
lib/dp-packet.h
lib/netdev-dpdk.c

index a8a515b..942265a 100755 (executable)
@@ -67,10 +67,10 @@ fi
 
 if [ "$DPDK" ]; then
     if [ -z "$DPDK_VER" ]; then
-           DPDK_VER="1.7.1"
+           DPDK_VER="1.8.0"
     fi
     install_dpdk $DPDK_VER
-    # Disregard bad function cassts until DPDK is fixed
+    # Disregard bad function casts until DPDK is fixed
     CFLAGS="$CFLAGS -Wno-error=bad-function-cast -Wno-error=cast-align"
     EXTRA_OPTS+="--with-dpdk=./dpdk-$DPDK_VER/build"
 elif [ $CC != "clang" ]; then
index 4c443e5..276fe56 100644 (file)
@@ -16,13 +16,13 @@ OVS needs a system with 1GB hugepages support.
 Building and Installing:
 ------------------------
 
-Required DPDK 1.7
+Required DPDK 1.8.0
 
 1. Configure build & install DPDK:
   1. Set `$DPDK_DIR`
 
      ```
-     export DPDK_DIR=/usr/src/dpdk-1.7.1
+     export DPDK_DIR=/usr/src/dpdk-1.8.0
      cd $DPDK_DIR
      ```
 
@@ -158,7 +158,7 @@ Using the DPDK with ovs-vswitchd:
    ```
 
 6. Add bridge & ports
-          
+
    To use ovs-vswitchd with DPDK, create a bridge with datapath_type
    "netdev" in the configuration database.  For example:
 
index 9cae74d..5d0fee7 100644 (file)
@@ -60,9 +60,9 @@ struct dp_packet {
 #ifdef DPDK_NETDEV
     struct rte_mbuf mbuf;       /* DPDK mbuf */
 #else
-    void *base_;                 /* First byte of allocated space. */
-    void *data_;                 /* First byte actually in use. */
-    uint32_t size_;              /* Number of bytes in use. */
+    void *base_;                /* First byte of allocated space. */
+    uint16_t data_ofs;          /* First byte actually in use. */
+    uint32_t size_;             /* Number of bytes in use. */
     uint32_t dp_hash;           /* Packet hash. */
 #endif
     uint32_t allocated;         /* Number of bytes allocated. */
@@ -382,16 +382,6 @@ static inline const void *dp_packet_get_nd_payload(const struct dp_packet *b)
 #ifdef DPDK_NETDEV
 BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0);
 
-static inline void * dp_packet_data(const struct dp_packet *b)
-{
-    return b->mbuf.pkt.data;
-}
-
-static inline void dp_packet_set_data(struct dp_packet *b, void *d)
-{
-    b->mbuf.pkt.data = d;
-}
-
 static inline void * dp_packet_base(const struct dp_packet *b)
 {
     return b->mbuf.buf_addr;
@@ -404,27 +394,41 @@ static inline void dp_packet_set_base(struct dp_packet *b, void *d)
 
 static inline uint32_t dp_packet_size(const struct dp_packet *b)
 {
-    return b->mbuf.pkt.pkt_len;
+    return b->mbuf.pkt_len;
 }
 
 static inline void dp_packet_set_size(struct dp_packet *b, uint32_t v)
 {
-    b->mbuf.pkt.data_len = v;    /* Current seg length. */
-    b->mbuf.pkt.pkt_len = v;     /* Total length of all segments linked to
-                                  * this segment. */
+    /* netdev-dpdk does not currently support segmentation; consequently, for
+     * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may
+     * be used interchangably.
+     *
+     * On the datapath, it is expected that the size of packets
+     * (and thus 'v') will always be <= UINT16_MAX; this means that there is no
+     * loss of accuracy in assigning 'v' to 'data_len'.
+     *
+     * However, control ofpbufs may well be larger than UINT16_MAX (i.e. 'v' >
+     * UINT16_MAX); even though the value is truncated when assigned to
+     * 'data_len', loss of accuracy is avoided in this situation by using
+     * 'pkt_len' to represent the packet size.
+     */
+    b->mbuf.data_len = (uint16_t)v;  /* Current seg length. */
+    b->mbuf.pkt_len = v;             /* Total length of all segments linked to
+                                      * this segment. */
+
 }
 
-#else
-static inline void * dp_packet_data(const struct dp_packet *b)
+static inline uint16_t __packet_data(const struct dp_packet *b)
 {
-    return b->data_;
+    return b->mbuf.data_off;
 }
 
-static inline void dp_packet_set_data(struct dp_packet *b, void *d)
+static inline void __packet_set_data(struct dp_packet *b, uint16_t v)
 {
-    b->data_ = d;
+    b->mbuf.data_off = v;
 }
 
+#else
 static inline void * dp_packet_base(const struct dp_packet *b)
 {
     return b->base_;
@@ -444,8 +448,34 @@ static inline void dp_packet_set_size(struct dp_packet *b, uint32_t v)
 {
     b->size_ = v;
 }
+
+static inline uint16_t __packet_data(const struct dp_packet *b)
+{
+    return b->data_ofs;
+}
+
+static inline void __packet_set_data(struct dp_packet *b, uint16_t v)
+{
+    b->data_ofs = v;
+}
+
 #endif
 
+static inline void * dp_packet_data(const struct dp_packet *b)
+{
+    return __packet_data(b) != UINT16_MAX ?
+           (char *)dp_packet_base(b) + __packet_data(b) : NULL;
+}
+
+static inline void dp_packet_set_data(struct dp_packet *b, void *data)
+{
+    if (data) {
+        __packet_set_data(b, (char *)data - (char *)dp_packet_base(b));
+    } else {
+        __packet_set_data(b, UINT16_MAX);
+    }
+}
+
 static inline void dp_packet_reset_packet(struct dp_packet *b, int off)
 {
     dp_packet_set_size(b, dp_packet_size(b) - off);
@@ -457,7 +487,7 @@ static inline void dp_packet_reset_packet(struct dp_packet *b, int off)
 static inline uint32_t dp_packet_get_dp_hash(struct dp_packet *p)
 {
 #ifdef DPDK_NETDEV
-    return p->mbuf.pkt.hash.rss;
+    return p->mbuf.hash.rss;
 #else
     return p->dp_hash;
 #endif
@@ -467,7 +497,7 @@ static inline void dp_packet_set_dp_hash(struct dp_packet *p,
                                            uint32_t hash)
 {
 #ifdef DPDK_NETDEV
-    p->mbuf.pkt.hash.rss = hash;
+    p->mbuf.hash.rss = hash;
 #else
     p->dp_hash = hash;
 #endif
index 2d56054..1ba8310 100644 (file)
@@ -47,6 +47,9 @@
 #include "unixctl.h"
 #include "openvswitch/vlog.h"
 
+#include "rte_config.h"
+#include "rte_mbuf.h"
+
 VLOG_DEFINE_THIS_MODULE(dpdk);
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
 
@@ -264,13 +267,12 @@ __rte_pktmbuf_init(struct rte_mempool *mp,
     m->buf_len = (uint16_t)buf_len;
 
     /* keep some headroom between start of buffer and data */
-    m->pkt.data = (char*) m->buf_addr + RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
+    m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
 
     /* init some constant fields */
-    m->type = RTE_MBUF_PKT;
     m->pool = mp;
-    m->pkt.nb_segs = 1;
-    m->pkt.in_port = 0xff;
+    m->nb_segs = 1;
+    m->port = 0xff;
 }
 
 static void
@@ -824,7 +826,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet ** pkts,
         }
 
         /* We have to do a copy for now */
-        memcpy(mbufs[newcnt]->pkt.data, dp_packet_data(pkts[i]), size);
+        memcpy(rte_pktmbuf_mtod(mbufs[newcnt], void *), dp_packet_data(pkts[i]), size);
 
         rte_pktmbuf_data_len(mbufs[newcnt]) = size;
         rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;
@@ -1269,22 +1271,6 @@ dpdk_common_init(void)
     ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
 }
 
-static int
-dpdk_class_init(void)
-{
-    int result;
-
-    result = rte_eal_pci_probe();
-    if (result) {
-        VLOG_ERR("Cannot probe PCI");
-        return -result;
-    }
-
-    VLOG_INFO("Ethernet Device Count: %d", (int)rte_eth_dev_count());
-
-    return 0;
-}
-
 /* Client Rings */
 
 static int
@@ -1509,7 +1495,7 @@ dpdk_init(int argc, char **argv)
 const struct netdev_class dpdk_class =
     NETDEV_DPDK_CLASS(
         "dpdk",
-        dpdk_class_init,
+        NULL,
         netdev_dpdk_construct,
         netdev_dpdk_set_multiq,
         netdev_dpdk_eth_send);