From fccce1ef79294066fc7e3dc5b36c5915573d0e47 Mon Sep 17 00:00:00 2001 From: Xavier Simonart Date: Wed, 26 Dec 2018 15:26:27 +0100 Subject: Prevent dropping ARP packets JIRA: SAMPLEVNF-152 When system is overloaded, ARP packets were sometimes dropped, as any other packets. This was causing two issues: - The count of TX non dataplane packets was wrong - If many consecutive ARP packets were dropped, the underlying switch might see its ARP timer expiring, causing performance degradation (packets being broadcasted). ARP packets are now always sent as no-drop. Change-Id: I9a86cbf8c4b56a178f86bc789153f1fa49ddf73f Signed-off-by: Xavier Simonart --- VNFs/DPPD-PROX/packet_utils.c | 5 +++-- VNFs/DPPD-PROX/task_base.h | 1 + VNFs/DPPD-PROX/task_init.c | 19 ++++++++----------- VNFs/DPPD-PROX/tx_pkt.c | 33 +++++++++++++++++++++++++++++++++ VNFs/DPPD-PROX/tx_pkt.h | 2 ++ 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c index e93f430c..274d2f84 100644 --- a/VNFs/DPPD-PROX/packet_utils.c +++ b/VNFs/DPPD-PROX/packet_utils.c @@ -325,9 +325,10 @@ void handle_ctrl_plane_pkts(struct task_base *tbase, struct rte_mbuf **mbufs, ui break; case ARP_REPLY_FROM_CTRL: case ARP_REQ_FROM_CTRL: - TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1); out[0] = 0; - tbase->aux->tx_pkt_l2(tbase, &mbufs[j], 1, out); + // tx_ctrlplane_pkt does not drop packets + tbase->aux->tx_ctrlplane_pkt(tbase, &mbufs[j], 1, out); + TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1); break; } } diff --git a/VNFs/DPPD-PROX/task_base.h b/VNFs/DPPD-PROX/task_base.h index b4a33372..64d17436 100644 --- a/VNFs/DPPD-PROX/task_base.h +++ b/VNFs/DPPD-PROX/task_base.h @@ -174,6 +174,7 @@ struct task_base_aux { int (*tx_pkt_hw)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out); uint16_t (*tx_pkt_try)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts); void (*stop)(struct task_base *tbase); + int (*tx_ctrlplane_pkt)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out); void (*start)(struct task_base *tbase); void (*stop_last)(struct task_base *tbase); void (*start_first)(struct task_base *tbase); diff --git a/VNFs/DPPD-PROX/task_init.c b/VNFs/DPPD-PROX/task_init.c index 2361d32c..08ccaf97 100644 --- a/VNFs/DPPD-PROX/task_init.c +++ b/VNFs/DPPD-PROX/task_init.c @@ -208,7 +208,7 @@ static size_t init_rx_tx_rings_ports(struct task_args *targ, struct task_base *t if ((targ->nb_txrings != 0) && (!targ->tx_opt_ring) && (!(targ->flags & TASK_ARG_DROP))) { // Transmitting to a ring in NO DROP. We need to make sure the receiving task in not running on the same core. // Otherwise we might end up in a dead lock: trying in a loop to transmit to a task which cannot receive anymore - // (as npt being scheduled). + // (as not being scheduled). struct core_task ct; struct task_args *dtarg; for (unsigned int j = 0; j < targ->nb_txrings; j++) { @@ -277,6 +277,7 @@ static size_t init_rx_tx_rings_ports(struct task_args *targ, struct task_base *t prev = prev->tx_opt_ring_task; } } + if (targ->nb_txrings == 1 || targ->nb_txports == 1 || targ->tx_opt_ring) { if (targ->task_init->flag_features & TASK_FEATURE_NEVER_DISCARDS) { if (targ->tx_opt_ring) { @@ -350,13 +351,6 @@ struct task_base *init_task_struct(struct task_args *targ) offset = init_rx_tx_rings_ports(targ, tbase, offset); tbase->aux = (struct task_base_aux *)(((uint8_t *)tbase) + offset); - if (targ->nb_txports != 0) { - if (targ->flags & TASK_ARG_L3) { - tbase->aux->tx_pkt_l2 = tbase->tx_pkt; - tbase->tx_pkt = tx_pkt_l3; - } - } - if (targ->task_init->flag_features & TASK_FEATURE_RX_ALL) { task_base_add_rx_pkt_function(tbase, rx_pkt_all); tbase->aux->all_mbufs = prox_zmalloc(MAX_RX_PKT_ALL * sizeof(* tbase->aux->all_mbufs), task_socket); @@ -372,10 +366,13 @@ struct task_base *init_task_struct(struct task_args *targ) if (targ->flags & TASK_ARG_L3) { plog_info("\tTask configured in L3 mode\n"); tbase->l3.ctrl_plane_ring = targ->ctrl_plane_ring; - } - if (targ->nb_txports != 0) { - if (targ->flags & TASK_ARG_L3) + if (targ->nb_txports != 0) { + tbase->aux->tx_pkt_l2 = tbase->tx_pkt; + tbase->tx_pkt = tx_pkt_l3; + // Make sure control plane packets such as arp are not dropped + tbase->aux->tx_ctrlplane_pkt = targ->nb_txrings ? tx_ctrlplane_sw : tx_ctrlplane_hw; task_init_l3(tbase, targ); + } } targ->tbase = tbase; diff --git a/VNFs/DPPD-PROX/tx_pkt.c b/VNFs/DPPD-PROX/tx_pkt.c index c5047e56..d494236c 100644 --- a/VNFs/DPPD-PROX/tx_pkt.c +++ b/VNFs/DPPD-PROX/tx_pkt.c @@ -762,6 +762,39 @@ int tx_pkt_drop_all(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n } return n_pkts; } +static inline void dump_pkts(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts) +{ + uint32_t n_dump = tbase->aux->task_rt_dump.n_print_tx; + uint32_t n_trace = tbase->aux->task_rt_dump.n_trace; + + if (unlikely(n_dump)) { + n_dump = n_pkts < n_dump? n_pkts : n_dump; + for (uint32_t i = 0; i < n_dump; ++i) { + plogdx_info(mbufs[i], "TX: "); + } + tbase->aux->task_rt_dump.n_print_tx -= n_dump; + } else if (unlikely(n_trace)) { + n_trace = n_pkts < n_trace? n_pkts : n_trace; + for (uint32_t i = 0; i < n_trace; ++i) { + plogdx_info(mbufs[i], "TX: "); + } + tbase->aux->task_rt_dump.n_trace - n_trace; + } +} + +// ctrlplane packets are slow path, hence cost of checking if dump ortrace is needed in not too important +// easier to have this implementation than an implementation similar to dataplane tx +int tx_ctrlplane_hw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, __attribute__((unused)) uint8_t *out) +{ + dump_pkts(tbase, mbufs, n_pkts); + return txhw_no_drop(&tbase->tx_params_hw.tx_port_queue[0], mbufs, n_pkts, tbase); +} + +int tx_ctrlplane_sw(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, __attribute__((unused)) uint8_t *out) +{ + dump_pkts(tbase, mbufs, n_pkts); + return ring_enq_no_drop(tbase->tx_params_sw.tx_rings[0], mbufs, n_pkts, tbase); +} static inline int tx_ring_all(struct task_base *tbase, struct rte_ring *ring, uint16_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, uint32_t ip) { diff --git a/VNFs/DPPD-PROX/tx_pkt.h b/VNFs/DPPD-PROX/tx_pkt.h index e8caed52..a6881531 100644 --- a/VNFs/DPPD-PROX/tx_pkt.h +++ b/VNFs/DPPD-PROX/tx_pkt.h @@ -64,6 +64,8 @@ int tx_pkt_no_drop_hw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t int tx_pkt_no_drop_sw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); int tx_pkt_hw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); int tx_pkt_sw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); +int tx_ctrlplane_hw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); +int tx_ctrlplane_sw(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); int tx_pkt_trace(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); int tx_pkt_dump(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out); -- cgit 1.2.3-korg