From patchwork Wed May 15 10:54:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?QWJkdWxsYWggw5ZtZXIgWWFtYcOn?= X-Patchwork-Id: 140125 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0B38D44035; Wed, 15 May 2024 12:54:53 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D258C402BE; Wed, 15 May 2024 12:54:52 +0200 (CEST) Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) by mails.dpdk.org (Postfix) with ESMTP id 26E8C4021D for ; Wed, 15 May 2024 12:54:51 +0200 (CEST) Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-a59b58fe083so141637566b.0 for ; Wed, 15 May 2024 03:54:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715770490; x=1716375290; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Qm24hMfmMy6wPSG/U6s3fUI+WZKoMC2FL6CeHXyKC7M=; b=Vh8+sAff4d8aiLbdZx1lIZKPHXQIVI5g+t5vqNngICBmJOHd0Cx3ix4ILZDgOsuDQb yYS8LHyow5HxpnBKS9OnJCvhi571Wqj+J1rJnIOYPs2EZmKiUCo9NcbgbYxxHfQzqYRy rMrWh3xq3p6xtHvmBpsk50OcHVcEz61eZLQqo9bfW0aHCcfH6VmsYIVvji6nLZJFSuvU 5ljopNDlnNtMlW44pM6OT8EpdOPMZCDpeBkVd+cpVihxLz1wj2RHB2Y2wnUEg7z5fmNl CZU6mJYK2UF2sM5sHZ9UzYMVJgDaNPOdXkdzF5c8/OdMD0DpXUC44ODPv8yyAktJVnoo To9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715770490; x=1716375290; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Qm24hMfmMy6wPSG/U6s3fUI+WZKoMC2FL6CeHXyKC7M=; b=c5GUX6R4Q+JrxmkdORSX0O9l5Ln+hcf+QZk/tMUB0cjXsn9rySBFh3alPu9xS6idbq 5zESqjRSywpSZrEpfuBpcMzygcgMwx57dCLhZ8S0j94CaZ8Z+NpmSs9Tso9+B6AyCUw7 jmHaRwINNtU1p7kugkRz8+t0izJynafmsx2lRzWu5eWw9SRVyHXpLtsMlNLEhrEpHkoE xDCdAAa5zwLYW7yCfPzrFY0w1k2V4Yrr8GhV7BPVR16Css9WR9jIoD9DXImk6/ZvqFk/ BQKV4vbRcO2j0vh2B6LW/hw+g+GxLfHLPIoZECINAvS2cFVvLqdiU7GkZlXeStIYsaS+ R/ew== X-Gm-Message-State: AOJu0YxpACI2FPVROTEWXequOgxhMMWe3kDpeJsPFgAFdleTiG5i2tqf ZM7wmvjutAEP9mS1Z00s7zV6h3EhcWfDYcPaMlZGAh01bevEPQRFuRssmJBl X-Google-Smtp-Source: AGHT+IEDJwS173+/YQJXvHHHmBQr3hJ6fm0ffSJ75Q33gd6bjfKJvUPEkpAxuAndOy0ucXfqVzsWuw== X-Received: by 2002:a17:906:7711:b0:a59:cb67:ceb9 with SMTP id a640c23a62f3a-a5a2d5cb6a1mr1048165766b.35.1715770490213; Wed, 15 May 2024 03:54:50 -0700 (PDT) Received: from dcu.otaknetworks.com ([212.156.37.190]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a5a1781d342sm850781166b.6.2024.05.15.03.54.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 May 2024 03:54:49 -0700 (PDT) From: =?utf-8?b?QWJkdWxsYWggw5ZtZXIgWWFtYcOn?= To: dev@dpdk.org Cc: Honnappa.Nagarahalli@arm.com, =?utf-8?b?QWJkdWxsYWggw5ZtZXIgWWFtYcOn?= Subject: [PATCH v6] lib/hash: add defer queue reclaim API Date: Wed, 15 May 2024 10:54:46 +0000 Message-Id: <20240515105446.1251717-1-aomeryamac@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch adds a new feature to the hash library to allow the user to reclaim the defer queue. This is useful when the user wants to force reclaim resources that are not being used. This API is only available if the RCU is enabled. Signed-off-by: Abdullah Ömer Yamaç Reviewed-by: Honnappa Nagarahalli --- app/test/test_hash.c | 87 ++++++++++++++++++++++++++++++++++++++ lib/hash/rte_cuckoo_hash.c | 21 +++++++++ lib/hash/rte_hash.h | 25 +++++++++++ lib/hash/version.map | 7 +++ 4 files changed, 140 insertions(+) diff --git a/app/test/test_hash.c b/app/test/test_hash.c index d586878a22..24d3b547ad 100644 --- a/app/test/test_hash.c +++ b/app/test/test_hash.c @@ -2183,6 +2183,90 @@ test_hash_rcu_qsbr_sync_mode(uint8_t ext_bkt) } +/* + * rte_hash_rcu_qsbr_dq_reclaim unit test. + */ +static int +test_hash_rcu_qsbr_dq_reclaim(void) +{ + size_t sz; + int32_t status; + unsigned int total_entries = 8; + unsigned int freed, pending, available; + uint32_t reclaim_keys[8] = {10, 11, 12, 13, 14, 15, 16, 17}; + struct rte_hash_rcu_config rcu_cfg = {0}; + struct rte_hash_parameters hash_params = { + .name = "test_hash_rcu_qsbr_dq_reclaim", + .entries = total_entries, + .key_len = sizeof(uint32_t), + .hash_func = NULL, + .hash_func_init_val = 0, + .socket_id = 0, + }; + + hash_params.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF; + + g_qsv = NULL; + g_handle = NULL; + + printf("\n# Running RCU QSBR DQ mode, reclaim defer queue functional test\n"); + + g_handle = rte_hash_create(&hash_params); + RETURN_IF_ERROR_RCU_QSBR(g_handle == NULL, "Hash creation failed"); + + /* Create RCU QSBR variable */ + sz = rte_rcu_qsbr_get_memsize(RTE_MAX_LCORE); + g_qsv = (struct rte_rcu_qsbr *)rte_zmalloc_socket( + NULL, sz, RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY); + RETURN_IF_ERROR_RCU_QSBR(g_qsv == NULL, "RCU QSBR variable creation failed"); + + status = rte_rcu_qsbr_init(g_qsv, RTE_MAX_LCORE); + RETURN_IF_ERROR_RCU_QSBR(status != 0, "RCU QSBR variable initialization failed"); + + rcu_cfg.v = g_qsv; + rcu_cfg.dq_size = total_entries; + rcu_cfg.mode = RTE_HASH_QSBR_MODE_DQ; + + /* Attach RCU QSBR to hash table */ + status = rte_hash_rcu_qsbr_add(g_handle, &rcu_cfg); + RETURN_IF_ERROR_RCU_QSBR(status != 0, "Attach RCU QSBR to hash table failed"); + + /* Register pseudo reader */ + status = rte_rcu_qsbr_thread_register(g_qsv, 0); + RETURN_IF_ERROR_RCU_QSBR(status != 0, "RCU QSBR thread registration failed"); + rte_rcu_qsbr_thread_online(g_qsv, 0); + + /* Fill half of the hash table */ + for (size_t i = 0; i < total_entries / 2; i++) + status = rte_hash_add_key(g_handle, &reclaim_keys[i]); + + /* Try to put these elements into the defer queue*/ + for (size_t i = 0; i < total_entries / 2; i++) + rte_hash_del_key(g_handle, &reclaim_keys[i]); + + /* Reader quiescent */ + rte_rcu_qsbr_quiescent(g_qsv, 0); + + status = rte_hash_add_key(g_handle, &reclaim_keys[0]); + RETURN_IF_ERROR_RCU_QSBR(status < 0, "failed to add key (pos[%u]=%d)", 0, status); + + /* This should be (total_entries / 2) + 1 (last add) */ + unsigned int hash_size = rte_hash_count(g_handle); + + /* Freed size should be (total_entries / 2) */ + rte_hash_rcu_qsbr_dq_reclaim(g_handle, &freed, &pending, &available); + + rte_hash_free(g_handle); + rte_free(g_qsv); + + if (hash_size != (total_entries / 2 + 1) || freed != (total_entries / 2)) { + printf("Failed to reclaim defer queue\n"); + return -1; + } + + return 0; +} + /* * Do all unit and performance tests. */ @@ -2261,6 +2345,9 @@ test_hash(void) if (test_hash_rcu_qsbr_sync_mode(1) < 0) return -1; + if (test_hash_rcu_qsbr_dq_reclaim() < 0) + return -1; + return 0; } diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c index 9cf94645f6..52ccada12a 100644 --- a/lib/hash/rte_cuckoo_hash.c +++ b/lib/hash/rte_cuckoo_hash.c @@ -1588,6 +1588,27 @@ rte_hash_rcu_qsbr_add(struct rte_hash *h, struct rte_hash_rcu_config *cfg) return 0; } +int rte_hash_rcu_qsbr_dq_reclaim(struct rte_hash *h, unsigned int *freed, unsigned int *pending, + unsigned int *available) +{ + int ret; + + if (h == NULL || h->hash_rcu_cfg == NULL) { + HASH_LOG(ERR, "Invalid input parameter"); + rte_errno = EINVAL; + return 1; + } + + ret = rte_rcu_qsbr_dq_reclaim(h->dq, h->hash_rcu_cfg->max_reclaim_size, freed, pending, + available); + if (ret != 0) { + HASH_LOG(ERR, "%s: could not reclaim the defer queue in hash table", __func__); + return 1; + } + + return 0; +} + static inline void remove_entry(const struct rte_hash *h, struct rte_hash_bucket *bkt, unsigned int i) diff --git a/lib/hash/rte_hash.h b/lib/hash/rte_hash.h index 7ecc021111..e1e0375fd5 100644 --- a/lib/hash/rte_hash.h +++ b/lib/hash/rte_hash.h @@ -674,6 +674,31 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32 */ int rte_hash_rcu_qsbr_add(struct rte_hash *h, struct rte_hash_rcu_config *cfg); +/** + * Reclaim resources from the defer queue. + * This API reclaim the resources from the defer queue if rcu is enabled. + * + * @param h + * The hash object to reclaim resources. + * @param freed + * Number of resources that were freed. + * @param pending + * Number of resources pending on the defer queue. + * This number might not be accurate if multi-thread safety is configured. + * @param available + * Number of resources that can be added to the defer queue. + * This number might not be accurate if multi-thread safety is configured. + * @return + * On success - 0 + * On error - 1 with error code set in rte_errno. + * Possible rte_errno codes are: + * - EINVAL - invalid pointer + */ +__rte_experimental +int rte_hash_rcu_qsbr_dq_reclaim(struct rte_hash *h, unsigned int *freed, + unsigned int *pending, + unsigned int *available); + #ifdef __cplusplus } #endif diff --git a/lib/hash/version.map b/lib/hash/version.map index 6f4bcdb71b..d348dd9196 100644 --- a/lib/hash/version.map +++ b/lib/hash/version.map @@ -53,3 +53,10 @@ INTERNAL { rte_thash_gfni_stub; rte_thash_gfni_bulk_stub; }; + +EXPERIMENTAL { + global: + + # added in 24.07 + rte_hash_rcu_qsbr_dq_reclaim; +};