From patchwork Mon Apr 13 14:21:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 68313 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4C29BA0577; Mon, 13 Apr 2020 17:20:08 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 263BD1C01E; Mon, 13 Apr 2020 17:20:08 +0200 (CEST) Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by dpdk.org (Postfix) with ESMTP id 899CA1BF26 for ; Mon, 13 Apr 2020 17:20:06 +0200 (CEST) Received: by mail-pf1-f195.google.com with SMTP id y25so2336744pfn.5 for ; Mon, 13 Apr 2020 08:20:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yZ65jqE6uVO8M/yseZChZN/Y5dZubPDoCrY4awKariU=; b=sBG1CnzoJ9PGv6ATJl7Pizpsv1JN97b5kmfzroFpbl7lLIUL03shAKTkyhNNsd92pp WCMN7gQuIBTXxcAOlGU04dPZ25gcTKmXWa6YeeKSN0Ytyg1n1Eh2YOXbVxmddgmk0uSW zljuduzyomKlVN0MfP0OmXdeKQafSKoskhpXkvXTtZkyP+mahv7qlrJRFvRECQ2iSybe 0x2JfQRBnWP1aFC4IxZXc4bmi7pR54FPNtiZFEhTjEtPnxzNqlAmiWbcVog1gOir3W0R 4rSe62oPFZcYq6xrKT3DbiO1fHVCMnWpwo0zS0yUWkAWlQ4onqpTCoF4nfVLKja/VDn9 IIKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yZ65jqE6uVO8M/yseZChZN/Y5dZubPDoCrY4awKariU=; b=JVYnQAwmFhRlzmNGwyJI4gfXr7syBcoukFf3QAjOX0CthMYG7h7pQEdale+N+Wp99M oOMuqdMUdi8DENc6lU1wWibD9weRgAlnw8Qj1lnU3C3WJgfpjcEQ02tSFOpqOtjFrvNa EU4FDWRepEONYR0qVmLv60bAF7sGjrU+4Re953iaf29rGFH5dtSz/0kw/ZwdSe33Spq4 gJyKb2Xn9Rm+bbvlIJGuzFiRejRZaJubdVR0dHRYt93mzzQlMQNWTLPZxEjsfYWwwS4I /F2qukysbXGJKblILu1tH3O5hLth5OYmfPW297pAAxeTqsHu1uqlYo6WpLQbL45GRJSh /xqQ== X-Gm-Message-State: AGi0PuZOooqjSXvUySqessR3rmo8kTO021ykCWpDOtOVfOsZJ3+OV8yy f1OG21wrCa00qJG+Cx9uuC8= X-Google-Smtp-Source: APiQypIrUMw1hdhx4Qed3GKdyAcFjRIjICbjnReAQgH3eSzjygPFpkxcMRnADhbuPM7BJLbId/hbpg== X-Received: by 2002:a63:1d52:: with SMTP id d18mr16969764pgm.443.1586791205642; Mon, 13 Apr 2020 08:20:05 -0700 (PDT) Received: from local.opencloud.tech.localdomain ([115.171.63.184]) by smtp.gmail.com with ESMTPSA id d23sm8887600pfq.210.2020.04.13.08.20.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Apr 2020 08:20:04 -0700 (PDT) From: xiangxia.m.yue@gmail.com To: olivier.matz@6wind.com, arybchenko@solarflare.com, gage.eads@intel.com, artem.andreev@oktetlabs.ru, jerinj@marvell.com, ndabilpuram@marvell.com, vattunuru@marvell.com, hemant.agrawal@nxp.com, david.marchand@redhat.com, anatoly.burakov@intel.com, bruce.richardson@intel.com Cc: dev@dpdk.org, Tonghao Zhang Date: Mon, 13 Apr 2020 22:21:53 +0800 Message-Id: <1586787714-13890-1-git-send-email-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1583114253-15345-1-git-send-email-xiangxia.m.yue@gmail.com> References: <1583114253-15345-1-git-send-email-xiangxia.m.yue@gmail.com> Subject: [dpdk-dev] [PATCH dpdk-dev v3 1/2] eal: introduce rte-init queue for libraries initialization 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" From: Tonghao Zhang This patch introduces rte-init queue, users can register a callback for theirs initialization. After the almost resource of DPDK are available (e.g. memzone, ring), invoke eal_rte_init_run(). With this way, users don't introduce additional codes in the eal layer. Suggested-by: Olivier Matz Suggested-by: Jerin Jacob Signed-off-by: Tonghao Zhang --- This patch will be used for next patch. and should be applied after http://patches.dpdk.org/patch/68119/ because of __rte_experimal v3: * add rte-init autotest * add __rte_experimal prefix * change return type of rte_init_register to int * update doc/api/doxy-api-index.md * update rte_eal_version.map * update comments * remove unused *.h in rte_init.h v2: * rename rte_last_init_register ->rte_init_register * rename rte_last_init struct ->rte_init * rename rte_init_cb ->rte_init_cb_t * free the rte_init node when not used * remove rte_init and others to eal_private.h * add comments * fix checkpatch warning --- app/test/Makefile | 1 + app/test/autotest_data.py | 6 +++ app/test/meson.build | 1 + app/test/test_rte_init.c | 35 +++++++++++++ doc/api/doxy-api-index.md | 1 + lib/librte_eal/common/eal_common_init.c | 87 +++++++++++++++++++++++++++++++++ lib/librte_eal/common/eal_private.h | 23 +++++++++ lib/librte_eal/common/meson.build | 1 + lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/freebsd/eal.c | 6 +++ lib/librte_eal/include/rte_init.h | 68 ++++++++++++++++++++++++++ lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/linux/eal.c | 6 +++ lib/librte_eal/rte_eal_version.map | 1 + 14 files changed, 238 insertions(+) create mode 100644 app/test/test_rte_init.c create mode 100644 lib/librte_eal/common/eal_common_init.c create mode 100644 lib/librte_eal/include/rte_init.h diff --git a/app/test/Makefile b/app/test/Makefile index 1f080d162659..494606ad4226 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -148,6 +148,7 @@ SRCS-y += test_alarm.c SRCS-y += test_interrupts.c SRCS-y += test_version.c SRCS-y += test_func_reentrancy.c +SRCS-y += test_rte_init.c SRCS-y += test_service_cores.c diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index 7b1d01389be4..d06c27d68b4a 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -267,6 +267,12 @@ "Report": None, }, { + "Name": "RTE INIT autotest", + "Command": "rte_init_autotest", + "Func": default_autotest, + "Report": None, + }, + { "Name": "Atomics autotest", "Command": "atomic_autotest", "Func": default_autotest, diff --git a/app/test/meson.build b/app/test/meson.build index 351d29cb657d..98a952a9285d 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -79,6 +79,7 @@ test_sources = files('commands.c', 'test_mempool.c', 'test_mempool_perf.c', 'test_memzone.c', + 'test_rte_init.c', 'test_meter.c', 'test_metrics.c', 'test_mcslock.c', diff --git a/app/test/test_rte_init.c b/app/test/test_rte_init.c new file mode 100644 index 000000000000..f6143bc76310 --- /dev/null +++ b/app/test/test_rte_init.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 DPDK Community + */ + +#include + +#include + +#include "test.h" + +static int +rte_init_cb(__rte_unused const void *arg) +{ + return 0; +} + +static int +test_rte_init(void) +{ + printf("test rte-init register API\n"); + if (rte_init_register(rte_init_cb, NULL, RTE_INIT_PRE) != 0) + return -1; + + printf("test rte-init cb\n"); + if (rte_init_register(NULL, NULL, RTE_INIT_PRE) != -EINVAL) + return -1; + + printf("test rte-init type\n"); + if (rte_init_register(NULL, NULL, 10) != -EINVAL) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(rte_init_autotest, test_rte_init); diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index dff496be0980..fa02c5f9f287 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -178,6 +178,7 @@ The public API headers are grouped by topics: - **misc**: [EAL config] (@ref rte_eal.h), + [RTE INIT] (@ref rte_init.h), [common] (@ref rte_common.h), [experimental APIs] (@ref rte_compat.h), [ABI versioning] (@ref rte_function_versioning.h), diff --git a/lib/librte_eal/common/eal_common_init.c b/lib/librte_eal/common/eal_common_init.c new file mode 100644 index 000000000000..f5ae5c51b667 --- /dev/null +++ b/lib/librte_eal/common/eal_common_init.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 DPDK Community + */ + +#include + +#include +#include +#include + +#include "eal_private.h" + +static struct rte_init_list rte_init_list = + TAILQ_HEAD_INITIALIZER(rte_init_list); + +int +rte_init_register(rte_init_cb_t cb, const void *arg, enum rte_init_type type) +{ + struct rte_init *last; + + if (cb == NULL) { + RTE_LOG(ERR, EAL, "RTE INIT cb is NULL.\n"); + return -EINVAL; + } + + if (type != RTE_INIT_PRE && type != RTE_INIT_POST) { + RTE_LOG(ERR, EAL, "RTE INIT type is invalid.\n"); + return -EINVAL; + } + + last = malloc(sizeof(*last)); + if (last == NULL) { + RTE_LOG(ERR, EAL, + "Allocate memory for rte_init node failed.\n"); + return -ENOMEM; + } + + last->type = type; + last->arg = arg; + last->cb = cb; + + TAILQ_INSERT_TAIL(&rte_init_list, last, next); + + return 0; +} + +static int +eal_rte_init_run_type(enum rte_init_type type) +{ + struct rte_init *last; + int ret; + + TAILQ_FOREACH(last, &rte_init_list, next) { + if (last->type != type) + continue; + + ret = last->cb(last->arg); + if (ret < 0) + return ret; + } + + return 0; +} + +int +eal_rte_init_run(void) +{ + struct rte_init *last; + struct rte_init *tmp; + int ret; + + ret = eal_rte_init_run_type(RTE_INIT_PRE); + if (ret < 0) + return ret; + + ret = eal_rte_init_run_type(RTE_INIT_POST); + if (ret < 0) + return ret; + + /* Free rte_init node, not used anymore. */ + TAILQ_FOREACH_SAFE(last, &rte_init_list, next, tmp) { + TAILQ_REMOVE(&rte_init_list, last, next); + free(last); + } + + return 0; +} diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index ddcfbe2e4442..f0bcc977eb9d 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -11,6 +11,7 @@ #include #include +#include /** * Structure storing internal configuration (per-lcore) @@ -60,6 +61,28 @@ struct rte_config { } __attribute__((__packed__)); /** + * A structure describing a generic initialization. + */ +struct rte_init { + TAILQ_ENTRY(rte_init) next; + enum rte_init_type type; + rte_init_cb_t cb; + const void *arg; +}; + +/** Double linked list of rte_init. */ +TAILQ_HEAD(rte_init_list, rte_init); + +/** + * Run the callback registered in the global double linked list. + * + * @return + * - 0 on success + * - Negative on error + */ +int eal_rte_init_run(void); + +/** * Get the global configuration structure. * * @return diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index 02d9280cc351..ad0ce6a19015 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -43,6 +43,7 @@ sources += files( 'eal_common_thread.c', 'eal_common_timer.c', 'eal_common_uuid.c', + 'eal_common_init.c', 'hotplug_mp.c', 'malloc_elem.c', 'malloc_heap.c', diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index e5d4d8ff260b..89c5649f16e6 100644 --- a/lib/librte_eal/freebsd/Makefile +++ b/lib/librte_eal/freebsd/Makefile @@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_init.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c index 6ae37e7e69be..63af98cb6ca7 100644 --- a/lib/librte_eal/freebsd/eal.c +++ b/lib/librte_eal/freebsd/eal.c @@ -874,6 +874,12 @@ static void rte_eal_init_alert(const char *msg) eal_check_mem_on_local_socket(); + if (eal_rte_init_run() < 0) { + rte_eal_init_alert("Cannot init objects in rte-init queue"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); diff --git a/lib/librte_eal/include/rte_init.h b/lib/librte_eal/include/rte_init.h new file mode 100644 index 000000000000..83c7fd47daec --- /dev/null +++ b/lib/librte_eal/include/rte_init.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 DPDK Community + */ + +#ifndef _RTE_INIT_H_ +#define _RTE_INIT_H_ + +#include + +/** + * @file + * + * RTE INIT Registration Interface + * + * This file exposes API for other libraries initialization callback. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Implementation specific callback function which is + * responsible for specificed initialization. + * + * This is invoked when almost resources are available. + * + * @return + * 0 for successfully invoked + * Negative for unsuccessfully invoked with error value + */ +typedef int (*rte_init_cb_t)(const void *arg); + +/** + * The RTE INIT type of callback function registered. + */ +enum rte_init_type { + RTE_INIT_PRE, /**< RTE INITs are invoked with high priority. */ + RTE_INIT_POST /**< Last RTE INITs invoked. */ +}; + +/** + * Register a rte_init callback. + * + * @param cb + * A pointer to a rte_init_cb structure, which will be invoked + * in rte_eal_init(). + * + * @param arg + * The cb will use that as param. + * + * @param type + * The type of rte_init registered. + * + * @return + * 0 for success register callback. + * -EINVAL one of the parameters was invalid. + * -ENOMEM no appropriate memory allocated. + */ +__rte_experimental +int rte_init_register(rte_init_cb_t cb, const void *arg, + enum rte_init_type type); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_INIT_H_ */ diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile index e5f44959c66c..918d94bec91e 100644 --- a/lib/librte_eal/linux/Makefile +++ b/lib/librte_eal/linux/Makefile @@ -67,6 +67,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_init.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c diff --git a/lib/librte_eal/linux/eal.c b/lib/librte_eal/linux/eal.c index 9530ee55f8e3..dd0c2589f6c4 100644 --- a/lib/librte_eal/linux/eal.c +++ b/lib/librte_eal/linux/eal.c @@ -1203,6 +1203,12 @@ static void rte_eal_init_alert(const char *msg) eal_check_mem_on_local_socket(); + if (eal_rte_init_run() < 0) { + rte_eal_init_alert("Cannot init objects in rte-init queue"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index f9ede5b41c69..23aa30f542db 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -338,4 +338,5 @@ EXPERIMENTAL { # added in 20.05 rte_log_can_log; + rte_init_register; }; From patchwork Mon Apr 13 14:21:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 68314 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id F0490A0577; Mon, 13 Apr 2020 17:20:16 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5C08E1C037; Mon, 13 Apr 2020 17:20:13 +0200 (CEST) Received: from mail-pj1-f66.google.com (mail-pj1-f66.google.com [209.85.216.66]) by dpdk.org (Postfix) with ESMTP id 4F9F61BE9D for ; Mon, 13 Apr 2020 17:20:12 +0200 (CEST) Received: by mail-pj1-f66.google.com with SMTP id mn19so3915898pjb.0 for ; Mon, 13 Apr 2020 08:20:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=f2gnX54kZLzFZHdQw+9h+BM1SFfWAdNrK5iMXJKifBU=; b=fn3jsA6TS/uX8xiWflvfsxE59lwkbztbH+5qwllg15wE7CQ5SX6dDSYI4hTYpCzkT4 2PBGQ9Ey+SY18m4QLRU1xiDLMiOqM2tOlflXKEchiwrGUtmKDgaaSStOUo7cVnPJFsKE B95K6L9tMPzXJo2wJ1fdNVuVTuFnd7ozEELGsMI4FjgyQk19g5poLVXqfxm21liWAPE4 x1uD2pm1G8kUVHZllOCe5hjrbMEA9SbettYFE+gUap0C1emjW5M4Lga2VjgNiA2gnQha OF/mTzWqM3aN/QT8XPuLqv0ZSmAQh83hHpe4S8u8GffOFDTGhyP/6/HQ9Ia9Rht1sTN0 sMBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f2gnX54kZLzFZHdQw+9h+BM1SFfWAdNrK5iMXJKifBU=; b=RiZfIRZbBHswpKKGxYXH/xkDYrkYPe5ESf9msHxjtOdNgVByOr0UPp/UmSQ2h23dcI bScvKAQarPGHEaUT0Y5nTulSPGinxUvjZ9etgrQ3goRF53+rDAb0sB7z6eslcrO6ZhZ/ 8opPBKbgU3PO7L0mua0mnMKUEjJCmDbpnhpa9INaEg+0ANYliUmKUXIHTiibPHdiCwdt KJKjoHk3SfwHfxBWiB/SvoOd7/7VYheoYeoWiUVpxqCzOVAnNOc5Hixwyq+j90R+t5KY DuwyyGLmtxy9mLEKPs1BopwFON9vKFxQqtsO8SLwf+0dpUrbb9buotRwd8vsYh2Y6JjN 3vWQ== X-Gm-Message-State: AGi0PuZM/jRm0nGXQWki8YQTdLteGn52Tt5T9PhtI83ZeIuG0av/Tuc0 F5eISzYWvTQDAStFgJimz1w= X-Google-Smtp-Source: APiQypIcubnlczZiqM72mbJtnqSuw5SAtrUeuxzL3bu6OodDSH9yDbGZ1YFHAI6VCzsmvwpAQw3Eaw== X-Received: by 2002:a17:902:aa97:: with SMTP id d23mr17673875plr.244.1586791211511; Mon, 13 Apr 2020 08:20:11 -0700 (PDT) Received: from local.opencloud.tech.localdomain ([115.171.63.184]) by smtp.gmail.com with ESMTPSA id d23sm8887600pfq.210.2020.04.13.08.20.06 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Apr 2020 08:20:10 -0700 (PDT) From: xiangxia.m.yue@gmail.com To: olivier.matz@6wind.com, arybchenko@solarflare.com, gage.eads@intel.com, artem.andreev@oktetlabs.ru, jerinj@marvell.com, ndabilpuram@marvell.com, vattunuru@marvell.com, hemant.agrawal@nxp.com, david.marchand@redhat.com, anatoly.burakov@intel.com, bruce.richardson@intel.com Cc: dev@dpdk.org, Tonghao Zhang Date: Mon, 13 Apr 2020 22:21:54 +0800 Message-Id: <1586787714-13890-2-git-send-email-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1586787714-13890-1-git-send-email-xiangxia.m.yue@gmail.com> References: <1583114253-15345-1-git-send-email-xiangxia.m.yue@gmail.com> <1586787714-13890-1-git-send-email-xiangxia.m.yue@gmail.com> Subject: [dpdk-dev] [PATCH dpdk-dev v3 2/2] mempool: use shared memzone for rte_mempool_ops 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" From: Tonghao Zhang The order of mempool initiation affects mempool index in the rte_mempool_ops_table. For example, when building APPs with: $ gcc -lrte_mempool_bucket -lrte_mempool_ring ... The "bucket" mempool will be registered firstly, and its index in table is 0 while the index of "ring" mempool is 1. DPDK uses the mk/rte.app.mk to build APPs, and others, for example, Open vSwitch, use the libdpdk.a or libdpdk.so to build it. The mempool lib linked in dpdk and Open vSwitch is different. The mempool can be used between primary and secondary process, such as dpdk-pdump and pdump-pmd/Open vSwitch(pdump enabled). There will be a crash because dpdk-pdump creates the "ring_mp_mc" ring which index in table is 0, but the index of "bucket" ring is 0 in Open vSwitch. If Open vSwitch use the index 0 to get mempool ops and malloc memory from mempool. The crash will occur: bucket_dequeue (access null and crash) rte_mempool_get_ops (should get "ring_mp_mc", but get "bucket" mempool) rte_mempool_ops_dequeue_bulk ... rte_pktmbuf_alloc rte_pktmbuf_copy pdump_copy pdump_rx rte_eth_rx_burst To avoid the crash, there are some solution: * constructor priority: Different mempool uses different priority in RTE_INIT, but it's not easy to maintain. * change mk/rte.app.mk: Change the order in mk/rte.app.mk to be same as libdpdk.a/libdpdk.so, but when adding a new mempool driver in future, we must make sure the order. * register mempool orderly: Sort the mempool when registering, so the lib linked will not affect the index in mempool table. but the number of mempool libraries may be different. * shared memzone: The primary process allocates a struct in shared memory named memzone, When we register a mempool ops, we first get a name and id from the shared struct: with the lock held, lookup for the registered name and return its index, else get the last id and copy the name in the struct. Previous discussion: https://mails.dpdk.org/archives/dev/2020-March/159354.html Suggested-by: Olivier Matz Suggested-by: Jerin Jacob Signed-off-by: Tonghao Zhang --- v2: * fix checkpatch warning --- lib/librte_mempool/rte_mempool.h | 28 +++++++++++- lib/librte_mempool/rte_mempool_ops.c | 89 ++++++++++++++++++++++++++++-------- 2 files changed, 96 insertions(+), 21 deletions(-) diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index c90cf31467b2..2709b9e1d51b 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -50,6 +50,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -678,7 +679,6 @@ struct rte_mempool_ops { */ struct rte_mempool_ops_table { rte_spinlock_t sl; /**< Spinlock for add/delete. */ - uint32_t num_ops; /**< Number of used ops structs in the table. */ /** * Storage for all possible ops structs. */ @@ -910,6 +910,30 @@ int rte_mempool_ops_get_info(const struct rte_mempool *mp, */ int rte_mempool_register_ops(const struct rte_mempool_ops *ops); +struct rte_mempool_shared_ops { + size_t num_mempool_ops; + struct { + char name[RTE_MEMPOOL_OPS_NAMESIZE]; + } mempool_ops[RTE_MEMPOOL_MAX_OPS_IDX]; + + rte_spinlock_t mempool; +}; + +static inline int +mempool_ops_register_cb(const void *arg) +{ + const struct rte_mempool_ops *h = (const struct rte_mempool_ops *)arg; + + return rte_mempool_register_ops(h); +} + +static inline void +mempool_ops_register(const struct rte_mempool_ops *ops) +{ + rte_init_register(mempool_ops_register_cb, (const void *)ops, + RTE_INIT_PRE); +} + /** * Macro to statically register the ops of a mempool handler. * Note that the rte_mempool_register_ops fails silently here when @@ -918,7 +942,7 @@ int rte_mempool_ops_get_info(const struct rte_mempool *mp, #define MEMPOOL_REGISTER_OPS(ops) \ RTE_INIT(mp_hdlr_init_##ops) \ { \ - rte_mempool_register_ops(&ops); \ + mempool_ops_register(&ops); \ } /** diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c index 22c5251eb068..b10fda662db6 100644 --- a/lib/librte_mempool/rte_mempool_ops.c +++ b/lib/librte_mempool/rte_mempool_ops.c @@ -14,43 +14,95 @@ /* indirect jump table to support external memory pools. */ struct rte_mempool_ops_table rte_mempool_ops_table = { .sl = RTE_SPINLOCK_INITIALIZER, - .num_ops = 0 }; -/* add a new ops struct in rte_mempool_ops_table, return its index. */ -int -rte_mempool_register_ops(const struct rte_mempool_ops *h) +static int +rte_mempool_register_shared_ops(const char *name) { - struct rte_mempool_ops *ops; - int16_t ops_index; + static bool mempool_shared_ops_inited; + struct rte_mempool_shared_ops *shared_ops; + const struct rte_memzone *mz; + uint32_t ops_index = 0; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY && + !mempool_shared_ops_inited) { + + mz = rte_memzone_reserve("mempool_ops_shared", + sizeof(*shared_ops), 0, 0); + if (mz == NULL) + return -ENOMEM; + + shared_ops = mz->addr; + shared_ops->num_mempool_ops = 0; + rte_spinlock_init(&shared_ops->mempool); + + mempool_shared_ops_inited = true; + } else { + mz = rte_memzone_lookup("mempool_ops_shared"); + if (mz == NULL) + return -ENOMEM; + + shared_ops = mz->addr; + } - rte_spinlock_lock(&rte_mempool_ops_table.sl); + rte_spinlock_lock(&shared_ops->mempool); - if (rte_mempool_ops_table.num_ops >= - RTE_MEMPOOL_MAX_OPS_IDX) { - rte_spinlock_unlock(&rte_mempool_ops_table.sl); + if (shared_ops->num_mempool_ops >= RTE_MEMPOOL_MAX_OPS_IDX) { + rte_spinlock_unlock(&shared_ops->mempool); RTE_LOG(ERR, MEMPOOL, "Maximum number of mempool ops structs exceeded\n"); return -ENOSPC; } + while (shared_ops->mempool_ops[ops_index].name[0]) { + if (!strcmp(name, shared_ops->mempool_ops[ops_index].name)) { + rte_spinlock_unlock(&shared_ops->mempool); + return ops_index; + } + + ops_index++; + } + + strlcpy(shared_ops->mempool_ops[ops_index].name, name, + sizeof(shared_ops->mempool_ops[0].name)); + + shared_ops->num_mempool_ops++; + + rte_spinlock_unlock(&shared_ops->mempool); + return ops_index; +} + +/* add a new ops struct in rte_mempool_ops_table, return its index. */ +int +rte_mempool_register_ops(const struct rte_mempool_ops *h) +{ + struct rte_mempool_ops *ops; + int16_t ops_index; + if (h->alloc == NULL || h->enqueue == NULL || - h->dequeue == NULL || h->get_count == NULL) { - rte_spinlock_unlock(&rte_mempool_ops_table.sl); + h->dequeue == NULL || h->get_count == NULL) { RTE_LOG(ERR, MEMPOOL, "Missing callback while registering mempool ops\n"); + rte_errno = EINVAL; return -EINVAL; } if (strlen(h->name) >= sizeof(ops->name) - 1) { - rte_spinlock_unlock(&rte_mempool_ops_table.sl); - RTE_LOG(DEBUG, EAL, "%s(): mempool_ops <%s>: name too long\n", - __func__, h->name); + RTE_LOG(ERR, MEMPOOL, + "The registering mempool_ops <%s>: name too long\n", + h->name); rte_errno = EEXIST; return -EEXIST; } - ops_index = rte_mempool_ops_table.num_ops++; + ops_index = rte_mempool_register_shared_ops(h->name); + if (ops_index < 0) { + rte_errno = -ops_index; + return ops_index; + } + + rte_spinlock_lock(&rte_mempool_ops_table.sl); + ops = &rte_mempool_ops_table.ops[ops_index]; strlcpy(ops->name, h->name, sizeof(ops->name)); ops->alloc = h->alloc; @@ -165,9 +217,8 @@ struct rte_mempool_ops_table rte_mempool_ops_table = { if (mp->flags & MEMPOOL_F_POOL_CREATED) return -EEXIST; - for (i = 0; i < rte_mempool_ops_table.num_ops; i++) { - if (!strcmp(name, - rte_mempool_ops_table.ops[i].name)) { + for (i = 0; i < RTE_MEMPOOL_MAX_OPS_IDX; i++) { + if (!strcmp(name, rte_mempool_ops_table.ops[i].name)) { ops = &rte_mempool_ops_table.ops[i]; break; }