* [PATCH v13 0/7] add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1479922585-8640-1-git-send-email-tomaszx.kulasek@intel.com>
As discussed in that thread:
http://dpdk.org/ml/archives/dev/2015-September/023603.html
Different NIC models depending on HW offload requested might impose
different requirements on packets to be TX-ed in terms of:
- Max number of fragments per packet allowed
- Max number of fragments per TSO segments
- The way pseudo-header checksum should be pre-calculated
- L3/L4 header fields filling
- etc.
MOTIVATION:
-----------
1) Some work cannot (and didn't should) be done in rte_eth_tx_burst.
However, this work is sometimes required, and now, it's an
application issue.
2) Different hardware may have different requirements for TX offloads,
other subset can be supported and so on.
3) Some parameters (e.g. number of segments in ixgbe driver) may hung
device. These parameters may be vary for different devices.
For example i40e HW allows 8 fragments per packet, but that is after
TSO segmentation. While ixgbe has a 38-fragment pre-TSO limit.
4) Fields in packet may require different initialization (like e.g. will
require pseudo-header checksum precalculation, sometimes in a
different way depending on packet type, and so on). Now application
needs to care about it.
5) Using additional API (rte_eth_tx_prepare) before rte_eth_tx_burst let
to prepare packet burst in acceptable form for specific device.
6) Some additional checks may be done in debug mode keeping tx_burst
implementation clean.
PROPOSAL:
---------
To help user to deal with all these varieties we propose to:
1) Introduce rte_eth_tx_prepare() function to do necessary preparations
of packet burst to be safely transmitted on device for desired HW
offloads (set/reset checksum field according to the hardware
requirements) and check HW constraints (number of segments per
packet, etc).
While the limitations and requirements may differ for devices, it
requires to extend rte_eth_dev structure with new function pointer
"tx_pkt_prepare" which can be implemented in the driver to prepare
and verify packets, in devices specific way, before burst, what
should to prevent application to send malformed packets.
2) Also new fields will be introduced in rte_eth_desc_lim:
nb_seg_max and nb_mtu_seg_max, providing an information about max
segments in TSO and non-TSO packets acceptable by device.
This information is useful for application to not create/limit
malicious packet.
APPLICATION (CASE OF USE):
--------------------------
1) Application should to initialize burst of packets to send, set
required tx offload flags and required fields, like l2_len, l3_len,
l4_len, and tso_segsz
2) Application passes burst to the rte_eth_tx_prep to check conditions
required to send packets through the NIC.
3) The result of rte_eth_tx_prep can be used to send valid packets
and/or restore invalid if function fails.
e.g.
for (i = 0; i < nb_pkts; i++) {
/* initialize or process packet */
bufs[i]->tso_segsz = 800;
bufs[i]->ol_flags = PKT_TX_TCP_SEG | PKT_TX_IPV4
| PKT_TX_IP_CKSUM;
bufs[i]->l2_len = sizeof(struct ether_hdr);
bufs[i]->l3_len = sizeof(struct ipv4_hdr);
bufs[i]->l4_len = sizeof(struct tcp_hdr);
}
/* Prepare burst of TX packets */
nb_prep = rte_eth_tx_prepare(port, 0, bufs, nb_pkts);
if (nb_prep < nb_pkts) {
printf("Tx prepare failed\n");
/* nb_prep indicates here first invalid packet. rte_eth_tx_prep
* can be used on remaining packets to find another ones.
*/
}
/* Send burst of TX packets */
nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_prep);
/* Free any unsent packets. */
v13 changes:
- added support for vmxnet3
- reworded help information for "csum txprep" command
- renamed RTE_ETHDEV_TX_PREPARE to RTE_ETHDEV_TX_PREPARE_NOOP to
better suit its purpose.
v12 changes:
- renamed API function from "rte_eth_tx_prep" to "rte_eth_tx_prepare"
(to be not confused with "prepend")
- changed "rte_phdr_cksum_fix" to "rte_net_intel_cksum_prepare"
- added "csum txprep (on|off)" command to the csum engine allowing to
select txprep path for packet processing
v11 changed:
- updated comments
- added information to the API description about packet data
requirements/limitations.
v10 changes:
- moved drivers tx calback check in rte_eth_tx_prep after queue_id check
v9 changes:
- fixed headers structure fragmentation check
- moved fragmentation check into rte_validate_tx_offload()
v8 changes:
- mbuf argument in rte_validate_tx_offload declared as const
v7 changes:
- comments reworded/added
- changed errno values returned from Tx prep API
- added check in rte_phdr_cksum_fix if headers are in the first
data segment and can be safetly modified
- moved rte_validate_tx_offload to rte_mbuf
- moved rte_phdr_cksum_fix to rte_net.h
- removed rte_pkt.h new file as useless
v6 changes:
- added performance impact test results to the patch description
v5 changes:
- rebased csum engine modification
- added information to the csum engine about performance tests
- some performance improvements
v4 changes:
- tx_prep is now set to default behavior (NULL) for simple/vector path
in fm10k, i40e and ixgbe drivers to increase performance, when
Tx offloads are not intentionally available
v3 changes:
- reworked csum testpmd engine instead adding new one,
- fixed checksum initialization procedure to include also outer
checksum offloads,
- some minor formattings and optimalizations
v2 changes:
- rte_eth_tx_prep() returns number of packets when device doesn't
support tx_prep functionality,
- introduced CONFIG_RTE_ETHDEV_TX_PREP allowing to turn off tx_prep
Ananyev, Konstantin (1):
vmxnet3: add Tx preparation
Tomasz Kulasek (6):
ethdev: add Tx preparation
e1000: add Tx preparation
fm10k: add Tx preparation
i40e: add Tx preparation
ixgbe: add Tx preparation
testpmd: use Tx preparation in csum engine
app/test-pmd/cmdline.c | 49 ++++++++++++
app/test-pmd/csumonly.c | 33 ++++++--
app/test-pmd/testpmd.c | 5 ++
app/test-pmd/testpmd.h | 2 +
config/common_base | 9 +++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 13 +++
drivers/net/e1000/e1000_ethdev.h | 11 +++
drivers/net/e1000/em_ethdev.c | 5 +-
drivers/net/e1000/em_rxtx.c | 48 ++++++++++-
drivers/net/e1000/igb_ethdev.c | 4 +
drivers/net/e1000/igb_rxtx.c | 52 +++++++++++-
drivers/net/fm10k/fm10k.h | 6 ++
drivers/net/fm10k/fm10k_ethdev.c | 5 ++
drivers/net/fm10k/fm10k_rxtx.c | 50 +++++++++++-
drivers/net/i40e/i40e_ethdev.c | 3 +
drivers/net/i40e/i40e_rxtx.c | 74 ++++++++++++++++-
drivers/net/i40e/i40e_rxtx.h | 8 ++
drivers/net/ixgbe/ixgbe_ethdev.c | 3 +
drivers/net/ixgbe/ixgbe_ethdev.h | 5 +-
drivers/net/ixgbe/ixgbe_rxtx.c | 56 +++++++++++++
drivers/net/ixgbe/ixgbe_rxtx.h | 2 +
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 +
drivers/net/vmxnet3/vmxnet3_ethdev.h | 2 +
drivers/net/vmxnet3/vmxnet3_rxtx.c | 57 +++++++++++++
lib/librte_ether/rte_ethdev.h | 115 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 64 +++++++++++++++
lib/librte_net/rte_net.h | 85 ++++++++++++++++++++
27 files changed, 757 insertions(+), 13 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH v13 1/7] ethdev: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Added API for `rte_eth_tx_prepare`
uint16_t rte_eth_tx_prepare(uint8_t port_id, uint16_t queue_id,
struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
Added fields to the `struct rte_eth_desc_lim`:
uint16_t nb_seg_max;
/**< Max number of segments per whole packet. */
uint16_t nb_mtu_seg_max;
/**< Max number of segments per one MTU */
Added functions:
int rte_validate_tx_offload(struct rte_mbuf *m)
to validate general requirements for tx offload set in mbuf of packet
such a flag completness. In current implementation this function is
called optionaly when RTE_LIBRTE_ETHDEV_DEBUG is enabled.
int rte_net_intel_cksum_prepare(struct rte_mbuf *m)
to fix pseudo header checksum for TSO and non-TSO tcp/udp packets
before hardware tx checksum offload.
- for non-TSO tcp/udp packets full pseudo-header checksum is
counted and set.
- for TSO the IP payload length is not included.
PERFORMANCE TESTS
-----------------
This feature was tested with modified csum engine from test-pmd.
The packet checksum preparation was moved from application to Tx
preparation step placed before burst.
We may expect some overhead costs caused by:
1) using additional callback before burst,
2) rescanning burst,
3) additional condition checking (packet validation),
4) worse optimization (e.g. packet data access, etc.)
We tested it using ixgbe Tx preparation implementation with some parts
disabled to have comparable information about the impact of different
parts of implementation.
IMPACT:
1) For unimplemented Tx preparation callback the performance impact is
negligible,
2) For packet condition check without checksum modifications (nb_segs,
available offloads, etc.) is 14626628/14252168 (~2.62% drop),
3) Full support in ixgbe driver (point 2 + packet checksum
initialization) is 14060924/13588094 (~3.48% drop)
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
config/common_base | 9 ++++
lib/librte_ether/rte_ethdev.h | 115 +++++++++++++++++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 64 +++++++++++++++++++++++
lib/librte_net/rte_net.h | 85 ++++++++++++++++++++++++++++++
4 files changed, 273 insertions(+)
diff --git a/config/common_base b/config/common_base
index 652a839..2c5352e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -123,6 +123,15 @@ CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
#
+# Use real NOOP to turn off TX preparation stage
+#
+# While the behaviour of ``rte_ethdev_tx_prepare`` may change after turning on
+# real NOOP, this configuration shouldn't be never enabled globaly, and can be
+# used in appropriate target configuration file with a following restrictions
+#
+CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
+
+#
# Support NIC bypass logic
#
CONFIG_RTE_NIC_BYPASS=n
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9678179..b3052db 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -182,6 +182,7 @@
#include <rte_pci.h>
#include <rte_dev.h>
#include <rte_devargs.h>
+#include <rte_errno.h>
#include "rte_ether.h"
#include "rte_eth_ctrl.h"
#include "rte_dev_info.h"
@@ -702,6 +703,8 @@ struct rte_eth_desc_lim {
uint16_t nb_max; /**< Max allowed number of descriptors. */
uint16_t nb_min; /**< Min allowed number of descriptors. */
uint16_t nb_align; /**< Number of descriptors should be aligned to. */
+ uint16_t nb_seg_max; /**< Max number of segments per whole packet. */
+ uint16_t nb_mtu_seg_max; /**< Max number of segments per one MTU */
};
/**
@@ -1191,6 +1194,11 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq,
uint16_t nb_pkts);
/**< @internal Send output packets on a transmit queue of an Ethernet device. */
+typedef uint16_t (*eth_tx_prep_t)(void *txq,
+ struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+/**< @internal Prepare output packets on a transmit queue of an Ethernet device. */
+
typedef int (*flow_ctrl_get_t)(struct rte_eth_dev *dev,
struct rte_eth_fc_conf *fc_conf);
/**< @internal Get current flow control parameter on an Ethernet device */
@@ -1625,6 +1633,7 @@ struct rte_eth_rxtx_callback {
struct rte_eth_dev {
eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
+ eth_tx_prep_t tx_pkt_prepare; /**< Pointer to PMD transmit prepare function. */
struct rte_eth_dev_data *data; /**< Pointer to device data */
const struct eth_driver *driver;/**< Driver for this device */
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
@@ -2819,6 +2828,112 @@ int rte_eth_dev_set_vlan_ether_type(uint8_t port_id,
return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
}
+/**
+ * Process a burst of output packets on a transmit queue of an Ethernet device.
+ *
+ * The rte_eth_tx_prepare() function is invoked to prepare output packets to be
+ * transmitted on the output queue *queue_id* of the Ethernet device designated
+ * by its *port_id*.
+ * The *nb_pkts* parameter is the number of packets to be prepared which are
+ * supplied in the *tx_pkts* array of *rte_mbuf* structures, each of them
+ * allocated from a pool created with rte_pktmbuf_pool_create().
+ * For each packet to send, the rte_eth_tx_prepare() function performs
+ * the following operations:
+ *
+ * - Check if packet meets devices requirements for tx offloads.
+ *
+ * - Check limitations about number of segments.
+ *
+ * - Check additional requirements when debug is enabled.
+ *
+ * - Update and/or reset required checksums when tx offload is set for packet.
+ *
+ * Since this function can modify packet data, provided mbufs must be safely
+ * writable (e.g. modified data cannot be in shared segment).
+ *
+ * The rte_eth_tx_prepare() function returns the number of packets ready to be
+ * sent. A return value equal to *nb_pkts* means that all packets are valid and
+ * ready to be sent, otherwise stops processing on the first invalid packet and
+ * leaves the rest packets untouched.
+ *
+ * When this functionality is not implemented in the driver, all packets are
+ * are returned untouched.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * The value must be a valid port id.
+ * @param queue_id
+ * The index of the transmit queue through which output packets must be
+ * sent.
+ * The value must be in the range [0, nb_tx_queue - 1] previously supplied
+ * to rte_eth_dev_configure().
+ * @param tx_pkts
+ * The address of an array of *nb_pkts* pointers to *rte_mbuf* structures
+ * which contain the output packets.
+ * @param nb_pkts
+ * The maximum number of packets to process.
+ * @return
+ * The number of packets correct and ready to be sent. The return value can be
+ * less than the value of the *tx_pkts* parameter when some packet doesn't
+ * meet devices requirements with rte_errno set appropriately:
+ * - -EINVAL: offload flags are not correctly set
+ * - -ENOTSUP: the offload feature is not supported by the hardware
+ *
+ */
+
+#ifndef RTE_ETHDEV_TX_PREPARE_NOOP
+
+static inline uint16_t
+rte_eth_tx_prepare(uint8_t port_id, uint16_t queue_id,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ struct rte_eth_dev *dev;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ RTE_PMD_DEBUG_TRACE("Invalid TX port_id=%d\n", port_id);
+ rte_errno = -EINVAL;
+ return 0;
+ }
+#endif
+
+ dev = &rte_eth_devices[port_id];
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ if (queue_id >= dev->data->nb_tx_queues) {
+ RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", queue_id);
+ rte_errno = -EINVAL;
+ return 0;
+ }
+#endif
+
+ if (!dev->tx_pkt_prepare)
+ return nb_pkts;
+
+ return (*dev->tx_pkt_prepare)(dev->data->tx_queues[queue_id],
+ tx_pkts, nb_pkts);
+}
+
+#else
+
+/*
+ * Native NOOP operation for compilation targets which doesn't require any
+ * preparations steps, and functional NOOP may introduce unnecessary performance
+ * drop.
+ *
+ * Generally this is not a good idea to turn it on globally and didn't should
+ * be used if behavior of tx_preparation can change.
+ */
+
+static inline uint16_t
+rte_eth_tx_prepare(__rte_unused uint8_t port_id, __rte_unused uint16_t queue_id,
+ __rte_unused struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ return nb_pkts;
+}
+
+#endif
+
typedef void (*buffer_tx_error_fn)(struct rte_mbuf **unsent, uint16_t count,
void *userdata);
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ead7c6e..39ee5ed 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -283,6 +283,19 @@
*/
#define PKT_TX_OUTER_IPV6 (1ULL << 60)
+/**
+ * Bit Mask of all supported packet Tx offload features flags, which can be set
+ * for packet.
+ */
+#define PKT_TX_OFFLOAD_MASK ( \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_OUTER_IP_CKSUM | \
+ PKT_TX_TCP_SEG | \
+ PKT_TX_QINQ_PKT | \
+ PKT_TX_VLAN_PKT | \
+ PKT_TX_TUNNEL_MASK)
+
#define __RESERVED (1ULL << 61) /**< reserved for future mbuf use */
#define IND_ATTACHED_MBUF (1ULL << 62) /**< Indirect attached mbuf */
@@ -1647,6 +1660,57 @@ static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail
}
/**
+ * Validate general requirements for tx offload in mbuf.
+ *
+ * This function checks correctness and completeness of Tx offload settings.
+ *
+ * @param m
+ * The packet mbuf to be validated.
+ * @return
+ * 0 if packet is valid
+ */
+static inline int
+rte_validate_tx_offload(const struct rte_mbuf *m)
+{
+ uint64_t ol_flags = m->ol_flags;
+ uint64_t inner_l3_offset = m->l2_len;
+
+ /* Does packet set any of available offloads? */
+ if (!(ol_flags & PKT_TX_OFFLOAD_MASK))
+ return 0;
+
+ if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+ inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
+
+ /* Headers are fragmented */
+ if (rte_pktmbuf_data_len(m) < inner_l3_offset + m->l3_len + m->l4_len)
+ return -ENOTSUP;
+
+ /* IP checksum can be counted only for IPv4 packet */
+ if ((ol_flags & PKT_TX_IP_CKSUM) && (ol_flags & PKT_TX_IPV6))
+ return -EINVAL;
+
+ /* IP type not set when required */
+ if (ol_flags & (PKT_TX_L4_MASK | PKT_TX_TCP_SEG))
+ if (!(ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6)))
+ return -EINVAL;
+
+ /* Check requirements for TSO packet */
+ if (ol_flags & PKT_TX_TCP_SEG)
+ if ((m->tso_segsz == 0) ||
+ ((ol_flags & PKT_TX_IPV4) &&
+ !(ol_flags & PKT_TX_IP_CKSUM)))
+ return -EINVAL;
+
+ /* PKT_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
+ if ((ol_flags & PKT_TX_OUTER_IP_CKSUM) &&
+ !(ol_flags & PKT_TX_OUTER_IPV4))
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
* Dump an mbuf structure to a file.
*
* Dump all fields for the given packet mbuf and all its associated
diff --git a/lib/librte_net/rte_net.h b/lib/librte_net/rte_net.h
index d4156ae..85f356d 100644
--- a/lib/librte_net/rte_net.h
+++ b/lib/librte_net/rte_net.h
@@ -38,6 +38,11 @@
extern "C" {
#endif
+#include <rte_ip.h>
+#include <rte_udp.h>
+#include <rte_tcp.h>
+#include <rte_sctp.h>
+
/**
* Structure containing header lengths associated to a packet, filled
* by rte_net_get_ptype().
@@ -86,6 +91,86 @@ struct rte_net_hdr_lens {
uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
struct rte_net_hdr_lens *hdr_lens, uint32_t layers);
+/**
+ * Prepare pseudo header checksum
+ *
+ * This function prepares pseudo header checksum for TSO and non-TSO tcp/udp in
+ * provided mbufs packet data.
+ *
+ * - for non-TSO tcp/udp packets full pseudo-header checksum is counted and set
+ * in packet data,
+ * - for TSO the IP payload length is not included in pseudo header.
+ *
+ * This function expects that used headers are in the first data segment of
+ * mbuf, are not fragmented and can be safely modified.
+ *
+ * @param m
+ * The packet mbuf to be fixed.
+ * @return
+ * 0 if checksum is initialized properly
+ */
+static inline int
+rte_net_intel_cksum_prepare(struct rte_mbuf *m)
+{
+ struct ipv4_hdr *ipv4_hdr;
+ struct ipv6_hdr *ipv6_hdr;
+ struct tcp_hdr *tcp_hdr;
+ struct udp_hdr *udp_hdr;
+ uint64_t ol_flags = m->ol_flags;
+ uint64_t inner_l3_offset = m->l2_len;
+
+ if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
+ inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
+
+ if ((ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) {
+ if (ol_flags & PKT_TX_IPV4) {
+ ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+ inner_l3_offset);
+
+ if (ol_flags & PKT_TX_IP_CKSUM)
+ ipv4_hdr->hdr_checksum = 0;
+
+ udp_hdr = (struct udp_hdr *)((char *)ipv4_hdr +
+ m->l3_len);
+ udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
+ ol_flags);
+ } else {
+ ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
+ inner_l3_offset);
+ /* non-TSO udp */
+ udp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *,
+ inner_l3_offset + m->l3_len);
+ udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
+ ol_flags);
+ }
+ } else if ((ol_flags & PKT_TX_TCP_CKSUM) ||
+ (ol_flags & PKT_TX_TCP_SEG)) {
+ if (ol_flags & PKT_TX_IPV4) {
+ ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
+ inner_l3_offset);
+
+ if (ol_flags & PKT_TX_IP_CKSUM)
+ ipv4_hdr->hdr_checksum = 0;
+
+ /* non-TSO tcp or TSO */
+ tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr +
+ m->l3_len);
+ tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
+ ol_flags);
+ } else {
+ ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
+ inner_l3_offset);
+ /* non-TSO tcp or TSO */
+ tcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *,
+ inner_l3_offset + m->l3_len);
+ tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
+ ol_flags);
+ }
+ }
+
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 2/7] e1000: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
drivers/net/e1000/e1000_ethdev.h | 11 ++++++++
drivers/net/e1000/em_ethdev.c | 5 +++-
drivers/net/e1000/em_rxtx.c | 48 ++++++++++++++++++++++++++++++++++-
drivers/net/e1000/igb_ethdev.c | 4 +++
drivers/net/e1000/igb_rxtx.c | 52 +++++++++++++++++++++++++++++++++++++-
5 files changed, 117 insertions(+), 3 deletions(-)
diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h
index 6c25c8d..bd0f277 100644
--- a/drivers/net/e1000/e1000_ethdev.h
+++ b/drivers/net/e1000/e1000_ethdev.h
@@ -138,6 +138,11 @@
#define E1000_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
#define E1000_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+#define IGB_TX_MAX_SEG UINT8_MAX
+#define IGB_TX_MAX_MTU_SEG UINT8_MAX
+#define EM_TX_MAX_SEG UINT8_MAX
+#define EM_TX_MAX_MTU_SEG UINT8_MAX
+
/* structure for interrupt relative data */
struct e1000_interrupt {
uint32_t flags;
@@ -315,6 +320,9 @@ int eth_igb_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
uint16_t eth_igb_xmit_pkts(void *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t eth_igb_prep_pkts(void *txq, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
uint16_t eth_igb_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
@@ -376,6 +384,9 @@ int eth_em_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
uint16_t eth_em_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t eth_em_prep_pkts(void *txq, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
uint16_t eth_em_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..a004ee9 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -300,6 +300,7 @@ static int eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
eth_dev->dev_ops = ð_em_ops;
eth_dev->rx_pkt_burst = (eth_rx_burst_t)ð_em_recv_pkts;
eth_dev->tx_pkt_burst = (eth_tx_burst_t)ð_em_xmit_pkts;
+ eth_dev->tx_pkt_prepare = (eth_tx_prep_t)ð_em_prep_pkts;
/* for secondary processes, we don't initialise any further as primary
* has already done this work. Only check we don't need a different
@@ -1079,6 +1080,8 @@ static int eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
.nb_max = E1000_MAX_RING_DESC,
.nb_min = E1000_MIN_RING_DESC,
.nb_align = EM_TXD_ALIGN,
+ .nb_seg_max = EM_TX_MAX_SEG,
+ .nb_mtu_seg_max = EM_TX_MAX_MTU_SEG,
};
dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 41f51c0..7e271ad 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,7 @@
#include <rte_udp.h>
#include <rte_tcp.h>
#include <rte_sctp.h>
+#include <rte_net.h>
#include <rte_string_fns.h>
#include "e1000_logs.h"
@@ -77,6 +78,14 @@
#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */
+#define E1000_TX_OFFLOAD_MASK ( \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_VLAN_PKT)
+
+#define E1000_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ E1000_TX_OFFLOAD_MASK)
+
/**
* Structure associated with each descriptor of the RX ring of a RX queue.
*/
@@ -618,6 +627,43 @@ struct em_tx_queue {
/*********************************************************************
*
+ * TX prep functions
+ *
+ **********************************************************************/
+uint16_t
+eth_em_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int i, ret;
+ struct rte_mbuf *m;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+
+ if (m->ol_flags & E1000_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
+
+/*********************************************************************
+ *
* RX functions
*
**********************************************************************/
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..015ef46 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -369,6 +369,8 @@ static void eth_igbvf_interrupt_handler(struct rte_intr_handle *handle,
.nb_max = E1000_MAX_RING_DESC,
.nb_min = E1000_MIN_RING_DESC,
.nb_align = IGB_RXD_ALIGN,
+ .nb_seg_max = IGB_TX_MAX_SEG,
+ .nb_mtu_seg_max = IGB_TX_MAX_MTU_SEG,
};
static const struct eth_dev_ops eth_igb_ops = {
@@ -760,6 +762,7 @@ struct rte_igb_xstats_name_off {
eth_dev->dev_ops = ð_igb_ops;
eth_dev->rx_pkt_burst = ð_igb_recv_pkts;
eth_dev->tx_pkt_burst = ð_igb_xmit_pkts;
+ eth_dev->tx_pkt_prepare = ð_igb_prep_pkts;
/* for secondary processes, we don't initialise any further as primary
* has already done this work. Only check we don't need a different
@@ -963,6 +966,7 @@ struct rte_igb_xstats_name_off {
eth_dev->dev_ops = &igbvf_eth_dev_ops;
eth_dev->rx_pkt_burst = ð_igb_recv_pkts;
eth_dev->tx_pkt_burst = ð_igb_xmit_pkts;
+ eth_dev->tx_pkt_prepare = ð_igb_prep_pkts;
/* for secondary processes, we don't initialise any further as primary
* has already done this work. Only check we don't need a different
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index dbd37ac..8a3a3db 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -65,6 +65,7 @@
#include <rte_udp.h>
#include <rte_tcp.h>
#include <rte_sctp.h>
+#include <rte_net.h>
#include <rte_string_fns.h>
#include "e1000_logs.h"
@@ -78,6 +79,9 @@
PKT_TX_L4_MASK | \
PKT_TX_TCP_SEG)
+#define IGB_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ IGB_TX_OFFLOAD_MASK)
+
/**
* Structure associated with each descriptor of the RX ring of a RX queue.
*/
@@ -616,6 +620,51 @@ struct igb_tx_queue {
/*********************************************************************
*
+ * TX prep functions
+ *
+ **********************************************************************/
+uint16_t
+eth_igb_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int i, ret;
+ struct rte_mbuf *m;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+
+ /* Check some limitations for TSO in hardware */
+ if (m->ol_flags & PKT_TX_TCP_SEG)
+ if ((m->tso_segsz > IGB_TSO_MAX_MSS) || (m->l2_len + m->l3_len +
+ m->l4_len > IGB_TSO_MAX_HDRLEN)) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ if (m->ol_flags & IGB_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
+
+/*********************************************************************
+ *
* RX functions
*
**********************************************************************/
@@ -1364,6 +1413,7 @@ struct igb_tx_queue {
igb_reset_tx_queue(txq, dev);
dev->tx_pkt_burst = eth_igb_xmit_pkts;
+ dev->tx_pkt_prepare = ð_igb_prep_pkts;
dev->data->tx_queues[queue_idx] = txq;
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 3/7] fm10k: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
drivers/net/fm10k/fm10k.h | 6 +++++
drivers/net/fm10k/fm10k_ethdev.c | 5 ++++
drivers/net/fm10k/fm10k_rxtx.c | 50 +++++++++++++++++++++++++++++++++++++-
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/drivers/net/fm10k/fm10k.h b/drivers/net/fm10k/fm10k.h
index 05aa1a2..c6fed21 100644
--- a/drivers/net/fm10k/fm10k.h
+++ b/drivers/net/fm10k/fm10k.h
@@ -69,6 +69,9 @@
#define FM10K_MAX_RX_DESC (FM10K_MAX_RX_RING_SZ / sizeof(union fm10k_rx_desc))
#define FM10K_MAX_TX_DESC (FM10K_MAX_TX_RING_SZ / sizeof(struct fm10k_tx_desc))
+#define FM10K_TX_MAX_SEG UINT8_MAX
+#define FM10K_TX_MAX_MTU_SEG UINT8_MAX
+
/*
* byte aligment for HW RX data buffer
* Datasheet requires RX buffer addresses shall either be 512-byte aligned or
@@ -356,6 +359,9 @@ uint16_t fm10k_recv_scattered_pkts(void *rx_queue,
uint16_t fm10k_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t fm10k_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
int fm10k_rxq_vec_setup(struct fm10k_rx_queue *rxq);
int fm10k_rx_vec_condition_check(struct rte_eth_dev *);
void fm10k_rx_queue_release_mbufs_vec(struct fm10k_rx_queue *rxq);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 923690c..a116822 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1447,6 +1447,8 @@ static int fm10k_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
.nb_max = FM10K_MAX_TX_DESC,
.nb_min = FM10K_MIN_TX_DESC,
.nb_align = FM10K_MULT_TX_DESC,
+ .nb_seg_max = FM10K_TX_MAX_SEG,
+ .nb_mtu_seg_max = FM10K_TX_MAX_MTU_SEG,
};
dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
@@ -2755,8 +2757,10 @@ static void __attribute__((cold))
fm10k_txq_vec_setup(txq);
}
dev->tx_pkt_burst = fm10k_xmit_pkts_vec;
+ dev->tx_pkt_prepare = NULL;
} else {
dev->tx_pkt_burst = fm10k_xmit_pkts;
+ dev->tx_pkt_prepare = fm10k_prep_pkts;
PMD_INIT_LOG(DEBUG, "Use regular Tx func");
}
}
@@ -2835,6 +2839,7 @@ static void __attribute__((cold))
dev->dev_ops = &fm10k_eth_dev_ops;
dev->rx_pkt_burst = &fm10k_recv_pkts;
dev->tx_pkt_burst = &fm10k_xmit_pkts;
+ dev->tx_pkt_prepare = &fm10k_prep_pkts;
/* only initialize in the primary process */
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index 32cc7ff..144e5e6 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
#include <rte_ethdev.h>
#include <rte_common.h>
+#include <rte_net.h>
#include "fm10k.h"
#include "base/fm10k_type.h"
@@ -65,6 +66,15 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
}
#endif
+#define FM10K_TX_OFFLOAD_MASK ( \
+ PKT_TX_VLAN_PKT | \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_TCP_SEG)
+
+#define FM10K_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ FM10K_TX_OFFLOAD_MASK)
+
/* @note: When this function is changed, make corresponding change to
* fm10k_dev_supported_ptypes_get()
*/
@@ -597,3 +607,41 @@ static inline void tx_xmit_pkt(struct fm10k_tx_queue *q, struct rte_mbuf *mb)
return count;
}
+
+uint16_t
+fm10k_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int i, ret;
+ struct rte_mbuf *m;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+
+ if ((m->ol_flags & PKT_TX_TCP_SEG) &&
+ (m->tso_segsz < FM10K_TSO_MINMSS)) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ if (m->ol_flags & FM10K_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 4/7] i40e: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 3 ++
drivers/net/i40e/i40e_rxtx.c | 74 +++++++++++++++++++++++++++++++++++++++-
drivers/net/i40e/i40e_rxtx.h | 8 +++++
3 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..5761357 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -943,6 +943,7 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
dev->dev_ops = &i40e_eth_dev_ops;
dev->rx_pkt_burst = i40e_recv_pkts;
dev->tx_pkt_burst = i40e_xmit_pkts;
+ dev->tx_pkt_prepare = i40e_prep_pkts;
/* for secondary processes, we don't initialise any further as primary
* has already done this work. Only check we don't need a different
@@ -2645,6 +2646,8 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
.nb_max = I40E_MAX_RING_DESC,
.nb_min = I40E_MIN_RING_DESC,
.nb_align = I40E_ALIGN_RING_DESC,
+ .nb_seg_max = I40E_TX_MAX_SEG,
+ .nb_mtu_seg_max = I40E_TX_MAX_MTU_SEG,
};
if (pf->flags & I40E_FLAG_VMDQ) {
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 7ae7d9f..d248396 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,8 @@
#include <rte_tcp.h>
#include <rte_sctp.h>
#include <rte_udp.h>
+#include <rte_ip.h>
+#include <rte_net.h>
#include "i40e_logs.h"
#include "base/i40e_prototype.h"
@@ -79,6 +81,17 @@
PKT_TX_TCP_SEG | \
PKT_TX_OUTER_IP_CKSUM)
+#define I40E_TX_OFFLOAD_MASK ( \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_OUTER_IP_CKSUM | \
+ PKT_TX_TCP_SEG | \
+ PKT_TX_QINQ_PKT | \
+ PKT_TX_VLAN_PKT)
+
+#define I40E_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ I40E_TX_OFFLOAD_MASK)
+
static uint16_t i40e_xmit_pkts_simple(void *tx_queue,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
@@ -1411,6 +1424,63 @@ static inline int __attribute__((always_inline))
return nb_tx;
}
+/*********************************************************************
+ *
+ * TX prep functions
+ *
+ **********************************************************************/
+uint16_t
+i40e_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int i, ret;
+ uint64_t ol_flags;
+ struct rte_mbuf *m;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+ ol_flags = m->ol_flags;
+
+ /**
+ * m->nb_segs is uint8_t, so m->nb_segs is always less than
+ * I40E_TX_MAX_SEG.
+ * We check only a condition for m->nb_segs > I40E_TX_MAX_MTU_SEG.
+ */
+ if (!(ol_flags & PKT_TX_TCP_SEG)) {
+ if (m->nb_segs > I40E_TX_MAX_MTU_SEG) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+ } else if ((m->tso_segsz < I40E_MIN_TSO_MSS) ||
+ (m->tso_segsz > I40E_MAX_TSO_MSS)) {
+ /* MSS outside the range (256B - 9674B) are considered
+ * malicious
+ */
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ if (ol_flags & I40E_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+ return i;
+}
+
/*
* Find the VSI the queue belongs to. 'queue_idx' is the queue index
* application used, which assume having sequential ones. But from driver's
@@ -2763,9 +2833,11 @@ void __attribute__((cold))
PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
dev->tx_pkt_burst = i40e_xmit_pkts_simple;
}
+ dev->tx_pkt_prepare = NULL;
} else {
PMD_INIT_LOG(DEBUG, "Xmit tx finally be used.");
dev->tx_pkt_burst = i40e_xmit_pkts;
+ dev->tx_pkt_prepare = i40e_prep_pkts;
}
}
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index ecdb13c..9df8a56 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -63,6 +63,12 @@
#define I40E_MIN_RING_DESC 64
#define I40E_MAX_RING_DESC 4096
+#define I40E_MIN_TSO_MSS 256
+#define I40E_MAX_TSO_MSS 9674
+
+#define I40E_TX_MAX_SEG UINT8_MAX
+#define I40E_TX_MAX_MTU_SEG 8
+
#undef container_of
#define container_of(ptr, type, member) ({ \
typeof(((type *)0)->member)(*__mptr) = (ptr); \
@@ -223,6 +229,8 @@ uint16_t i40e_recv_scattered_pkts(void *rx_queue,
uint16_t i40e_xmit_pkts(void *tx_queue,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t i40e_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
int i40e_tx_queue_init(struct i40e_tx_queue *txq);
int i40e_rx_queue_init(struct i40e_rx_queue *rxq);
void i40e_free_tx_resources(struct i40e_tx_queue *txq);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 5/7] ixgbe: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 3 ++
drivers/net/ixgbe/ixgbe_ethdev.h | 5 +++-
drivers/net/ixgbe/ixgbe_rxtx.c | 56 ++++++++++++++++++++++++++++++++++++++
drivers/net/ixgbe/ixgbe_rxtx.h | 2 ++
4 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..a75f59d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -517,6 +517,8 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
.nb_max = IXGBE_MAX_RING_DESC,
.nb_min = IXGBE_MIN_RING_DESC,
.nb_align = IXGBE_TXD_ALIGN,
+ .nb_seg_max = IXGBE_TX_MAX_SEG,
+ .nb_mtu_seg_max = IXGBE_TX_MAX_SEG,
};
static const struct eth_dev_ops ixgbe_eth_dev_ops = {
@@ -1103,6 +1105,7 @@ struct rte_ixgbe_xstats_name_off {
eth_dev->dev_ops = &ixgbe_eth_dev_ops;
eth_dev->rx_pkt_burst = &ixgbe_recv_pkts;
eth_dev->tx_pkt_burst = &ixgbe_xmit_pkts;
+ eth_dev->tx_pkt_prepare = &ixgbe_prep_pkts;
/*
* For secondary processes, we don't initialise any further as primary
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 4ff6338..e229cf5 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -396,6 +396,9 @@ uint16_t ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t ixgbe_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
int ixgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index b2d9f45..dbe83e7 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -70,6 +70,7 @@
#include <rte_string_fns.h>
#include <rte_errno.h>
#include <rte_ip.h>
+#include <rte_net.h>
#include "ixgbe_logs.h"
#include "base/ixgbe_api.h"
@@ -87,6 +88,9 @@
PKT_TX_TCP_SEG | \
PKT_TX_OUTER_IP_CKSUM)
+#define IXGBE_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ IXGBE_TX_OFFLOAD_MASK)
+
#if 1
#define RTE_PMD_USE_PREFETCH
#endif
@@ -905,6 +909,56 @@ static inline int __attribute__((always_inline))
/*********************************************************************
*
+ * TX prep functions
+ *
+ **********************************************************************/
+uint16_t
+ixgbe_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ int i, ret;
+ uint64_t ol_flags;
+ struct rte_mbuf *m;
+ struct ixgbe_tx_queue *txq = (struct ixgbe_tx_queue *)tx_queue;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+ ol_flags = m->ol_flags;
+
+ /**
+ * Check if packet meets requirements for number of segments
+ *
+ * NOTE: for ixgbe it's always (40 - WTHRESH) for both TSO and non-TSO
+ */
+
+ if (m->nb_segs > IXGBE_TX_MAX_SEG - txq->wthresh) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ if (ol_flags & IXGBE_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
+
+/*********************************************************************
+ *
* RX functions
*
**********************************************************************/
@@ -2282,6 +2336,7 @@ void __attribute__((cold))
if (((txq->txq_flags & IXGBE_SIMPLE_FLAGS) == IXGBE_SIMPLE_FLAGS)
&& (txq->tx_rs_thresh >= RTE_PMD_IXGBE_TX_MAX_BURST)) {
PMD_INIT_LOG(DEBUG, "Using simple tx code path");
+ dev->tx_pkt_prepare = NULL;
#ifdef RTE_IXGBE_INC_VECTOR
if (txq->tx_rs_thresh <= RTE_IXGBE_TX_MAX_FREE_BUF_SZ &&
(rte_eal_process_type() != RTE_PROC_PRIMARY ||
@@ -2302,6 +2357,7 @@ void __attribute__((cold))
(unsigned long)txq->tx_rs_thresh,
(unsigned long)RTE_PMD_IXGBE_TX_MAX_BURST);
dev->tx_pkt_burst = ixgbe_xmit_pkts;
+ dev->tx_pkt_prepare = ixgbe_prep_pkts;
}
}
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 2608b36..7bbd9b8 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -80,6 +80,8 @@
#define RTE_IXGBE_WAIT_100_US 100
#define RTE_IXGBE_VMTXSW_REGISTER_COUNT 2
+#define IXGBE_TX_MAX_SEG 40
+
#define IXGBE_PACKET_TYPE_MASK_82599 0X7F
#define IXGBE_PACKET_TYPE_MASK_X550 0X10FF
#define IXGBE_PACKET_TYPE_MASK_TUNNEL 0XFF
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 6/7] vmxnet3: add Tx preparation
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev; +Cc: Ananyev, Konstantin
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 +++
drivers/net/vmxnet3/vmxnet3_ethdev.h | 2 ++
drivers/net/vmxnet3/vmxnet3_rxtx.c | 57 ++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 8bb13e5..f85be91 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -237,6 +237,7 @@ static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
+ eth_dev->tx_pkt_prepare = vmxnet3_prep_pkts;
pci_dev = eth_dev->pci_dev;
/*
@@ -326,6 +327,7 @@ static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
eth_dev->dev_ops = NULL;
eth_dev->rx_pkt_burst = NULL;
eth_dev->tx_pkt_burst = NULL;
+ eth_dev->tx_pkt_prepare = NULL;
rte_free(eth_dev->data->mac_addrs);
eth_dev->data->mac_addrs = NULL;
@@ -728,6 +730,8 @@ static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
.nb_max = VMXNET3_TX_RING_MAX_SIZE,
.nb_min = VMXNET3_DEF_TX_RING_SIZE,
.nb_align = 1,
+ .nb_seg_max = UINT8_MAX,
+ .nb_mtu_seg_max = VMXNET3_MAX_TXD_PER_PKT,
};
dev_info->rx_offload_capa =
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.h b/drivers/net/vmxnet3/vmxnet3_ethdev.h
index 7d3b11e..469db71 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.h
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.h
@@ -171,5 +171,7 @@ uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
uint16_t vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t vmxnet3_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
#endif /* _VMXNET3_ETHDEV_H_ */
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index b109168..0c35738 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -69,6 +69,7 @@
#include <rte_sctp.h>
#include <rte_string_fns.h>
#include <rte_errno.h>
+#include <rte_net.h>
#include "base/vmxnet3_defs.h"
#include "vmxnet3_ring.h"
@@ -76,6 +77,14 @@
#include "vmxnet3_logs.h"
#include "vmxnet3_ethdev.h"
+#define VMXNET3_TX_OFFLOAD_MASK ( \
+ PKT_TX_VLAN_PKT | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_TCP_SEG)
+
+#define VMXNET3_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ VMXNET3_TX_OFFLOAD_MASK)
+
static const uint32_t rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
static int vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t*, uint8_t);
@@ -350,6 +359,54 @@
}
uint16_t
+vmxnet3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int32_t ret;
+ uint32_t i;
+ uint64_t ol_flags;
+ struct rte_mbuf *m;
+
+ for (i = 0; i != nb_pkts; i++) {
+ m = tx_pkts[i];
+ ol_flags = m->ol_flags;
+
+ /*
+ * Non-TSO packet cannot occupy more than
+ * VMXNET3_MAX_TXD_PER_PKT TX descriptors.
+ */
+ if ((ol_flags & PKT_TX_TCP_SEG) == 0 &&
+ m->nb_segs > VMXNET3_MAX_TXD_PER_PKT) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ /* check that only supported TX offloads are requested. */
+ if ((ol_flags & VMXNET3_TX_OFFLOAD_NOTSUP_MASK) != 0 ||
+ (ol_flags & PKT_TX_L4_MASK) ==
+ PKT_TX_SCTP_CKSUM) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
+
+uint16_t
vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
--
1.7.9.5
^ permalink raw reply related
* [PATCH v13 7/7] testpmd: use Tx preparation in csum engine
From: Tomasz Kulasek @ 2016-12-13 17:41 UTC (permalink / raw)
To: dev
In-Reply-To: <1481650914-40324-1-git-send-email-tomaszx.kulasek@intel.com>
Added "csum txprep (on|off)" command which allows to switch to the
tx path using Tx preparation API.
By default unchanged implementation is used.
Using Tx preparation path, pseudo header calculation for udp/tcp/tso
packets from application, and used Tx preparation API for
packet preparation and verification.
Adding additional step to the csum engine costs about 3-4% of performance
drop, on my setup with ixgbe driver. It's caused mostly by the need
of reaccessing and modification of packet data.
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test-pmd/cmdline.c | 49 +++++++++++++++++++++++++++
app/test-pmd/csumonly.c | 33 ++++++++++++++----
app/test-pmd/testpmd.c | 5 +++
app/test-pmd/testpmd.h | 2 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 13 +++++++
5 files changed, 95 insertions(+), 7 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d03a592..499a00b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -366,6 +366,10 @@ static void cmd_help_long_parsed(void *parsed_result,
"csum show (port_id)\n"
" Display tx checksum offload configuration\n\n"
+ "csum txprep (on|off)"
+ " Enable tx preparation path in csum forward engine"
+ "\n\n"
+
"tso set (segsize) (portid)\n"
" Enable TCP Segmentation Offload in csum forward"
" engine.\n"
@@ -3528,6 +3532,50 @@ struct cmd_csum_tunnel_result {
},
};
+/* Enable/disable tx preparation path */
+struct cmd_csum_txprep_result {
+ cmdline_fixed_string_t csum;
+ cmdline_fixed_string_t parse;
+ cmdline_fixed_string_t onoff;
+};
+
+static void
+cmd_csum_txprep_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_csum_txprep_result *res = parsed_result;
+
+ if (!strcmp(res->onoff, "on"))
+ tx_prepare = 1;
+ else
+ tx_prepare = 0;
+
+}
+
+cmdline_parse_token_string_t cmd_csum_txprep_csum =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_txprep_result,
+ csum, "csum");
+cmdline_parse_token_string_t cmd_csum_txprep_parse =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_txprep_result,
+ parse, "txprep");
+cmdline_parse_token_string_t cmd_csum_txprep_onoff =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_txprep_result,
+ onoff, "on#off");
+
+cmdline_parse_inst_t cmd_csum_txprep = {
+ .f = cmd_csum_txprep_parsed,
+ .data = NULL,
+ .help_str = "csum txprep on|off: Enable/Disable tx preparation path "
+ "for csum engine",
+ .tokens = {
+ (void *)&cmd_csum_txprep_csum,
+ (void *)&cmd_csum_txprep_parse,
+ (void *)&cmd_csum_txprep_onoff,
+ NULL,
+ },
+};
+
/* *** ENABLE HARDWARE SEGMENTATION IN TX NON-TUNNELED PACKETS *** */
struct cmd_tso_set_result {
cmdline_fixed_string_t tso;
@@ -11518,6 +11566,7 @@ struct cmd_set_vf_mac_addr_result {
(cmdline_parse_inst_t *)&cmd_csum_set,
(cmdline_parse_inst_t *)&cmd_csum_show,
(cmdline_parse_inst_t *)&cmd_csum_tunnel,
+ (cmdline_parse_inst_t *)&cmd_csum_txprep,
(cmdline_parse_inst_t *)&cmd_tso_set,
(cmdline_parse_inst_t *)&cmd_tso_show,
(cmdline_parse_inst_t *)&cmd_tunnel_tso_set,
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 57e6ae2..3afa9ab 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -372,8 +372,10 @@ struct simple_gre_hdr {
udp_hdr->dgram_cksum = 0;
if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) {
ol_flags |= PKT_TX_UDP_CKSUM;
- udp_hdr->dgram_cksum = get_psd_sum(l3_hdr,
- info->ethertype, ol_flags);
+ if (!tx_prepare)
+ udp_hdr->dgram_cksum = get_psd_sum(
+ l3_hdr, info->ethertype,
+ ol_flags);
} else {
udp_hdr->dgram_cksum =
get_udptcp_checksum(l3_hdr, udp_hdr,
@@ -385,12 +387,15 @@ struct simple_gre_hdr {
tcp_hdr->cksum = 0;
if (tso_segsz) {
ol_flags |= PKT_TX_TCP_SEG;
- tcp_hdr->cksum = get_psd_sum(l3_hdr, info->ethertype,
- ol_flags);
+ if (!tx_prepare)
+ tcp_hdr->cksum = get_psd_sum(l3_hdr,
+ info->ethertype, ol_flags);
+
} else if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {
ol_flags |= PKT_TX_TCP_CKSUM;
- tcp_hdr->cksum = get_psd_sum(l3_hdr, info->ethertype,
- ol_flags);
+ if (!tx_prepare)
+ tcp_hdr->cksum = get_psd_sum(l3_hdr,
+ info->ethertype, ol_flags);
} else {
tcp_hdr->cksum =
get_udptcp_checksum(l3_hdr, tcp_hdr,
@@ -648,6 +653,7 @@ struct simple_gre_hdr {
void *l3_hdr = NULL, *outer_l3_hdr = NULL; /* can be IPv4 or IPv6 */
uint16_t nb_rx;
uint16_t nb_tx;
+ uint16_t nb_prep;
uint16_t i;
uint64_t rx_ol_flags, tx_ol_flags;
uint16_t testpmd_ol_flags;
@@ -857,7 +863,20 @@ struct simple_gre_hdr {
printf("\n");
}
}
- nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
+
+ if (tx_prepare) {
+ nb_prep = rte_eth_tx_prepare(fs->tx_port, fs->tx_queue,
+ pkts_burst, nb_rx);
+ if (nb_prep != nb_rx)
+ printf("Preparing packet burst to transmit failed: %s\n",
+ rte_strerror(rte_errno));
+
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst,
+ nb_prep);
+ } else
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst,
+ nb_rx);
+
/*
* Retry if necessary
*/
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index a0332c2..634f10b 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -180,6 +180,11 @@ struct fwd_engine * fwd_engines[] = {
enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
/**< Split policy for packets to TX. */
+/*
+ * Enable Tx preparation path in the "csum" engine.
+ */
+uint8_t tx_prepare;
+
uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9c1e703..488a6e1 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -383,6 +383,8 @@ enum tx_pkt_split {
extern enum tx_pkt_split tx_pkt_split;
+extern uint8_t tx_prepare;
+
extern uint16_t nb_pkt_per_burst;
extern uint16_t mb_mempool_cache;
extern int8_t rx_pthresh;
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f1c269a..d77336e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -750,6 +750,19 @@ Display tx checksum offload configuration::
testpmd> csum show (port_id)
+csum txprep
+~~~~~~~~~~~
+
+Select TX preparation path for the ``csum`` forwarding engine::
+
+ testpmd> csum txprep (on|off)
+
+If enabled, the csum forward engine uses TX preparation API for full packet
+preparation and verification before TX burst.
+
+If disabled, csum engine initializes all required fields on application level
+and TX preparation stage is not executed.
+
tso set
~~~~~~~
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 04/13] acl: allow zero verdict
From: Michal Miroslaw @ 2016-12-13 18:02 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev@dpdk.org
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0E7567@irsmsx105.ger.corp.intel.com>
On Tue, Dec 13, 2016 at 05:27:31PM +0000, Ananyev, Konstantin wrote:
>
>
> > -----Original Message-----
> > From: Michal Miroslaw [mailto:mirq-linux@rere.qmqm.pl]
> > Sent: Tuesday, December 13, 2016 4:14 PM
> > To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 04/13] acl: allow zero verdict
> >
> > On Tue, Dec 13, 2016 at 03:13:42PM +0000, Ananyev, Konstantin wrote:
> > [...]
> > > > > > > > Subject: [dpdk-dev] [PATCH 04/13] acl: allow zero verdict
> > > > > > > >
> > > > > > > > Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> > > > > > > > ---
> > > > > > > > lib/librte_acl/rte_acl.c | 3 +--
> > > > > > > > lib/librte_acl/rte_acl.h | 2 --
> > > > > > > > lib/librte_table/rte_table_acl.c | 2 +-
> > > > > > > > 3 files changed, 2 insertions(+), 5 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c
> > > > > > > > index 8b7e92c..d1f40be 100644
> > > > > > > > --- a/lib/librte_acl/rte_acl.c
> > > > > > > > +++ b/lib/librte_acl/rte_acl.c
> > > > > > > > @@ -313,8 +313,7 @@ acl_check_rule(const struct rte_acl_rule_data *rd)
> > > > > > > > if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
> > > > > > > > rd->category_mask) == 0 ||
> > > > > > > > rd->priority > RTE_ACL_MAX_PRIORITY ||
> > > > > > > > - rd->priority < RTE_ACL_MIN_PRIORITY ||
> > > > > > > > - rd->userdata == RTE_ACL_INVALID_USERDATA)
> > > > > > > > + rd->priority < RTE_ACL_MIN_PRIORITY)
> > > > > > > > return -EINVAL;
> > > > > > > > return 0;
> > > > > > > > }
> > > > > > >
> > > > > > > I am not sure, how it supposed to work properly?
> > > > > > > Zero value is reserved and ifnicates that no match were found for that input.
> > > > > >
> > > > > > This is actually in use by us. In our use we don't need to differentiate
> > > > > > matching a rule with zero verdict vs not matching a rule at all. I also
> > > > > > have a patch that changes the value returned in non-matching case, but
> > > > > > it's in "dirty hack" state, as of yet.
> > > > >
> > > > > With that chane rte_acl_classify() might produce invalid results.
> > > > > Even if you don't need it (I still don't understand how) , it doesn't mean other people
> > > > > don't need it either and it is ok to change it.
> > > > >
> > > > > >
> > > > > > The ACL code does not treat zero userdata specially, so this is only
> > > > > > a policy choice and as such would be better to be made by the user.
> > > > >
> > > > > I believe it does.
> > > > > userdata==0 is a reserved value.
> > > > > When rte_acl_clasify() returns 0 for that particular input, it means 'no matches were found'.
> > > >
> > > > Dear Konstantin,
> > > >
> > > > Can you describe how the ACL code treats zero specially? I could not find
> > > > anything, really. The only thing I found is that iff I use zero userdata
> > > > in a rule I won't be able to differentiate a case where it matched from
> > > > a case where no rule matched.
> > >
> > > Yes, that's what I am talking about.
> > >
> > > > If I all my rules have non-zero userdata,
> > > > then this patch changes nothing.
> > >
> > > Ok, then why do you remove a code that does checking for invalid userdata==0?
> > > That supposed to prevent user to setup invalid value by mistake.
> > >
> > > But if I have a table where 0 means drop
> > > > (default-drop policy) then being able to use zero userdata in DROP rules
> > > > makes the ACLs just that more useful.
> > >
> > > Ok, and what prevents you from do +1 to your policy values before
> > > you insert it into the ACL table and -1 after you retrieved it via rte_acl_classify()?
> >
> > The check is enforcing an assumption that all users want to distinguish
> > the cases whether any rule matched and whether no rules matched. Not all
> > users do, hence the assumption is invalid and this patch removes it.
>
> The check is based on the assumption that users might need to distinguish
> the situation when no rules were matched.
> To support that we need a reserved userdata value, which would mean
> NO_MATCH.
> From what I heard, most users do need this ability, those who don't
> can easily overcome it.
That's actually my point. Some users need the distinction, so they don't use
zero userdata in their rules and have their work done. Some users don't need
it and would prefer to just use the convenience of zero being no-match signal
to insert "non-matching" rules (now they have to check two values for the
same signal).
> > Yes, people can work around it by loosing 1 of 2^32 useful values and
> > convoluting their code.
> Yes, one of 2^32 values is reserved.
> Any reason why (2^32 - 1) values might not be enough?
Sure. We're using userdata as a bitmask of actions to take on the packet,
and because of this restriction we're loosing half of the userdata field.
If we would add this "decrement if non-zero" workaround this would keep
biting us on every occasion where we touch the ACL verdict code.
> > You seem to argue that 0 is somehow an invalid value, but I can't find
> > anything in the ACL that would require it to be so. Could you point me
> > to the code in DPDK where this actually matters?
>
> It was a while, when I looked into ACL code in details, but as remember
> that's the only reason: we need some value to be reserved as NO_MATCH.
> Let say in build_trie() we set results to zero for rules with unused categories:
> for (m = context->cfg.num_categories; 0 != m--; ) {
> if (rule->f->data.category_mask & (1 << m)) {
> end->mrt->results[m] = rule->f->data.userdata;
> end->mrt->priority[m] = rule->f->data.priority;
> } else {
> end->mrt->results[m] = 0;
> end->mrt->priority[m] = 0;
> }
> }
So, if I understand correctly, 0 is a default value for category result.
Any matching rule with priority >= 0 will override it (leaving last highest
priority rule's userdata). This will just work the same for anyone needing
the distinction (when he doesn't use userdata == 0) and also for those who
don't -- when the restriction is removed.
I think that it comes to documenting the behaviour and let users choose
their way. At the beginning I haven't found any mention of the restriction
in the docs, so I had to spend a fair amount of time to find out why the
zero is so special (it wasn't).
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: [PATCH v13 6/7] vmxnet3: add Tx preparation
From: Yong Wang @ 2016-12-13 18:15 UTC (permalink / raw)
To: Tomasz Kulasek, dev@dpdk.org; +Cc: Ananyev, Konstantin
In-Reply-To: <1481650914-40324-7-git-send-email-tomaszx.kulasek@intel.com>
Looks good and two nits below.
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Tomasz Kulasek
> Sent: Tuesday, December 13, 2016 9:42 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: [dpdk-dev] [PATCH v13 6/7] vmxnet3: add Tx preparation
>
> From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 +++
> drivers/net/vmxnet3/vmxnet3_ethdev.h | 2 ++
> drivers/net/vmxnet3/vmxnet3_rxtx.c | 57
> ++++++++++++++++++++++++++++++++++
> 3 files changed, 63 insertions(+)
>
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> index 8bb13e5..f85be91 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> @@ -237,6 +237,7 @@ static void vmxnet3_mac_addr_set(struct
> rte_eth_dev *dev,
> eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
> eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
> eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
> + eth_dev->tx_pkt_prepare = vmxnet3_prep_pkts;
> pci_dev = eth_dev->pci_dev;
>
> /*
> @@ -326,6 +327,7 @@ static void vmxnet3_mac_addr_set(struct
> rte_eth_dev *dev,
> eth_dev->dev_ops = NULL;
> eth_dev->rx_pkt_burst = NULL;
> eth_dev->tx_pkt_burst = NULL;
> + eth_dev->tx_pkt_prepare = NULL;
>
> rte_free(eth_dev->data->mac_addrs);
> eth_dev->data->mac_addrs = NULL;
> @@ -728,6 +730,8 @@ static void vmxnet3_mac_addr_set(struct
> rte_eth_dev *dev,
> .nb_max = VMXNET3_TX_RING_MAX_SIZE,
> .nb_min = VMXNET3_DEF_TX_RING_SIZE,
> .nb_align = 1,
> + .nb_seg_max = UINT8_MAX,
To be consistent with other drivers, can you define VMXNET3_TX_MAX_SEG as UINT8_MAX and use it here?
> + .nb_mtu_seg_max = VMXNET3_MAX_TXD_PER_PKT,
> };
>
> dev_info->rx_offload_capa =
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.h
> b/drivers/net/vmxnet3/vmxnet3_ethdev.h
> index 7d3b11e..469db71 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.h
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.h
> @@ -171,5 +171,7 @@ uint16_t vmxnet3_recv_pkts(void *rx_queue, struct
> rte_mbuf **rx_pkts,
> uint16_t nb_pkts);
> uint16_t vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> uint16_t nb_pkts);
> +uint16_t vmxnet3_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> + uint16_t nb_pkts);
>
> #endif /* _VMXNET3_ETHDEV_H_ */
> diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c
> b/drivers/net/vmxnet3/vmxnet3_rxtx.c
> index b109168..0c35738 100644
> --- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
> +++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
> @@ -69,6 +69,7 @@
> #include <rte_sctp.h>
> #include <rte_string_fns.h>
> #include <rte_errno.h>
> +#include <rte_net.h>
>
> #include "base/vmxnet3_defs.h"
> #include "vmxnet3_ring.h"
> @@ -76,6 +77,14 @@
> #include "vmxnet3_logs.h"
> #include "vmxnet3_ethdev.h"
>
> +#define VMXNET3_TX_OFFLOAD_MASK ( \
> + PKT_TX_VLAN_PKT | \
> + PKT_TX_L4_MASK | \
> + PKT_TX_TCP_SEG)
> +
> +#define VMXNET3_TX_OFFLOAD_NOTSUP_MASK \
> + (PKT_TX_OFFLOAD_MASK ^ VMXNET3_TX_OFFLOAD_MASK)
> +
> static const uint32_t rxprod_reg[2] = {VMXNET3_REG_RXPROD,
> VMXNET3_REG_RXPROD2};
>
> static int vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t*, uint8_t);
> @@ -350,6 +359,54 @@
> }
>
> uint16_t
> +vmxnet3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf
> **tx_pkts,
> + uint16_t nb_pkts)
> +{
> + int32_t ret;
> + uint32_t i;
> + uint64_t ol_flags;
> + struct rte_mbuf *m;
> +
> + for (i = 0; i != nb_pkts; i++) {
> + m = tx_pkts[i];
> + ol_flags = m->ol_flags;
> +
> + /*
> + * Non-TSO packet cannot occupy more than
> + * VMXNET3_MAX_TXD_PER_PKT TX descriptors.
> + */
> + if ((ol_flags & PKT_TX_TCP_SEG) == 0 &&
> + m->nb_segs >
> VMXNET3_MAX_TXD_PER_PKT) {
> + rte_errno = -EINVAL;
> + return i;
> + }
> +
> + /* check that only supported TX offloads are requested. */
> + if ((ol_flags & VMXNET3_TX_OFFLOAD_NOTSUP_MASK) != 0
> ||
> + (ol_flags & PKT_TX_L4_MASK) ==
> + PKT_TX_SCTP_CKSUM) {
> + rte_errno = -EINVAL;
Return ENOTSUP instead of EINVAL here?
> + return i;
> + }
> +
> +#ifdef RTE_LIBRTE_ETHDEV_DEBUG
> + ret = rte_validate_tx_offload(m);
> + if (ret != 0) {
> + rte_errno = ret;
> + return i;
> + }
> +#endif
> + ret = rte_net_intel_cksum_prepare(m);
> + if (ret != 0) {
> + rte_errno = ret;
> + return i;
> + }
> + }
> +
> + return i;
> +}
> +
> +uint16_t
> vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> uint16_t nb_pkts)
> {
> --
> 1.7.9.5
^ permalink raw reply
* Re: [PATCH 02/13] mbuf: rte_pktmbuf_free_bulk()
From: Stephen Hemminger @ 2016-12-13 21:41 UTC (permalink / raw)
To: Michał Mirosław; +Cc: dev
In-Reply-To: <0af54798c5e025c95e1315ef9b33f4c930177f24.1481590851.git.mirq-linux@rere.qmqm.pl>
On Tue, 13 Dec 2016 02:08:15 +0100 (CET)
Michał Mirosław <mirq-linux@rere.qmqm.pl> wrote:
> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
>
> ---
> lib/librte_mbuf/rte_mbuf.h | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index ead7c6e..a95d99f 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -1248,6 +1248,21 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)
> }
>
> /**
> + * Free multiple packet mbufs back into their original mempool(s).
> + *
> + * @param mp
> + * Pointer to array of packet mbufs to be freed.
> + * @param n
> + * Count of packet mbufs to free.
> + */
> +static inline void rte_pktmbuf_free_bulk(struct rte_mbuf **mp, uint32_t n)
> +{
> + uint32_t i;
> + for (i = 0; i < n; ++i)
> + rte_pktmbuf_free(mp[i]);
> +}
Why not do something smarter that uses mempool_put_bulk?
^ permalink raw reply
* Re: [PATCH 04/13] acl: allow zero verdict
From: Ananyev, Konstantin @ 2016-12-13 21:55 UTC (permalink / raw)
To: Michal Miroslaw; +Cc: dev@dpdk.org
In-Reply-To: <20161213180240.is54unzdj3yfexq5@rere.qmqm.pl>
> -----Original Message-----
> From: Michal Miroslaw [mailto:mirq-linux@rere.qmqm.pl]
> Sent: Tuesday, December 13, 2016 6:03 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 04/13] acl: allow zero verdict
>
> On Tue, Dec 13, 2016 at 05:27:31PM +0000, Ananyev, Konstantin wrote:
> >
> >
> > > -----Original Message-----
> > > From: Michal Miroslaw [mailto:mirq-linux@rere.qmqm.pl]
> > > Sent: Tuesday, December 13, 2016 4:14 PM
> > > To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 04/13] acl: allow zero verdict
> > >
> > > On Tue, Dec 13, 2016 at 03:13:42PM +0000, Ananyev, Konstantin wrote:
> > > [...]
> > > > > > > > > Subject: [dpdk-dev] [PATCH 04/13] acl: allow zero verdict
> > > > > > > > >
> > > > > > > > > Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> > > > > > > > > ---
> > > > > > > > > lib/librte_acl/rte_acl.c | 3 +--
> > > > > > > > > lib/librte_acl/rte_acl.h | 2 --
> > > > > > > > > lib/librte_table/rte_table_acl.c | 2 +-
> > > > > > > > > 3 files changed, 2 insertions(+), 5 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c
> > > > > > > > > index 8b7e92c..d1f40be 100644
> > > > > > > > > --- a/lib/librte_acl/rte_acl.c
> > > > > > > > > +++ b/lib/librte_acl/rte_acl.c
> > > > > > > > > @@ -313,8 +313,7 @@ acl_check_rule(const struct rte_acl_rule_data *rd)
> > > > > > > > > if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
> > > > > > > > > rd->category_mask) == 0 ||
> > > > > > > > > rd->priority > RTE_ACL_MAX_PRIORITY ||
> > > > > > > > > - rd->priority < RTE_ACL_MIN_PRIORITY ||
> > > > > > > > > - rd->userdata == RTE_ACL_INVALID_USERDATA)
> > > > > > > > > + rd->priority < RTE_ACL_MIN_PRIORITY)
> > > > > > > > > return -EINVAL;
> > > > > > > > > return 0;
> > > > > > > > > }
> > > > > > > >
> > > > > > > > I am not sure, how it supposed to work properly?
> > > > > > > > Zero value is reserved and ifnicates that no match were found for that input.
> > > > > > >
> > > > > > > This is actually in use by us. In our use we don't need to differentiate
> > > > > > > matching a rule with zero verdict vs not matching a rule at all. I also
> > > > > > > have a patch that changes the value returned in non-matching case, but
> > > > > > > it's in "dirty hack" state, as of yet.
> > > > > >
> > > > > > With that chane rte_acl_classify() might produce invalid results.
> > > > > > Even if you don't need it (I still don't understand how) , it doesn't mean other people
> > > > > > don't need it either and it is ok to change it.
> > > > > >
> > > > > > >
> > > > > > > The ACL code does not treat zero userdata specially, so this is only
> > > > > > > a policy choice and as such would be better to be made by the user.
> > > > > >
> > > > > > I believe it does.
> > > > > > userdata==0 is a reserved value.
> > > > > > When rte_acl_clasify() returns 0 for that particular input, it means 'no matches were found'.
> > > > >
> > > > > Dear Konstantin,
> > > > >
> > > > > Can you describe how the ACL code treats zero specially? I could not find
> > > > > anything, really. The only thing I found is that iff I use zero userdata
> > > > > in a rule I won't be able to differentiate a case where it matched from
> > > > > a case where no rule matched.
> > > >
> > > > Yes, that's what I am talking about.
> > > >
> > > > > If I all my rules have non-zero userdata,
> > > > > then this patch changes nothing.
> > > >
> > > > Ok, then why do you remove a code that does checking for invalid userdata==0?
> > > > That supposed to prevent user to setup invalid value by mistake.
> > > >
> > > > But if I have a table where 0 means drop
> > > > > (default-drop policy) then being able to use zero userdata in DROP rules
> > > > > makes the ACLs just that more useful.
> > > >
> > > > Ok, and what prevents you from do +1 to your policy values before
> > > > you insert it into the ACL table and -1 after you retrieved it via rte_acl_classify()?
> > >
> > > The check is enforcing an assumption that all users want to distinguish
> > > the cases whether any rule matched and whether no rules matched. Not all
> > > users do, hence the assumption is invalid and this patch removes it.
> >
> > The check is based on the assumption that users might need to distinguish
> > the situation when no rules were matched.
> > To support that we need a reserved userdata value, which would mean
> > NO_MATCH.
> > From what I heard, most users do need this ability, those who don't
> > can easily overcome it.
>
> That's actually my point. Some users need the distinction, so they don't use
> zero userdata in their rules and have their work done. Some users don't need
> it and would prefer to just use the convenience of zero being no-match signal
> to insert "non-matching" rules (now they have to check two values for the
> same signal).
>
> > > Yes, people can work around it by loosing 1 of 2^32 useful values and
> > > convoluting their code.
> > Yes, one of 2^32 values is reserved.
> > Any reason why (2^32 - 1) values might not be enough?
>
> Sure. We're using userdata as a bitmask of actions to take on the packet,
> and because of this restriction we're loosing half of the userdata field.
> If we would add this "decrement if non-zero" workaround this would keep
> biting us on every occasion where we touch the ACL verdict code.
>
> > > You seem to argue that 0 is somehow an invalid value, but I can't find
> > > anything in the ACL that would require it to be so. Could you point me
> > > to the code in DPDK where this actually matters?
> >
> > It was a while, when I looked into ACL code in details, but as remember
> > that's the only reason: we need some value to be reserved as NO_MATCH.
> > Let say in build_trie() we set results to zero for rules with unused categories:
> > for (m = context->cfg.num_categories; 0 != m--; ) {
> > if (rule->f->data.category_mask & (1 << m)) {
> > end->mrt->results[m] = rule->f->data.userdata;
> > end->mrt->priority[m] = rule->f->data.priority;
> > } else {
> > end->mrt->results[m] = 0;
> > end->mrt->priority[m] = 0;
> > }
> > }
>
> So, if I understand correctly, 0 is a default value for category result.
> Any matching rule with priority >= 0 will override it (leaving last highest
> priority rule's userdata). This will just work the same for anyone needing
> the distinction (when he doesn't use userdata == 0) and also for those who
> don't -- when the restriction is removed.
>
> I think that it comes to documenting the behaviour and let users choose
> their way. At the beginning I haven't found any mention of the restriction
> in the docs, so I had to spend a fair amount of time to find out why the
> zero is so special (it wasn't).
Ok, so you suggest the following:
1. Zero value for both userdata and results still has a special meaning: NO_MATCH.
2. Allow user to create a rule(s) that would on hit return NO_MATCH for it,
as if no rule was matched by that input (i.e. rule's userdata==0).
Is my understanding correct?
Konstantin
^ permalink raw reply
* Re: [PATCH v2 01/12] eal: define container_of macro
From: Jan Blunck @ 2016-12-13 22:24 UTC (permalink / raw)
To: Shreyansh Jain
Cc: dev, David Marchand, Thomas Monjalon, Ferruh Yigit, jianbo.liu,
Jan Viktorin
In-Reply-To: <1481636232-2300-2-git-send-email-shreyansh.jain@nxp.com>
On Tue, Dec 13, 2016 at 2:37 PM, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> From: Jan Blunck <jblunck@infradead.org>
>
> This macro is based on Jan Viktorin's original patch but also checks the
> type of the passed pointer against the type of the member.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> [shreyansh.jain@nxp.com: Fix checkpatch error]
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> [jblunck@infradead.org: add type checking and __extension__]
> Signed-off-by: Jan Blunck <jblunck@infradead.org>
>
> --
> v2:
> - fix checkpatch error
> ---
> lib/librte_eal/common/include/rte_common.h | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
> index db5ac91..3eb8d11 100644
> --- a/lib/librte_eal/common/include/rte_common.h
> +++ b/lib/librte_eal/common/include/rte_common.h
> @@ -331,6 +331,27 @@ rte_bsf32(uint32_t v)
> #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
> #endif
>
> +/**
> + * Return pointer to the wrapping struct instance.
> + *
> + * Example:
> + *
> + * struct wrapper {
> + * ...
> + * struct child c;
> + * ...
> + * };
> + *
> + * struct child *x = obtain(...);
> + * struct wrapper *w = container_of(x, struct wrapper, c);
> + */
> +#ifndef container_of
> +#define container_of(ptr, type, member) (__extension__ ({ \
> + typeof(((type *)0)->member) * _ptr = (ptr); \
> + (type *)(((char *)_ptr) - offsetof(type, member));\
> + }))
This is a checkpatch false positive. It should be fine to ignore this.
IIRC we already discussed this before.
> +#endif
> +
> #define _RTE_STR(x) #x
> /** Take a macro value and get a string version of it */
> #define RTE_STR(x) _RTE_STR(x)
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH v2 25/32] app/testpmd: handle i40e in VF VLAN filter command
From: Lu, Wenzhuo @ 2016-12-14 0:42 UTC (permalink / raw)
To: Yigit, Ferruh, dev@dpdk.org; +Cc: Iremonger, Bernard
In-Reply-To: <5224578d-3ec2-48e6-5ce3-91cd4bc467b0@intel.com>
Hi Ferruh,
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Tuesday, December 13, 2016 9:41 PM
> To: Lu, Wenzhuo; dev@dpdk.org
> Cc: Iremonger, Bernard
> Subject: Re: [dpdk-dev] [PATCH v2 25/32] app/testpmd: handle i40e in VF VLAN
> filter command
>
> Hi Wenzhuo,
>
> On 12/7/2016 3:32 AM, Wenzhuo Lu wrote:
> > modify set_vf_rx_vlan function to handle the i40e PMD.
> >
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
>
> Latest applied patches [1] conflict with some testpmd patches of this patchset.
>
> Can you please rebase this patchset on top of the latest next-net?
Sure, we'll rework this series of patches based on the newest next-net.
>
> [1]
> http://dpdk.org/dev/patchwork/patch/17896 - 17902
>
> Thanks,
> ferruh
^ permalink raw reply
* Re: [PATCH 20/31] app/testpmd: use VFD APIs on i40e
From: Lu, Wenzhuo @ 2016-12-14 0:44 UTC (permalink / raw)
To: Yigit, Ferruh, dev@dpdk.org; +Cc: Chen, Jing D, Iremonger, Bernard
In-Reply-To: <b192e6d3-69ed-a2c5-b8e2-ccb73f45353b@intel.com>
Hi Ferruh,
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday, December 14, 2016 12:57 AM
> To: Lu, Wenzhuo; dev@dpdk.org
> Cc: Chen, Jing D; Iremonger, Bernard
> Subject: Re: [dpdk-dev] [PATCH 20/31] app/testpmd: use VFD APIs on i40e
>
> On 12/2/2016 12:12 AM, Wenzhuo Lu wrote:
> > The new VF Daemon (VFD) APIs is implemented on i40e. Change testpmd
> > code to use them, inlcuding VF MAC anti-spoofing, VF VLAN
> > anti-spoofing, TX loopback, VF VLAN strip, VF VLAN insert.
> >
> > Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> > Signed-off-by: Chen Jing D(Mark) <jing.d.chen@intel.com>
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
> > app/test-pmd/cmdline.c | 92
> > ++++++++++++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 85 insertions(+), 7 deletions(-)
> >
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > 63b55dc..1284d6c 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> <...>
> > @@ -11059,8 +11109,20 @@ struct cmd_vf_vlan_insert_result { {
> > struct cmd_vf_vlan_insert_result *res = parsed_result;
> > int ret;
> > + struct rte_eth_dev_info dev_info;
> > +
> > + memset(&dev_info, 0, sizeof(dev_info));
> > + rte_eth_dev_info_get(res->port_id, &dev_info);
> > +
> > + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> > + ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id,
> > + res->vlan_id);
> > + else if (strstr(dev_info.driver_name, "i40e") != NULL)
> > + ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id,
> > + res->vlan_id);
>
> This code is within "#ifdef RTE_LIBRTE_IXGBE_PMD", so i40e check can fail if
> IXGBE_PMD disabled, need to update surrounding ifdef.
>
> Same for rest.
Yes, will handle it. Thanks.
>
> <...>
^ permalink raw reply
* Re: [PATCH] doc: fix environment variable typo
From: Remy Horton @ 2016-12-14 1:03 UTC (permalink / raw)
To: Baruch Siach, dev; +Cc: John McNamara
In-Reply-To: <fce9d7d4be77343de88e6b43e2323f173fffe088.1481636426.git.baruch@tkos.co.il>
On 13/12/2016 21:40, Baruch Siach wrote:
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> doc/guides/sample_app_ug/ethtool.rst | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Missing fixline
Fixes: bda68ab9d1e7 ("examples/ethtool: add user-space ethtool sample
application")
Otherwise, well spotted.. :)
Acked-by: Remy Horton <remy.horton@intel.com>
^ permalink raw reply
* [PATCH 07/28] eal/arm64: fix memory barrier definition for arm64
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob, stable
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
dsb instruction based barrier is used for non smp
version of memory barrier.
Fixes: d708f01b7102 ("eal/arm: add atomic operations for ARMv8")
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
CC: Jianbo Liu <jianbo.liu@linaro.org>
CC: stable@dpdk.org
---
lib/librte_eal/common/include/arch/arm/rte_atomic_64.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index d854aac..bc7de64 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -43,7 +43,8 @@ extern "C" {
#include "generic/rte_atomic.h"
-#define dmb(opt) do { asm volatile("dmb " #opt : : : "memory"); } while (0)
+#define dsb(opt) { asm volatile("dsb " #opt : : : "memory"); }
+#define dmb(opt) { asm volatile("dmb " #opt : : : "memory"); }
/**
* General memory barrier.
@@ -54,7 +55,7 @@ extern "C" {
*/
static inline void rte_mb(void)
{
- dmb(ish);
+ dsb(sy);
}
/**
@@ -66,7 +67,7 @@ static inline void rte_mb(void)
*/
static inline void rte_wmb(void)
{
- dmb(ishst);
+ dsb(st);
}
/**
@@ -78,7 +79,7 @@ static inline void rte_wmb(void)
*/
static inline void rte_rmb(void)
{
- dmb(ishld);
+ dsb(ld);
}
#define rte_smp_mb() rte_mb()
--
2.5.5
^ permalink raw reply related
* [PATCH 00/28] introduce I/O device memory read/write operations
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
Based on the disussion in the below-mentioned thread,
http://dev.dpdk.narkive.com/DpIRqDuy/dpdk-dev-patch-v2-i40e-fix-eth-i40e-dev-init-sequence-on-thunderx
This patchset introduces 8-bit, 16-bit, 32bit, 64bit I/O device
memory read/write operations along with the relaxed versions.
The weakly-ordered machine like ARM needs additional I/O barrier for
device memory read/write access over PCI bus.
By introducing the eal abstraction for I/O device memory read/write access,
The drivers can access I/O device memory in architecture-agnostic manner.
The relaxed version does not have additional I/O memory barrier, useful in
accessing the device registers of integrated controllers which
implicitly strongly ordered with respect to memory access.
This patchset split into three functional set:
patchset 1-9: Introduce I/O device memory barrier eal abstraction and
implement it for all the architectures.
patchset 10-13: Introduce I/O device memory read/write operations eal abstraction
and implement it for all the architectures using previoud I/O device memory
barrier.
patchset 14-28: Replace the raw readl/writel in the drivers with
new rte_read[b/w/l/q], rte_write[b/w/l/q] eal abstraction
Note:
1) We couldn't test the patch on all the Hardwares due to unavailability.
Appreciate the feedback from ARCH and PMD maintainers.
2) patch 13/28 has flase positive check patch error with asm syntax
ERROR:BRACKET_SPACE: space prohibited before open square bracket '['
#92: FILE: lib/librte_eal/common/include/arch/arm/rte_io_64.h:54:
+ : [val] "=r" (val)
Jerin Jacob (14):
eal: introduce I/O device memory barriers
eal/x86: define I/O device memory barriers for IA
eal/tile: define I/O device memory barriers for tile
eal/ppc64: define I/O device memory barriers for ppc64
eal/arm: separate smp barrier definition for ARMv7 and ARMv8
eal/armv7: define I/O device memory barriers for ARMv7
eal/arm64: fix memory barrier definition for arm64
eal/arm64: define smp barrier definition for arm64
eal/arm64: define I/O device memory barriers for arm64
eal: introduce I/O device memory read/write operations
eal: generic implementation for I/O device read/write access
eal: let all architectures use generic I/O implementation
eal/arm64: override I/O device read/write access for arm64
net/thunderx: use eal I/O device memory read/write API
Santosh Shukla (14):
crypto/qat: use eal I/O device memory read/write API
net/bnx2x: use eal I/O device memory read/write API
net/bnxt: use eal I/O device memory read/write API
net/cxgbe: use eal I/O device memory read/write API
net/e1000: use eal I/O device memory read/write API
net/ena: use eal I/O device memory read/write API
net/enic: use eal I/O device memory read/write API
net/fm10k: use eal I/O device memory read/write API
net/i40e: use eal I/O device memory read/write API
net/ixgbe: use eal I/O device memory read/write API
net/nfp: use eal I/O device memory read/write API
net/qede: use eal I/O device memory read/write API
net/virtio: use eal I/O device memory read/write API
net/vmxnet3: use eal I/O device memory read/write API
doc/api/doxy-api-index.md | 3 +-
.../qat/qat_adf/adf_transport_access_macros.h | 15 +-
drivers/net/bnx2x/bnx2x.h | 32 +--
drivers/net/bnxt/bnxt_hwrm.c | 8 +-
drivers/net/cxgbe/base/adapter.h | 13 +-
drivers/net/cxgbe/cxgbe_compat.h | 3 +-
drivers/net/e1000/base/e1000_osdep.h | 25 +-
drivers/net/ena/base/ena_plat_dpdk.h | 5 +-
drivers/net/enic/enic_compat.h | 17 +-
drivers/net/fm10k/base/fm10k_osdep.h | 27 +-
drivers/net/i40e/base/i40e_osdep.h | 14 +-
drivers/net/ixgbe/base/ixgbe_osdep.h | 13 +-
drivers/net/nfp/nfp_net_pmd.h | 9 +-
drivers/net/qede/base/bcm_osal.h | 18 +-
drivers/net/thunderx/base/nicvf_plat.h | 45 +--
drivers/net/virtio/virtio_pci.c | 14 +-
drivers/net/vmxnet3/vmxnet3_ethdev.h | 14 +-
lib/librte_eal/common/Makefile | 3 +-
.../common/include/arch/arm/rte_atomic.h | 6 -
.../common/include/arch/arm/rte_atomic_32.h | 12 +
.../common/include/arch/arm/rte_atomic_64.h | 21 +-
lib/librte_eal/common/include/arch/arm/rte_io.h | 51 ++++
lib/librte_eal/common/include/arch/arm/rte_io_64.h | 183 ++++++++++++
.../common/include/arch/ppc_64/rte_atomic.h | 6 +
lib/librte_eal/common/include/arch/ppc_64/rte_io.h | 47 +++
.../common/include/arch/tile/rte_atomic.h | 6 +
lib/librte_eal/common/include/arch/tile/rte_io.h | 47 +++
.../common/include/arch/x86/rte_atomic.h | 6 +
lib/librte_eal/common/include/arch/x86/rte_io.h | 47 +++
lib/librte_eal/common/include/generic/rte_atomic.h | 27 ++
lib/librte_eal/common/include/generic/rte_io.h | 317 +++++++++++++++++++++
31 files changed, 928 insertions(+), 126 deletions(-)
create mode 100644 lib/librte_eal/common/include/arch/arm/rte_io.h
create mode 100644 lib/librte_eal/common/include/arch/arm/rte_io_64.h
create mode 100644 lib/librte_eal/common/include/arch/ppc_64/rte_io.h
create mode 100644 lib/librte_eal/common/include/arch/tile/rte_io.h
create mode 100644 lib/librte_eal/common/include/arch/x86/rte_io.h
create mode 100644 lib/librte_eal/common/include/generic/rte_io.h
--
2.5.5
^ permalink raw reply
* [PATCH 01/28] eal: introduce I/O device memory barriers
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
This commit introduce rte_io_mb(), rte_io_wmb() and rte_io_rmb(), in
order to enable memory barriers between I/O device and CPU.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
lib/librte_eal/common/include/generic/rte_atomic.h | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 43a704e..7b81705 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -100,6 +100,33 @@ static inline void rte_smp_wmb(void);
*/
static inline void rte_smp_rmb(void);
+/**
+ * General memory barrier for I/O device
+ *
+ * Guarantees that the LOAD and STORE operations that precede the
+ * rte_io_mb() call are visible to I/O device or CPU before the
+ * LOAD and STORE operations that follow it.
+ */
+static inline void rte_io_mb(void);
+
+/**
+ * Write memory barrier for I/O device
+ *
+ * Guarantees that the STORE operations that precede the
+ * rte_io_wmb() call are visible to I/O device before the STORE
+ * operations that follow it.
+ */
+static inline void rte_io_wmb(void);
+
+/**
+ * Read memory barrier for IO device
+ *
+ * Guarantees that the LOAD operations on I/O device that precede the
+ * rte_io_rmb() call are visible to CPU before the LOAD
+ * operations that follow it.
+ */
+static inline void rte_io_rmb(void);
+
#endif /* __DOXYGEN__ */
/**
--
2.5.5
^ permalink raw reply related
* [PATCH 03/28] eal/tile: define I/O device memory barriers for tile
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob, Zhigang Lu
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
The patch does not provide any functional change for tile.
I/O barriers are mapped to existing smp barriers.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
CC: Zhigang Lu <zlu@ezchip.com>
---
lib/librte_eal/common/include/arch/tile/rte_atomic.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/librte_eal/common/include/arch/tile/rte_atomic.h b/lib/librte_eal/common/include/arch/tile/rte_atomic.h
index 28825ff..1f332ee 100644
--- a/lib/librte_eal/common/include/arch/tile/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/tile/rte_atomic.h
@@ -85,6 +85,12 @@ static inline void rte_rmb(void)
#define rte_smp_rmb() rte_compiler_barrier()
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_compiler_barrier()
+
+#define rte_io_rmb() rte_compiler_barrier()
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply related
* [PATCH 04/28] eal/ppc64: define I/O device memory barriers for ppc64
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob, Chao Zhu
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
The patch does not provide any functional change for ppc_64.
I/O barriers are mapped to existing smp barriers.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
CC: Chao Zhu <chaozhu@linux.vnet.ibm.com>
---
lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h b/lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h
index fb4fccb..150810c 100644
--- a/lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h
@@ -87,6 +87,12 @@ extern "C" {
#define rte_smp_rmb() rte_rmb()
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_wmb()
+
+#define rte_io_rmb() rte_rmb()
+
/*------------------------- 16 bit atomic operations -------------------------*/
/* To be compatible with Power7, use GCC built-in functions for 16 bit
* operations */
--
2.5.5
^ permalink raw reply related
* [PATCH 05/28] eal/arm: separate smp barrier definition for ARMv7 and ARMv8
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
Separate the smp barrier definition for arm and arm64 for fine
control on smp barrier definition for each architecture.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
lib/librte_eal/common/include/arch/arm/rte_atomic.h | 6 ------
lib/librte_eal/common/include/arch/arm/rte_atomic_32.h | 6 ++++++
lib/librte_eal/common/include/arch/arm/rte_atomic_64.h | 6 ++++++
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic.h b/lib/librte_eal/common/include/arch/arm/rte_atomic.h
index 454a12b..f3f3b6e 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic.h
@@ -39,10 +39,4 @@
#include <rte_atomic_32.h>
#endif
-#define rte_smp_mb() rte_mb()
-
-#define rte_smp_wmb() rte_wmb()
-
-#define rte_smp_rmb() rte_rmb()
-
#endif /* _RTE_ATOMIC_ARM_H_ */
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
index 9ae1e78..dd627a0 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
@@ -67,6 +67,12 @@ extern "C" {
*/
#define rte_rmb() __sync_synchronize()
+#define rte_smp_mb() rte_mb()
+
+#define rte_smp_wmb() rte_wmb()
+
+#define rte_smp_rmb() rte_rmb()
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 671caa7..d854aac 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -81,6 +81,12 @@ static inline void rte_rmb(void)
dmb(ishld);
}
+#define rte_smp_mb() rte_mb()
+
+#define rte_smp_wmb() rte_wmb()
+
+#define rte_smp_rmb() rte_rmb()
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply related
* [PATCH 02/28] eal/x86: define I/O device memory barriers for IA
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
The patch does not provide any functional change for IA.
I/O barriers are mapped to existing smp barriers.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
CC: Bruce Richardson <bruce.richardson@intel.com>
CC: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_eal/common/include/arch/x86/rte_atomic.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic.h b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
index 00b1cdf..4eac666 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
@@ -61,6 +61,12 @@ extern "C" {
#define rte_smp_rmb() rte_compiler_barrier()
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_compiler_barrier()
+
+#define rte_io_rmb() rte_compiler_barrier()
+
/*------------------------- 16 bit atomic operations -------------------------*/
#ifndef RTE_FORCE_INTRINSICS
--
2.5.5
^ permalink raw reply related
* [PATCH 06/28] eal/armv7: define I/O device memory barriers for ARMv7
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
The patch does not provide any functional change for ARMv7.
I/O barriers are mapped to existing smp barriers.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
CC: Jan Viktorin <viktorin@rehivetech.com>
CC: Jianbo Liu <jianbo.liu@linaro.org>
---
lib/librte_eal/common/include/arch/arm/rte_atomic_32.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
index dd627a0..14c0486 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_32.h
@@ -73,6 +73,12 @@ extern "C" {
#define rte_smp_rmb() rte_rmb()
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_wmb()
+
+#define rte_io_rmb() rte_rmb()
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply related
* [PATCH 08/28] eal/arm64: define smp barrier definition for arm64
From: Jerin Jacob @ 2016-12-14 1:55 UTC (permalink / raw)
To: dev
Cc: konstantin.ananyev, thomas.monjalon, bruce.richardson, jianbo.liu,
viktorin, Jerin Jacob
In-Reply-To: <1481680558-4003-1-git-send-email-jerin.jacob@caviumnetworks.com>
dmb instruction based barrier is used for smp version of memory barrier.
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
lib/librte_eal/common/include/arch/arm/rte_atomic_64.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index bc7de64..78ebea2 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -82,11 +82,11 @@ static inline void rte_rmb(void)
dsb(ld);
}
-#define rte_smp_mb() rte_mb()
+#define rte_smp_mb() dmb(ish)
-#define rte_smp_wmb() rte_wmb()
+#define rte_smp_wmb() dmb(ishst)
-#define rte_smp_rmb() rte_rmb()
+#define rte_smp_rmb() dmb(ishld)
#ifdef __cplusplus
}
--
2.5.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox