From patchwork Wed Apr 9 09:03:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ciprian Barbu X-Patchwork-Id: 28070 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f69.google.com (mail-oa0-f69.google.com [209.85.219.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7ABB02145A for ; Wed, 9 Apr 2014 09:04:51 +0000 (UTC) Received: by mail-oa0-f69.google.com with SMTP id i7sf9646152oag.4 for ; Wed, 09 Apr 2014 02:04:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=qKuViT6Lu4/tsz0bkscHadBPm4rbeB7P7XZVW6pny3A=; b=QEW1l5QY24oK7TXB57T8VVKfhe3EYmu4qxfaTa0frVFRNFhE4EYZi5vnn1663+VOrl 6uwpKv8pWQvm7duZ1fBJ6z+pvy2cQXg7gq1rbC7M4mqJweRGaNYbm5eUW2449g+IKevv xzD6ch29aZs1+MQB58sxD5tJhlmnfb//W5PX2KuZkv3dEO3JQzDrarfHtLecs9YlJPlT RROSTE1TRtjIkkU40wbxOleK3uOtlaRg34GRhLXWqG7RO4HeNmEdVjbXVVtr+VVxiRjI nlD0Hjhb9gxMVJq0nJyXke2WXidj4BKbE2m+suPTxXcaABtDVxbxOFYHseTDpisQX+tw eavw== X-Gm-Message-State: ALoCoQlzT5yILDl4sW0EtdKE4sRtSKfm8yEoSNu6E0Y/4ndygAqeMytzMPbtu1ghQAx0ceFJ16wx X-Received: by 10.182.19.164 with SMTP id g4mr4342983obe.21.1397034291034; Wed, 09 Apr 2014 02:04:51 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.85.82 with SMTP id m76ls529292qgd.62.gmail; Wed, 09 Apr 2014 02:04:50 -0700 (PDT) X-Received: by 10.52.173.165 with SMTP id bl5mr6456276vdc.13.1397034290898; Wed, 09 Apr 2014 02:04:50 -0700 (PDT) Received: from mail-vc0-f174.google.com (mail-vc0-f174.google.com [209.85.220.174]) by mx.google.com with ESMTPS id vv9si47303vcb.91.2014.04.09.02.04.50 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 09 Apr 2014 02:04:50 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.174; Received: by mail-vc0-f174.google.com with SMTP id ld13so1770484vcb.5 for ; Wed, 09 Apr 2014 02:04:50 -0700 (PDT) X-Received: by 10.220.170.202 with SMTP id e10mr7786913vcz.20.1397034290809; Wed, 09 Apr 2014 02:04:50 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.12.8 with SMTP id v8csp312811vcv; Wed, 9 Apr 2014 02:04:50 -0700 (PDT) X-Received: by 10.224.61.200 with SMTP id u8mr10944342qah.18.1397034290432; Wed, 09 Apr 2014 02:04:50 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id gv6si131653qcb.33.2014.04.09.02.04.49 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 09 Apr 2014 02:04:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1WXoOl-0002Tp-Sn; Wed, 09 Apr 2014 09:02:23 +0000 Received: from mail-lb0-f178.google.com ([209.85.217.178]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1WXoO0-00014J-L9 for lng-odp@lists.linaro.org; Wed, 09 Apr 2014 09:01:36 +0000 Received: by mail-lb0-f178.google.com with SMTP id s7so888717lbd.23 for ; Wed, 09 Apr 2014 02:03:56 -0700 (PDT) X-Received: by 10.112.142.105 with SMTP id rv9mr853369lbb.42.1397034236170; Wed, 09 Apr 2014 02:03:56 -0700 (PDT) Received: from sestofb10.enea.se (sestofw01.enea.se. [192.36.1.252]) by mx.google.com with ESMTPSA id x5sm334267lbk.5.2014.04.09.02.03.55 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 09 Apr 2014 02:03:55 -0700 (PDT) From: Ciprian Barbu To: lng-odp@lists.linaro.org Date: Wed, 9 Apr 2014 11:03:38 +0200 Message-Id: <1397034218-2971-6-git-send-email-ciprian.barbu@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1397034218-2971-1-git-send-email-ciprian.barbu@linaro.org> References: <1397034218-2971-1-git-send-email-ciprian.barbu@linaro.org> Subject: [lng-odp] [PATCH 5/5] Fix netmap pkt I/O to poll all hardware rings X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ciprian.barbu@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Before this patch, the netmap pkt I/O lost a lot of packets on RX and TX side, because it was only taking into account the first rings (RX and TX). Signed-off-by: Ciprian Barbu --- platform/linux-generic/include/odp_packet_netmap.h | 2 + platform/linux-generic/source/odp_packet_netmap.c | 137 +++++++++++++++------ 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/platform/linux-generic/include/odp_packet_netmap.h b/platform/linux-generic/include/odp_packet_netmap.h index eae936a..0c75c7f 100644 --- a/platform/linux-generic/include/odp_packet_netmap.h +++ b/platform/linux-generic/include/odp_packet_netmap.h @@ -33,6 +33,8 @@ typedef struct { size_t buf_size; /**< size of buffer payload in 'pool' */ int netmap_mode; struct nm_desc_t *nm_desc; + uint32_t begin; + uint32_t end; struct netmap_ring *rxring; struct netmap_ring *txring; odp_queue_t tx_access; /* Used for exclusive access to send packets */ diff --git a/platform/linux-generic/source/odp_packet_netmap.c b/platform/linux-generic/source/odp_packet_netmap.c index e54964b..e3b6bc9 100644 --- a/platform/linux-generic/source/odp_packet_netmap.c +++ b/platform/linux-generic/source/odp_packet_netmap.c @@ -52,6 +52,7 @@ #define ETH_PROMISC 1 /* TODO: maybe this should be exported to the user */ #define WAITLINK_TMO 2 +#define POLL_TMO 50 static int nm_do_ioctl(pkt_netmap_t * const pkt_nm, unsigned long cmd, int subcmd) @@ -156,11 +157,22 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, char *netdev, pkt_nm->nm_desc->mem); if (nm_params->netmap_mode == ODP_NETMAP_MODE_SW) { + pkt_nm->begin = pkt_nm->nm_desc->req.nr_rx_rings; + pkt_nm->end = pkt_nm->begin + 1; pkt_nm->rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, pkt_nm->nm_desc->req.nr_rx_rings); pkt_nm->txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, pkt_nm->nm_desc->req.nr_tx_rings); + } else if (nm_params->ringid & NETMAP_HW_RING) { + pkt_nm->begin = nm_params->ringid & NETMAP_RING_MASK; + pkt_nm->end = pkt_nm->begin + 1; + pkt_nm->rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, + pkt_nm->begin); + pkt_nm->txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, + pkt_nm->begin); } else { + pkt_nm->begin = 0; + pkt_nm->end = pkt_nm->nm_desc->req.nr_rx_rings; pkt_nm->rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, 0); pkt_nm->txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, 0); } @@ -233,10 +245,11 @@ int close_pkt_netmap(pkt_netmap_t * const pkt_nm) int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[], unsigned len) { - struct netmap_ring *rxring; + struct netmap_ring *rxring = pkt_nm->rxring; int fd; unsigned nb_rx = 0; uint32_t limit, rx; + uint32_t ringid = pkt_nm->begin; odp_packet_t pkt = ODP_PACKET_INVALID; #ifdef NETMAP_BLOCKING_IO struct pollfd fds[1]; @@ -249,19 +262,27 @@ int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[], fds[0].events = POLLIN; #endif - rxring = pkt_nm->rxring; while (nb_rx < len) { #ifdef NETMAP_BLOCKING_IO - ret = poll(&fds[0], 1, 50); + ret = poll(&fds[0], 1, POLL_TMO); if (ret <= 0 || (fds[0].revents & POLLERR)) break; #else ioctl(fd, NIOCRXSYNC, NULL); #endif - if (nm_ring_empty(rxring)) { - /* No data on the wire, return to scheduler */ - break; + /* Find first ring not empty */ + while (nm_ring_empty(rxring)) { + ringid++; + + /* Return to scheduler if no more data to meet the + requested amount (len) */ + if (ringid == pkt_nm->end) { + ODP_DBG("No more data on the wire\n"); + break; + } + + rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, ringid); } limit = len - nb_rx; @@ -342,55 +363,91 @@ int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[], int send_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[], unsigned len) { + struct netmap_ring *txring = pkt_nm->txring; int fd; - uint32_t i; - uint32_t limit; - void *txbuf; - struct netmap_ring *txring; - struct netmap_slot *slot; + unsigned nb_tx = 0; + uint32_t limit, tx; + uint32_t ringid = pkt_nm->begin; odp_packet_t pkt; odp_buffer_t token; - fd = pkt_nm->nm_desc->fd; +#ifdef NETMAP_BLOCKING_IO + struct pollfd fds[2]; + int ret; +#endif - txring = pkt_nm->txring; - limit = nm_ring_space(txring); - if (len < limit) - limit = len; + fd = pkt_nm->nm_desc->fd; +#ifdef NETMAP_BLOCKING_IO + fds[0].fd = fd; + fds[0].events = POLLOUT; +#endif - ODP_DBG("Sending %d packets out of %d to netmap %p %u\n", - limit, len, txring, txring->cur); token = odp_queue_deq(pkt_nm->tx_access); - for (i = 0; i < limit; i++) { - size_t frame_len; - uint32_t cur; - uint8_t *frame; + while (nb_tx < len) { +#ifdef NETMAP_BLOCKING_IO + ret = poll(&fds[0], 1, POLL_TMO); + if (ret <= 0 || (fds[0].revents & POLLERR)) + break; +#else + ioctl(fd, NIOCTXSYNC, NULL); +#endif + + /* Find first ring not empty */ + while (nm_ring_empty(txring)) { + ringid++; + + /* Return to scheduler if no more space to meet the + requested amount (len) */ + if (ringid == pkt_nm->end) { + ODP_DBG("No more space in TX rings\n"); + break; + } + + txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, ringid); + } - cur = txring->cur; - slot = &txring->slot[cur]; - txbuf = NETMAP_BUF(txring, slot->buf_idx); + limit = len - nb_tx; + if (nm_ring_space(txring) < limit) + limit = nm_ring_space(txring); - pkt = pkt_table[i]; - frame = odp_packet_start(pkt); - frame_len = odp_packet_get_len(pkt); + ODP_DBG("Sending %d packets out of %d to netmap %p %u\n", + limit, len, txring, txring->cur); - memcpy(txbuf, frame, frame_len); - slot->len = frame_len; - txring->head = nm_ring_next(txring, cur); - txring->cur = nm_ring_next(txring, cur); + for (tx = 0; tx < limit; tx++) { + struct netmap_slot *tslot; + size_t frame_len; + uint32_t cur; + uint8_t *frame; + void *txbuf; + + cur = txring->cur; + tslot = &txring->slot[cur]; + txbuf = NETMAP_BUF(txring, tslot->buf_idx); + + pkt = pkt_table[nb_tx]; + frame = odp_packet_start(pkt); + frame_len = odp_packet_get_len(pkt); + + memcpy(txbuf, frame, frame_len); + tslot->len = frame_len; + txring->head = nm_ring_next(txring, cur); + txring->cur = txring->head; + nb_tx++; + } } odp_queue_enq(pkt_nm->tx_access, token); - /* The netmap examples don't use this anymore, don't know why ... */ - /* ioctl(fd, NIOCTXSYNC, NULL); */ - (void)fd; - if (limit) - ODP_DBG("===> sent %03u frames to netmap adapter\n", limit); +#ifndef NETMAP_BLOCKING_IO + ioctl(fd, NIOCTXSYNC, NULL); +#endif + + if (nb_tx) + ODP_DBG("===> sent %03u frames to netmap adapter\n", nb_tx); - for (i = 0; i < len; i++) - odp_packet_free(pkt_table[i]); + for (tx = 0; tx < len; tx++) + odp_packet_free(pkt_table[tx]); - return limit; + return nb_tx; }