Skip to content

Commit

Permalink
net/memif: fix chained mbuf determination
Browse files Browse the repository at this point in the history
[ upstream commit 3e3f736 ]

Previously, TX functions call rte_pktmbuf_is_contiguous to determine
whether an mbuf is chained. However, rte_pktmbuf_is_contiguous is
designed to work on the first mbuf of a packet only. In case a packet
contains three or more segment mbufs in a chain, it may cause truncated
packets or rte_mbuf_sanity_check panics.

This patch updates TX functions to determine chained mbufs using
mbuf_head->nb_segs field, which works in all cases. Moreover, it
maintains that the second cacheline is only accessed when chained mbuf
is actually present.

Fixes: 09c7e63 ("net/memif: introduce memory interface PMD")
Fixes: 43b815d ("net/memif: support zero-copy slave")

Signed-off-by: Junxiao Shi <git@mail1.yoursunny.com>
Reviewed-by: Jakub Grajciar <jgrajcia@cisco.com>
  • Loading branch information
yoursunny authored and cpaelzer committed Nov 30, 2021
1 parent 9228c06 commit 3312677
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/net/memif/rte_eth_memif.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ memif_dev_info(struct rte_eth_dev *dev __rte_unused, struct rte_eth_dev_info *de
dev_info->max_rx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS;
dev_info->max_tx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS;
dev_info->min_rx_bufsize = 0;
dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS;

return 0;
}
Expand Down Expand Up @@ -540,7 +541,7 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
rte_eth_devices[mq->in_port].process_private;
memif_ring_t *ring = memif_get_ring_from_queue(proc_private, mq);
uint16_t slot, saved_slot, n_free, ring_size, mask, n_tx_pkts = 0;
uint16_t src_len, src_off, dst_len, dst_off, cp_len;
uint16_t src_len, src_off, dst_len, dst_off, cp_len, nb_segs;
memif_ring_type_t type = mq->type;
memif_desc_t *d0;
struct rte_mbuf *mbuf;
Expand Down Expand Up @@ -588,6 +589,7 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)

while (n_tx_pkts < nb_pkts && n_free) {
mbuf_head = *bufs++;
nb_segs = mbuf_head->nb_segs;
mbuf = mbuf_head;

saved_slot = slot;
Expand Down Expand Up @@ -631,7 +633,7 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
d0->length = dst_off;
}

if (rte_pktmbuf_is_contiguous(mbuf) == 0) {
if (--nb_segs > 0) {
mbuf = mbuf->next;
goto next_in_chain;
}
Expand Down Expand Up @@ -668,6 +670,7 @@ memif_tx_one_zc(struct pmd_process_private *proc_private, struct memif_queue *mq
uint16_t slot, uint16_t n_free)
{
memif_desc_t *d0;
uint16_t nb_segs = mbuf->nb_segs;
int used_slots = 1;

next_in_chain:
Expand All @@ -688,7 +691,7 @@ memif_tx_one_zc(struct pmd_process_private *proc_private, struct memif_queue *mq
d0->flags = 0;

/* check if buffer is chained */
if (rte_pktmbuf_is_contiguous(mbuf) == 0) {
if (--nb_segs > 0) {
if (n_free < 2)
return 0;
/* mark buffer as chained */
Expand Down

0 comments on commit 3312677

Please sign in to comment.