From: Xiao Wang Date: Mon, 4 Jul 2016 07:51:08 +0000 (+0800) Subject: net/fm10k: fix Rx descriptor read timing X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=af15ee640dfe2b45f1358638d41037e82604be4a;p=dpdk.git net/fm10k: fix Rx descriptor read timing We find that when traffic is light, a small number of packets will have wrong metadata (e.g. packet type), however this issue will not happen when traffic is heavy. The root cause is some fields in fm10k_rx_desc are read at the wrong time, since the descriptor (being 16-bytes big) is not read as a single atomic operation. When the input speed is slower than software's capability, fm10k scalar Rx function accesses descriptors at about the same time as HW writes them, so the scenario can occur: some fields like pkt_info in fm10k_rx_desc are read before HW writeback but some fields like DD bit are read after HW writeback, this will lead to the later packet parsing function using incorrect value. This patch fixes this issue by reading and parsing Rx descriptor only after first checking that the DD bit is set. Fixes: 4b61d3bfa941 ("fm10k: add receive and tranmit") Fixes: c82dd0a7bfa5 ("fm10k: add scatter receive") Signed-off-by: Wang Xiao W Acked-by: Bruce Richardson --- diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c index dd92a91e20..5b2d04bf58 100644 --- a/drivers/net/fm10k/fm10k_rxtx.c +++ b/drivers/net/fm10k/fm10k_rxtx.c @@ -114,10 +114,10 @@ fm10k_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, nb_pkts = RTE_MIN(nb_pkts, q->alloc_thresh); for (count = 0; count < nb_pkts; ++count) { + if (!(q->hw_ring[next_dd].d.staterr & FM10K_RXD_STATUS_DD)) + break; mbuf = q->sw_ring[next_dd]; desc = q->hw_ring[next_dd]; - if (!(desc.d.staterr & FM10K_RXD_STATUS_DD)) - break; #ifdef RTE_LIBRTE_FM10K_DEBUG_RX dump_rxd(&desc); #endif @@ -228,10 +228,10 @@ fm10k_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, nb_seg = RTE_MIN(nb_pkts, q->alloc_thresh); for (count = 0; count < nb_seg; count++) { + if (!(q->hw_ring[next_dd].d.staterr & FM10K_RXD_STATUS_DD)) + break; mbuf = q->sw_ring[next_dd]; desc = q->hw_ring[next_dd]; - if (!(desc.d.staterr & FM10K_RXD_STATUS_DD)) - break; #ifdef RTE_LIBRTE_FM10K_DEBUG_RX dump_rxd(&desc); #endif