From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 18D7CA058B; Wed, 25 Mar 2020 22:17:18 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C98631C0AB; Wed, 25 Mar 2020 22:16:24 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 060781C0AC for ; Wed, 25 Mar 2020 22:16:22 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 02PLGFX9008331; Wed, 25 Mar 2020 14:16:22 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0818; bh=IOP6fCW6sjfp6YYA/W68NTfei/jW0vQGFiTHiSqHa48=; b=B8nTmI1xgG4FWMM3C3PeA46odTdp7NMwplmmwVx06jpHqjatqNxN0cNHfml7NAnA42qm cxqRt+r3NAiybm/EqlBC0ElQmL+3q8ewgydjbtCx1wvHv+mtm9ZpqwaO8msz4KThHgMq 27C0wEmpwbicKhiYKfjKEvvTCvhrBHvvIpqKjHRpvIY5eGJttzQFCIYyxKhbki7o1CXz OpVEJkzgCNGrXod2TgFI5dkSqppXW8DrD4kGc4t2NY+IShC/4U0DPaOEVq1bEs//7NMj mOWQ1c1Gf4Br7TghYoOP2HMAlbmc2mZNArg+fGhMsGwkJx18zPr0qJ89W/aTcx5fG1zq /g== Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0a-0016f401.pphosted.com with ESMTP id 2ywg9ntexx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 25 Mar 2020 14:16:22 -0700 Received: from SC-EXCH03.marvell.com (10.93.176.83) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Mar 2020 14:16:20 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 25 Mar 2020 14:16:20 -0700 Received: from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14]) by maili.marvell.com (Postfix) with ESMTP id 753E53F7044; Wed, 25 Mar 2020 14:16:18 -0700 (PDT) From: To: CC: , , , , , , Jerin Jacob Date: Thu, 26 Mar 2020 02:45:39 +0530 Message-ID: <20200325211603.240288-10-jerinj@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200325211603.240288-1-jerinj@marvell.com> References: <20200318190241.3150971-1-jerinj@marvell.com> <20200325211603.240288-1-jerinj@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.645 definitions=2020-03-25_11:2020-03-24, 2020-03-25 signatures=0 Subject: [dpdk-dev] [PATCH v2 09/32] eal/trace: implement trace memory allocation 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: Jerin Jacob Trace memory will be allocated per thread to enable lockless trace events updates to the memory. The allocator will first attempt to allocate from hugepage, if not available from hugepage then fallback to malloc memory. Later in the patches series, This API will be hooked to DPDK fastpath and control plane thread creation API. It is possible for non DPDK thread to use trace events, in that case, trace memory will be allocated on the first event emission. Signed-off-by: Jerin Jacob --- lib/librte_eal/common/eal_common_trace.c | 97 +++++++++++++++++++ .../common/eal_common_trace_utils.c | 20 ++++ lib/librte_eal/common/eal_trace.h | 29 ++++++ lib/librte_eal/common/include/rte_trace.h | 13 +++ .../common/include/rte_trace_provider.h | 19 ++++ lib/librte_eal/rte_eal_version.map | 2 + 6 files changed, 180 insertions(+) diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c index e889c6f0e..4f032273c 100644 --- a/lib/librte_eal/common/eal_common_trace.c +++ b/lib/librte_eal/common/eal_common_trace.c @@ -16,6 +16,7 @@ #include "eal_trace.h" RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz); +RTE_DEFINE_PER_LCORE(void *, trace_mem); RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]); RTE_DEFINE_PER_LCORE(int, ctf_count); @@ -37,6 +38,9 @@ trace_list_head_get(void) int eal_trace_init(void) { + /* Trace memory should start with 8B aligned for natural alignment */ + RTE_BUILD_BUG_ON((offsetof(struct __rte_trace_header, mem) % 8) != 0); + /* One of the Trace registration failed */ if (trace.register_errno) { rte_errno = trace.register_errno; @@ -83,6 +87,7 @@ eal_trace_fini(void) { if (rte_trace_global_is_disabled()) return; + trace_mem_per_thread_free(); trace_metadata_destroy(); } @@ -327,6 +332,98 @@ rte_trace_by_name(const char *name) return NULL; } +static inline size_t +list_sz(uint32_t index) +{ + return sizeof(struct thread_mem_meta) * (index + 1); +} + +void +__rte_trace_mem_per_thread_alloc(void) +{ + struct trace *trace = trace_obj_get(); + struct __rte_trace_header *header; + uint32_t count; + + if (rte_trace_global_is_disabled()) + return; + + if (RTE_PER_LCORE(trace_mem)) + return; + + rte_spinlock_lock(&trace->lock); + + count = trace->nb_trace_mem_list; + + /* Allocate room for storing the thread trace mem meta */ + trace->lcore_meta = realloc(trace->lcore_meta, list_sz(count)); + + /* Provide dummy space for fastpath to consume */ + if (trace->lcore_meta == NULL) { + trace_crit("trace mem meta memory realloc failed"); + header = NULL; goto fail; + } + + /* First attempt from huge page */ + header = rte_malloc(NULL, trace_mem_sz(trace->buff_len), 8); + if (header) { + trace->lcore_meta[count].area = TRACE_AREA_HUGEPAGE; + goto found; + } + + /* Second attempt from heap */ + header = malloc(trace_mem_sz(trace->buff_len)); + if (header == NULL) { + trace_crit("trace mem malloc attempt failed"); + header = NULL; goto fail; + + } + + /* Second attempt from heap is success */ + trace->lcore_meta[count].area = TRACE_AREA_HEAP; + + /* Initialize the trace header */ +found: + header->offset = 0; + header->len = trace->buff_len; + header->stream_header.magic = TRACE_CTF_MAGIC; + rte_uuid_copy(header->stream_header.uuid, trace->uuid); + header->stream_header.lcore_id = rte_lcore_id(); + + /* Store the thread name */ + char *name = header->stream_header.thread_name; + memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX); + rte_thread_getname(pthread_self(), name, + __RTE_TRACE_EMIT_STRING_LEN_MAX); + + trace->lcore_meta[count].mem = header; + trace->nb_trace_mem_list++; +fail: + RTE_PER_LCORE(trace_mem) = header; + rte_spinlock_unlock(&trace->lock); +} + +void +trace_mem_per_thread_free(void) +{ + struct trace *trace = trace_obj_get(); + uint32_t count; + void *mem; + + if (rte_trace_global_is_disabled()) + return; + + rte_spinlock_lock(&trace->lock); + for (count = 0; count < trace->nb_trace_mem_list; count++) { + mem = trace->lcore_meta[count].mem; + if (trace->lcore_meta[count].area == TRACE_AREA_HUGEPAGE) + rte_free(mem); + else if (trace->lcore_meta[count].area == TRACE_AREA_HEAP) + free(mem); + } + rte_spinlock_unlock(&trace->lock); +} + int __rte_trace_point_register(rte_trace_t *handle, const char *name, uint32_t level, void (*register_fn)(void)) diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c index f65672119..b288a72f0 100644 --- a/lib/librte_eal/common/eal_common_trace_utils.c +++ b/lib/librte_eal/common/eal_common_trace_utils.c @@ -14,6 +14,26 @@ #include "eal_filesystem.h" #include "eal_trace.h" +const char * +trace_mode_to_string(enum rte_trace_mode mode) +{ + switch (mode) { + case RTE_TRACE_MODE_OVERWRITE: return "overwrite"; + case RTE_TRACE_MODE_DISCARD: return "discard"; + default: return "unknown"; + } +} + +const char * +trace_area_to_string(enum trace_area_e area) +{ + switch (area) { + case TRACE_AREA_HEAP: return "heap"; + case TRACE_AREA_HUGEPAGE: return "hugepage"; + default: return "unknown"; + } +} + static bool trace_entry_compare(const char *name) { diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h index 4c77796ce..848d1dfc0 100644 --- a/lib/librte_eal/common/eal_trace.h +++ b/lib/librte_eal/common/eal_trace.h @@ -6,10 +6,15 @@ #define __EAL_TRACE_H #include +#include +#include #include #include #include +#include "eal_private.h" +#include "eal_thread.h" + #define trace_err(fmt, args...)\ RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\ __func__, __LINE__, ## args) @@ -22,6 +27,8 @@ #define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN) #define TRACE_CTF_FIELD_SIZE 384 #define TRACE_POINT_NAME_SIZE 64 +#define TRACE_CTF_MAGIC 0xC1FC1FC1 + struct trace_point { STAILQ_ENTRY(trace_point) next; @@ -30,6 +37,16 @@ struct trace_point { char ctf_field[TRACE_CTF_FIELD_SIZE]; }; +enum trace_area_e { + TRACE_AREA_HEAP, + TRACE_AREA_HUGEPAGE, +}; + +struct thread_mem_meta { + void *mem; + enum trace_area_e area; +}; + struct trace { char dir[PATH_MAX]; int dir_offset; @@ -37,8 +54,11 @@ struct trace { bool global_status; enum rte_trace_mode mode; rte_uuid_t uuid; + uint32_t buff_len; uint32_t level; uint32_t nb_trace_points; + uint32_t nb_trace_mem_list; + struct thread_mem_meta *lcore_meta; uint64_t epoch_sec; uint64_t epoch_nsec; uint64_t uptime_ticks; @@ -58,6 +78,12 @@ trace_id_get(rte_trace_t *trace) __RTE_TRACE_FIELD_ID_SHIFT; } +static inline size_t +trace_mem_sz(uint32_t len) +{ + return len + sizeof(struct __rte_trace_header); +} + /* Trace object functions */ struct trace *trace_obj_get(void); @@ -66,12 +92,15 @@ STAILQ_HEAD(trace_point_head, trace_point); struct trace_point_head *trace_list_head_get(void); /* Util functions */ +const char *trace_mode_to_string(enum rte_trace_mode mode); +const char *trace_area_to_string(enum trace_area_e area); bool trace_has_duplicate_entry(void); void trace_uuid_generate(void); int trace_metadata_create(void); void trace_metadata_destroy(void); int trace_mkdir(void); int trace_epoch_time_save(void); +void trace_mem_per_thread_free(void); /* EAL interface */ int eal_trace_init(void); diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h index 90b9d5894..8293c23c8 100644 --- a/lib/librte_eal/common/include/rte_trace.h +++ b/lib/librte_eal/common/include/rte_trace.h @@ -515,6 +515,19 @@ _tp _args \ #endif /* __DOXYGEN__ */ +/** @internal Macro to define maximum emit length of string datatype. */ +#define __RTE_TRACE_EMIT_STRING_LEN_MAX 32 + +/** + * @internal @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Allocate trace memory buffer per thread. + * + */ +__rte_experimental +void __rte_trace_mem_per_thread_alloc(void); + /** * @internal @warning * @b EXPERIMENTAL: this API may change without prior notice diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h index b4da87ba1..2257de85b 100644 --- a/lib/librte_eal/common/include/rte_trace_provider.h +++ b/lib/librte_eal/common/include/rte_trace_provider.h @@ -9,6 +9,10 @@ #ifndef _RTE_TRACE_PROVIDER_H_ #define _RTE_TRACE_PROVIDER_H_ +#include +#include +#include + #define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48) #define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63) @@ -20,5 +24,20 @@ #define __RTE_TRACE_FIELD_LEVEL_SHIFT (32) #define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT) +struct __rte_trace_stream_header { + uint32_t magic; + rte_uuid_t uuid; + uint32_t lcore_id; + char thread_name[__RTE_TRACE_EMIT_STRING_LEN_MAX]; +} __rte_packed; + +struct __rte_trace_header { + uint32_t offset; + uint32_t len; + struct __rte_trace_stream_header stream_header; + uint8_t mem[]; +}; + +RTE_DECLARE_PER_LCORE(void *, trace_mem); #endif /* _RTE_TRACE_PROVIDER_H_ */ diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index ca1f2cc86..c4f87af3b 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -338,7 +338,9 @@ EXPERIMENTAL { # added in 20.05 rte_thread_getname; + __rte_trace_mem_per_thread_alloc; __rte_trace_point_register; + per_lcore_trace_mem; rte_trace_global_is_enabled; rte_trace_global_is_disabled; rte_trace_is_id_invalid; -- 2.25.1