From patchwork Sat Oct 27 09:17:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Van Haaren, Harry" X-Patchwork-Id: 47512 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 09AEC532C; Sat, 27 Oct 2018 11:19:44 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 00BF34C8C for ; Sat, 27 Oct 2018 11:19:30 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Oct 2018 02:19:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,431,1534834800"; d="scan'208";a="84903873" Received: from silpixa00399779.ir.intel.com (HELO silpixa00399779.ger.corp.intel.com) ([10.237.223.188]) by orsmga008.jf.intel.com with ESMTP; 27 Oct 2018 02:19:28 -0700 From: Harry van Haaren To: dev@dpdk.org Cc: thomas@monjalon.net, bruce.richardson@intel.com, stephen@networkplumber.org, gaetan.rivet@6wind.com, shreyansh.jain@nxp.com, mattias.ronnblom@ericsson.com, Ciara Power , Brian Archbold , Kevin Laatz , Radu Nicolau Date: Sat, 27 Oct 2018 10:17:41 +0100 Message-Id: <20181027091750.17254-4-harry.van.haaren@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181027091750.17254-1-harry.van.haaren@intel.com> References: <20181026235933.79779-1-harry.van.haaren@intel.com> <20181027091750.17254-1-harry.van.haaren@intel.com> Subject: [dpdk-dev] [PATCH v10 03/12] telemetry: initial telemetry infrastructure 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: Ciara Power This patch adds the infrastructure and initial code for the telemetry library. The telemetry init is registered with eal_init(). We can then check to see if --telemetry was passed as an eal option. If --telemetry was parsed, then we call telemetry init at the end of eal init. Control threads are used to get CPU cycles for telemetry, which are configured in this patch also. Signed-off-by: Ciara Power Signed-off-by: Brian Archbold Signed-off-by: Kevin Laatz Signed-off-by: Radu Nicolau Acked-by: Harry van Haaren --- v10: - change position of Telemetry in index Doxygen index (Thomas) - Add MAINTAINER file entry for lib/telemetry files (Thomas) - Removed -ljansson from mk/rte.app.mk (Thomas) - Removed pkg-config jansson check in mk/rte.vars.mk (Thomas) - Set CONFIG_TELEMETRY=N by default (Thomas) --- MAINTAINERS | 3 + config/common_base | 5 + doc/api/doxy-api-index.md | 1 + doc/api/doxy-api.conf.in | 1 + lib/Makefile | 2 + lib/librte_telemetry/Makefile | 27 ++++ lib/librte_telemetry/meson.build | 7 + lib/librte_telemetry/rte_telemetry.c | 123 ++++++++++++++++++ lib/librte_telemetry/rte_telemetry.h | 51 ++++++++ lib/librte_telemetry/rte_telemetry_internal.h | 32 +++++ .../rte_telemetry_version.map | 8 ++ lib/meson.build | 2 +- mk/rte.app.mk | 3 +- 13 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 lib/librte_telemetry/Makefile create mode 100644 lib/librte_telemetry/meson.build create mode 100644 lib/librte_telemetry/rte_telemetry.c create mode 100644 lib/librte_telemetry/rte_telemetry.h create mode 100644 lib/librte_telemetry/rte_telemetry_internal.h create mode 100644 lib/librte_telemetry/rte_telemetry_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 17ee5b9d3..a50214d7a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1208,6 +1208,9 @@ F: test/bpf/ F: test/test/test_bpf.c F: doc/guides/prog_guide/bpf_lib.rst +Telemetry - EXPERIMENTAL +M: Kevin Laatz +F: lib/librte_telemetry/ Test Applications ----------------- diff --git a/config/common_base b/config/common_base index 38beaabb3..4ba8f651d 100644 --- a/config/common_base +++ b/config/common_base @@ -756,6 +756,11 @@ CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n CONFIG_RTE_LIBRTE_HASH=y CONFIG_RTE_LIBRTE_HASH_DEBUG=n +# +# Compile librte_telemetry +# +CONFIG_RTE_LIBRTE_TELEMETRY=n + # # Compile librte_efd # diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index a3039d168..cd2b7e413 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -29,6 +29,7 @@ The public API headers are grouped by topics: [metrics] (@ref rte_metrics.h), [bitrate] (@ref rte_bitrate.h), [latency] (@ref rte_latencystats.h), + [telemetry] (@ref rte_telemetry.h), [devargs] (@ref rte_devargs.h), [PCI] (@ref rte_pci.h), [vfio] (@ref rte_vfio.h) diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in index 3b652ac9c..77ba327a8 100644 --- a/doc/api/doxy-api.conf.in +++ b/doc/api/doxy-api.conf.in @@ -56,6 +56,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/lib/librte_sched \ @TOPDIR@/lib/librte_security \ @TOPDIR@/lib/librte_table \ + @TOPDIR@/lib/librte_telemetry \ @TOPDIR@/lib/librte_timer \ @TOPDIR@/lib/librte_vhost INPUT += @API_EXAMPLES@ diff --git a/lib/Makefile b/lib/Makefile index 062cbdfd7..b7370ef97 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -106,6 +106,8 @@ DEPDIRS-librte_gso := librte_eal librte_mbuf librte_ethdev librte_net DEPDIRS-librte_gso += librte_mempool DIRS-$(CONFIG_RTE_LIBRTE_BPF) += librte_bpf DEPDIRS-librte_bpf := librte_eal librte_mempool librte_mbuf librte_ethdev +DIRS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += librte_telemetry +DEPDIRS-librte_telemetry := librte_eal librte_metrics librte_ethdev ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefile new file mode 100644 index 000000000..a2d4ff166 --- /dev/null +++ b/lib/librte_telemetry/Makefile @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Intel Corporation + +include $(RTE_SDK)/mk/rte.vars.mk + +# library name +LIB = librte_telemetry.a + +CFLAGS += -O3 +CFLAGS += -I$(SRCDIR) +CFLAGS += -DALLOW_EXPERIMENTAL_API + +LDLIBS += -lrte_eal -lrte_ethdev +LDLIBS += -lrte_metrics +LDLIBS += -lpthread + +EXPORT_MAP := rte_telemetry_version.map + +LIBABIVER := 1 + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) := rte_telemetry.c + +# export include files +SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include := rte_telemetry.h + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meson.build new file mode 100644 index 000000000..7716076a9 --- /dev/null +++ b/lib/librte_telemetry/meson.build @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Intel Corporation + +sources = files('rte_telemetry.c') +headers = files('rte_telemetry.h', 'rte_telemetry_internal.h') +deps += ['metrics', 'ethdev'] +cflags += '-DALLOW_EXPERIMENTAL_API' diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c new file mode 100644 index 000000000..7f4ad0342 --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include + +#include +#include +#include +#include + +#include "rte_telemetry.h" +#include "rte_telemetry_internal.h" + +#define SLEEP_TIME 10 + +static telemetry_impl *static_telemetry; + +static int32_t +rte_telemetry_run(void *userdata) +{ + struct telemetry_impl *telemetry = userdata; + + if (telemetry == NULL) { + TELEMETRY_LOG_WARN("TELEMETRY could not be initialised"); + return -1; + } + + return 0; +} + +static void +*rte_telemetry_run_thread_func(void *userdata) +{ + int ret; + struct telemetry_impl *telemetry = userdata; + + if (telemetry == NULL) { + TELEMETRY_LOG_ERR("%s passed a NULL instance", __func__); + pthread_exit(0); + } + + while (telemetry->thread_status) { + rte_telemetry_run(telemetry); + ret = usleep(SLEEP_TIME); + if (ret < 0) + TELEMETRY_LOG_ERR("Calling thread could not be put to sleep"); + } + pthread_exit(0); +} + +int32_t __rte_experimental +rte_telemetry_init() +{ + int ret; + pthread_attr_t attr; + const char *telemetry_ctrl_thread = "telemetry"; + + if (static_telemetry) { + TELEMETRY_LOG_WARN("TELEMETRY structure already initialised"); + return -EALREADY; + } + + static_telemetry = calloc(1, sizeof(struct telemetry_impl)); + if (static_telemetry == NULL) { + TELEMETRY_LOG_ERR("Memory could not be allocated"); + return -ENOMEM; + } + + static_telemetry->socket_id = rte_socket_id(); + rte_metrics_init(static_telemetry->socket_id); + + ret = pthread_attr_init(&attr); + if (ret != 0) { + TELEMETRY_LOG_ERR("Pthread attribute init failed"); + return -EPERM; + } + + ret = rte_ctrl_thread_create(&static_telemetry->thread_id, + telemetry_ctrl_thread, &attr, rte_telemetry_run_thread_func, + (void *)static_telemetry); + static_telemetry->thread_status = 1; + + if (ret < 0) { + ret = rte_telemetry_cleanup(); + if (ret < 0) + TELEMETRY_LOG_ERR("TELEMETRY cleanup failed"); + return -EPERM; + } + + return 0; +} + +int32_t __rte_experimental +rte_telemetry_cleanup(void) +{ + struct telemetry_impl *telemetry = static_telemetry; + telemetry->thread_status = 0; + pthread_join(telemetry->thread_id, NULL); + free(telemetry); + static_telemetry = NULL; + return 0; +} + +int telemetry_log_level; +RTE_INIT(rte_telemetry_register); + +static struct rte_option option = { + .opt_str = "--telemetry", + .cb = &rte_telemetry_init, + .enabled = 0 +}; + +static void +rte_telemetry_register(void) +{ + telemetry_log_level = rte_log_register("lib.telemetry"); + if (telemetry_log_level >= 0) + rte_log_set_level(telemetry_log_level, RTE_LOG_ERR); + + rte_option_register(&option); +} diff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/rte_telemetry.h new file mode 100644 index 000000000..97674ae2d --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include + +#ifndef _RTE_TELEMETRY_H_ +#define _RTE_TELEMETRY_H_ + +/** + * @file + * RTE Telemetry + * + * The telemetry library provides a method to retrieve statistics from + * DPDK by sending a JSON encoded message over a socket. DPDK will send + * a JSON encoded response containing telemetry data. + ***/ + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Initialize Telemetry + * + * @return + * 0 on successful initialisation. + * @return + * -ENOMEM on memory allocation error + * @return + * -EPERM on unknown error failure + * @return + * -EALREADY if Telemetry is already initialised. + */ +int32_t __rte_experimental +rte_telemetry_init(void); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Clean up and free memory. + * + * @return + * 0 on success + * @return + * -EPERM on failure + */ +int32_t __rte_experimental +rte_telemetry_cleanup(void); + +#endif diff --git a/lib/librte_telemetry/rte_telemetry_internal.h b/lib/librte_telemetry/rte_telemetry_internal.h new file mode 100644 index 000000000..4e810a84c --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry_internal.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include + +#ifndef _RTE_TELEMETRY_INTERNAL_H_ +#define _RTE_TELEMETRY_INTERNAL_H_ + +/* Logging Macros */ +extern int telemetry_log_level; + +#define TELEMETRY_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ##level, telemetry_log_level, "%s(): "fmt "\n", \ + __func__, ##args) + +#define TELEMETRY_LOG_ERR(fmt, args...) \ + TELEMETRY_LOG(ERR, fmt, ## args) + +#define TELEMETRY_LOG_WARN(fmt, args...) \ + TELEMETRY_LOG(WARNING, fmt, ## args) + +#define TELEMETRY_LOG_INFO(fmt, args...) \ + TELEMETRY_LOG(INFO, fmt, ## args) + +typedef struct telemetry_impl { + pthread_t thread_id; + int thread_status; + uint32_t socket_id; +} telemetry_impl; + +#endif diff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map new file mode 100644 index 000000000..bbcd9a796 --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry_version.map @@ -0,0 +1,8 @@ +EXPERIMENTAL { + global: + + rte_telemetry_cleanup; + rte_telemetry_init; + + local: *; +}; diff --git a/lib/meson.build b/lib/meson.build index 2b903fa37..9d1f353d2 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -25,7 +25,7 @@ libraries = [ 'compat', # just a header, used for versioning # add pkt framework libs which use other libs from above 'port', 'table', 'pipeline', # flow_classify lib depends on pkt framework table lib - 'flow_classify', 'bpf'] + 'flow_classify', 'bpf', 'telemetry'] default_cflags = machine_args if cc.has_argument('-Wno-format-truncation') diff --git a/mk/rte.app.mk b/mk/rte.app.mk index c0036daf8..a14e83c71 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -51,7 +51,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --no-whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats -_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE) += -lrte_bitratestats _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += -lrte_latencystats _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power @@ -80,6 +79,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_SECURITY) += -lrte_security _LDLIBS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV) += -lrte_compressdev _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev _LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV) += -lrte_rawdev +_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics +_LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += -lrte_telemetry _LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring