From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.lysator.liu.se (mail.lysator.liu.se [130.236.254.3]) by dpdk.org (Postfix) with ESMTP id C9501239 for ; Tue, 19 Mar 2019 09:13:01 +0100 (CET) Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id 49F9F40008 for ; Tue, 19 Mar 2019 09:13:01 +0100 (CET) Received: by mail.lysator.liu.se (Postfix, from userid 1004) id 36B3440012; Tue, 19 Mar 2019 09:13:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on bernadotte.lysator.liu.se X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,AWL autolearn=disabled version=3.4.1 X-Spam-Score: -1.0 Received: from [192.168.1.59] (host-90-232-144-184.mobileonline.telia.com [90.232.144.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPSA id 0E8F440008; Tue, 19 Mar 2019 09:12:59 +0100 (CET) To: Xiaolong Ye , dev@dpdk.org Cc: Qi Zhang , Karlsson Magnus , Topel Bjorn References: <20190301080947.91086-1-xiaolong.ye@intel.com> <20190319071256.26302-1-xiaolong.ye@intel.com> <20190319071256.26302-6-xiaolong.ye@intel.com> From: =?UTF-8?Q?Mattias_R=c3=b6nnblom?= Message-ID: <6b786b77-f9b6-cb0b-634b-701e92a1c3a2@lysator.liu.se> Date: Tue, 19 Mar 2019 09:12:59 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 In-Reply-To: <20190319071256.26302-6-xiaolong.ye@intel.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV using ClamSMTP Subject: Re: [dpdk-dev] [PATCH v2 5/6] net/af_xdp: enable zero copy X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Mar 2019 08:13:02 -0000 On 2019-03-19 08:12, Xiaolong Ye wrote: > Try to check if external mempool (from rx_queue_setup) is fit for > af_xdp, if it is, it will be registered to af_xdp socket directly and > there will be no packet data copy on Rx and Tx. > > Signed-off-by: Xiaolong Ye > --- > drivers/net/af_xdp/rte_eth_af_xdp.c | 128 ++++++++++++++++++++-------- > 1 file changed, 91 insertions(+), 37 deletions(-) > > diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c > index fc60cb5c5..c22791e51 100644 > --- a/drivers/net/af_xdp/rte_eth_af_xdp.c > +++ b/drivers/net/af_xdp/rte_eth_af_xdp.c > @@ -62,6 +62,7 @@ struct xsk_umem_info { > struct xsk_umem *umem; > struct rte_mempool *mb_pool; > void *buffer; > + uint8_t zc; > }; > > struct pkt_rx_queue { > @@ -76,6 +77,7 @@ struct pkt_rx_queue { > > struct pkt_tx_queue *pair; > uint16_t queue_idx; > + uint8_t zc; > }; > > struct pkt_tx_queue { > @@ -191,17 +193,24 @@ eth_af_xdp_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) > uint32_t len = xsk_ring_cons__rx_desc(rx, idx_rx++)->len; > char *pkt = xsk_umem__get_data(rxq->umem->buffer, addr); > > - mbuf = rte_pktmbuf_alloc(rxq->mb_pool); > - if (mbuf) { > - memcpy(rte_pktmbuf_mtod(mbuf, void*), pkt, len); > + if (rxq->zc) { > + mbuf = addr_to_mbuf(rxq->umem, addr); > rte_pktmbuf_pkt_len(mbuf) = > rte_pktmbuf_data_len(mbuf) = len; > - rx_bytes += len; > bufs[count++] = mbuf; > } else { > - dropped++; > + mbuf = rte_pktmbuf_alloc(rxq->mb_pool); > + if (mbuf) { if (likely(mbuf != NULL)) > + memcpy(rte_pktmbuf_mtod(mbuf, void*), pkt, len); Use rte_memcpy. > + rte_pktmbuf_pkt_len(mbuf) = > + rte_pktmbuf_data_len(mbuf) = len; > + rx_bytes += len; > + bufs[count++] = mbuf; > + } else { > + dropped++; > + } > + rte_pktmbuf_free(addr_to_mbuf(umem, addr)); > } > - rte_pktmbuf_free(addr_to_mbuf(umem, addr)); > } > > xsk_ring_cons__release(rx, rcvd); > @@ -285,22 +294,29 @@ eth_af_xdp_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) > - ETH_AF_XDP_DATA_HEADROOM; > desc = xsk_ring_prod__tx_desc(&txq->tx, idx_tx + i); > mbuf = bufs[i]; > - if (mbuf->pkt_len <= buf_len) { > - mbuf_to_tx = rte_pktmbuf_alloc(umem->mb_pool); > - if (!mbuf_to_tx) { > - rte_pktmbuf_free(mbuf); > - continue; > - } > - desc->addr = mbuf_to_addr(umem, mbuf_to_tx); > + if (txq->pair->zc && mbuf->pool == umem->mb_pool) { > + desc->addr = mbuf_to_addr(umem, mbuf); > desc->len = mbuf->pkt_len; > - pkt = xsk_umem__get_data(umem->buffer, > - desc->addr); > - memcpy(pkt, rte_pktmbuf_mtod(mbuf, void *), > - desc->len); > valid++; > tx_bytes += mbuf->pkt_len; > + } else { > + if (mbuf->pkt_len <= buf_len) { > + mbuf_to_tx = rte_pktmbuf_alloc(umem->mb_pool); > + if (!mbuf_to_tx) { if (unlikely(mbuf_to_tx == NULL)) See DPDK coding conventions 1.8.1 for how to do pointer comparisons. > + rte_pktmbuf_free(mbuf); > + continue; > + } > + desc->addr = mbuf_to_addr(umem, mbuf_to_tx); > + desc->len = mbuf->pkt_len; > + pkt = xsk_umem__get_data(umem->buffer, > + desc->addr); > + memcpy(pkt, rte_pktmbuf_mtod(mbuf, void *), > + desc->len); rte_memcpy() > + valid++; > + tx_bytes += mbuf->pkt_len; > + } > + rte_pktmbuf_free(mbuf); > } > - rte_pktmbuf_free(mbuf); > } > > xsk_ring_prod__submit(&txq->tx, nb_pkts); > @@ -479,7 +495,7 @@ static inline uint64_t get_len(struct rte_mempool *mp) > return (uint64_t)(memhdr->len); > } > > -static struct xsk_umem_info *xdp_umem_configure(void) > +static struct xsk_umem_info *xdp_umem_configure(struct rte_mempool *mb_pool) > { > struct xsk_umem_info *umem; > struct xsk_umem_config usr_config = { > @@ -497,20 +513,25 @@ static struct xsk_umem_info *xdp_umem_configure(void) > return NULL; > } > > - snprintf(pool_name, 0x100, "af_xdp_ring"); > - umem->mb_pool = rte_pktmbuf_pool_create_with_flags(pool_name, > - ETH_AF_XDP_NUM_BUFFERS, > - 250, 0, > - ETH_AF_XDP_FRAME_SIZE - > - ETH_AF_XDP_MBUF_OVERHEAD, > - MEMPOOL_F_NO_SPREAD | MEMPOOL_F_PAGE_ALIGN, > - SOCKET_ID_ANY); > - > - if (!umem->mb_pool || umem->mb_pool->nb_mem_chunks != 1) { > - RTE_LOG(ERR, AF_XDP, > - "Failed to create rte_mempool\n"); > - goto err; > + if (!mb_pool) { 1.8.1 > + snprintf(pool_name, 0x100, "af_xdp_ring"); 0x100?? > + umem->mb_pool = rte_pktmbuf_pool_create_with_flags(pool_name, > + ETH_AF_XDP_NUM_BUFFERS, > + 250, 0, > + ETH_AF_XDP_FRAME_SIZE - > + ETH_AF_XDP_MBUF_OVERHEAD, > + MEMPOOL_F_NO_SPREAD | MEMPOOL_F_PAGE_ALIGN, > + SOCKET_ID_ANY); > + > + if (!umem->mb_pool || umem->mb_pool->nb_mem_chunks != 1) { 1.8.1 > + RTE_LOG(ERR, AF_XDP, "Failed to create rte_mempool\n"); > + goto err; > + } > + } else { > + umem->mb_pool = mb_pool; > + umem->zc = 1; > } > + > base_addr = (void *)get_base_addr(umem->mb_pool); > > ret = xsk_umem__create(&umem->umem, base_addr, > @@ -531,16 +552,43 @@ static struct xsk_umem_info *xdp_umem_configure(void) > return NULL; > } > > +static uint8_t > +check_mempool_zc(struct rte_mempool *mp) > +{ > + RTE_ASSERT(mp); > + > + /* must continues */ > + if (mp->nb_mem_chunks > 1) > + return 0; > + > + /* check header size */ > + if (mp->header_size != RTE_CACHE_LINE_SIZE) > + return 0; > + > + /* check base address */ > + if ((uint64_t)get_base_addr(mp) % getpagesize() != 0) This should be an uintptr_t cast. > + return 0; > + > + /* check chunk size */ > + if ((mp->elt_size + mp->header_size + mp->trailer_size) % > + ETH_AF_XDP_FRAME_SIZE != 0) > + return 0; > + > + return 1; > +} > + > static int > xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq, > - int ring_size) > + int ring_size, struct rte_mempool *mb_pool) > { > struct xsk_socket_config cfg; > struct pkt_tx_queue *txq = rxq->pair; > + struct rte_mempool *mp; > int ret = 0; > int reserve_size; > > - rxq->umem = xdp_umem_configure(); > + mp = check_mempool_zc(mb_pool) ? mb_pool : NULL; > + rxq->umem = xdp_umem_configure(mp); > if (!rxq->umem) { > ret = -ENOMEM; > goto err; > @@ -627,15 +675,21 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, > > rxq->mb_pool = mb_pool; > > - if (xsk_configure(internals, rxq, nb_rx_desc)) { > - RTE_LOG(ERR, AF_XDP, > - "Failed to configure xdp socket\n"); > + if (xsk_configure(internals, rxq, nb_rx_desc, mb_pool)) { > + RTE_LOG(ERR, AF_XDP, "Failed to configure xdp socket\n"); > ret = -EINVAL; > goto err; > } > > internals->umem = rxq->umem; > > + if (mb_pool == internals->umem->mb_pool) > + rxq->zc = internals->umem->zc; > + > + if (rxq->zc) > + RTE_LOG(INFO, AF_XDP, > + "zero copy enabled on rx queue %d\n", rx_queue_id); > + > dev->data->rx_queues[rx_queue_id] = rxq; > return 0; > > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id A013CA00E6 for ; Tue, 19 Mar 2019 09:13:04 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3E80E11A4; Tue, 19 Mar 2019 09:13:03 +0100 (CET) Received: from mail.lysator.liu.se (mail.lysator.liu.se [130.236.254.3]) by dpdk.org (Postfix) with ESMTP id C9501239 for ; Tue, 19 Mar 2019 09:13:01 +0100 (CET) Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id 49F9F40008 for ; Tue, 19 Mar 2019 09:13:01 +0100 (CET) Received: by mail.lysator.liu.se (Postfix, from userid 1004) id 36B3440012; Tue, 19 Mar 2019 09:13:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on bernadotte.lysator.liu.se X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,AWL autolearn=disabled version=3.4.1 X-Spam-Score: -1.0 Received: from [192.168.1.59] (host-90-232-144-184.mobileonline.telia.com [90.232.144.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPSA id 0E8F440008; Tue, 19 Mar 2019 09:12:59 +0100 (CET) To: Xiaolong Ye , dev@dpdk.org Cc: Qi Zhang , Karlsson Magnus , Topel Bjorn References: <20190301080947.91086-1-xiaolong.ye@intel.com> <20190319071256.26302-1-xiaolong.ye@intel.com> <20190319071256.26302-6-xiaolong.ye@intel.com> From: =?UTF-8?Q?Mattias_R=c3=b6nnblom?= Message-ID: <6b786b77-f9b6-cb0b-634b-701e92a1c3a2@lysator.liu.se> Date: Tue, 19 Mar 2019 09:12:59 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 In-Reply-To: <20190319071256.26302-6-xiaolong.ye@intel.com> Content-Type: text/plain; charset="UTF-8"; format="flowed" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV using ClamSMTP Subject: Re: [dpdk-dev] [PATCH v2 5/6] net/af_xdp: enable zero copy X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Message-ID: <20190319081259.2oRXGI_UgwVoBtMdYnYSfFJi68G9dMT8lLaEUydo7sc@z> On 2019-03-19 08:12, Xiaolong Ye wrote: > Try to check if external mempool (from rx_queue_setup) is fit for > af_xdp, if it is, it will be registered to af_xdp socket directly and > there will be no packet data copy on Rx and Tx. > > Signed-off-by: Xiaolong Ye > --- > drivers/net/af_xdp/rte_eth_af_xdp.c | 128 ++++++++++++++++++++-------- > 1 file changed, 91 insertions(+), 37 deletions(-) > > diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c > index fc60cb5c5..c22791e51 100644 > --- a/drivers/net/af_xdp/rte_eth_af_xdp.c > +++ b/drivers/net/af_xdp/rte_eth_af_xdp.c > @@ -62,6 +62,7 @@ struct xsk_umem_info { > struct xsk_umem *umem; > struct rte_mempool *mb_pool; > void *buffer; > + uint8_t zc; > }; > > struct pkt_rx_queue { > @@ -76,6 +77,7 @@ struct pkt_rx_queue { > > struct pkt_tx_queue *pair; > uint16_t queue_idx; > + uint8_t zc; > }; > > struct pkt_tx_queue { > @@ -191,17 +193,24 @@ eth_af_xdp_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) > uint32_t len = xsk_ring_cons__rx_desc(rx, idx_rx++)->len; > char *pkt = xsk_umem__get_data(rxq->umem->buffer, addr); > > - mbuf = rte_pktmbuf_alloc(rxq->mb_pool); > - if (mbuf) { > - memcpy(rte_pktmbuf_mtod(mbuf, void*), pkt, len); > + if (rxq->zc) { > + mbuf = addr_to_mbuf(rxq->umem, addr); > rte_pktmbuf_pkt_len(mbuf) = > rte_pktmbuf_data_len(mbuf) = len; > - rx_bytes += len; > bufs[count++] = mbuf; > } else { > - dropped++; > + mbuf = rte_pktmbuf_alloc(rxq->mb_pool); > + if (mbuf) { if (likely(mbuf != NULL)) > + memcpy(rte_pktmbuf_mtod(mbuf, void*), pkt, len); Use rte_memcpy. > + rte_pktmbuf_pkt_len(mbuf) = > + rte_pktmbuf_data_len(mbuf) = len; > + rx_bytes += len; > + bufs[count++] = mbuf; > + } else { > + dropped++; > + } > + rte_pktmbuf_free(addr_to_mbuf(umem, addr)); > } > - rte_pktmbuf_free(addr_to_mbuf(umem, addr)); > } > > xsk_ring_cons__release(rx, rcvd); > @@ -285,22 +294,29 @@ eth_af_xdp_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) > - ETH_AF_XDP_DATA_HEADROOM; > desc = xsk_ring_prod__tx_desc(&txq->tx, idx_tx + i); > mbuf = bufs[i]; > - if (mbuf->pkt_len <= buf_len) { > - mbuf_to_tx = rte_pktmbuf_alloc(umem->mb_pool); > - if (!mbuf_to_tx) { > - rte_pktmbuf_free(mbuf); > - continue; > - } > - desc->addr = mbuf_to_addr(umem, mbuf_to_tx); > + if (txq->pair->zc && mbuf->pool == umem->mb_pool) { > + desc->addr = mbuf_to_addr(umem, mbuf); > desc->len = mbuf->pkt_len; > - pkt = xsk_umem__get_data(umem->buffer, > - desc->addr); > - memcpy(pkt, rte_pktmbuf_mtod(mbuf, void *), > - desc->len); > valid++; > tx_bytes += mbuf->pkt_len; > + } else { > + if (mbuf->pkt_len <= buf_len) { > + mbuf_to_tx = rte_pktmbuf_alloc(umem->mb_pool); > + if (!mbuf_to_tx) { if (unlikely(mbuf_to_tx == NULL)) See DPDK coding conventions 1.8.1 for how to do pointer comparisons. > + rte_pktmbuf_free(mbuf); > + continue; > + } > + desc->addr = mbuf_to_addr(umem, mbuf_to_tx); > + desc->len = mbuf->pkt_len; > + pkt = xsk_umem__get_data(umem->buffer, > + desc->addr); > + memcpy(pkt, rte_pktmbuf_mtod(mbuf, void *), > + desc->len); rte_memcpy() > + valid++; > + tx_bytes += mbuf->pkt_len; > + } > + rte_pktmbuf_free(mbuf); > } > - rte_pktmbuf_free(mbuf); > } > > xsk_ring_prod__submit(&txq->tx, nb_pkts); > @@ -479,7 +495,7 @@ static inline uint64_t get_len(struct rte_mempool *mp) > return (uint64_t)(memhdr->len); > } > > -static struct xsk_umem_info *xdp_umem_configure(void) > +static struct xsk_umem_info *xdp_umem_configure(struct rte_mempool *mb_pool) > { > struct xsk_umem_info *umem; > struct xsk_umem_config usr_config = { > @@ -497,20 +513,25 @@ static struct xsk_umem_info *xdp_umem_configure(void) > return NULL; > } > > - snprintf(pool_name, 0x100, "af_xdp_ring"); > - umem->mb_pool = rte_pktmbuf_pool_create_with_flags(pool_name, > - ETH_AF_XDP_NUM_BUFFERS, > - 250, 0, > - ETH_AF_XDP_FRAME_SIZE - > - ETH_AF_XDP_MBUF_OVERHEAD, > - MEMPOOL_F_NO_SPREAD | MEMPOOL_F_PAGE_ALIGN, > - SOCKET_ID_ANY); > - > - if (!umem->mb_pool || umem->mb_pool->nb_mem_chunks != 1) { > - RTE_LOG(ERR, AF_XDP, > - "Failed to create rte_mempool\n"); > - goto err; > + if (!mb_pool) { 1.8.1 > + snprintf(pool_name, 0x100, "af_xdp_ring"); 0x100?? > + umem->mb_pool = rte_pktmbuf_pool_create_with_flags(pool_name, > + ETH_AF_XDP_NUM_BUFFERS, > + 250, 0, > + ETH_AF_XDP_FRAME_SIZE - > + ETH_AF_XDP_MBUF_OVERHEAD, > + MEMPOOL_F_NO_SPREAD | MEMPOOL_F_PAGE_ALIGN, > + SOCKET_ID_ANY); > + > + if (!umem->mb_pool || umem->mb_pool->nb_mem_chunks != 1) { 1.8.1 > + RTE_LOG(ERR, AF_XDP, "Failed to create rte_mempool\n"); > + goto err; > + } > + } else { > + umem->mb_pool = mb_pool; > + umem->zc = 1; > } > + > base_addr = (void *)get_base_addr(umem->mb_pool); > > ret = xsk_umem__create(&umem->umem, base_addr, > @@ -531,16 +552,43 @@ static struct xsk_umem_info *xdp_umem_configure(void) > return NULL; > } > > +static uint8_t > +check_mempool_zc(struct rte_mempool *mp) > +{ > + RTE_ASSERT(mp); > + > + /* must continues */ > + if (mp->nb_mem_chunks > 1) > + return 0; > + > + /* check header size */ > + if (mp->header_size != RTE_CACHE_LINE_SIZE) > + return 0; > + > + /* check base address */ > + if ((uint64_t)get_base_addr(mp) % getpagesize() != 0) This should be an uintptr_t cast. > + return 0; > + > + /* check chunk size */ > + if ((mp->elt_size + mp->header_size + mp->trailer_size) % > + ETH_AF_XDP_FRAME_SIZE != 0) > + return 0; > + > + return 1; > +} > + > static int > xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq, > - int ring_size) > + int ring_size, struct rte_mempool *mb_pool) > { > struct xsk_socket_config cfg; > struct pkt_tx_queue *txq = rxq->pair; > + struct rte_mempool *mp; > int ret = 0; > int reserve_size; > > - rxq->umem = xdp_umem_configure(); > + mp = check_mempool_zc(mb_pool) ? mb_pool : NULL; > + rxq->umem = xdp_umem_configure(mp); > if (!rxq->umem) { > ret = -ENOMEM; > goto err; > @@ -627,15 +675,21 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, > > rxq->mb_pool = mb_pool; > > - if (xsk_configure(internals, rxq, nb_rx_desc)) { > - RTE_LOG(ERR, AF_XDP, > - "Failed to configure xdp socket\n"); > + if (xsk_configure(internals, rxq, nb_rx_desc, mb_pool)) { > + RTE_LOG(ERR, AF_XDP, "Failed to configure xdp socket\n"); > ret = -EINVAL; > goto err; > } > > internals->umem = rxq->umem; > > + if (mb_pool == internals->umem->mb_pool) > + rxq->zc = internals->umem->zc; > + > + if (rxq->zc) > + RTE_LOG(INFO, AF_XDP, > + "zero copy enabled on rx queue %d\n", rx_queue_id); > + > dev->data->rx_queues[rx_queue_id] = rxq; > return 0; > >