From mboxrd@z Thu Jan 1 00:00:00 1970 From: Olivier Matz Subject: [RFC 8/9] net/e1000: optimize rx queue descriptor count Date: Thu, 24 Nov 2016 10:54:20 +0100 Message-ID: <1479981261-19512-9-git-send-email-olivier.matz@6wind.com> References: <1479981261-19512-1-git-send-email-olivier.matz@6wind.com> Cc: thomas.monjalon@6wind.com, konstantin.ananyev@intel.com, wenzhuo.lu@intel.com, helin.zhang@intel.com To: dev@dpdk.org Return-path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id E49B05585 for ; Thu, 24 Nov 2016 10:59:38 +0100 (CET) In-Reply-To: <1479981261-19512-1-git-send-email-olivier.matz@6wind.com> 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" Use a binary search algorithm to find the first empty DD bit. The ring-empty and ring-full cases are managed separately as they are more likely to happen. PR=52423 Signed-off-by: Olivier Matz Acked-by: Ivan Boule --- drivers/net/e1000/em_rxtx.c | 55 +++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c index c1c724b..a469fd7 100644 --- a/drivers/net/e1000/em_rxtx.c +++ b/drivers/net/e1000/em_rxtx.c @@ -1385,24 +1385,51 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev, uint32_t eth_em_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) { -#define EM_RXQ_SCAN_INTERVAL 4 - volatile struct e1000_rx_desc *rxdp; + volatile uint8_t *status; struct em_rx_queue *rxq; - uint32_t desc = 0; + uint32_t offset, interval, resolution; + int32_t idx; rxq = dev->data->rx_queues[rx_queue_id]; - rxdp = &(rxq->rx_ring[rxq->rx_tail]); - - while ((desc < rxq->nb_rx_desc) && - (rxdp->status & E1000_RXD_STAT_DD)) { - desc += EM_RXQ_SCAN_INTERVAL; - rxdp += EM_RXQ_SCAN_INTERVAL; - if (rxq->rx_tail + desc >= rxq->nb_rx_desc) - rxdp = &(rxq->rx_ring[rxq->rx_tail + - desc - rxq->nb_rx_desc]); - } - return desc; + /* check if ring empty */ + idx = rxq->rx_tail; + status = &rxq->rx_ring[idx].status; + if (!(*status & E1000_RXD_STAT_DD)) + return 0; + + /* decrease the precision if ring is large */ + if (rxq->nb_rx_desc <= 256) + resolution = 4; + else + resolution = 16; + + /* check if ring full */ + idx = rxq->rx_tail - rxq->nb_rx_hold - resolution; + if (idx < 0) + idx += rxq->nb_rx_desc; + status = &rxq->rx_ring[idx].status; + if (*status & E1000_RXD_STAT_DD) + return rxq->nb_rx_desc; + + /* use a binary search */ + interval = (rxq->nb_rx_desc - rxq->nb_rx_hold) >> 1; + offset = interval; + + do { + idx = rxq->rx_tail + offset; + if (idx >= rxq->nb_rx_desc) + idx -= rxq->nb_rx_desc; + + interval >>= 1; + status = &rxq->rx_ring[idx].status; + if (*status & E1000_RXD_STAT_DD) + offset += interval; + else + offset -= interval; + } while (interval >= resolution); + + return offset; } int -- 2.8.1