From patchwork Fri Dec 4 01:05:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 9330 X-Patchwork-Delegate: bruce.richardson@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id AB8AE5A6C; Fri, 4 Dec 2015 02:05:00 +0100 (CET) Received: from mail-pa0-f50.google.com (mail-pa0-f50.google.com [209.85.220.50]) by dpdk.org (Postfix) with ESMTP id 4885A568A for ; Fri, 4 Dec 2015 02:04:59 +0100 (CET) Received: by pacdm15 with SMTP id dm15so77707103pac.3 for ; Thu, 03 Dec 2015 17:04:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XxJhsn31vXQB/TzyQ4hXmtpRu1PNbRC9rbK0Ef5V87k=; b=ejHWurcHUD4tP0VT66O4DJNpngD7PQUZRwOaZC4m3U10my+WM765nXxPGcEzT/ajMm 939eoTRhbLxPs1zBHK9bAvDdjO9ix1M3pdMB46n54hIca6rBOZPrRJlT7aCMK3I4+xwJ YuYYiLzjT9JzTS5w6ZKoOGhBlQVjMk3eHd28PCIrtaoR9i5d4paleCi0iwtviiowS/EF lEWoyOURMFiDXIX+hZof1asbxc/QEf3+A0vcWrA6IdubAF4ItgMFcdl6o+roAUEKOPuF tJLrcO8h3/POGFqhznSqpw9BulgVdtFhGFksw0tT+AnvLK11LyA0d0QCftQ8nl/tTmW3 UziQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XxJhsn31vXQB/TzyQ4hXmtpRu1PNbRC9rbK0Ef5V87k=; b=PHFgsrgaU554KrLWOnjnFChFu5gUocSRHP8eN0kP0ehHLhTE2wIHM5mQ7J+Fpq5s27 Icv4fJe+PaxCuMHVARYwT4EGybXZJaqYKn1cI9KAaeEGUCfyp6gEqZtCq43xKU9WSm5I ncHt8n32KFk3pN4kb48pGgoqTe2bACtBHY5PGYd6pldMAYbvhOYBM6tTpk+WGh2vGHts ZIcTUjTI4K6NBhMwzIndGG59KyydwW41N7nYV1V7Z3E+TIujqFDZ7bsQmx4QxkLyVqLK gelZSxYVekzaAEyu2NYyY2dxlLP6TbIEntsGEEiITBJmgfI0Uj3YT6cPalIEPN3VbQ3Q U7ZQ== X-Gm-Message-State: ALoCoQm2+19S3sp1pblmaiQMQUyHLxskzTvfmbLI4XqDO7uSZUI8IOSDLLFO6vZ+JFp4fxLZs5z1 X-Received: by 10.66.227.231 with SMTP id sd7mr17854250pac.60.1449191098640; Thu, 03 Dec 2015 17:04:58 -0800 (PST) Received: from xeon-e3.home.lan (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by smtp.gmail.com with ESMTPSA id 6sm13060124pfm.58.2015.12.03.17.04.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 Dec 2015 17:04:57 -0800 (PST) From: Stephen Hemminger To: yongwang@vmware.com Date: Thu, 3 Dec 2015 17:05:05 -0800 Message-Id: <1449191107-14222-2-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1449191107-14222-1-git-send-email-stephen@networkplumber.org> References: <1449191107-14222-1-git-send-email-stephen@networkplumber.org> Cc: dev@dpdk.org, Stephen Hemminger Subject: [dpdk-dev] [PATCH 1/3] vmxnet3: support mult-segment receive X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Stephen Hemminger The vmxnet3 interface specification supports having multiple receive rings. The first ring has buffers of BTYPE_HEAD which are used for the start of the packet, the second ring has buffers of type BTYPE_BODY which are used only if the received packet exceeds the available space of the head buffer. There can zero or more body buffers for one packet. What the driver does is post mbuf's to both rings. If a jumbo frame is received; then a multi-segment mbuf is created and this is returned. The previous version of the driver was filling both rings, but the second ring was never used. It would error out if it ever received a multi-segment mbuf. The logic is very similar to existing methods used in other OS's. This patch has been used internally by several companies and users for several releases and tested with Jumbo frames. Signed-off-by: Stephen Hemminger --- drivers/net/vmxnet3/vmxnet3_ring.h | 2 + drivers/net/vmxnet3/vmxnet3_rxtx.c | 78 +++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_ring.h b/drivers/net/vmxnet3/vmxnet3_ring.h index 612487e..55ceadf 100644 --- a/drivers/net/vmxnet3/vmxnet3_ring.h +++ b/drivers/net/vmxnet3/vmxnet3_ring.h @@ -171,6 +171,8 @@ typedef struct vmxnet3_rx_queue { uint32_t qid1; uint32_t qid2; Vmxnet3_RxQueueDesc *shared; + struct rte_mbuf *start_seg; + struct rte_mbuf *last_seg; struct vmxnet3_rxq_stats stats; bool stopped; uint16_t queue_id; /**< Device RX queue index. */ diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c index 4de5d89..00980a5 100644 --- a/drivers/net/vmxnet3/vmxnet3_rxtx.c +++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c @@ -575,35 +575,11 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx; rbi = rxq->cmd_ring[ring_idx].buf_info + idx; - if (unlikely(rcd->sop != 1 || rcd->eop != 1)) { - rte_pktmbuf_free_seg(rbi->m); - PMD_RX_LOG(DEBUG, "Packet spread across multiple buffers\n)"); - goto rcd_done; - } - PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx); VMXNET3_ASSERT(rcd->len <= rxd->len); VMXNET3_ASSERT(rbi->m); - if (unlikely(rcd->len == 0)) { - PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)", - ring_idx, idx); - VMXNET3_ASSERT(rcd->sop && rcd->eop); - rte_pktmbuf_free_seg(rbi->m); - goto rcd_done; - } - - /* Assuming a packet is coming in a single packet buffer */ - if (unlikely(rxd->btype != VMXNET3_RXD_BTYPE_HEAD)) { - PMD_RX_LOG(DEBUG, - "Alert : Misbehaving device, incorrect " - " buffer type used. iPacket dropped."); - rte_pktmbuf_free_seg(rbi->m); - goto rcd_done; - } - VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD); - /* Get the packet buffer pointer from buf_info */ rxm = rbi->m; @@ -615,7 +591,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) rxq->cmd_ring[ring_idx].next2comp = idx; /* For RCD with EOP set, check if there is frame error */ - if (unlikely(rcd->err)) { + if (unlikely(rcd->eop && rcd->err)) { rxq->stats.drop_total++; rxq->stats.drop_err++; @@ -641,9 +617,45 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) rxm->ol_flags = 0; rxm->vlan_tci = 0; - vmxnet3_rx_offload(rcd, rxm); + /* + * If this is the first buffer of the received packet, + * set the pointer to the first mbuf of the packet + * Otherwise, update the total length and the number of segments + * of the current scattered packet, and update the pointer to + * the last mbuf of the current packet. + */ + if (rcd->sop) { + VMXNET3_ASSERT(!rxq->start_seg); + VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD); + + if (unlikely(rcd->len == 0)) { + PMD_RX_LOG(DEBUG, + "Rx buf was skipped. rxring[%d][%d])", + ring_idx, idx); + rte_pktmbuf_free_seg(rxm); + goto rcd_done; + } + + rxq->start_seg = rxm; + vmxnet3_rx_offload(rcd, rxm); + } else { + struct rte_mbuf *start = rxq->start_seg; + + VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY); + VMXNET3_ASSERT(start != NULL); + + start->pkt_len += rxm->data_len; + start->nb_segs++; + + rxq->last_seg->next = rxm; + } + rxq->last_seg = rxm; + + if (rcd->eop) { + rx_pkts[nb_rx++] = rxq->start_seg; + rxq->start_seg = NULL; + } - rx_pkts[nb_rx++] = rxm; rcd_done: rxq->cmd_ring[ring_idx].next2comp = idx; VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp, rxq->cmd_ring[ring_idx].size); @@ -812,20 +824,9 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev, int size; uint8_t i; char mem_name[32]; - uint16_t buf_size; PMD_INIT_FUNC_TRACE(); - buf_size = rte_pktmbuf_data_room_size(mp) - - RTE_PKTMBUF_HEADROOM; - - if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) { - PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, " - "VMXNET3 don't support scatter packets yet", - buf_size, dev->data->dev_conf.rxmode.max_rx_pkt_len); - return -EINVAL; - } - rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue), RTE_CACHE_LINE_SIZE); if (rxq == NULL) { PMD_INIT_LOG(ERR, "Can not allocate rx queue structure"); @@ -944,6 +945,7 @@ vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev) } } rxq->stopped = FALSE; + rxq->start_seg = NULL; } for (i = 0; i < dev->data->nb_tx_queues; i++) {