From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wi0-f172.google.com (mail-wi0-f172.google.com [209.85.212.172]) by dpdk.org (Postfix) with ESMTP id DA36358F1 for ; Wed, 1 Jul 2015 11:04:02 +0200 (CEST) Received: by wiwl6 with SMTP id l6so157959393wiw.0 for ; Wed, 01 Jul 2015 02:04:02 -0700 (PDT) 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=YT7hjoFlp59LK0QNifdobzESJqfUrHLk16ATflcDwEs=; b=dUzlU3iT5xVvzGI60ddTrIeDY3/pONcCOpxvhuyFbcaITZGYl1dKSOVv6uyfpymjNA wy6EV9CGw1AQVWaedBTjiiBwuIh/jk56OYZVqNVARyjYkvQr7ER3atLX8nn+nBe9Au0C 0iqZLGVoAkCQAq0kC3RHyuZw3DTtbpNPM4r1gB1qbQRu+Gbh2shGi/f7qpLF+oLlYu/V upFuw+a9mvaUWZ7aZMqvXU5Y7NbSfdy4W0kO6MQcxFg0dGG5nPB34pbi5TIHUk94TS8c wzW87VsyRlXjMoVgGJGJ5NQjK8f2NxHhYGgcPm4oD4bdmCXooFkF8i/6N8pPPRk6RR3b Ke2g== X-Gm-Message-State: ALoCoQkFXb1D0QvBMatqABth9y5XZiZIsSL1V84KYS2Q5JeYQN/rESIFeb4wB+WRajo95pHbG8z/ X-Received: by 10.194.110.100 with SMTP id hz4mr47494229wjb.6.1435741442753; Wed, 01 Jul 2015 02:04:02 -0700 (PDT) Received: from localhost.localdomain ([90.152.119.35]) by mx.google.com with ESMTPSA id p2sm2368418wix.11.2015.07.01.02.04.01 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 01 Jul 2015 02:04:01 -0700 (PDT) From: Zoltan Kiss To: dev@dpdk.org Date: Wed, 1 Jul 2015 10:03:50 +0100 Message-Id: <1435741430-2088-1-git-send-email-zoltan.kiss@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1435258110-17140-1-git-send-email-zoltan.kiss@linaro.org> References: <1435258110-17140-1-git-send-email-zoltan.kiss@linaro.org> Subject: [dpdk-dev] [PATCH v2] mempool: improve cache search 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: , X-List-Received-Date: Wed, 01 Jul 2015 09:04:03 -0000 The current way has a few problems: - if cache->len < n, we copy our elements into the cache first, then into obj_table, that's unnecessary - if n >= cache_size (or the backfill fails), and we can't fulfil the request from the ring alone, we don't try to combine with the cache - if refill fails, we don't return anything, even if the ring has enough for our request This patch rewrites it severely: - at the first part of the function we only try the cache if cache->len < n - otherwise take our elements straight from the ring - if that fails but we have something in the cache, try to combine them - the refill happens at the end, and its failure doesn't modify our return value Signed-off-by: Zoltan Kiss --- v2: - fix subject - add unlikely for branch where request is fulfilled both from cache and ring lib/librte_mempool/rte_mempool.h | 63 +++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index 6d4ce9a..1e96f03 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -947,34 +947,14 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned lcore_id = rte_lcore_id(); uint32_t cache_size = mp->cache_size; - /* cache is not enabled or single consumer */ + cache = &mp->local_cache[lcore_id]; + /* cache is not enabled or single consumer or not enough */ if (unlikely(cache_size == 0 || is_mc == 0 || - n >= cache_size || lcore_id >= RTE_MAX_LCORE)) + cache->len < n || lcore_id >= RTE_MAX_LCORE)) goto ring_dequeue; - cache = &mp->local_cache[lcore_id]; cache_objs = cache->objs; - /* Can this be satisfied from the cache? */ - if (cache->len < n) { - /* No. Backfill the cache first, and then fill from it */ - uint32_t req = n + (cache_size - cache->len); - - /* How many do we require i.e. number to fill the cache + the request */ - ret = rte_ring_mc_dequeue_bulk(mp->ring, &cache->objs[cache->len], req); - if (unlikely(ret < 0)) { - /* - * In the offchance that we are buffer constrained, - * where we are not able to allocate cache + n, go to - * the ring directly. If that fails, we are truly out of - * buffers. - */ - goto ring_dequeue; - } - - cache->len += req; - } - /* Now fill in the response ... */ for (index = 0, len = cache->len - 1; index < n; ++index, len--, obj_table++) *obj_table = cache_objs[len]; @@ -983,7 +963,8 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table, __MEMPOOL_STAT_ADD(mp, get_success, n); - return 0; + ret = 0; + goto cache_refill; ring_dequeue: #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ @@ -994,11 +975,45 @@ ring_dequeue: else ret = rte_ring_sc_dequeue_bulk(mp->ring, obj_table, n); +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 + if (unlikely(ret < 0 && is_mc == 1 && cache->len > 0)) { + uint32_t req = n - cache->len; + + ret = rte_ring_mc_dequeue_bulk(mp->ring, obj_table, req); + if (ret == 0) { + cache_objs = cache->objs; + obj_table += req; + for (index = 0; index < cache->len; + ++index, ++obj_table) + *obj_table = cache_objs[index]; + cache->len = 0; + } + } +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ + if (ret < 0) __MEMPOOL_STAT_ADD(mp, get_fail, n); else __MEMPOOL_STAT_ADD(mp, get_success, n); +#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0 +cache_refill: + /* If previous dequeue was OK and we have less than n, start refill */ + if (ret == 0 && cache_size > 0 && cache->len < n) { + uint32_t req = cache_size - cache->len; + + cache_objs = cache->objs; + ret = rte_ring_mc_dequeue_bulk(mp->ring, + &cache->objs[cache->len], + req); + if (likely(ret == 0)) + cache->len += req; + else + /* Don't spoil the return value */ + ret = 0; + } +#endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */ + return ret; } -- 1.9.1