aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-dpdk/odp_packet_dpdk.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-dpdk/odp_packet_dpdk.c')
-rw-r--r--platform/linux-dpdk/odp_packet_dpdk.c128
1 files changed, 88 insertions, 40 deletions
diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c
index 238f733cd..c4fa3f0b7 100644
--- a/platform/linux-dpdk/odp_packet_dpdk.c
+++ b/platform/linux-dpdk/odp_packet_dpdk.c
@@ -127,6 +127,9 @@ typedef struct {
typedef struct ODP_ALIGNED_CACHE {
/* --- Fast path data --- */
+ /* Function for mbuf to ODP packet conversion */
+ int (*mbuf_to_pkt_fn)(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], uint16_t num);
+
/* DPDK port identifier */
uint16_t port_id;
struct {
@@ -187,6 +190,11 @@ extern void *pktio_entry_ptr[ODP_CONFIG_PKTIO_ENTRIES];
static uint32_t mtu_get_pkt_dpdk(pktio_entry_t *pktio_entry);
+static inline int input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], uint16_t num);
+
+static inline int input_pkts_minimal(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
+ uint16_t num);
+
uint16_t _odp_dpdk_pktio_port_id(pktio_entry_t *pktio_entry)
{
const pkt_dpdk_t *pkt_dpdk = pkt_priv(pktio_entry);
@@ -901,6 +909,12 @@ static int dpdk_start(pktio_entry_t *pktio_entry)
}
}
+ /* Use simpler function when packet parsing and classifying are not required */
+ if (pktio_entry->parse_layer == ODP_PROTO_LAYER_NONE)
+ pkt_dpdk->mbuf_to_pkt_fn = input_pkts_minimal;
+ else
+ pkt_dpdk->mbuf_to_pkt_fn = input_pkts;
+
/* Start device */
ret = rte_eth_dev_start(port_id);
if (ret < 0) {
@@ -929,19 +943,60 @@ static inline void prefetch_pkt(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- odp_prefetch(&pkt_hdr->p);
+ odp_prefetch_store(&pkt_hdr->p);
}
-static inline int input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], int num)
+/**
+ * Input packets when packet parsing and classifier are disabled
+ */
+static inline int input_pkts_minimal(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
+ uint16_t num)
{
uint16_t i;
- uint16_t num_pkts = 0;
- odp_pktin_config_opt_t pktin_cfg = pktio_entry->config.pktin;
- odp_pktio_t input = pktio_entry->handle;
odp_time_t ts_val;
odp_time_t *ts = NULL;
- uint16_t num_prefetch = RTE_MIN(num, NUM_RX_PREFETCH);
+ const uint8_t ts_ena = (pktio_entry->config.pktin.bit.ts_all ||
+ pktio_entry->config.pktin.bit.ts_ptp);
+ const odp_pktio_t input = pktio_entry->handle;
+ const uint16_t num_prefetch = RTE_MIN(num, NUM_RX_PREFETCH);
+
+ for (i = 0; i < num_prefetch; i++)
+ prefetch_pkt(pkt_table[i]);
+
+ if (ts_ena) {
+ ts_val = odp_time_global();
+ ts = &ts_val;
+ }
+
+ for (i = 0; i < num; ++i) {
+ odp_packet_t pkt = pkt_table[i];
+ odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
+
+ if (odp_likely(i + num_prefetch < num))
+ prefetch_pkt(pkt_table[i + num_prefetch]);
+
+ packet_init(pkt_hdr, input);
+
+ packet_set_ts(pkt_hdr, ts);
+ }
+
+ return num;
+}
+
+/**
+ * input packets when packet parsing is required
+ */
+static inline int input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], uint16_t num)
+{
+ uint16_t i;
+ uint16_t num_pkts = 0, num_cls = 0;
+ odp_time_t ts_val;
+ odp_time_t *ts = NULL;
+ const odp_pktin_config_opt_t pktin_cfg = pktio_entry->config.pktin;
+ const odp_pktio_t input = pktio_entry->handle;
const odp_proto_layer_t layer = pktio_entry->parse_layer;
+ const int cls_enabled = pktio_cls_enabled(pktio_entry);
+ const uint16_t num_prefetch = RTE_MIN(num, NUM_RX_PREFETCH);
for (i = 0; i < num_prefetch; i++)
prefetch_pkt(pkt_table[i]);
@@ -955,47 +1010,34 @@ static inline int input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[
odp_packet_t pkt = pkt_table[i];
odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
struct rte_mbuf *mbuf = pkt_to_mbuf(pkt);
+ int ret;
if (odp_likely(i + num_prefetch < num))
prefetch_pkt(pkt_table[i + num_prefetch]);
packet_init(pkt_hdr, input);
- if (layer != ODP_PROTO_LAYER_NONE) {
- int ret;
-
- ret = _odp_dpdk_packet_parse_common(pkt_hdr,
- rte_pktmbuf_mtod(mbuf, uint8_t *),
- rte_pktmbuf_pkt_len(mbuf),
- rte_pktmbuf_data_len(mbuf),
- mbuf, layer, pktin_cfg);
- if (odp_unlikely(ret)) {
- odp_atomic_inc_u64(&pktio_entry->stats_extra.in_errors);
+ ret = _odp_dpdk_packet_parse_common(pkt_hdr,
+ rte_pktmbuf_mtod(mbuf, uint8_t *),
+ rte_pktmbuf_pkt_len(mbuf),
+ rte_pktmbuf_data_len(mbuf),
+ mbuf, layer, pktin_cfg);
+ if (odp_unlikely(ret)) {
+ odp_atomic_inc_u64(&pktio_entry->stats_extra.in_errors);
- if (ret < 0) {
- odp_packet_free(pkt);
- continue;
- }
+ if (ret < 0) {
+ odp_packet_free(pkt);
+ continue;
}
-
- if (odp_unlikely(num_pkts != i))
- pkt_table[num_pkts] = pkt;
}
+
packet_set_ts(pkt_hdr, ts);
odp_prefetch(rte_pktmbuf_mtod(mbuf, char *));
- num_pkts++;
- }
-
- if (pktio_cls_enabled(pktio_entry)) {
- int success = 0;
- for (i = 0; i < num_pkts; i++) {
- odp_packet_t pkt = pkt_table[i];
+ if (cls_enabled) {
odp_pool_t new_pool;
uint8_t *data = odp_packet_data(pkt);
- odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- int ret;
ret = _odp_cls_classify_packet(pktio_entry, data, &new_pool, pkt_hdr);
if (odp_unlikely(ret)) {
@@ -1014,23 +1056,29 @@ static inline int input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[
odp_atomic_inc_u64(&pktio_entry->stats_extra.in_discards);
continue;
}
- pkt_table[i] = new_pkt;
pkt = new_pkt;
}
- if (success != i)
- pkt_table[success] = pkt;
- ++success;
+ /* Enqueue packets directly to classifier destination queue */
+ pkt_table[num_cls++] = pkt;
+ num_cls = _odp_cls_enq(pkt_table, num_cls, (i + 1 == num));
+ } else {
+ pkt_table[num_pkts++] = pkt;
}
- num_pkts = success;
}
+ /* Enqueue remaining classified packets */
+ if (odp_unlikely(num_cls))
+ _odp_cls_enq(pkt_table, num_cls, true);
+
return num_pkts;
}
int _odp_input_pkts(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], int num)
{
- return input_pkts(pktio_entry, pkt_table, num);
+ pkt_dpdk_t * const pkt_dpdk = pkt_priv(pktio_entry);
+
+ return pkt_dpdk->mbuf_to_pkt_fn(pktio_entry, pkt_table, num);
}
static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index,
@@ -1071,10 +1119,10 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index,
odp_ticketlock_unlock(&pkt_dpdk->rx_lock[index]);
/* Packets may also me received through eventdev, so don't add any
- * processing here. Instead, perform all processing in input_pkts()
+ * processing here. Instead, perform all processing in mbuf_to_pkt_fn()
* which is also called by eventdev. */
if (nb_rx)
- return input_pkts(pktio_entry, pkt_table, nb_rx);
+ return pkt_dpdk->mbuf_to_pkt_fn(pktio_entry, pkt_table, nb_rx);
return 0;
}