Skip to content

Commit

Permalink
DPDK: update to DPDK 2.1
Browse files Browse the repository at this point in the history
- support both DPDK 2.0 and 2.1
- use mbuf priv_size for vr_packet
- use new packet type flags
- use rte_pktmbuf_mtod_offset()
- count out HW XEC counter from ierrors
- use RTE_PORT_STATS_COLLECT

Change-Id: I2015961e95bb02a78b7419f7098a1e48bd622356
Closes-bug: 1430629
  • Loading branch information
semihalf-berestovskyy-andriy committed Sep 18, 2015
1 parent 3dcdb0d commit 72f6ca0
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 25 deletions.
30 changes: 26 additions & 4 deletions dpdk/dpdk_vrouter.c
Expand Up @@ -65,21 +65,43 @@ static int dpdk_argc = RTE_DIM(dpdk_argv) - 10;
/* Timestamp logger */
static FILE *timestamp_log_stream;

/* Pktmbuf constructor with vr_packet support */
#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))
/* A packet mbuf pool constructor with vr_packet support */
void vr_dpdk_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
{
struct rte_pktmbuf_pool_private priv;

/* Set private mbuf size for vr_packet. */
priv.mbuf_data_room_size = mp->elt_size - sizeof(struct rte_mbuf)
- sizeof(struct vr_packet);
priv.mbuf_priv_size = sizeof(struct vr_packet);

rte_pktmbuf_pool_init(mp, &priv);
}
#else
void vr_dpdk_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg)
{
rte_pktmbuf_pool_init(mp, opaque_arg);
}
#endif

/* The packet mbuf constructor with vr_packet support */
void
vr_dpdk_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i)
{
struct rte_mbuf *m = _m;
struct vr_packet *pkt;
rte_pktmbuf_init(mp, opaque_arg, _m, i);

#if (RTE_VERSION < RTE_VERSION_NUM(2, 1, 0, 0))
/* decrease rte packet size to fit vr_packet struct */
m->buf_len -= sizeof(struct vr_packet);
RTE_VERIFY(0 < m->buf_len);

/* start of buffer is just after vr_packet structure */
m->buf_addr += sizeof(struct vr_packet);
m->buf_physaddr += sizeof(struct vr_packet);
#endif

/* basic vr_packet initialization */
pkt = vr_dpdk_mbuf_to_pkt(m);
Expand All @@ -95,7 +117,7 @@ dpdk_mempools_create(void)
vr_dpdk.rss_mempool = rte_mempool_create("rss_mempool", VR_DPDK_RSS_MEMPOOL_SZ,
VR_DPDK_MBUF_SZ, VR_DPDK_RSS_MEMPOOL_CACHE_SZ,
sizeof(struct rte_pktmbuf_pool_private),
rte_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
vr_dpdk_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
rte_socket_id(), 0);
if (vr_dpdk.rss_mempool == NULL) {
RTE_LOG(CRIT, VROUTER, "Error creating RSS mempool: %s (%d)\n",
Expand All @@ -107,7 +129,7 @@ dpdk_mempools_create(void)
vr_dpdk.frag_direct_mempool = rte_mempool_create("frag_direct_mempool",
VR_DPDK_FRAG_DIRECT_MEMPOOL_SZ, VR_DPDK_FRAG_DIRECT_MBUF_SZ,
VR_DPDK_FRAG_DIRECT_MEMPOOL_CACHE_SZ,
sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
sizeof(struct rte_pktmbuf_pool_private), vr_dpdk_pktmbuf_pool_init,
NULL, vr_dpdk_pktmbuf_init, NULL, rte_socket_id(), 0);
if (vr_dpdk.frag_direct_mempool == NULL) {
RTE_LOG(CRIT, VROUTER, "Error creating FRAG_DIRECT mempool: %s (%d)\n",
Expand Down Expand Up @@ -141,7 +163,7 @@ dpdk_mempools_create(void)
vr_dpdk.free_mempools[i] = rte_mempool_create(mempool_name,
VR_DPDK_VM_MEMPOOL_SZ, VR_DPDK_MBUF_SZ, VR_DPDK_VM_MEMPOOL_CACHE_SZ,
sizeof(struct rte_pktmbuf_pool_private),
rte_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
vr_dpdk_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
rte_socket_id(), 0);
if (vr_dpdk.free_mempools[i] == NULL) {
RTE_LOG(CRIT, VROUTER, "Error creating VM mempool %d: %s (%d)\n",
Expand Down
19 changes: 15 additions & 4 deletions dpdk/vr_dpdk_ethdev.c
Expand Up @@ -704,7 +704,9 @@ dpdk_mbuf_rss_hash(struct rte_mbuf *mbuf)
/* TODO: IPv6 support */
/* TODO: VLAN support */
if (likely(eth_hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))) {
mbuf->ol_flags |= PKT_RX_IPV4_HDR;
#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))
mbuf->packet_type |= RTE_PTYPE_L3_IPV4;
#endif
ipv4_hdr = (struct ipv4_hdr *)((uintptr_t)eth_hdr
+ sizeof(struct ether_hdr));
ipv4_addr_ptr = (uint64_t *)((uintptr_t)ipv4_hdr
Expand All @@ -723,8 +725,17 @@ dpdk_mbuf_rss_hash(struct rte_mbuf *mbuf)
!vr_ip_fragment((struct vr_ip *)ipv4_hdr))) {
switch (ipv4_hdr->next_proto_id) {
case IPPROTO_TCP:
#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))
mbuf->packet_type |= RTE_PTYPE_L4_TCP;
#endif
l4_ptr = (uint32_t *)((uintptr_t)ipv4_hdr + iph_len);

hash = rte_hash_crc_4byte(*l4_ptr, hash);
break;
case IPPROTO_UDP:
mbuf->ol_flags |= PKT_RX_IPV4_HDR_EXT;
#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))
mbuf->packet_type |= RTE_PTYPE_L4_UDP;
#endif
l4_ptr = (uint32_t *)((uintptr_t)ipv4_hdr + iph_len);

hash = rte_hash_crc_4byte(*l4_ptr, hash);
Expand Down Expand Up @@ -754,8 +765,8 @@ vr_dpdk_ethdev_rx_emulate(struct vr_interface *vif, struct rte_mbuf *pkts[VR_DPD

/* prefetch the mbufs */
for (i = 0; i < nb_pkts; i++) {
rte_prefetch0(rte_pktmbuf_mtod(pkts[i], void *));
rte_prefetch0(rte_pktmbuf_mtod(pkts[i], uint8_t *) + RTE_CACHE_LINE_SIZE);
rte_prefetch0(rte_pktmbuf_mtod(pkts[i], uint8_t *));
rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[i], uint8_t *, RTE_CACHE_LINE_SIZE));
}

/* emulate VLAN stripping if needed */
Expand Down
4 changes: 2 additions & 2 deletions dpdk/vr_dpdk_host.c
Expand Up @@ -323,7 +323,7 @@ dpdk_pktmbuf_copy_bits(const struct rte_mbuf *mbuf, int offset,
do {
if (offset < rte_pktmbuf_data_len(mbuf)) {
/* copy a piece of data */
from = (void *)(rte_pktmbuf_mtod(mbuf, uintptr_t) + offset);
from = (void *)(rte_pktmbuf_mtod_offset(mbuf, uintptr_t, offset));
copy = rte_pktmbuf_data_len(mbuf) - offset;
if (copy > len)
copy = len;
Expand Down Expand Up @@ -640,7 +640,7 @@ dpdk_pheader_pointer(struct vr_packet *pkt, unsigned short hdr_len, void *buf)
int len = rte_pktmbuf_data_len(m) - offset;
void *tmp_buf = buf;

rte_memcpy(tmp_buf, rte_pktmbuf_mtod(m, char *) + offset, len);
rte_memcpy(tmp_buf, rte_pktmbuf_mtod_offset(m, char *, offset), len);
hdr_len -= len;
tmp_buf = (void *)((uintptr_t)tmp_buf + len);

Expand Down
29 changes: 29 additions & 0 deletions dpdk/vr_dpdk_interface.c
Expand Up @@ -1303,6 +1303,35 @@ dpdk_dev_stats_update(struct vr_interface *vif, unsigned lcore_id)
if (rte_eth_stats_get(port_id, &eth_stats) != 0)
return;

#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))
/*
* TODO: In DPDK 2.1 ierrors includes XEC (l3_l4_xsum_error) counter.
* The counter seems to include no check sum UDP packets. As a workaround
* we count out the XEC from ierrors using rte_eth_xstats_get().
*/
struct rte_eth_xstats *eth_xstats = NULL;
int nb_xstats, i;
nb_xstats = rte_eth_xstats_get(port_id, eth_xstats, 0);
if (nb_xstats > 0) {
eth_xstats = rte_malloc("xstats",
sizeof(*eth_xstats)*nb_xstats, 0);
if (eth_xstats != NULL) {
if (rte_eth_xstats_get(port_id, eth_xstats, nb_xstats)
== nb_xstats) {
/* look for XEC counter */
for (i = 0; i < nb_xstats; i++) {
if (strncmp(eth_xstats[i].name, "l3_l4_xsum_error",
sizeof(eth_xstats[i].name)) == 0) {
eth_stats.ierrors -= eth_xstats[i].value;
break;
}
}
}
rte_free(eth_xstats);
}
}
#endif

/* per-lcore device counters */
lcore = vr_dpdk.lcores[lcore_id];
if (lcore == NULL)
Expand Down
4 changes: 2 additions & 2 deletions dpdk/vr_dpdk_knidev.c
Expand Up @@ -24,7 +24,7 @@
/*
* KNI Reader
*/
#if DPDK_KNIDEV_READER_STATS_COLLECT == 1
#ifdef RTE_PORT_STATS_COLLECT

#define DPDK_KNIDEV_READER_STATS_PKTS_IN_ADD(port, val) \
port->stats.n_pkts_in += val
Expand Down Expand Up @@ -121,7 +121,7 @@ dpdk_knidev_reader_stats_read(void *port,
/*
* KNI Writer
*/
#if DPDK_KNIDEV_WRITER_STATS_COLLECT == 1
#ifdef RTE_PORT_STATS_COLLECT

#define DPDK_KNIDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
port->stats.n_pkts_in += val
Expand Down
2 changes: 1 addition & 1 deletion dpdk/vr_dpdk_usocket.c
Expand Up @@ -785,7 +785,7 @@ usock_alloc(unsigned short proto, unsigned short type)
usockp->usock_mbuf_pool = rte_mempool_create("packet_mbuf_pool",
PKT0_MBUF_POOL_SIZE, PKT0_MBUF_PACKET_SIZE,
PKT0_MBUF_POOL_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private),
rte_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
vr_dpdk_pktmbuf_pool_init, NULL, vr_dpdk_pktmbuf_init, NULL,
rte_socket_id(), 0);
if (!usockp->usock_mbuf_pool)
goto error_exit;
Expand Down
6 changes: 3 additions & 3 deletions dpdk/vr_dpdk_virtio.c
Expand Up @@ -469,7 +469,7 @@ vr_dpdk_guest_phys_to_host_virt(vr_uvh_client_t *vru_cl, uint64_t paddr)
return NULL;
}

#if DPDK_VIRTIO_READER_STATS_COLLECT == 1
#ifdef RTE_PORT_STATS_COLLECT

#define DPDK_VIRTIO_READER_STATS_PKTS_IN_ADD(port, val) \
port->stats.n_pkts_in += val
Expand Down Expand Up @@ -626,7 +626,7 @@ dpdk_virtio_from_vm_rx(void *port, struct rte_mbuf **pkts, uint32_t max_pkts)
return pkts_sent;
}

#if DPDK_VIRTIO_WRITER_STATS_COLLECT == 1
#ifdef RTE_PORT_STATS_COLLECT

#define DPDK_VIRTIO_WRITER_STATS_PKTS_IN_ADD(port, val) \
port->stats.n_pkts_in += val
Expand Down Expand Up @@ -754,7 +754,7 @@ dpdk_virtio_dev_to_vm_tx_burst(struct dpdk_virtio_writer *p,
while (total_copied < pkt_len) {
/* Copy mbuf data to buffer */
rte_memcpy((void *)(uintptr_t)(buff_addr + vb_offset),
rte_pktmbuf_mtod(buff, const void *) + offset,
rte_pktmbuf_mtod_offset(buff, const void *, offset),
len_to_cpy);

offset += len_to_cpy;
Expand Down
13 changes: 4 additions & 9 deletions include/vr_dpdk.h
Expand Up @@ -18,6 +18,7 @@
#define _VR_DPDK_H_

#include "vr_os.h"
#include "vr_dpdk_compat.h"
#include "vr_interface.h"
#include "vr_packet.h"
#include "vr_fragment.h"
Expand Down Expand Up @@ -477,14 +478,6 @@ struct vr_dpdk_global {

extern struct vr_dpdk_global vr_dpdk;

/**
* Enable sent/received/dropped packets statistics
*/
#define DPDK_KNIDEV_WRITER_STATS_COLLECT 1
#define DPDK_KNIDEV_READER_STATS_COLLECT 1
#define DPDK_VIRTIO_WRITER_STATS_COLLECT 1
#define DPDK_VIRTIO_READER_STATS_COLLECT 1

/*
* rte_mbuf <=> vr_packet conversion
*
Expand Down Expand Up @@ -540,7 +533,9 @@ vr_dpdk_mbuf_reset(struct vr_packet *pkt)
/*
* dpdk_vrouter.c
*/
/* pktmbuf constructor with vr_packet support */
/* A packet mbuf pool constructor with vr_packet support */
void vr_dpdk_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
/* The packet mbuf constructor with vr_packet support */
void vr_dpdk_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i);
/* Check if the stop flag is set */
int vr_dpdk_is_stop_flag_set(void);
Expand Down
53 changes: 53 additions & 0 deletions include/vr_dpdk_compat.h
@@ -0,0 +1,53 @@
/*
* vr_dpdk_compat.h - DPDK compatibility definitions
*
* Copyright (c) 2015 Semihalf.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <rte_version.h>

#ifndef __VRDPDKCOMPAT_H__
#define __VRDPDKCOMPAT_H__

/*
* DPDK 2.1
*/
#if (RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0))

/*
* DPDK 2.0
*/
#elif (RTE_VERSION >= RTE_VERSION_NUM(2, 0, 0, 0))

/* Enable port statistics. */
#define RTE_PORT_STATS_COLLECT

/**
* A macro that points to an offset into the data in the mbuf.
*
* The returned pointer is cast to type t. Before using this
* function, the user must ensure that the first segment is large
* enough to accommodate its data.
*
* @param m
* The packet mbuf.
* @param o
* The offset into the mbuf data.
* @param t
* The type to cast the result into.
*/
#define rte_pktmbuf_mtod_offset(m, t, o) \
((t)((char *)(m)->buf_addr + (m)->data_off + (o)))

#endif /* RTE_VERSION */

#endif /* __VRDPDKCOMPAT_H__ */

0 comments on commit 72f6ca0

Please sign in to comment.