[dpdk-dev] [PATCH v8 5/5] doc/rel_notes: add virtio offload feature in new feature section

2016-02-05 Thread Jijiang Liu
Update new feature section with virtio offload feature description.

Signed-off-by: Jijiang Liu 
---
 doc/guides/rel_notes/release_2_3.rst |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/doc/guides/rel_notes/release_2_3.rst 
b/doc/guides/rel_notes/release_2_3.rst
index 7945694..47d4cb0 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -39,6 +39,11 @@ This section should contain new features added in this 
release. Sample format:

   Enabled virtio 1.0 support for virtio pmd driver.

+* **Support virtio offload in us-vhost."
+
+  Add the feature negotiation of checksum and TSO between us-vhost and vanilla
+  Linux virtio guest, and add these offload features support in the vhost lib.
+

 Resolved Issues
 ---
-- 
1.7.7.6



[dpdk-dev] [PATCH v8 4/5] example/vhost: add virtio offload test in vhost sample

2016-02-05 Thread Jijiang Liu
Change the codes in vhost sample to test virtio offload feature.

These changes include,

1. add two test options: tx-csum and tso.

2. add virtio_tx_offload() function to test vhost TX offload feature
   for VM to NIC case;

however, for VM to VM case, it doesn't need to call this function,
  the reason is explained in patch 2.

Signed-off-by: Jijiang Liu 
Acked-by: Yuanhan Liu 

---
 examples/vhost/main.c |  105 +++-
 1 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 044c680..210e631 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -51,6 +51,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -198,6 +201,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -428,6 +438,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -563,7 +581,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -589,6 +609,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -643,6 +665,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tso = ret;
+   }
+
/* Specify the retries delay time (in useconds) on RX. 
*/
if (!strncmp(long_option[option_index].name, 
"rx-retry-delay", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
@@ -1101,6 +1145,58 @@ find_local_dest(struct virtio_net *dev, struct rte_mbuf 
*m,
return 0;
 }

+static uint16_t
+get_psd_sum(void *l3_hdr, uint64_t ol_flags)
+{
+   if (ol_flags & PKT_TX_IPV4)
+   return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+   else /* assume ethertype == ETHER_TYPE_IPv6 */
+   return rte_ipv6_phdr_cksum(l3_hdr

[dpdk-dev] [PATCH v8 3/5] sample/vhost: remove the ipv4_hdr structure defination

2016-02-05 Thread Jijiang Liu
Remove the ipv4_hdr structure defination in vhost sample.

The same structure has already defined in the rte_ip.h file, so we
  remove the defination from the sample, and include that header file.

Signed-off-by: Jijiang Liu 
Acked-by: Yuanhan Liu 

---
 examples/vhost/main.c |   15 +--
 1 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..044c680 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -292,20 +293,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
-- 
1.7.7.6



[dpdk-dev] [PATCH v8 2/5] vhost/lib: add guest offload setting

2016-02-05 Thread Jijiang Liu
Add guest offload setting in vhost lib.

Virtio 1.0 spec (5.1.6.4 Processing of Incoming Packets) says:

1. If the VIRTIO_NET_F_GUEST_CSUM feature was negotiated, the
   VIRTIO_NET_HDR_F_NEEDS_CSUM bit in flags can be set: if so,
   the packet checksum at offset csum_offset from csum_start
   and any preceding checksums have been validated. The checksum
   on the packet is incomplete and csum_start and csum_offset
   indicate how to calculate it (see Packet Transmission point 1).

2. If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were
   negotiated, then gso_type MAY be something other than
   VIRTIO_NET_HDR_GSO_NONE, and gso_size field indicates the
   desired MSS (see Packet Transmission point 2).

In order to support these features, the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Enqueue these offloads: convert some fields in mbuf to the fields in 
virtio_net_hdr.

There are more explanations for the implementation.

For VM2VM case, there is no need to do checksum, for we think the
  data should be reliable enough, and setting VIRTIO_NET_HDR_F_NEEDS_CSUM
  at RX side will let the TCP layer to bypass the checksum validation,
  so that the RX side could receive the packet in the end.

In terms of us-vhost, at vhost RX side, the offload information is
  inherited from mbuf, which is in turn inherited from TX side. If we
  can still get those info at RX side, it means the packet is from
  another VM at same host. So, it's safe to set the
  VIRTIO_NET_HDR_F_NEEDS_CSUM, to skip checksum validation.

Signed-off-by: Jijiang Liu 
Acked-by: Yuanhan Liu 

---
 lib/librte_vhost/vhost_rxtx.c |   47 +++-
 lib/librte_vhost/virtio-net.c |5 +++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 47d5f85..9d97e19 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -54,6 +54,44 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t 
qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
 }

+static void
+virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
+{
+   memset(net_hdr, 0, sizeof(struct virtio_net_hdr));
+
+   if (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
+
+   switch (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct tcp_hdr,
+   cksum));
+   break;
+   case PKT_TX_UDP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct udp_hdr,
+   dgram_cksum));
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct sctp_hdr,
+   cksum));
+   break;
+   }
+   }
+
+   if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
+   if (m_buf->ol_flags & PKT_TX_IPV4)
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   else
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   net_hdr->gso_size = m_buf->tso_segsz;
+   net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
+   + m_buf->l4_len;
+   }
+
+   return;
+}
+
 /**
  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
  * be received from the physical port or from another virtio device. A packet
@@ -67,7 +105,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 {
struct vhost_virtqueue *vq;
struct vring_desc *desc;
-   struct rte_mbuf *buff;
+   struct rte_mbuf *buff, *first_buff;
/* The virtio_hdr is initialised to 0. */
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
uint64_t buff_addr = 0;
@@ -139,6 +177,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
desc = &vq->desc[head[packet_success]];

buff = pkts[packet_success];
+   first_buff = buff;

/* Convert from gpa to vva (guest physical addr -> vhost 
virtual addr) */
buff_addr = gpa_to_vva(dev, desc->addr);
@@ -221,7 +260,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,

if (unlikely(uncompleted_pkt == 1))
continue;
-
+
+   virtio_enqueue_offload(first_buff, &virtio_hdr.hdr);
+
  

[dpdk-dev] [PATCH v8 1/5] vhost/lib: add vhost TX offload capabilities in vhost lib

2016-02-05 Thread Jijiang Liu
Add vhost TX offload (CSUM and TSO) support capabilities in vhost lib.

In order to support these features, and the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features
   negotiation.

2. Dequeue TX offload: convert the fileds in virtio_net_hdr to the
   related fileds in mbuf.

Signed-off-by: Jijiang Liu 
Acked-by: Yuanhan Liu 

---
 lib/librte_vhost/vhost_rxtx.c |  103 +
 lib/librte_vhost/virtio-net.c |6 ++-
 2 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..47d5f85 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,97 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV6;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -576,11 +672,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
  

[dpdk-dev] [PATCH v8 0/5] add virtio offload support in us-vhost

2016-02-05 Thread Jijiang Liu
Adds virtio offload support in us-vhost.

The patch set adds the feature negotiation of checksum and TSO between
  us-vhost and vanilla Linux virtio guest, and add these offload features
  support in the vhost lib, and change vhost sample to test them.

In short, this patch set supports the followings,

- DPDK vhost CSUM & TSO for VM2NIC case

- CSUM and TSO support between legacy virtio-net and DPDK vhost for
  VM2VM and NIC2VM cases.

v8 changes:
  Add release notes update.

v7 changes:
  Rebase latest codes and format patch comments.

v6 change:
  Rebase latest codes.

v5 changes:
  Add more clear descriptions to explain these changes.
  reset the 'virtio_net_hdr' value in the virtio_enqueue_offload() function.
  reorganize patches. 


v4 changes:
  remove virtio-net change, only keep vhost changes.
  add guest TX offload capabilities to support VM to VM case.
  split the cleanup code as a separate patch.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads.

Tested-by: Qian Xu 

---
Jijiang Liu (4):
  add vhost offload capabilities
  remove ipv4_hdr structure from vhost sample.
  add guest offload setting ln the vhost lib.
  change vhost application to test checksum and TSO for VM to NIC case

 examples/vhost/main.c |  120 -
 lib/librte_vhost/vhost_rxtx.c |  150 -
 lib/librte_vhost/virtio-net.c |9 ++-
 3 files changed, 259 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v7 4/4] example/vhost: add virtio offload test in vhost sample

2016-02-05 Thread Jijiang Liu
Change the codes in vhost sample to test virtio offload feature.

These changes include,

1. add two test options: tx-csum and tso.

2. add virtio_tx_offload() function to test vhost TX offload feature
   for VM to NIC case;

however, for VM to VM case, it doesn't need to call this function,
  the reason is explained in patch 2.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  105 +++-
 1 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 044c680..210e631 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -51,6 +51,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -198,6 +201,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -428,6 +438,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -563,7 +581,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -589,6 +609,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -643,6 +665,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tso = ret;
+   }
+
/* Specify the retries delay time (in useconds) on RX. 
*/
if (!strncmp(long_option[option_index].name, 
"rx-retry-delay", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
@@ -1101,6 +1145,58 @@ find_local_dest(struct virtio_net *dev, struct rte_mbuf 
*m,
return 0;
 }

+static uint16_t
+get_psd_sum(void *l3_hdr, uint64_t ol_flags)
+{
+   if (ol_flags & PKT_TX_IPV4)
+   return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+   else /* assume ethertype == ETHER_TYPE_IPv6 */
+   return rte_ipv6_phdr_cksum(l3_hdr, ol_flags);
+}
+
+static void virt

[dpdk-dev] [PATCH v7 3/4] sample/vhost: remove the ipv4_hdr structure defination

2016-02-05 Thread Jijiang Liu
Remove the ipv4_hdr structure defination in vhost sample.

The same structure has already defined in the rte_ip.h file, so we
  remove the defination from the sample, and include that header file.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   15 +--
 1 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..044c680 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -292,20 +293,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
-- 
1.7.7.6



[dpdk-dev] [PATCH v7 2/4] vhost/lib: add guest offload setting

2016-02-05 Thread Jijiang Liu
Add guest offload setting in vhost lib.

Virtio 1.0 spec (5.1.6.4 Processing of Incoming Packets) says:

1. If the VIRTIO_NET_F_GUEST_CSUM feature was negotiated, the
   VIRTIO_NET_HDR_F_NEEDS_CSUM bit in flags can be set: if so,
   the packet checksum at offset csum_offset from csum_start
   and any preceding checksums have been validated. The checksum
   on the packet is incomplete and csum_start and csum_offset
   indicate how to calculate it (see Packet Transmission point 1).

2. If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were
   negotiated, then gso_type MAY be something other than
   VIRTIO_NET_HDR_GSO_NONE, and gso_size field indicates the
   desired MSS (see Packet Transmission point 2).

In order to support these features, the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Enqueue these offloads: convert some fields in mbuf to the fields in 
virtio_net_hdr.

There are more explanations for the implementation.

For VM2VM case, there is no need to do checksum, for we think the
  data should be reliable enough, and setting VIRTIO_NET_HDR_F_NEEDS_CSUM
  at RX side will let the TCP layer to bypass the checksum validation,
  so that the RX side could receive the packet in the end.

In terms of us-vhost, at vhost RX side, the offload information is
  inherited from mbuf, which is in turn inherited from TX side. If we
  can still get those info at RX side, it means the packet is from
  another VM at same host. So, it's safe to set the
  VIRTIO_NET_HDR_F_NEEDS_CSUM, to skip checksum validation.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   47 +++-
 lib/librte_vhost/virtio-net.c |5 +++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 47d5f85..9d97e19 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -54,6 +54,44 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t 
qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
 }

+static void
+virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
+{
+   memset(net_hdr, 0, sizeof(struct virtio_net_hdr));
+
+   if (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
+
+   switch (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct tcp_hdr,
+   cksum));
+   break;
+   case PKT_TX_UDP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct udp_hdr,
+   dgram_cksum));
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct sctp_hdr,
+   cksum));
+   break;
+   }
+   }
+
+   if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
+   if (m_buf->ol_flags & PKT_TX_IPV4)
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   else
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   net_hdr->gso_size = m_buf->tso_segsz;
+   net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
+   + m_buf->l4_len;
+   }
+
+   return;
+}
+
 /**
  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
  * be received from the physical port or from another virtio device. A packet
@@ -67,7 +105,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 {
struct vhost_virtqueue *vq;
struct vring_desc *desc;
-   struct rte_mbuf *buff;
+   struct rte_mbuf *buff, *first_buff;
/* The virtio_hdr is initialised to 0. */
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
uint64_t buff_addr = 0;
@@ -139,6 +177,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
desc = &vq->desc[head[packet_success]];

buff = pkts[packet_success];
+   first_buff = buff;

/* Convert from gpa to vva (guest physical addr -> vhost 
virtual addr) */
buff_addr = gpa_to_vva(dev, desc->addr);
@@ -221,7 +260,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,

if (unlikely(uncompleted_pkt == 1))
continue;
-
+
+   virtio_enqueue_offload(first_buff, &virtio_hdr.hdr);
+
rte_memcpy

[dpdk-dev] [PATCH v7 1/4] vhost/lib: add vhost TX offload capabilities in vhost lib

2016-02-05 Thread Jijiang Liu
Add vhost TX offload (CSUM and TSO) support capabilities in vhost lib.

In order to support these features, and the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features
   negotiation.

2. Dequeue TX offload: convert the fileds in virtio_net_hdr to the
   related fileds in mbuf.


Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  103 +
 lib/librte_vhost/virtio-net.c |6 ++-
 2 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..47d5f85 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,97 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV6;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -576,11 +672,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_

[dpdk-dev] [PATCH v7 0/4] add virtio offload support in us-vhost

2016-02-05 Thread Jijiang Liu
Adds virtio offload support in us-vhost.

The patch set adds the feature negotiation of checksum and TSO between
  us-vhost and vanilla Linux virtio guest, and add these offload features
  support in the vhost lib, and change vhost sample to test them.

In short, this patch set supports the followings,

- DPDK vhost CSUM & TSO for VM2NIC case

- CSUM and TSO support between legacy virtio-net and DPDK vhost for
  VM2VM and NIC2VM cases.

v7 changes:
  Rebase latest codes and format patch comments.

v6 change:
  Rebase latest codes.

v5 changes:
  Add more clear descriptions to explain these changes.
  reset the 'virtio_net_hdr' value in the virtio_enqueue_offload() function.
  reorganize patches. 


v4 changes:
  remove virtio-net change, only keep vhost changes.
  add guest TX offload capabilities to support VM to VM case.
  split the cleanup code as a separate patch.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads.


---
Jijiang Liu (4):
  add vhost offload capabilities
  remove ipv4_hdr structure from vhost sample.
  add guest offload setting ln the vhost lib.
  change vhost application to test checksum and TSO for VM to NIC case

 examples/vhost/main.c |  120 -
 lib/librte_vhost/vhost_rxtx.c |  150 -
 lib/librte_vhost/virtio-net.c |9 ++-
 3 files changed, 259 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 6/6] driver/i40e: tunnel configure in i40e

2015-12-23 Thread Jijiang Liu
Add i40e_udp_tunnel_flow_configre() to implement the configuration of flow rule 
with 'src IP, dst IP, src port, dst port and tunnel ID' using flow director.

Signed-off-by: Jijiang Liu 
---
 drivers/net/i40e/i40e_ethdev.c |   41 
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7e03a1f..7d8c8d7 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -469,6 +469,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
.rss_hash_conf_get= i40e_dev_rss_hash_conf_get,
.udp_tunnel_add   = i40e_dev_udp_tunnel_add,
.udp_tunnel_del   = i40e_dev_udp_tunnel_del,
+   .tunnel_configure = i40e_dev_tunnel_configure,
.filter_ctrl  = i40e_dev_filter_ctrl,
.rxq_info_get = i40e_rxq_info_get,
.txq_info_get = i40e_txq_info_get,
@@ -6029,6 +6030,46 @@ i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
return ret;
 }

+static int
+i40e_udp_tunnel_flow_configre(struct i40e_pf *pf, rte_eth_tunnel_conf 
*tunnel_conf)
+{
+   int  idx, ret;
+   uint8_t filter_idx;
+   struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+
+   /* set filter with src IP + dst IP + src port + dst port + tunnel id*/
+   /* flow director setting */ 
+   
+   return 0;
+}
+
+/* Add UDP tunneling port */
+static int
+i40e_dev_tunnel_conf(struct rte_eth_dev *dev,
+struct rte_eth_tunnel_conf *tunnel_conf)
+{
+   int ret = 0;
+   struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+   if (tunnel_tunnel == NULL)
+   return -EINVAL;
+
+   switch (udp_tunnel->prot_type) {
+   case RTE_TUNNEL_TYPE_VXLAN:
+   case RTE_TUNNEL_TYPE_GENEVE:
+   case RTE_TUNNEL_TYPE_TEREDO:
+   ret = i40e_udp_tunnel_flow_configure(pf, tunnel_conf);
+   break;
+
+   default:
+   PMD_DRV_LOG(ERR, "Invalid tunnel type");
+   ret = -1;
+   break;
+   }
+
+   return ret;
+}
+
 /* Calculate the maximum number of contiguous PF queues that are configured */
 static int
 i40e_pf_calc_configured_queues_num(struct i40e_pf *pf)
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 5/6] rte_ether: implement encap and decap APIs

2015-12-23 Thread Jijiang Liu
Using SIMD instruction to accelarate encapsulation operation.

Signed-off-by: Jijiang Liu 
---
 lib/librte_ether/libtunnel/rte_vxlan_opt.c |  251 
 1 files changed, 251 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_ether/libtunnel/rte_vxlan_opt.c

diff --git a/lib/librte_ether/libtunnel/rte_vxlan_opt.c 
b/lib/librte_ether/libtunnel/rte_vxlan_opt.c
new file mode 100644
index 000..e59ed2c
--- /dev/null
+++ b/lib/librte_ether/libtunnel/rte_vxlan_opt.c
@@ -0,0 +1,251 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "vxlan_opt.h"
+
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+
+#define PORT_MIN49152
+#define PORT_MAX65535
+#define PORT_RANGE ((PORT_MAX - PORT_MIN) + 1)
+
+#define DUMMY_FOR_TEST
+#define RTE_DEFAULT_VXLAN_PORT 4789
+ 
+#define LOOP   4
+#define MAC_LEN6
+#define PREFIX ETHER_HDR_LEN + 4
+#define UDP_PRE_SZ (sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr))
+#define IP_PRE_SZ  (UDP_PRE_SZ + sizeof(struct ipv4_hdr))
+#define VXLAN_PKT_HDR_SIZE   (IP_PRE_SZ + ETHER_HDR_LEN)
+ 
+#define VXLAN_SIZE sizeof(struct vxlan_hdr)
+#define INNER_PRE_SZ   (14 + 20 + 8 + 8)
+#define DECAP_OFFSET   (16 + 8 + 8)
+#define DETECT_OFFSET  12
+
+struct eth_pkt_info {
+   uint8_t l2_len;
+   uint16_t ethertype;
+   uint16_t l3_len;
+   uint16_t l4_proto;
+   uint16_t l4_len;
+};
+
+/* 16Bytes tx meta data */
+struct vxlan_tx_meta {
+   uint32_t sip;
+   uint32_t dip;
+   uint32_t vni;
+   uint16_t sport;
+} __attribute__((__aligned__(16)));
+
+
+/* Parse an IPv4 header to fill l3_len, l4_len, and l4_proto */
+static void
+parse_ipv4(struct ipv4_hdr *ipv4_hdr, struct eth_pkt_info *info)
+{
+   struct tcp_hdr *tcp_hdr;
+
+   info->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   info->l4_proto = ipv4_hdr->next_proto_id;
+
+   /* only fill l4_len for TCP, it's useful for TSO */
+   if (info->l4_proto == IPPROTO_TCP) {
+   tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + info->l3_len);
+   info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   } else
+   info->l4_len = 0;
+}
+
+/* Parse an IPv6 header to fill l3_len, l4_len, and l4_proto */
+static void
+parse_ipv6(struct ipv6_hdr *ipv6_hdr, struct eth_pkt_info *info)
+{
+   struct tcp_hdr *tcp_hdr;
+
+   info->l3_len = sizeof(struct ipv6_hdr);
+   info->l4_proto = ipv6_hdr->proto;
+
+   /* only fill l4_len for TCP, it's useful for TSO */
+   if (info->l4_proto == IPPROTO_TCP) {
+   tcp_hdr = (struct tcp_hdr *)((char *)ipv6_hdr + info->l3_len);
+   info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   } else
+   info->l4_len = 0;
+}
+
+/*
+ * Parse an ethernet header to fill the ethertype, l2_len, l3_len and
+ * ipproto. This function is able to recognize IPv4/IPv6 with one optional vlan
+ * header. The l4_len argument is onl

[dpdk-dev] [RFC PATCH 4/6] rte_ether: define rte_eth_vxlan_decap and rte_eth_vxlan_encap

2015-12-23 Thread Jijiang Liu
This function parameters should be the same as callback function 
(rte_rx/tx_callback_fn).

But we can redefine some parameters as 'unused'.

Signed-off-by: Jijiang Liu 
---
 lib/librte_ether/libtunnel/rte_vxlan_opt.h |   49 
 1 files changed, 49 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_ether/libtunnel/rte_vxlan_opt.h

diff --git a/lib/librte_ether/libtunnel/rte_vxlan_opt.h 
b/lib/librte_ether/libtunnel/rte_vxlan_opt.h
new file mode 100644
index 000..d9412fc
--- /dev/null
+++ b/lib/librte_ether/libtunnel/rte_vxlan_opt.h
@@ -0,0 +1,49 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VXLAN_OPT_H_
+#define _RTE_VXLAN_OPT_H_
+
+extern void rte_vxlan_encap_burst (uint8_t port, uint16_t queue,
+  struct rte_mbuf *pkts[],
+  uint16_t nb_pkts,
+  uint16_t max_pkts,
+  void *user_param);
+
+extern uint16_t rte_vxlan_decap_burst(uint8_t port,
+ uint16_t queue,
+ struct rte_mbuf *pkts[],
+ uint16_t nb_pkts,
+ void *user_param);
+
+#endif /* _RTE_VXLAN_OPT_H_ */
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 3/6] rte_ether: implement tunnel config API

2015-12-23 Thread Jijiang Liu
Signed-off-by: Jijiang Liu 
---
 lib/librte_ether/rte_ethdev.c |   60 +
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c3eed49..6725398 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1004,6 +1004,66 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, 
uint16_t nb_tx_q,
return 0;
 }

+int
+rte_eth_dev_tunnel_configure(uint8_t port_id,
+struct rte_eth_tunnel_conf *tunnel_conf)
+{
+   struct rte_eth_dev *dev;
+   struct rte_eth_dev_info dev_info;
+   int diag;
+
+   /* This function is only safe when called from the primary process
+   * * in a multi-process setup*/
+   RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
+
+   RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+   
+   dev = &rte_eth_devices[port_id];
+
+   RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
+
+   /*
+* * Check that the numbers of RX and TX queues are not greater
+* * than the configured number of RX and TX queues supported by the
+* * configured device.
+* */
+   (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
+   if (tunnel_conf->rx_queue > dev->data->nb_rx_queues - 1) {
+   RTE_PMD_DEBUG_TRACE("ethdev port_id=%d nb_rx_queues=%d > %d\n",
+   port_id, nb_rx_q, dev_info.max_rx_queues);
+   return -EINVAL;
+   }
+
+   if (tunnel_conf->tx_queue > dev->data->nb_rx_queues -1 ) {
+   RTE_PMD_DEBUG_TRACE("ethdev port_id=%d nb_tx_queues=%d > %d\n",
+   port_id, nb_tx_q, dev_info.max_tx_queues);
+   return -EINVAL;
+   }
+
+   tunnel_conf->tunnel_flow = rte_zmalloc(NULL,
+   sizeof(struct rte_eth_tunnel_flow)
+   * tunnel_conf->nb_flow, 0);
+   
+   /* Copy the dev_conf parameter into the dev structure */
+   memcpy(dev->data->dev_conf.tunnel_conf[tunnel_conf->rx_queue],
+   tunnel_conf, sizeof(struct rte_eth_tunnel_conf));
+
+   rte_eth_add_rx_callback(port_id, tunnel_conf->rx_queue,
+   rte_eth_tunnel_decap, (void *)tunnel_conf);
+
+   rte_eth_add_tx_callback(port_id, tunnel_conf->tx_queue,
+   rte_eth_tunnel_encap, (void *)tunnel_conf)
+
+   diag = (*dev->dev_ops->tunnel_configure)(dev);
+   if (diag != 0) {
+   RTE_PMD_DEBUG_TRACE("port%d dev_tunnel_configure = %d\n",
+   port_id, diag);
+   return diag;
+   }
+
+   return 0;
+}
+
 static void
 rte_eth_dev_config_restore(uint8_t port_id)
 {
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 2/6] rte_ether: define tunnel flow structure and APIs

2015-12-23 Thread Jijiang Liu
Add the struct 'rte_eth_tunnel_conf' and the tunnel configuration API. 

Signed-off-by: Jijiang Liu 
---
 lib/librte_ether/rte_ethdev.h |   28 
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bada8ad..cb4d9a2 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -630,6 +630,18 @@ struct rte_eth_rxconf {
uint8_t rx_deferred_start; /**< Do not start queue with 
rte_eth_dev_start(). */
 };

+/**
+ * A structure used to configure tunnel flow of an Ethernet port.
+ */
+struct rte_eth_tunnel_conf {
+   uint16_t rx_queue;
+   uint16_t tx_queue;
+   uint16_t udp_tunnel_port;
+   uint16_t nb_flow;
+   uint16_t filter_type;
+   struct rte_eth_tunnel_flow *tunnel_flow;
+};
+
 #define ETH_TXQ_FLAGS_NOMULTSEGS 0x0001 /**< nb_segs=1 for all mbufs */
 #define ETH_TXQ_FLAGS_NOREFCOUNT 0x0002 /**< refcnt can be ignored */
 #define ETH_TXQ_FLAGS_NOMULTMEMP 0x0004 /**< all bufs come from same mempool */
@@ -810,6 +822,7 @@ struct rte_eth_conf {
 #define DEV_RX_OFFLOAD_TCP_CKSUM   0x0008
 #define DEV_RX_OFFLOAD_TCP_LRO 0x0010
 #define DEV_RX_OFFLOAD_QINQ_STRIP  0x0020
+#define DEV_RX_OFFLOAD_TUNNEL_DECAP 0x0040

 /**
  * TX offload capabilities of a device.
@@ -1210,6 +1223,10 @@ typedef int (*eth_udp_tunnel_add_t)(struct rte_eth_dev 
*dev,

 typedef int (*eth_udp_tunnel_del_t)(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *tunnel_udp);
+
+typedef int (*eth_tunnel_flow_conf_t)(struct rte_eth_dev *dev,
+ struct rte_eth_tunnel_conf *tunnel_conf);
+
 /**< @internal Delete tunneling UDP info */

 typedef int (*eth_set_mc_addr_list_t)(struct rte_eth_dev *dev,
@@ -1385,6 +1402,7 @@ struct eth_dev_ops {
eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter 
*/
eth_udp_tunnel_add_t   udp_tunnel_add;
eth_udp_tunnel_del_t   udp_tunnel_del;
+   eth_tunnel_flow_conf_t tunnel_configure;
eth_set_queue_rate_limit_t set_queue_rate_limit;   /**< Set queue rate 
limit */
eth_set_vf_rate_limit_tset_vf_rate_limit;   /**< Set VF rate limit 
*/
/** Update redirection table. */
@@ -1821,6 +1839,16 @@ extern int rte_eth_dev_configure(uint8_t port_id,
 const struct rte_eth_conf *eth_conf);

 /**
+ * Configure an Ethernet device for tunnelling packet.
+ *
+ * @return
+ *   - 0: Success, device configured.
+ *- <0: Error code returned by the driver configuration function.
+ */
+extern int rte_eth_dev_tunnel_configure(uint8_t port_id,
+   struct rte_eth_tunnel_conf 
*tunnel_conf);
+
+/**
  * Allocate and set up a receive queue for an Ethernet device.
  *
  * The function allocates a contiguous block of memory for *nb_rx_desc*
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 1/6] rte_ether: extend rte_eth_tunnel_flow structure

2015-12-23 Thread Jijiang Liu
The purpose of extending this structure is to support more tunnel filter 
conditions.

Signed-off-by: Jijiang Liu 
---
 lib/librte_ether/rte_eth_ctrl.h |   14 +++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..39f52d9 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -494,9 +494,17 @@ enum rte_eth_fdir_tunnel_type {
  * NVGRE
  */
 struct rte_eth_tunnel_flow {
-   enum rte_eth_fdir_tunnel_type tunnel_type; /**< Tunnel type to match. */
-   uint32_t tunnel_id;/**< Tunnel ID to match. 
TNI, VNI... */
-   struct ether_addr mac_addr;/**< Mac address to match. */
+   enum rte_eth_tunnel_type tunnel_type;
+   uint64_t tunnel_id;  /**< Tunnel ID to match. TNI, VNI... */
+   struct ether_addr outer_src_mac;  /* for TX */
+   struct ether_addr outer_peer_mac; /* for TX */
+   enum rte_tunnel_iptype outer_ip_type; /**< IP address type. */
+   union {
+   struct rte_eth_ipv4_flow outer_ipv4;
+   struct rte_eth_ipv6_flow outer_ipv6;
+   } outer_ip_addr;
+   uint16_t dst_port;
+   uint16_t src_port;
 };

 /**
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 0/6] General tunneling APIs

2015-12-23 Thread Jijiang Liu
I want to define a set of General tunneling APIs, which are used to accelarate 
tunneling packet processing in DPDK,
In this RFC patch set, I wll explain my idea using some codes.

1. Using flow director offload to define a tunnel flow in a pair of queues.

flow rule: src IP + dst IP + src port + dst port + tunnel ID (for VXLAN)

For example:
struct rte_eth_tunnel_conf{
.tunnel_type = VXLAN,
.rx_queue = 1,
.tx_queue = 1,
.filter_type = 'src ip + dst ip + src port + dst port + tunnel id' 
.flow_tnl {
.tunnel_type = VXLAN,
.tunnel_id = 100,
.remote_mac = 11.22.33.44.55.66,
 .ip_type = ipv4, 
 .outer_ipv4.src_ip = 192.168.10.1
 .outer_ipv4.dst_ip = 10.239.129.11
 .src_port = 1000,
 .dst_port =2000
};

2. Configure tunnel flow for a device and for a pair of queues.

rte_eth_dev_tunnel_configure(0, &rte_eth_tunnel_conf);

In this API, it will call RX decapsulation and TX encapsulation callback 
function if HW doesn't support encap/decap, and
a space will be allocated for tunnel configuration and store a pointer to this 
new allocated space as dev->post_rx/tx_burst_cbs[].param.

rte_eth_add_rx_callback(port_id, tunnel_conf.rx_queue,
rte_eth_tunnel_decap, (void *)tunnel_conf);
rte_eth_add_tx_callback(port_id, tunnel_conf.tx_queue,
rte_eth_tunnel_encap, (void *)tunnel_conf)

3. Using rte_vxlan_decap_burst() to do decapsulation of tunneling packet.

4. Using rte_vxlan_encap_burst() to do encapsulation of tunneling packet.
   The 'src ip, dst ip, src port, dst port and  tunnel ID" can be got from 
tunnel configuration.
   And SIMD is used to accelarate the operation. 

How to use these APIs, there is a example below:

1)at config phase

dev_config(port, ...);
tunnel_config(port,...);
...
dev_start(port);
...
rx_burst(port, rxq,... );
tx_burst(port, txq,...);


2)at transmitting packet phase
The only outer src/dst MAC address need to be set for TX tunnel configuration 
in dev->post_tx_burst_cbs[].param.

In this patch set, I have not finished all of codes, the purpose of sending 
patch set is that I would like to collect more comments and sugestions on this 
idea.


Jijiang Liu (6):
  extend rte_eth_tunnel_flow
  define tunnel flow structure and APIs
  implement tunnel flow APIs
  define rte_vxlan_decap/encap
  implement rte_vxlan_decap/encap
  i40e tunnel configure

 drivers/net/i40e/i40e_ethdev.c |   41 +
 lib/librte_ether/libtunnel/rte_vxlan_opt.c |  251 
 lib/librte_ether/libtunnel/rte_vxlan_opt.h |   49 ++
 lib/librte_ether/rte_eth_ctrl.h|   14 ++-
 lib/librte_ether/rte_ethdev.h  |   28 +++
 lib/librte_ether/rte_ethdev.c  |   60 ++
 5 files changed, 440 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_ether/libtunnel/rte_vxlan_opt.c
 create mode 100644 lib/librte_ether/libtunnel/rte_vxlan_opt.h

-- 
1.7.7.6



[dpdk-dev] [PATCH v6 4/4] example/vhost: add virtio offload test in vhost sample

2015-12-21 Thread Jijiang Liu
Change the codes in vhost sample to test virtio offload feature.

These changes include,

1. add two test options: tx-csum and tso.

2. add virtio_tx_offload() function to test vhost TX offload feature for VM to 
NIC case;

however, for VM to VM case, it doesn't need to call this function, the reason 
is explained in patch 2.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  105 +++-
 1 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 044c680..210e631 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -51,6 +51,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -198,6 +201,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -428,6 +438,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -563,7 +581,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -589,6 +609,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -643,6 +665,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tso = ret;
+   }
+
/* Specify the retries delay time (in useconds) on RX. 
*/
if (!strncmp(long_option[option_index].name, 
"rx-retry-delay", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
@@ -1101,6 +1145,58 @@ find_local_dest(struct virtio_net *dev, struct rte_mbuf 
*m,
return 0;
 }

+static uint16_t
+get_psd_sum(void *l3_hdr, uint64_t ol_flags)
+{
+   if (ol_flags & PKT_TX_IPV4)
+   return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+   else /* assume ethertype == ETHER_TYPE_IPv6 */
+   return rte_ipv6_phdr_cksum(l3_hdr, ol_flags);
+}
+
+static void virt

[dpdk-dev] [PATCH v6 3/4] sample/vhost: remove the ipv4_hdr structure defination

2015-12-21 Thread Jijiang Liu
Remove the ipv4_hdr structure defination in vhost sample.

The same structure has already defined in the rte_ip.h file, so we remove the 
defination from the sample, and include that header file.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   15 +--
 1 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..044c680 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -292,20 +293,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
-- 
1.7.7.6



[dpdk-dev] [PATCH v6 2/4] vhost/lib: add guest offload setting

2015-12-21 Thread Jijiang Liu
Add guest offload setting in vhost lib.

Refer to the feature bits description in the Virtual I/O Device (VIRTIO) 
Version 1.0 below, 

1. VIRTIO_NET_F_GUEST_CSUM (1) Driver handles packets with partial checksum.

2. If the VIRTIO_NET_F_GUEST_CSUM feature was negotiated, the 
VIRTIO_NET_HDR_F_NEEDS_- CSUM bit in flags MAY be set: if so, the checksum on 
the packet is incomplete and csum_start and csum_offset indicate how to 
calculate it (see Packet Transmission point 1).

3. If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were negotiated, then 
gso_type MAY be something other than VIRTIO_NET_HDR_GSO_NONE, and gso_size 
field indicates the desired MSS (see Packet Transmission point 2).

In order to support these features, the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Enqueue these offloads: convert some fields in mbuf to the fields in 
virtio_net_hdr.

There are more explanations for the implementation.

For VM2VM case, there is no need to do checksum, for we
think the data should be reliable enough, and setting 
VIRTIO_NET_HDR_F_NEEDS_CSUM
at RX side will let the TCP layer to bypass the checksum validation,
so that the RX side could receive the packet in the end.

In terms of us-vhost, at vhost RX side, the offload information is inherited 
from mbuf, which is
in turn inherited from TX side. If we can still get those info at RX
side, it means the packet is from another VM at same host.  So, it's
safe to set the VIRTIO_NET_HDR_F_NEEDS_CSUM, to skip checksum validation.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   47 +++-
 lib/librte_vhost/virtio-net.c |5 +++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 47d5f85..9d97e19 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -54,6 +54,44 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t 
qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
 }

+static void
+virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
+{
+   memset(net_hdr, 0, sizeof(struct virtio_net_hdr));
+
+   if (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
+
+   switch (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct tcp_hdr,
+   cksum));
+   break;
+   case PKT_TX_UDP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct udp_hdr,
+   dgram_cksum));
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct sctp_hdr,
+   cksum));
+   break;
+   }
+   }
+
+   if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
+   if (m_buf->ol_flags & PKT_TX_IPV4)
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   else
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   net_hdr->gso_size = m_buf->tso_segsz;
+   net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
+   + m_buf->l4_len;
+   }
+
+   return;
+}
+
 /**
  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
  * be received from the physical port or from another virtio device. A packet
@@ -67,7 +105,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 {
struct vhost_virtqueue *vq;
struct vring_desc *desc;
-   struct rte_mbuf *buff;
+   struct rte_mbuf *buff, *first_buff;
/* The virtio_hdr is initialised to 0. */
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
uint64_t buff_addr = 0;
@@ -139,6 +177,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
desc = &vq->desc[head[packet_success]];

buff = pkts[packet_success];
+   first_buff = buff;

/* Convert from gpa to vva (guest physical addr -> vhost 
virtual addr) */
buff_addr = gpa_to_vva(dev, desc->addr);
@@ -221,7 +260,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,

if (unlikely(uncompleted_pkt == 1))
continue;
-
+
+   virtio_enqueue_offload(first_buff, &virtio_hdr.hdr);
+
rte_memcpy((void *)(uintptr_t)buff_hdr_addr,
(const void

[dpdk-dev] [PATCH v6 1/4] vhost/lib: add vhost TX offload capabilities in vhost lib

2015-12-21 Thread Jijiang Liu
Add vhost TX offload(CSUM and TSO) support capabilities in vhost lib.

Refer to feature bits in Virtual I/O Device (VIRTIO) Version 1.0 below,

VIRTIO_NET_F_CSUM (0) Device handles packets with partial checksum. This 
"checksum offload" is a common feature on modern network cards.
VIRTIO_NET_F_HOST_TSO4 (11) Device can receive TSOv4.
VIRTIO_NET_F_HOST_TSO6 (12) Device can receive TSOv6.

In order to support these features, and the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Dequeue TX offload: convert the fileds in virtio_net_hdr to the related 
fileds in mbuf.


Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  103 +
 lib/librte_vhost/virtio-net.c |6 ++-
 2 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..47d5f85 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,97 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV6;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_v

[dpdk-dev] [PATCH v6 0/4] add virtio offload support in us-vhost

2015-12-21 Thread Jijiang Liu
Adds virtio offload support in us-vhost.

The patch set adds the feature negotiation of checksum and TSO between us-vhost 
and vanilla Linux virtio guest, and add these offload features support in the 
vhost lib, and change vhost sample to test them.

In short, this patch set supports the followings,

 1. DPDK vhost CSUM & TSO for VM2NIC case

 2. CSUM and TSO support between legacy virtio-net and DPDK vhost for VM2VM and 
NIC2VM cases.

v6 change:
  Rebase latest codes.

v5 changes:
  Add more clear descriptions to explain these changes.
  reset the 'virtio_net_hdr' value in the virtio_enqueue_offload() function.
  reorganize patches. 


v4 change:
  remove virtio-net change, only keep vhost changes.
  add guest TX offload capabilities to support VM to VM case.
  split the cleanup code as a separate patch.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads.

*** BLURB HERE ***

Jijiang Liu (4):
  add vhost offload capabilities
  remove ipv4_hdr structure from vhost sample.
  add guest offload setting ln the vhost lib.
  change vhost application to test checksum and TSO for VM to NIC case

 examples/vhost/main.c |  120 -
 lib/librte_vhost/vhost_rxtx.c |  150 -
 lib/librte_vhost/virtio-net.c |9 ++-
 3 files changed, 259 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v3] doc: announce ABI change for struct rte_eth_conf

2015-12-14 Thread Jijiang Liu
In current codes, tunnel configuration information is not stored in a device 
configuration, and it will get nothing if application want to retrieve tunnel 
config, so I think it is necessary to add rte_eth_dev_tunnel_configure() 
function is to do the configurations including flow and classification 
information and store it in a device configuration.

And tunneling packet encapsulation operation will benifit from the change.

There are more descriptions for the ABI changes below,

The struct 'rte_eth_tunnel_conf' is a new, its defination like below,
struct rte_eth_tunnel_conf {
   uint16_t tx_queue;
   uint16_t filter_type;   
   struct rte_eth_tunnel_flow flow_tnl;
};

The ABI change announcement of struct 'rte_eth_tunnel_flow' have already sent 
out, refer to [1].  

[1]http://dpdk.org/ml/archives/dev/2015-December/029837.html.

The change of struct 'rte_eth_conf' like below, but it have not finalized yet.
struct rte_eth_conf {
...
uint32_t dcb_capability_en;
struct rte_fdir_conf fdir_conf; /**< FDIR configuration. */
struct rte_intr_conf intr_conf; /**< Interrupt mode configuration. */
struct rte_eth_tunnel_conf *tunnel_conf[RTE_MAX_QUEUES_PER_PORT];
/**< Tunnel configuration. */
};

v2 change:
  Add more description for the change.

v3 change:
  Change ABI announcement description.

Signed-off-by: Jijiang Liu 
---
 doc/guides/rel_notes/deprecation.rst |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 5c458f2..9dbe89e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,3 +23,9 @@ Deprecation Notices
 * ABI changes are planned for struct rte_eth_tunnel_flow in order to extend 
new fileds to support
   tunneling packet configuration in unified tunneling APIs. The release 2.2 
does not contain these ABI
   changes, but release 2.3 will, and no backwards compatibility is planned.
+
+* ABI changes are planned for the struct rte_eth_conf in order to add 
'tunnel_conf' variable
+  in the struct to store tunnel configuration when using new API 
rte_eth_dev_tunnel_configure
+  (uint8_t port_id, uint16_t rx_queue, struct rte_eth_tunnel_conf * 
tunnel_conf) to configure
+  tunnel flow and classification information. The release 2.2 does not contain 
these ABI change,
+  but release 2.3 will, and no backward compatibility is planned.
-- 
1.7.7.6



[dpdk-dev] [PATCH v2] doc: announce ABI change for struct rte_eth_conf

2015-12-11 Thread Jijiang Liu
In current codes, tunnel configuration information is not stored in a device 
configuration, and it will get nothing if application want to retrieve tunnel 
config, so I think it is necessary 
to add rte_eth_dev_tunnel_configure() function is to do the configurations 
including flow and classification information and store it in a device 
configuration.

And tunneling packet encapsulation operation will benifit from the change.

v2 change:
  Add more description for the change.

Signed-off-by: Jijiang Liu 
---
 doc/guides/rel_notes/deprecation.rst |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 5c458f2..df10249 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,3 +23,8 @@ Deprecation Notices
 * ABI changes are planned for struct rte_eth_tunnel_flow in order to extend 
new fileds to support
   tunneling packet configuration in unified tunneling APIs. The release 2.2 
does not contain these ABI
   changes, but release 2.3 will, and no backwards compatibility is planned.
+
+* ABI changes are planned for struct rte_eth_conf in order to support tunnel 
configuration using unified tunneling APIs,
+  which is the rte_eth_dev_tunnel_configure(uint8_t port_id, 
rte_eth_tunnel_conf * tunnel_conf)
+  API is planned to add. And the 'tunnel_conf' shloud be stored in global 
'rte_eth_conf'.
+  The release 2.2 does not contain these ABI change, but release 2.3 will, and 
no backwards compatibility is planned.
-- 
1.7.7.6



[dpdk-dev] [PATCH] doc: announce ABI change for struct rte_eth_tunnel_flow

2015-12-09 Thread Jijiang Liu
The struct 'rte_eth_tunnel_flow' is only used by struct 'rte_eth_fdir_flow' 
now, but its name is generic,
and I plan to extend new fileds like below to support generic configuration for 
tunneling packet.

struct rte_eth_tunnel_flow {
enum rte_eth_fdir_tunnel_type tunnel_type; /**< Tunnel type to match. */
uint32_t tunnel_id;/**< Tunnel ID to match. 
TNI, VNI... */
uint16_t flags;
struct ether_addr outer_mac_src;
struct ether_addr outer_mac_dst;
union {
struct rte_eth_ipv4_flow outer_ipv4;
struct rte_eth_ipv6_flow outer_ipv6;
   };
uint16_t dst_port;
uint16_t src_port;
struct ether_addr mac_addr;/**< Mac address to match. */
union {
struct rte_eth_ipv4_flow ipv4;
struct rte_eth_ipv6_flow ipv6;
};
 };

Note: It have not finalized yet.

Signed-off-by: Jijiang Liu 
---
 doc/guides/rel_notes/deprecation.rst |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 1c7ab01..5c458f2 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,3 +19,7 @@ Deprecation Notices
   and table action handlers will be updated:
   the pipeline parameter will be added, the packets mask parameter will be
   either removed (for input port action handler) or made input-only.
+
+* ABI changes are planned for struct rte_eth_tunnel_flow in order to extend 
new fileds to support
+  tunneling packet configuration in unified tunneling APIs. The release 2.2 
does not contain these ABI
+  changes, but release 2.3 will, and no backwards compatibility is planned.
-- 
1.7.7.6



[dpdk-dev] [PATCH] doc: announce ABI change for struct rte_eth_conf

2015-12-07 Thread Jijiang Liu
Announce ABI change for struct rte_eth_conf.

Signed-off-by: Jijiang Liu 
---
 doc/guides/rel_notes/deprecation.rst |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 1c7ab01..f50f0c7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,3 +19,7 @@ Deprecation Notices
   and table action handlers will be updated:
   the pipeline parameter will be added, the packets mask parameter will be
   either removed (for input port action handler) or made input-only.
+
+* ABI changes are planned for struct rte_eth_conf in order to support
+  tunneling packet configuration in unified tunneling API. The release 2.2 
does not contain these ABI
+  changes, but release 2.3 will, and no backwards compatibility is planned.
-- 
1.7.7.6



[dpdk-dev] [PATCH v5 4/4] example/vhost: add virtio offload test in vhost sample

2015-11-12 Thread Jijiang Liu
Change the codes in vhost sample to test virtio offload feature.

These changes include,

1. add two test options: tx-csum and tso.

2. add virtio_tx_offload() function to test vhost TX offload feature for VM to 
NIC case; 
however, for VM to VM case, it doesn't need to call this function, the reason 
is explained in patch 2.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  105 +++-
 1 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 044c680..210e631 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -51,6 +51,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -198,6 +201,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -428,6 +438,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -563,7 +581,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -589,6 +609,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -643,6 +665,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tso = ret;
+   }
+
/* Specify the retries delay time (in useconds) on RX. 
*/
if (!strncmp(long_option[option_index].name, 
"rx-retry-delay", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
@@ -1101,6 +1145,58 @@ find_local_dest(struct virtio_net *dev, struct rte_mbuf 
*m,
return 0;
 }

+static uint16_t
+get_psd_sum(void *l3_hdr, uint64_t ol_flags)
+{
+   if (ol_flags & PKT_TX_IPV4)
+   return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+   else /* assume ethertype == ETHER_TYPE_IPv6 */
+   return rte_ipv6_phdr_cksum(l3_hdr, ol_flags);
+}
+
+static void virt

[dpdk-dev] [PATCH v5 3/4] sample/vhost: remove the ipv4_hdr structure defination

2015-11-12 Thread Jijiang Liu
Remove the ipv4_hdr structure defination in vhost sample.

The same structure has already defined in the rte_ip.h file, so we remove the 
defination from the sample, and include that header file.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   15 +--
 1 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..044c680 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -292,20 +293,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
-- 
1.7.7.6



[dpdk-dev] [PATCH v5 2/4] vhost/lib: add guest offload setting

2015-11-12 Thread Jijiang Liu
Add guest offload setting in vhost lib.

Refer to the feature bits description in the Virtual I/O Device (VIRTIO) 
Version 1.0 below, 

1. VIRTIO_NET_F_GUEST_CSUM (1) Driver handles packets with partial checksum.

2. If the VIRTIO_NET_F_GUEST_CSUM feature was negotiated, the 
VIRTIO_NET_HDR_F_NEEDS_- CSUM bit in flags MAY be set: if so, the checksum on 
the packet is incomplete and csum_start and csum_offset indicate how to 
calculate it (see Packet Transmission point 1).

3. If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were negotiated, then 
gso_type MAY be something other than VIRTIO_NET_HDR_GSO_NONE, and gso_size 
field indicates the desired MSS (see Packet Transmission point 2).

In order to support these features, the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Enqueue these offloads: convert some fields in mbuf to the fields in 
virtio_net_hdr.

There are more explanations for the implementation.

For VM2VM case, there is no need to do checksum, for we
think the data should be reliable enough, and setting 
VIRTIO_NET_HDR_F_NEEDS_CSUM
at RX side will let the TCP layer to bypass the checksum validation,
so that the RX side could receive the packet in the end.

In terms of us-vhost, at vhost RX side, the offload information is inherited 
from mbuf, which is
in turn inherited from TX side. If we can still get those info at RX
side, it means the packet is from another VM at same host.  So, it's
safe to set the VIRTIO_NET_HDR_F_NEEDS_CSUM, to skip checksum validation.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   47 +++-
 lib/librte_vhost/virtio-net.c |5 +++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 47d5f85..9d97e19 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -54,6 +54,44 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t 
qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
 }

+static void
+virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
+{
+   memset(net_hdr, 0, sizeof(struct virtio_net_hdr));
+
+   if (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
+
+   switch (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct tcp_hdr,
+   cksum));
+   break;
+   case PKT_TX_UDP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct udp_hdr,
+   dgram_cksum));
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct sctp_hdr,
+   cksum));
+   break;
+   }
+   }
+
+   if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
+   if (m_buf->ol_flags & PKT_TX_IPV4)
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   else
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   net_hdr->gso_size = m_buf->tso_segsz;
+   net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
+   + m_buf->l4_len;
+   }
+
+   return;
+}
+
 /**
  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
  * be received from the physical port or from another virtio device. A packet
@@ -67,7 +105,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 {
struct vhost_virtqueue *vq;
struct vring_desc *desc;
-   struct rte_mbuf *buff;
+   struct rte_mbuf *buff, *first_buff;
/* The virtio_hdr is initialised to 0. */
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
uint64_t buff_addr = 0;
@@ -139,6 +177,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
desc = &vq->desc[head[packet_success]];

buff = pkts[packet_success];
+   first_buff = buff;

/* Convert from gpa to vva (guest physical addr -> vhost 
virtual addr) */
buff_addr = gpa_to_vva(dev, desc->addr);
@@ -221,7 +260,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,

if (unlikely(uncompleted_pkt == 1))
continue;
-
+   
+   virtio_enqueue_offload(first_buff, &virtio_hdr.hdr);
+   
rte_memcpy((void *)(uintptr_t)buff_hdr_addr,
   

[dpdk-dev] [PATCH v5 1/4] vhost/lib: add vhost TX offload capabilities in vhost lib

2015-11-12 Thread Jijiang Liu
Add vhost TX offload(CSUM and TSO) support capabilities in vhost lib.

Refer to feature bits in Virtual I/O Device (VIRTIO) Version 1.0 below,

VIRTIO_NET_F_CSUM (0) Device handles packets with partial checksum. This 
"checksum offload" is a common feature on modern network cards.
VIRTIO_NET_F_HOST_TSO4 (11) Device can receive TSOv4.
VIRTIO_NET_F_HOST_TSO6 (12) Device can receive TSOv6.

In order to support these features, and the following changes are added,

1. Extend 'VHOST_SUPPORTED_FEATURES' macro to add the offload features 
negotiation.

2. Dequeue TX offload: convert the fileds in virtio_net_hdr to the related 
fileds in mbuf.


Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  103 +
 lib/librte_vhost/virtio-net.c |6 ++-
 2 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..47d5f85 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,97 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV6;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_v

[dpdk-dev] [PATCH v5 0/4] add virtio offload support in us-vhost

2015-11-12 Thread Jijiang Liu
Adds virtio offload support in us-vhost.

The patch set adds the feature negotiation of checksum and TSO between us-vhost 
and vanilla Linux virtio guest, and add these offload features support in the 
vhost lib, and change vhost sample to test them.

v5 changes:
  Add more clear descriptions to explain these changes.
  reset the 'virtio_net_hdr' value in the virtio_enqueue_offload() function.
  reorganize patches. 


v4 change:
  remove virtio-net change, only keep vhost changes.
  add guest TX offload capabilities to support VM to VM case.
  split the cleanup code as a separate patch.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads.

*** BLURB HERE ***

Jijiang Liu (4):
  add vhost offload capabilities
  remove ipv4_hdr structure from vhost sample.
  add guest offload setting ln the vhost lib.
  change vhost application to test checksum and TSO for VM to NIC case

 examples/vhost/main.c |  120 -
 lib/librte_vhost/vhost_rxtx.c |  150 -
 lib/librte_vhost/virtio-net.c |9 ++-
 3 files changed, 259 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v4 8/8] virtio/lib:add guest offload handle

2015-11-11 Thread Jijiang Liu
Enqueue guest offload(CSUM and TSO) handle.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   45 +++-
 1 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9e70990..468fed8 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -54,6 +54,42 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t 
qp_nb)
return (is_tx ^ (idx & 1)) == 0 && idx < qp_nb * VIRTIO_QNUM;
 }

+static void
+virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
+{
+   if (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
+
+   switch (m_buf->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct tcp_hdr,
+   cksum));
+   break;
+   case PKT_TX_UDP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct udp_hdr,
+   dgram_cksum));
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   net_hdr->csum_offset = (offsetof(struct sctp_hdr,
+   cksum));
+   break;
+   }
+   }
+
+   if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
+   if (m_buf->ol_flags & PKT_TX_IPV4)
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   else
+   net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   net_hdr->gso_size = m_buf->tso_segsz;
+   net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
+   + m_buf->l4_len;
+   }
+
+   return;
+}
+
 /**
  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
  * be received from the physical port or from another virtio device. A packet
@@ -67,7 +103,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 {
struct vhost_virtqueue *vq;
struct vring_desc *desc;
-   struct rte_mbuf *buff;
+   struct rte_mbuf *buff, *first_buff;
/* The virtio_hdr is initialised to 0. */
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
uint64_t buff_addr = 0;
@@ -139,6 +175,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
desc = &vq->desc[head[packet_success]];

buff = pkts[packet_success];
+   first_buff = buff;

/* Convert from gpa to vva (guest physical addr -> vhost 
virtual addr) */
buff_addr = gpa_to_vva(dev, desc->addr);
@@ -221,7 +258,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,

if (unlikely(uncompleted_pkt == 1))
continue;
-
+   
+   virtio_enqueue_offload(first_buff, &virtio_hdr.hdr);
+   
rte_memcpy((void *)(uintptr_t)buff_hdr_addr,
(const void *)&virtio_hdr, vq->vhost_hlen);

@@ -295,6 +334,8 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t 
queue_id,
LOG_DEBUG(VHOST_DATA, "(%"PRIu64") RX: Num merge buffers %d\n",
dev->device_fh, virtio_hdr.num_buffers);

+   virtio_enqueue_offload(pkt, &virtio_hdr.hdr);   
+
rte_memcpy((void *)(uintptr_t)vb_hdr_addr,
(const void *)&virtio_hdr, vq->vhost_hlen);

-- 
1.7.7.6



[dpdk-dev] [PATCH v4 7/8] virtio/lib:add virtio guest offload capabilities

2015-11-11 Thread Jijiang Liu
Add virtio guest offload capabilities.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index 81bd309..839a333 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -80,7 +80,10 @@ static struct virtio_net_config_ll *ll_root;
(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
-   (1ULL << VIRTIO_NET_F_CSUM))
+   (1ULL << VIRTIO_NET_F_CSUM)| \
+   (1ULL << VIRTIO_NET_F_GUEST_CSUM) | \
+   (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_GUEST_TSO6))

 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;

-- 
1.7.7.6



[dpdk-dev] [PATCH v4 6/8] examples/vhost:support TX offload in vhost sample

2015-11-11 Thread Jijiang Liu
Change the vhost sample to support and test TX offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  110 +++-
 1 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 044c680..24e2c26 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -51,6 +51,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -198,6 +201,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -428,6 +438,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -563,7 +581,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -589,6 +609,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -643,6 +665,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tso = ret;
+   }
+
/* Specify the retries delay time (in useconds) on RX. 
*/
if (!strncmp(long_option[option_index].name, 
"rx-retry-delay", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
@@ -1101,6 +1145,63 @@ find_local_dest(struct virtio_net *dev, struct rte_mbuf 
*m,
return 0;
 }

+static uint16_t
+get_psd_sum(void *l3_hdr, uint64_t ol_flags)
+{
+   if (ol_flags & PKT_TX_IPV4)
+   return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+   else /* assume ethertype == ETHER_TYPE_IPv6 */
+   return rte_ipv6_phdr_cksum(l3_hdr, ol_flags);
+}
+
+static void virtio_tx_offload(struct rte_mbuf *m)
+{
+   void *l3_hdr;
+   struct ipv4_hdr *ipv4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+   struct udp_hdr *udp_hdr = NULL;
+   struct sctp_hdr *sctp_hdr = NULL;
+   struct ether_hdr *eth_hdr = rte_pktm

[dpdk-dev] [PATCH v4 5/8] sample/vhost:remove ip_hdr structure defination

2015-11-11 Thread Jijiang Liu
Remove the ip_hdr structure defination.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   15 +--
 1 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..044c680 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -292,20 +293,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
-- 
1.7.7.6



[dpdk-dev] [PATCH v4 4/8] virtio/lib:dequeue vhost TX offload

2015-11-11 Thread Jijiang Liu
Dequeue vhost TX offload(CSUM and TSO) in vhost lib

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  104 -
 1 files changed, 103 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..9e70990 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,97 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->ol_flags |= PKT_TX_IPV6;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -576,11 +672,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t head[MAX_PKT_BURST];
uint32_t used_idx;
uint32_t i;
uint16_t free_entries, entry_success = 0;
uint16_t avail_idx;
+   struct virtio_net_hdr *hdr = NULL;

if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->v

[dpdk-dev] [PATCH v4 3/8] virtio/lib:add vhost TX checksum support capabilities

2015-11-11 Thread Jijiang Liu
Add vhost TX offload(CSUM and TSO) support capabilities.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index 14278de..81bd309 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -77,7 +77,11 @@ static struct virtio_net_config_ll *ll_root;
(VHOST_SUPPORTS_MQ)| \
(1ULL << VIRTIO_F_VERSION_1)   | \
(1ULL << VHOST_F_LOG_ALL)  | \
-   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES))
+   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
+   (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH v4 2/8] driver/virtio:record virtual address of virtio net header

2015-11-11 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 74c00ee..dd39715 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -414,6 +414,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH v4 1/8] driver/virtio:add virtual address for virtio net header

2015-11-11 Thread Jijiang Liu
The virtual address for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 689c321..5b43eeb 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -190,6 +190,7 @@ struct virtqueue {
uint16_t vq_avail_idx;
uint64_t mbuf_initializer; /**< value to init mbufs. */
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

struct rte_mbuf **sw_ring; /**< RX software ring. */
/* dummy mbuf, for wraparound when processing RX ring. */
-- 
1.7.7.6



[dpdk-dev] [PATCH v4 0/8] add virtio offload support in us-vhost

2015-11-11 Thread Jijiang Liu
Adds virtio offload support in us-vhost.

The patch set adds the negotiation support between us-vhost and vanilla Linux 
virtio guest for TX offload(checksum and TSO), and add the offload support in 
the vhost libs and change vhost sample to test these changes.

v4 change:
  remove virtio-net change, only keep vhost changes.
  add guest TX offload capabilities to support VM to VM case.
  split the cleanup code as a seperate patch.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads.

*** BLURB HERE ***

Jijiang Liu (8):
  add virtual addr of virtio net header
  store vir address of virtio hdr
  add vhost TX offload capabilities(CSUM/TSO)
  add dequeue offload handle in vhost lib
  remove ip_hdr defination in vhost sample
  change vhost app to support virtio offload test
  add guest offload(CSUM/TSO)
  add guest tx offload handle in vhost lib

 drivers/net/virtio/virtio_ethdev.c |3 +
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |  125 ++
 lib/librte_vhost/vhost_rxtx.c  |  149 +++-
 lib/librte_vhost/virtio-net.c  |9 ++-
 5 files changed, 266 insertions(+), 21 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v3 8/8] examples/vhost:support TX offload in vhost sample

2015-11-04 Thread Jijiang Liu
Change the vhost sample to support and test TX offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  128 ++---
 1 files changed, 111 insertions(+), 17 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9eac2d0..06e1e8b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -140,6 +144,8 @@

 #define MBUF_EXT_MEM(mb)   (rte_mbuf_from_indirect(mb) != (mb))

+#define VIRTIO_TX_CKSUM_OFFLOAD_MASK (PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;

@@ -197,6 +203,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -292,20 +305,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
@@ -441,6 +440,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -576,7 +583,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -602,6 +611,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -656,6 +667,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0

[dpdk-dev] [PATCH v3 7/8] lib/librte_vhost:dequeue vhost TX offload

2015-11-04 Thread Jijiang Liu
Dequeue vhost TX offload in vhost lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  108 -
 1 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 9322ce6..86bfa60 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -37,7 +37,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -568,6 +573,101 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->ol_flags |= PKT_TX_IPV6;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if ((hdr->csum_start == m->l2_len) &&
+   (hdr->csum_offset == offsetof(struct ipv4_hdr,
+   hdr_checksum)))
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   else if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -576,11 +676,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t h

[dpdk-dev] [PATCH v3 6/8] driver/virtio:enqueue vhost TX offload

2015-11-04 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   61 ++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..b99f5b5 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -199,6 +203,58 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
 }

 static int
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+
+   /* if vhost TX checksum offload is required */
+   if (m->ol_flags & PKT_TX_IP_CKSUM) {
+   hdr->csum_start = m->l2_len;
+   hdr->csum_offset = offsetof(struct ipv4_hdr, hdr_checksum);
+   } else if (m->ol_flags & PKT_TX_L4_MASK) {
+   hdr->csum_start = m->l2_len + m->l3_len;
+   switch (m->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
+   break;
+   case PKT_TX_UDP_CKSUM:
+   hdr->csum_offset = offsetof(struct udp_hdr,
+   dgram_cksum);
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   hdr->csum_offset = offsetof(struct sctp_hdr, cksum);
+   break;
+   default:
+   break;
+   }
+   } else
+   hdr->flags = 0;
+
+   /* if vhost TSO offload is required */
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO4))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO6))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   } else
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+   return 0;
+}
+
+static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
struct vq_desc_extra *dxp;
@@ -221,6 +277,11 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   if (vtpci_with_feature(txvq->hw, VIRTIO_NET_F_CSUM)) {
+   if (virtqueue_enqueue_offload(txvq, cookie, idx, head_size) < 0)
+   return -EPERM;
+   }
+
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 5/8] driver/virtio:enqueue vhost TX offload

2015-11-04 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index 14278de..81bd309 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -77,7 +77,11 @@ static struct virtio_net_config_ll *ll_root;
(VHOST_SUPPORTS_MQ)| \
(1ULL << VIRTIO_F_VERSION_1)   | \
(1ULL << VHOST_F_LOG_ALL)  | \
-   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES))
+   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
+   (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH v3 4/8] driver/virtio:fill virtio device info for TX offload

2015-11-04 Thread Jijiang Liu
Fill virtio device info for TX offload.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index cb5dfee..b831c02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1559,6 +1559,16 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->default_txconf = (struct rte_eth_txconf) {
.txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS
};
+
+   if (hw->guest_features & (1u << VIRTIO_NET_F_CSUM))
+   dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
+   DEV_TX_OFFLOAD_UDP_CKSUM |
+   DEV_TX_OFFLOAD_TCP_CKSUM |
+   DEV_TX_OFFLOAD_SCTP_CKSUM;
+
+   if ((hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO4)) ||
+   (hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO6)))
+   dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 }

 /*
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 3/8] driver/virtio:add vhost TX checksum support capability in virtio-net

2015-11-04 Thread Jijiang Liu
Add vhost TX checksum and TSO capabilities in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..6ee95c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,10 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6 | \
+1u << VIRTIO_NET_F_CSUM)

 /*
  * CQ function prototype
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 2/8] driver/virtio: record virtual address of virtio net header

2015-11-04 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 1/8] driver/virtio:add virtual addr for virtio net header

2015-11-04 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 689c321..5b43eeb 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -190,6 +190,7 @@ struct virtqueue {
uint16_t vq_avail_idx;
uint64_t mbuf_initializer; /**< value to init mbufs. */
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

struct rte_mbuf **sw_ring; /**< RX software ring. */
/* dummy mbuf, for wraparound when processing RX ring. */
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 0/8] add vhost TX offload support

2015-11-04 Thread Jijiang Liu
Adds vhost TX offload support.

The patch set add the negotiation between us-vhost and virtio-net for vhost TX 
offload(checksum and TSO), and add the TX offload support in the libs and 
change vhost sample and csum application to test these changes.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads. 

Jijiang Liu (8):
  add virtual address of virtio net header
  store virtual address of virtio hdr
  add vhost TX offload support capability in virtio-net
  fill virtio device information for TX offloads.
  add vhost TX offload support capability in vhost
  enqueue TX offload
  dequeue TX offload
  change vhost App to support TX offload
  fix csumonly fwd issue 

 drivers/net/virtio/virtio_ethdev.c |13 ++ 
 drivers/net/virtio/virtio_ethdev.h |5 +-
 drivers/net/virtio/virtio_rxtx.c   |   61 +
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |  128 +++-
 lib/librte_vhost/vhost_rxtx.c  |  108 ++-
 lib/librte_vhost/virtio-net.c  |6 ++-
 8 files changed, 302 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v3 8/8] examples/vhost:support TX offload in vhost sample

2015-11-04 Thread Jijiang Liu
Change the vhost sample to support and test TX offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  128 ++---
 1 files changed, 111 insertions(+), 17 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9eac2d0..06e1e8b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -140,6 +144,8 @@

 #define MBUF_EXT_MEM(mb)   (rte_mbuf_from_indirect(mb) != (mb))

+#define VIRTIO_TX_CKSUM_OFFLOAD_MASK (PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;

@@ -197,6 +203,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -292,20 +305,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
@@ -441,6 +440,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -576,7 +583,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -602,6 +611,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -656,6 +667,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0

[dpdk-dev] [PATCH v3 7/8] lib/librte_vhost:dequeue vhost TX offload

2015-11-04 Thread Jijiang Liu
Dequeue vhost TX offload in vhost lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  108 -
 1 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 7026bfa..a888ba9 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -36,7 +36,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -548,6 +553,101 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->ol_flags |= PKT_TX_IPV6;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if ((hdr->csum_start == m->l2_len) &&
+   (hdr->csum_offset == offsetof(struct ipv4_hdr,
+   hdr_checksum)))
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   else if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -556,11 +656,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t h

[dpdk-dev] [PATCH v3 6/8] driver/virtio:enqueue vhost TX offload

2015-11-04 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   61 ++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..b99f5b5 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -199,6 +203,58 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
 }

 static int
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+
+   /* if vhost TX checksum offload is required */
+   if (m->ol_flags & PKT_TX_IP_CKSUM) {
+   hdr->csum_start = m->l2_len;
+   hdr->csum_offset = offsetof(struct ipv4_hdr, hdr_checksum);
+   } else if (m->ol_flags & PKT_TX_L4_MASK) {
+   hdr->csum_start = m->l2_len + m->l3_len;
+   switch (m->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
+   break;
+   case PKT_TX_UDP_CKSUM:
+   hdr->csum_offset = offsetof(struct udp_hdr,
+   dgram_cksum);
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   hdr->csum_offset = offsetof(struct sctp_hdr, cksum);
+   break;
+   default:
+   break;
+   }
+   } else
+   hdr->flags = 0;
+
+   /* if vhost TSO offload is required */
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO4))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO6))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   } else
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+   return 0;
+}
+
+static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
struct vq_desc_extra *dxp;
@@ -221,6 +277,11 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   if (vtpci_with_feature(txvq->hw, VIRTIO_NET_F_CSUM)) {
+   if (virtqueue_enqueue_offload(txvq, cookie, idx, head_size) < 0)
+   return -EPERM;
+   }
+
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 5/8] driver/virtio:enqueue vhost TX offload

2015-11-04 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index 14278de..81bd309 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -77,7 +77,11 @@ static struct virtio_net_config_ll *ll_root;
(VHOST_SUPPORTS_MQ)| \
(1ULL << VIRTIO_F_VERSION_1)   | \
(1ULL << VHOST_F_LOG_ALL)  | \
-   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES))
+   (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
+   (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH v3 4/8] driver/virtio:fill virtio device info for TX offload

2015-11-04 Thread Jijiang Liu
Fill virtio device info for TX offload.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index cb5dfee..b831c02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1559,6 +1559,16 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->default_txconf = (struct rte_eth_txconf) {
.txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS
};
+
+   if (hw->guest_features & (1u << VIRTIO_NET_F_CSUM))
+   dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
+   DEV_TX_OFFLOAD_UDP_CKSUM |
+   DEV_TX_OFFLOAD_TCP_CKSUM |
+   DEV_TX_OFFLOAD_SCTP_CKSUM;
+
+   if ((hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO4)) ||
+   (hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO6)))
+   dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 }

 /*
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 3/8] driver/virtio:add vhost TX checksum support capability in virtio-net

2015-11-04 Thread Jijiang Liu
Add vhost TX checksum and TSO capabilities in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..6ee95c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,10 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6 | \
+1u << VIRTIO_NET_F_CSUM)

 /*
  * CQ function prototype
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 2/8] driver/virtio: record virtual address of virtio net header

2015-11-04 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 1/8] driver/virtio:add virtual addr for virtio net header

2015-11-04 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..530f840 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -189,6 +189,7 @@ struct virtqueue {
uint16_t vq_used_cons_idx;
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

/* Statistics */
uint64_tpackets;
-- 
1.7.7.6



[dpdk-dev] [PATCH v3 0/8] add vhost TX offload support

2015-11-04 Thread Jijiang Liu
Adds vhost TX offload support.

The patch set add the negotiation between us-vhost and virtio-net for vhost TX 
offload(checksum and TSO), and add the TX offload support in the libs and 
change vhost sample and csum application to test these changes.

v3 change:
  rebase latest codes.

v2 change:
  fill virtio device information for TX offloads. 

Jijiang Liu (8):
  add virtual address of virtio net header
  store virtual address of virtio hdr
  add vhost TX offload support capability in virtio-net
  fill virtio device information for TX offloads.
  add vhost TX offload support capability in vhost
  enqueue TX offload
  dequeue TX offload
  change vhost App to support TX offload
  fix csumonly fwd issue 

 drivers/net/virtio/virtio_ethdev.c |13 ++ 
 drivers/net/virtio/virtio_ethdev.h |5 +-
 drivers/net/virtio/virtio_rxtx.c   |   61 +
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |  128 +++-
 lib/librte_vhost/vhost_rxtx.c  |  108 ++-
 lib/librte_vhost/virtio-net.c  |6 ++-
 8 files changed, 302 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v2 2/2] lib/lpm:fix an initialization issue of valid_group in the delete_depth_small()

2015-10-30 Thread Jijiang Liu
Fixes an initialization issue of 'valid_group' in the delete_depth_small 
function.

In this function, use new rte_lpm_tbl8_entry we call A to replace the old 
rte_lpm_tbl8_entry. But the valid_group do not set VALID, so it 
will be INVALID.

Then when adding a new route which depth is > 24,the tbl8_alloc() function will 
search the rte_lpm_tbl8_entrys to find INVALID 
valid_group, and it will return the A to the add_depth_big function, so A's 
data is overridden.

Signed-off-by: NaNa 

---
 lib/librte_lpm/rte_lpm.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 57ec2f0..3981452 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -769,6 +769,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,

struct rte_lpm_tbl8_entry new_tbl8_entry = {
.valid = VALID,
+   .valid_group = VALID,
.depth = sub_rule_depth,
.next_hop = lpm->rules_tbl
[sub_rule_index].next_hop,
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 1/2] lib/lpm:fix an issue of condition check in delete_depth_small()

2015-10-30 Thread Jijiang Liu
Fixes an issue of check logic in delete_depth_small function.

For a tbl24 entry, the 'ext_entry' field indicates whether we need to use 
tbl8_gindex to read the next_hop from a tbl8 entry, or whether it can be read 
directly from this entry.

If a route is deleted, the prefix of previous route is used to override the 
deleted route.

When checking the depth of the previous route the conditional checks both the 
ext_entry and the depth, but the "else" leg fails to take account that the 
condition could fail for one of two possible reasons, leading to an incorrect 
flow when 'ext_entry == 0' is true , but 'lpm->tbl24[i].depth > depth' is 
false. The fix here is to add a condition check to the else leg so that it only 
executes when ext_entry is set.

Signed-off-by: NaNa 

---
 lib/librte_lpm/rte_lpm.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 163ba3c..57ec2f0 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -734,8 +734,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
if (lpm->tbl24[i].ext_entry == 0 &&
lpm->tbl24[i].depth <= depth ) {
lpm->tbl24[i].valid = INVALID;
-   }
-   else {
+   } else if (lpm->tbl24[i].ext_entry == 1) {
/*
 * If TBL24 entry is extended, then there has
 * to be a rule with depth >= 25 in the
@@ -780,8 +779,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
if (lpm->tbl24[i].ext_entry == 0 &&
lpm->tbl24[i].depth <= depth ) {
lpm->tbl24[i] = new_tbl24_entry;
-   }
-   else {
+   } else  if (lpm->tbl24[i].ext_entry == 1) {
/*
 * If TBL24 entry is extended, then there has
 * to be a rule with depth >= 25 in the
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 0/2] Fix two issues in lpm

2015-10-30 Thread Jijiang Liu
Fixes two issues in the delete_depth_small() function.

v2 changes:
  Split a patch into two patches for two issues.
  Add more clear issue description. 


*** BLURB HERE ***

Jijiang Liu (2):
  fix an issue of condition check in delete_depth_small().
  fix an initialization issue of valid_group in the delete_depth_small()

 lib/librte_lpm/rte_lpm.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH v2 9/9] app/testpmd:modify MAC address of csum forwarding

2015-10-30 Thread Jijiang Liu
Modify MAC address of csum forwarding.

The change will affect on the csum fwd performance.
But I also think the change is necessary, or we cannot use csumonly fwd mode in 
a VM.

Signed-off-by: Jijiang Liu 
---
 app/test-pmd/csumonly.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e561dde..20d4274 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -622,6 +622,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
m->tso_segsz = info.tso_segsz;
m->ol_flags = ol_flags;
+   
+   ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+   ð_hdr->d_addr);
+
+   ether_addr_copy(&ports[fs->tx_port].eth_addr,
+   ð_hdr->s_addr);

/* if verbose mode is enabled, dump debug info */
if (verbose_level > 0) {
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 8/9] examples/vhost:support TX offload in vhost sample

2015-10-30 Thread Jijiang Liu
Change the vhost sample to support and test TX offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  128 ++---
 1 files changed, 111 insertions(+), 17 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9eac2d0..06e1e8b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -140,6 +144,8 @@

 #define MBUF_EXT_MEM(mb)   (rte_mbuf_from_indirect(mb) != (mb))

+#define VIRTIO_TX_CKSUM_OFFLOAD_MASK (PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;

@@ -197,6 +203,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -292,20 +305,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
@@ -441,6 +440,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -576,7 +583,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -602,6 +611,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -656,6 +667,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0

[dpdk-dev] [PATCH v2 7/9] lib/librte_vhost:dequeue vhost TX offload

2015-10-30 Thread Jijiang Liu
Dequeue vhost TX offload in vhost lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  108 -
 1 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 7026bfa..a888ba9 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -36,7 +36,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -548,6 +553,101 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->ol_flags |= PKT_TX_IPV6;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if ((hdr->csum_start == m->l2_len) &&
+   (hdr->csum_offset == offsetof(struct ipv4_hdr,
+   hdr_checksum)))
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   else if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -556,11 +656,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t h

[dpdk-dev] [PATCH v2 6/9] driver/virtio:enqueue vhost TX offload

2015-10-30 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   61 ++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..b99f5b5 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -199,6 +203,58 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
 }

 static int
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+
+   /* if vhost TX checksum offload is required */
+   if (m->ol_flags & PKT_TX_IP_CKSUM) {
+   hdr->csum_start = m->l2_len;
+   hdr->csum_offset = offsetof(struct ipv4_hdr, hdr_checksum);
+   } else if (m->ol_flags & PKT_TX_L4_MASK) {
+   hdr->csum_start = m->l2_len + m->l3_len;
+   switch (m->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
+   break;
+   case PKT_TX_UDP_CKSUM:
+   hdr->csum_offset = offsetof(struct udp_hdr,
+   dgram_cksum);
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   hdr->csum_offset = offsetof(struct sctp_hdr, cksum);
+   break;
+   default:
+   break;
+   }
+   } else
+   hdr->flags = 0;
+
+   /* if vhost TSO offload is required */
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO4))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO6))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   } else
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+   return 0;
+}
+
+static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
struct vq_desc_extra *dxp;
@@ -221,6 +277,11 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   if (vtpci_with_feature(txvq->hw, VIRTIO_NET_F_CSUM)) {
+   if (virtqueue_enqueue_offload(txvq, cookie, idx, head_size) < 0)
+   return -EPERM;
+   }
+
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 5/9] driver/virtio:add vhost TSO support capability

2015-10-30 Thread Jijiang Liu
Add vhost TSO support capability in vhost lib. 

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index d0f1764..a5989a2 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -71,7 +71,11 @@ static struct virtio_net_config_ll *ll_root;
 #define VHOST_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
(1ULL << VIRTIO_NET_F_CTRL_VQ) | \
(1ULL << VIRTIO_NET_F_CTRL_RX) | \
-   (1ULL << VHOST_F_LOG_ALL))
+   (1ULL << VHOST_F_LOG_ALL)  | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
+   (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH v2 4/9] driver/virtio:fill virtio device info for TX offload

2015-10-30 Thread Jijiang Liu
Fill virtio device info for TX offload.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index cb5dfee..b831c02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1559,6 +1559,16 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->default_txconf = (struct rte_eth_txconf) {
.txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS
};
+
+   if (hw->guest_features & (1u << VIRTIO_NET_F_CSUM))
+   dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
+   DEV_TX_OFFLOAD_UDP_CKSUM |
+   DEV_TX_OFFLOAD_TCP_CKSUM |
+   DEV_TX_OFFLOAD_SCTP_CKSUM;
+
+   if ((hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO4)) ||
+   (hw->guest_features & (1u << VIRTIO_NET_F_HOST_TSO6)))
+   dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 }

 /*
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 3/9] driver/virtio:add vhost TX checksum support capability in virtio-net

2015-10-30 Thread Jijiang Liu
Add vhost TX checksum and TSO capabilities in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..6ee95c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,10 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6 | \
+1u << VIRTIO_NET_F_CSUM)

 /*
  * CQ function prototype
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 2/9] driver/virtio: record virtual address of virtio net header

2015-10-30 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 1/9] driver/virtio:add virtual addr for virtio net header

2015-10-30 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..530f840 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -189,6 +189,7 @@ struct virtqueue {
uint16_t vq_used_cons_idx;
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

/* Statistics */
uint64_tpackets;
-- 
1.7.7.6



[dpdk-dev] [PATCH v2 0/9] add vhost TX offload support

2015-10-30 Thread Jijiang Liu
Adds vhost TX offload support.

The patch set add the negotiation between us-vhost and virtio-net for vhost TX 
offload(checksum and TSO), and add the TX offload support in the libs and 
change vhost sample and csum application to test these changes.

v2 change:
  fill virtio device information for TX offloads. 

Jijiang Liu (8):
  add virtual address of virtio net header
  store virtual address of virtio hdr
  add vhost TX offload support capability in virtio-net
  fill virtio device information for TX offloads.
  add vhost TX offload support capability in vhost
  enqueue TX offload
  dequeue TX offload
  change vhost App to support TX offload
  fix csumonly fwd issue 

 app/test-pmd/csumonly.c|6 ++
 drivers/net/virtio/virtio_ethdev.c |13 ++ 
 drivers/net/virtio/virtio_ethdev.h |5 +-
 drivers/net/virtio/virtio_rxtx.c   |   61 +
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |  128 +++-
 lib/librte_vhost/vhost_rxtx.c  |  108 ++-
 lib/librte_vhost/virtio-net.c  |6 ++-
 8 files changed, 308 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH] lib/lpm:fix two issues in the delete_depth_small()

2015-10-28 Thread Jijiang Liu
Fix two issues in the delete_depth_small() function.

1> The control is not strict in this function.

In the following structure,
struct rte_lpm_tbl24_entry {
union {
uint8_t next_hop;
uint8_t tbl8_gindex;
};
 uint8_t ext_entry :1;
}

When ext_entry = 0, use next_hop.only to process rte_lpm_tbl24_entry.

When ext_entry = 1, use tbl8_gindex to process the rte_lpm_tbl8_entry.

When using LPM24 + 8 algorithm, it will use ext_entry to decide to process 
rte_lpm_tbl24_entry structure or rte_lpm_tbl8_entry structure. 
If a route is deleted, the prefix of previous route is used to override the 
deleted route. when (lpm->tbl24[i].ext_entry == 0 && lpm->tbl24[i].depth > 
depth) 
it should be ignored, but due to the incorrect logic, the next_hop is used as 
tbl8_gindex and will process the rte_lpm_tbl8_entry.

2> Initialization of rte_lpm_tbl8_entry is incorrect in this function 

In this function, use new rte_lpm_tbl8_entry we call A to replace the old 
rte_lpm_tbl8_entry. But the valid_group do not set VALID, so it will be INVALID.
Then when adding a new route which depth is > 24,the tbl8_alloc() function will 
search the rte_lpm_tbl8_entrys to find INVALID valid_group, 
and it will return the A to the add_depth_big function, so A's data is 
overridden.

Signed-off-by: NaNa 

---
 lib/librte_lpm/rte_lpm.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 163ba3c..3981452 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -734,8 +734,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
if (lpm->tbl24[i].ext_entry == 0 &&
lpm->tbl24[i].depth <= depth ) {
lpm->tbl24[i].valid = INVALID;
-   }
-   else {
+   } else if (lpm->tbl24[i].ext_entry == 1) {
/*
 * If TBL24 entry is extended, then there has
 * to be a rule with depth >= 25 in the
@@ -770,6 +769,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,

struct rte_lpm_tbl8_entry new_tbl8_entry = {
.valid = VALID,
+   .valid_group = VALID,
.depth = sub_rule_depth,
.next_hop = lpm->rules_tbl
[sub_rule_index].next_hop,
@@ -780,8 +780,7 @@ delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
if (lpm->tbl24[i].ext_entry == 0 &&
lpm->tbl24[i].depth <= depth ) {
lpm->tbl24[i] = new_tbl24_entry;
-   }
-   else {
+   } else  if (lpm->tbl24[i].ext_entry == 1) {
/*
 * If TBL24 entry is extended, then there has
 * to be a rule with depth >= 25 in the
-- 
1.7.7.6



[dpdk-dev] [PATCH 8/8] app/testpmd:modify MAC address of csum forwarding

2015-10-21 Thread Jijiang Liu
The change will affect on the csum fwd performance.
But I also think the change is necessary, or we cannot use csumonly fwd mode in 
a VM.

Signed-off-by: Jijiang Liu 
---
 app/test-pmd/csumonly.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e561dde..20d4274 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -622,6 +622,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
m->tso_segsz = info.tso_segsz;
m->ol_flags = ol_flags;
+   
+   ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+   ð_hdr->d_addr);
+
+   ether_addr_copy(&ports[fs->tx_port].eth_addr,
+   ð_hdr->s_addr);

/* if verbose mode is enabled, dump debug info */
if (verbose_level > 0) {
-- 
1.7.7.6



[dpdk-dev] [PATCH 7/8] examples/vhost:support TX offload in vhost sample

2015-10-21 Thread Jijiang Liu
Change the vhost sample to support and test TX offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |  128 ++---
 1 files changed, 111 insertions(+), 17 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9eac2d0..06e1e8b 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "main.h"

@@ -140,6 +144,8 @@

 #define MBUF_EXT_MEM(mb)   (rte_mbuf_from_indirect(mb) != (mb))

+#define VIRTIO_TX_CKSUM_OFFLOAD_MASK (PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;

@@ -197,6 +203,13 @@ typedef enum {
 static uint32_t enable_stats = 0;
 /* Enable retries on RX. */
 static uint32_t enable_retry = 1;
+
+/* Disable TX checksum offload */
+static uint32_t enable_tx_csum;
+
+/* Disable TSO offload */
+static uint32_t enable_tso;
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -292,20 +305,6 @@ struct vlan_ethhdr {
__be16  h_vlan_encapsulated_proto;
 };

-/* IPv4 Header */
-struct ipv4_hdr {
-   uint8_t  version_ihl;   /**< version and header length */
-   uint8_t  type_of_service;   /**< type of service */
-   uint16_t total_length;  /**< length of packet */
-   uint16_t packet_id; /**< packet ID */
-   uint16_t fragment_offset;   /**< fragmentation offset */
-   uint8_t  time_to_live;  /**< time to live */
-   uint8_t  next_proto_id; /**< protocol ID */
-   uint16_t hdr_checksum;  /**< header checksum */
-   uint32_t src_addr;  /**< source address */
-   uint32_t dst_addr;  /**< destination address */
-} __attribute__((__packed__));
-
 /* Header lengths. */
 #define VLAN_HLEN   4
 #define VLAN_ETH_HLEN   18
@@ -441,6 +440,14 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (enable_tx_csum == 0)
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_CSUM);
+
+   if (enable_tso == 0) {
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+   rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO6);
+   }
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -576,7 +583,9 @@ us_vhost_usage(const char *prgname)
"   --rx-desc-num [0-N]: the number of descriptors on rx, "
"used only when zero copy is enabled.\n"
"   --tx-desc-num [0-N]: the number of descriptors on tx, "
-   "used only when zero copy is enabled.\n",
+   "used only when zero copy is enabled.\n"
+   "   --tx-csum [0|1] disable/enable TX checksum offload.\n"
+   "   --tso [0|1] disable/enable TCP segement offload.\n",
   prgname);
 }

@@ -602,6 +611,8 @@ us_vhost_parse_args(int argc, char **argv)
{"zero-copy", required_argument, NULL, 0},
{"rx-desc-num", required_argument, NULL, 0},
{"tx-desc-num", required_argument, NULL, 0},
+   {"tx-csum", required_argument, NULL, 0},
+   {"tso", required_argument, NULL, 0},
{NULL, 0, 0, 0},
};

@@ -656,6 +667,28 @@ us_vhost_parse_args(int argc, char **argv)
}
}

+   /* Enable/disable TX checksum offload. */
+   if (!strncmp(long_option[option_index].name, "tx-csum", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tx-csum [0|1]\n");
+   us_vhost_usage(prgname);
+   return -1;
+   } else
+   enable_tx_csum = ret;
+   }
+
+   /* Enable/disable TSO offload. */
+   if (!strncmp(long_option[option_index].name, "tso", 
MAX_LONG_OPT_SZ)) {
+   ret = parse_num_opt(optarg, 1);
+   if (ret == -1) {
+   RTE_LOG(INFO, VHOST_CONFIG, "Invalid 
argument for tso [0

[dpdk-dev] [PATCH 6/8] lib/librte_vhost:dequeue vhost TX offload

2015-10-21 Thread Jijiang Liu
Dequeue vhost TX offload in vhost lib.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |  108 -
 1 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 7026bfa..a888ba9 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -36,7 +36,12 @@

 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 

 #include "vhost-net.h"

@@ -548,6 +553,101 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static void
+parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
+{
+   struct ipv4_hdr *ipv4_hdr;
+   struct ipv6_hdr *ipv6_hdr;
+   void *l3_hdr = NULL;
+   struct ether_hdr *eth_hdr;
+   uint16_t ethertype;
+
+   eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+   m->l2_len = sizeof(struct ether_hdr);
+   ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+
+   if (ethertype == ETHER_TYPE_VLAN) {
+   struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+
+   m->l2_len += sizeof(struct vlan_hdr);
+   ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+   }
+
+   l3_hdr = (char *)eth_hdr + m->l2_len;
+
+   switch (ethertype) {
+   case ETHER_TYPE_IPv4:
+   ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
+   *l4_proto = ipv4_hdr->next_proto_id;
+   m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   m->ol_flags |= PKT_TX_IPV4;
+   break;
+   case ETHER_TYPE_IPv6:
+   ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
+   *l4_proto = ipv6_hdr->proto;
+   m->ol_flags |= PKT_TX_IPV6;
+   m->l3_len = sizeof(struct ipv6_hdr);
+   *l4_hdr = (char *)l3_hdr + m->l3_len;
+   break;
+   default:
+   m->l3_len = 0;
+   *l4_proto = 0;
+   break;
+   }
+}
+
+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
+{
+   uint16_t l4_proto = 0;
+   void *l4_hdr = NULL;
+   struct tcp_hdr *tcp_hdr = NULL;
+
+   parse_ethernet(m, &l4_proto, &l4_hdr);
+   if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+   if ((hdr->csum_start == m->l2_len) &&
+   (hdr->csum_offset == offsetof(struct ipv4_hdr,
+   hdr_checksum)))
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   else if (hdr->csum_start == (m->l2_len + m->l3_len)) {
+   switch (hdr->csum_offset) {
+   case (offsetof(struct tcp_hdr, cksum)):
+   if (l4_proto == IPPROTO_TCP)
+   m->ol_flags |= PKT_TX_TCP_CKSUM;
+   break;
+   case (offsetof(struct udp_hdr, dgram_cksum)):
+   if (l4_proto == IPPROTO_UDP)
+   m->ol_flags |= PKT_TX_UDP_CKSUM;
+   break;
+   case (offsetof(struct sctp_hdr, cksum)):
+   if (l4_proto == IPPROTO_SCTP)
+   m->ol_flags |= PKT_TX_SCTP_CKSUM;
+   break;
+   default:
+   break;
+   }
+   }
+   }
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   tcp_hdr = (struct tcp_hdr *)l4_hdr;
+   m->ol_flags |= PKT_TX_TCP_SEG;
+   m->tso_segsz = hdr->gso_size;
+   m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -556,11 +656,13 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t h

[dpdk-dev] [PATCH 5/8] driver/virtio:enqueue vhost TX offload

2015-10-21 Thread Jijiang Liu
Enqueue vhost TX checksum and TSO4/6 offload in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   61 ++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..b99f5b5 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -50,6 +50,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 

 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -199,6 +203,58 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
 }

 static int
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+
+   /* if vhost TX checksum offload is required */
+   if (m->ol_flags & PKT_TX_IP_CKSUM) {
+   hdr->csum_start = m->l2_len;
+   hdr->csum_offset = offsetof(struct ipv4_hdr, hdr_checksum);
+   } else if (m->ol_flags & PKT_TX_L4_MASK) {
+   hdr->csum_start = m->l2_len + m->l3_len;
+   switch (m->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_TCP_CKSUM:
+   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
+   break;
+   case PKT_TX_UDP_CKSUM:
+   hdr->csum_offset = offsetof(struct udp_hdr,
+   dgram_cksum);
+   break;
+   case PKT_TX_SCTP_CKSUM:
+   hdr->csum_offset = offsetof(struct sctp_hdr, cksum);
+   break;
+   default:
+   break;
+   }
+   } else
+   hdr->flags = 0;
+
+   /* if vhost TSO offload is required */
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO4))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO6))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   } else
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+   return 0;
+}
+
+static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
struct vq_desc_extra *dxp;
@@ -221,6 +277,11 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   if (vtpci_with_feature(txvq->hw, VIRTIO_NET_F_CSUM)) {
+   if (virtqueue_enqueue_offload(txvq, cookie, idx, head_size) < 0)
+   return -EPERM;
+   }
+
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [PATCH 4/8] driver/virtio:add vhost TX offload support capability

2015-10-21 Thread Jijiang Liu
Add vhost TX checksum and TSO support capability in vhost lib. 

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index d0f1764..a5989a2 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -71,7 +71,11 @@ static struct virtio_net_config_ll *ll_root;
 #define VHOST_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
(1ULL << VIRTIO_NET_F_CTRL_VQ) | \
(1ULL << VIRTIO_NET_F_CTRL_RX) | \
-   (1ULL << VHOST_F_LOG_ALL))
+   (1ULL << VHOST_F_LOG_ALL)  | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
+   (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH 3/8] driver/virtio:add vhost TX offload support capability in virtio-net

2015-10-21 Thread Jijiang Liu
Add vhost TX checksum and TSO capabilities in virtio-net lib.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..6ee95c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,10 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6 | \
+1u << VIRTIO_NET_F_CSUM)

 /*
  * CQ function prototype
-- 
1.7.7.6



[dpdk-dev] [PATCH 2/8] driver/virtio: record virtual address of virtio net header

2015-10-21 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH 1/8] driver/virtio:add virtual addr for virtio net header

2015-10-21 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..530f840 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -189,6 +189,7 @@ struct virtqueue {
uint16_t vq_used_cons_idx;
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

/* Statistics */
uint64_tpackets;
-- 
1.7.7.6



[dpdk-dev] [PATCH 0/8] add vhost TX offload support

2015-10-21 Thread Jijiang Liu
In fact, this patch set is v2 of [1], but I consider that the vhost checksum 
offload capability is also supported in this version, and send a new patch set 
out.

The patch set add the negotiation between us-vhost and virtio-net for vhost TX 
offload(checksum and TSO), and add the TX offload support in the libs and 
change vhost sample and csum application to test these changes.


[1]http://dpdk.org/ml/archives/dev/2015-September/023686.html 


Jijiang Liu (8):
  add virtual address of virtio net header
  store virtual address of virtio hdr
  add vhost TX offload support capability in virtio-net
  add vhost TX offload support capability in vhost
  enqueue TX offload
  dequeue TX offload
  change vhost App to support TX offload
  fix csumonly fwd issue 

 app/test-pmd/csumonly.c|6 ++
 drivers/net/virtio/virtio_ethdev.c |3 +
 drivers/net/virtio/virtio_ethdev.h |5 +-
 drivers/net/virtio/virtio_rxtx.c   |   61 +
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |  128 +++-
 lib/librte_vhost/vhost_rxtx.c  |  108 ++-
 lib/librte_vhost/virtio-net.c  |6 ++-
 8 files changed, 298 insertions(+), 20 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [PATCH] config:enlarge the default value of RTE_MAX_QUEUES_PER_PORT to 1024

2015-09-22 Thread Jijiang Liu
The default value of RTE_MAX_QUEUES_PER_PORT is 256, which is too small for 
some configurations for i40e. There will return an error when configured queue 
number is larger than 256 in 

rte_eth_dev_configure().

For example, in vHost sample, PF queue number: 64, configured vmdq pool number: 
63, each vmdq pool has 4 queues, there will be required 316 queues in a port.


Signed-off-by: Jijiang Liu 
---
 config/common_bsdapp   |2 +-
 config/common_linuxapp |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/config/common_bsdapp b/config/common_bsdapp
index c2374c0..0b169c8 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -137,7 +137,7 @@ CONFIG_RTE_LIBRTE_KVARGS=y
 CONFIG_RTE_LIBRTE_ETHER=y
 CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
 CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=256
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
 CONFIG_RTE_LIBRTE_IEEE1588=n
 CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
 CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 0078dc9..5deb55a 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -134,7 +134,7 @@ CONFIG_RTE_LIBRTE_KVARGS=y
 CONFIG_RTE_LIBRTE_ETHER=y
 CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
 CONFIG_RTE_MAX_ETHPORTS=32
-CONFIG_RTE_MAX_QUEUES_PER_PORT=256
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
 CONFIG_RTE_LIBRTE_IEEE1588=n
 CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
 CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
-- 
1.7.7.6



[dpdk-dev] [PATCH 8/8] app/testpmd: modify the mac of csum forwarding

2015-09-17 Thread Jijiang Liu
The change will affect on the csum fwd performance.
But I also think the change is necessary, or we cannot use csumonly fwd mode in 
a VM.

Signed-off-by: Jijiang Liu 
---
 app/test-pmd/csumonly.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 1bf3485..c4ba22e 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -636,6 +636,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
m->tso_segsz = info.tso_segsz;
m->ol_flags = ol_flags;

+   ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+   ð_hdr->d_addr);
+
+   ether_addr_copy(&ports[fs->tx_port].eth_addr,
+   ð_hdr->s_addr);

/* if verbose mode is enabled, dump debug info */
if (verbose_level > 0) {
-- 
1.7.7.6



[dpdk-dev] [PATCH 7/8] examples/vhost:support TSO in vhost sample

2015-09-17 Thread Jijiang Liu
Change the vhost sample in order to support and test TSO offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   20 ++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 1b137b9..482f7af 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -441,6 +442,9 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO)
+   rte_vhost_feature_enable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -1148,6 +1152,13 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf 
*m, uint16_t vlan_tag)
len = tx_q->len;

nh = rte_pktmbuf_mtod(m, struct ether_hdr *);
+   m->l2_len = sizeof(struct ether_hdr);
+   m->l3_len = sizeof(struct ipv4_hdr);
+   if (m->tso_segsz) {
+   m->l4_len = sizeof(struct tcp_hdr);
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   }
+
if (unlikely(nh->ether_type == rte_cpu_to_be_16(ETHER_TYPE_VLAN))) {
/* Guest has inserted the vlan tag. */
struct vlan_hdr *vh = (struct vlan_hdr *) (nh + 1);
@@ -1155,8 +1166,9 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf 
*m, uint16_t vlan_tag)
if ((vm2vm_mode == VM2VM_HARDWARE) &&
(vh->vlan_tci != vlan_tag_be))
vh->vlan_tci = vlan_tag_be;
+   m->l2_len += sizeof(struct vlan_hdr);
} else {
-   m->ol_flags = PKT_TX_VLAN_PKT;
+   m->ol_flags |= PKT_TX_VLAN_PKT;

/*
 * Find the right seg to adjust the data len when offset is
@@ -1841,10 +1853,14 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct 
rte_mbuf *m,
mbuf->buf_physaddr = m->buf_physaddr;
mbuf->buf_addr = m->buf_addr;
}
-   mbuf->ol_flags = PKT_TX_VLAN_PKT;
+   mbuf->ol_flags |= PKT_TX_VLAN_PKT;
mbuf->vlan_tci = vlan_tag;
mbuf->l2_len = sizeof(struct ether_hdr);
mbuf->l3_len = sizeof(struct ipv4_hdr);
+   if (mbuf->tso_segsz) {
+   mbuf->l4_len = sizeof(struct tcp_hdr);
+   mbuf->ol_flags |= PKT_TX_IP_CKSUM;
+   }
MBUF_HEADROOM_UINT32(mbuf) = (uint32_t)desc_idx;

tx_q->m_table[len] = mbuf;
-- 
1.7.7.6



[dpdk-dev] [PATCH 6/8] lib/librte_vhost:extend supported vhost features

2015-09-17 Thread Jijiang Liu
Add host TSO support into vhost features bits

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index b520ec5..2f9ac25 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -71,7 +71,10 @@ static struct virtio_net_config_ll *ll_root;
 #define VHOST_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
(1ULL << VIRTIO_NET_F_CTRL_VQ) | \
(1ULL << VIRTIO_NET_F_CTRL_RX) | \
-   (1ULL << VHOST_F_LOG_ALL))
+   (1ULL << VHOST_F_LOG_ALL)  | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [PATCH 5/8] lib/librte_vhost:dequeue vhost TSO offload

2015-09-17 Thread Jijiang Liu
Dequeue host TSO4/6 offload in host side.

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   29 -
 1 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 0d07338..b84ec64 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -545,6 +545,30 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(uint64_t addr, struct rte_mbuf *m)
+{
+   struct virtio_net_hdr *hdr =
+   (struct virtio_net_hdr *)((uintptr_t)addr);
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   m->ol_flags |= (PKT_TX_IPV4 | PKT_TX_TCP_SEG);
+   m->tso_segsz = hdr->gso_size;
+   break;
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   m->ol_flags |= (PKT_TX_IPV6 | PKT_TX_TCP_SEG);
+   m->tso_segsz = hdr->gso_size;
+   break;
+   default:
+   RTE_LOG(WARNING, VHOST_DATA,
+   "unsupported gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -553,6 +577,7 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t head[MAX_PKT_BURST];
uint32_t used_idx;
uint32_t i;
@@ -604,6 +629,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,

desc = &vq->desc[head[entry_success]];

+   vb_net_hdr_addr = gpa_to_vva(dev, desc->addr);
+
/* Discard first buffer as it is the virtio header */
if (desc->flags & VRING_DESC_F_NEXT) {
desc = &vq->desc[desc->next];
@@ -742,7 +769,7 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
break;

m->nb_segs = seg_num;
-
+   vhost_dequeue_offload(vb_net_hdr_addr, m);
pkts[entry_success] = m;
vq->last_used_idx++;
entry_success++;
-- 
1.7.7.6



[dpdk-dev] [PATCH 4/8] driver/virtio:enqueue TSO offload

2015-09-17 Thread Jijiang Liu
Enqueue host TSO4/6 offload in guest side.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   28 
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..68b293e 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -198,6 +198,31 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
return 0;
 }

+static int
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO4))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw,
+   VIRTIO_NET_F_HOST_TSO6))
+   return -1;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   }
+   return 0;
+}
+
 static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
@@ -221,6 +246,9 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   if (virtqueue_enqueue_offload(txvq, cookie, idx, head_size) < 0)
+   return -EPERM;
+
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [PATCH 3/8] driver/virtio: record virtual address of virtio net header

2015-09-17 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [PATCH 2/8] driver/virtio:add virtual addr for virtio net header

2015-09-17 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..530f840 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -189,6 +189,7 @@ struct virtqueue {
uint16_t vq_used_cons_idx;
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

/* Statistics */
uint64_tpackets;
-- 
1.7.7.6



[dpdk-dev] [PATCH 1/8] driver/virtio:add vhost TSO support capability

2015-09-17 Thread Jijiang Liu

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..3a66491 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,9 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6)

 /*
  * CQ function prototype
-- 
1.7.7.6



[dpdk-dev] [PATCH 0/8] add vhost TSO capability

2015-09-17 Thread Jijiang Liu
The patch set add the negotiation between us-vhost and virtio-net for vhost TSO 
feature, and enqueue/dequeue vhost TSO offload and change vhost sample and csum 
application to test these.

*** BLURB HERE ***

Jijiang Liu (8):
  add host TSO support in virtio_ethdev.h file
  add virtual addr for virtio net header in struct virtqueue.
  record the virtual addr for virtio net header
  enqueue TSO offload in virtio-net
  extend VHOST_SUPPORTED_FEATURES list for TSO support
  add TSO offload dequeue
  TSO support in vhost sample 
  fix an issue in csum file.

 app/test-pmd/csumonly.c|6 ++
 drivers/net/virtio/virtio_ethdev.c |3 +++
 drivers/net/virtio/virtio_ethdev.h |4 +++-
 drivers/net/virtio/virtio_rxtx.c   |   28 
 drivers/net/virtio/virtqueue.h |1 +
 examples/vhost/main.c  |   20 ++--
 lib/librte_vhost/vhost_rxtx.c  |   29 -
 lib/librte_vhost/virtio-net.c  |5 -
 8 files changed, 91 insertions(+), 5 deletions(-)

-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 8/8] app/testpmd: modify the mac of csum forwarding

2015-08-31 Thread Jijiang Liu
The change will affect on the csum fwd performance.
But I also think the change is necessary, or we cannot use csumonly fwd mode in 
a VM.

Signed-off-by: Jijiang Liu 
---
 app/test-pmd/csumonly.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 1bf3485..c4ba22e 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -636,6 +636,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
m->tso_segsz = info.tso_segsz;
m->ol_flags = ol_flags;
+   
+   ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+   ð_hdr->d_addr);
+
+   ether_addr_copy(&ports[fs->tx_port].eth_addr,
+   ð_hdr->s_addr);

/* if verbose mode is enabled, dump debug info */
if (verbose_level > 0) {
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 7/8] examples/vhost:support tso in vhost sample

2015-08-31 Thread Jijiang Liu
Change the vhost sample in order to support and test TSO offload.

Signed-off-by: Jijiang Liu 
---
 examples/vhost/main.c |   20 ++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 1b137b9..482f7af 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "main.h"

@@ -441,6 +442,9 @@ port_init(uint8_t port)

if (port >= rte_eth_dev_count()) return -1;

+   if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO)
+   rte_vhost_feature_enable(1ULL << VIRTIO_NET_F_HOST_TSO4);
+
rx_rings = (uint16_t)dev_info.max_rx_queues;
/* Configure ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
@@ -1148,6 +1152,13 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf 
*m, uint16_t vlan_tag)
len = tx_q->len;

nh = rte_pktmbuf_mtod(m, struct ether_hdr *);
+   m->l2_len = sizeof(struct ether_hdr);
+   m->l3_len = sizeof(struct ipv4_hdr);
+   if (m->tso_segsz) {
+   m->l4_len = sizeof(struct tcp_hdr);
+   m->ol_flags |= PKT_TX_IP_CKSUM;
+   }
+
if (unlikely(nh->ether_type == rte_cpu_to_be_16(ETHER_TYPE_VLAN))) {
/* Guest has inserted the vlan tag. */
struct vlan_hdr *vh = (struct vlan_hdr *) (nh + 1);
@@ -1155,8 +1166,9 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf 
*m, uint16_t vlan_tag)
if ((vm2vm_mode == VM2VM_HARDWARE) &&
(vh->vlan_tci != vlan_tag_be))
vh->vlan_tci = vlan_tag_be;
+   m->l2_len += sizeof(struct vlan_hdr); 
} else {
-   m->ol_flags = PKT_TX_VLAN_PKT;
+   m->ol_flags |= PKT_TX_VLAN_PKT;

/*
 * Find the right seg to adjust the data len when offset is
@@ -1841,10 +1853,14 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct 
rte_mbuf *m,
mbuf->buf_physaddr = m->buf_physaddr;
mbuf->buf_addr = m->buf_addr;
}
-   mbuf->ol_flags = PKT_TX_VLAN_PKT;
+   mbuf->ol_flags |= PKT_TX_VLAN_PKT;
mbuf->vlan_tci = vlan_tag;
mbuf->l2_len = sizeof(struct ether_hdr);
mbuf->l3_len = sizeof(struct ipv4_hdr);
+   if (mbuf->tso_segsz) {
+   mbuf->l4_len = sizeof(struct tcp_hdr);
+   mbuf->ol_flags |= PKT_TX_IP_CKSUM;
+   }
MBUF_HEADROOM_UINT32(mbuf) = (uint32_t)desc_idx;

tx_q->m_table[len] = mbuf;
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 6/8] lib/librte_vhost:extend supported vhost features

2015-08-31 Thread Jijiang Liu
Add TSO into supported vhost features

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/virtio-net.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index b520ec5..2f9ac25 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -71,7 +71,10 @@ static struct virtio_net_config_ll *ll_root;
 #define VHOST_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
(1ULL << VIRTIO_NET_F_CTRL_VQ) | \
(1ULL << VIRTIO_NET_F_CTRL_RX) | \
-   (1ULL << VHOST_F_LOG_ALL))
+   (1ULL << VHOST_F_LOG_ALL)  | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
+   (1ULL << VIRTIO_NET_F_HOST_TSO6))
+
 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;


-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 5/8] lib/librte_vhost:dequeue vhost TSO offload

2015-08-31 Thread Jijiang Liu
Dequeue vhost TSO offload

Signed-off-by: Jijiang Liu 
---
 lib/librte_vhost/vhost_rxtx.c |   29 -
 1 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 0d07338..9adfdb1 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -545,6 +545,30 @@ rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t 
queue_id,
return virtio_dev_rx(dev, queue_id, pkts, count);
 }

+static inline void __attribute__((always_inline))
+vhost_dequeue_offload(uint64_t addr, struct rte_mbuf *m)
+{
+   struct virtio_net_hdr *hdr =
+   (struct virtio_net_hdr *)((uintptr_t)addr);
+
+   if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+   switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+   case VIRTIO_NET_HDR_GSO_TCPV4:
+   m->ol_flags |= (PKT_TX_IPV4 | PKT_TX_TCP_SEG);
+   m->tso_segsz = hdr->gso_size;
+   break;
+   case VIRTIO_NET_HDR_GSO_TCPV6:
+   m->ol_flags |= (PKT_TX_IPV6 | PKT_TX_TCP_SEG);
+   m->tso_segsz = hdr->gso_size;
+   break;
+   default:
+   RTE_LOG(ERR, VHOST_DATA,
+   "bad gso type %u.\n", hdr->gso_type);
+   break;
+   }
+   }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -553,6 +577,7 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
struct vhost_virtqueue *vq;
struct vring_desc *desc;
uint64_t vb_addr = 0;
+   uint64_t vb_net_hdr_addr = 0;
uint32_t head[MAX_PKT_BURST];
uint32_t used_idx;
uint32_t i;
@@ -604,6 +629,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,

desc = &vq->desc[head[entry_success]];

+   vb_net_hdr_addr = gpa_to_vva(dev, desc->addr);
+
/* Discard first buffer as it is the virtio header */
if (desc->flags & VRING_DESC_F_NEXT) {
desc = &vq->desc[desc->next];
@@ -742,7 +769,7 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t 
queue_id,
break;

m->nb_segs = seg_num;
-
+   vhost_dequeue_offload(vb_net_hdr_addr, m);
pkts[entry_success] = m;
vq->last_used_idx++;
entry_success++;
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 4/8] driver/virtio:enqueue TSO offload

2015-08-31 Thread Jijiang Liu
Enqueue TSO4/6 offload.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_rxtx.c |   23 +++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c5b53bb..4c2d838 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -198,6 +198,28 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct 
rte_mbuf *cookie)
return 0;
 }

+static void
+virtqueue_enqueue_offload(struct virtqueue *txvq, struct rte_mbuf *m,
+   uint16_t idx, uint16_t hdr_sz)
+{
+   struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)(uintptr_t)
+   (txvq->virtio_net_hdr_addr + idx * hdr_sz);
+
+   if (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG) {
+   if (m->ol_flags & PKT_TX_IPV4) {
+   if (!vtpci_with_feature(txvq->hw, 
VIRTIO_NET_F_HOST_TSO4))
+   return;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+   } else if (m->ol_flags & PKT_TX_IPV6) {
+   if (!vtpci_with_feature(txvq->hw, 
VIRTIO_NET_F_HOST_TSO6))
+   return;
+   hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+   }
+   hdr->gso_size = m->tso_segsz;
+   hdr->hdr_len = m->l2_len + m->l3_len + m->l4_len;
+   }
+}
+
 static int
 virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
 {
@@ -221,6 +243,7 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq, struct 
rte_mbuf *cookie)
dxp->cookie = (void *)cookie;
dxp->ndescs = needed;

+   virtqueue_enqueue_offload(txvq, cookie, idx, head_size);
start_dp = txvq->vq_ring.desc;
start_dp[idx].addr =
txvq->virtio_net_hdr_mem + idx * head_size;
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 3/8] driver/virtio: record virtual address of virtio net header

2015-08-31 Thread Jijiang Liu
Record virtual address of virtio net header.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..cb5dfee 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -376,6 +376,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
}
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
+   vq->virtio_net_hdr_addr =
+   (uint64_t)(uintptr_t)vq->virtio_net_hdr_mz->addr;
+
memset(vq->virtio_net_hdr_mz->addr, 0,
vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 2/8] driver/virtio: add virtual addr for virtio net header

2015-08-31 Thread Jijiang Liu
The virtual addr for virtio net header need to be recorded.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtqueue.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..530f840 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -189,6 +189,7 @@ struct virtqueue {
uint16_t vq_used_cons_idx;
uint16_t vq_avail_idx;
phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */
+   uint64_t virtio_net_hdr_addr; /**< virtual addr for virtio net header */

/* Statistics */
uint64_tpackets;
-- 
1.7.7.6



[dpdk-dev] [RFC PATCH 1/8] driver/virtio:add vhost TSO support capability

2015-08-31 Thread Jijiang Liu
Extend the VIRTIO_PMD_GUEST_FEATURES for supporting vhost TSO.

Signed-off-by: Jijiang Liu 
---
 drivers/net/virtio/virtio_ethdev.h |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..3a66491 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,9 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u << VIRTIO_NET_F_CTRL_RX   | \
 1u << VIRTIO_NET_F_CTRL_VLAN | \
-1u << VIRTIO_NET_F_MRG_RXBUF)
+1u << VIRTIO_NET_F_MRG_RXBUF | \
+1u << VIRTIO_NET_F_HOST_TSO4 | \
+1u << VIRTIO_NET_F_HOST_TSO6)

 /*
  * CQ function prototype
-- 
1.7.7.6



  1   2   3   4   >