From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 82C774614E; Thu, 30 Jan 2025 15:59:20 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3E58C40B9A; Thu, 30 Jan 2025 15:59:16 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id B3DA440B99 for ; Thu, 30 Jan 2025 15:59:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1738249154; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hS90mPrC4ffkm7JYDo/SGBEDfUJZ0/1pkmLTkSIv71k=; b=T/f3rFNoyE1QcFU5+IoB5vOnkGuDbYn83OXZRAzqQXmsCO73g3PqW4143MZ5XWGZ7PNJZ7 JssCbHs7OphoKRBe47fFKalGeHZgbS/Vw7Cdl6u3WmxlTDX3AccsqWfiCU4LNOVrb5bQF6 G89jY+Bq77HA3nVsAcnDk8W+f0LyeP8= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-511-Xj8Jaq6AMnSVvDk2DWNgVg-1; Thu, 30 Jan 2025 09:59:11 -0500 X-MC-Unique: Xj8Jaq6AMnSVvDk2DWNgVg-1 X-Mimecast-MFC-AGG-ID: Xj8Jaq6AMnSVvDk2DWNgVg Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 82172195608F; Thu, 30 Jan 2025 14:59:09 +0000 (UTC) Received: from dmarchan.com (unknown [10.45.225.14]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EA7A2180094D; Thu, 30 Jan 2025 14:59:06 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Chengwen Feng , Kevin Laatz , Bruce Richardson , Jerin Jacob , Sunil Kumar Kori , Tyler Retzlaff Subject: [PATCH v2 3/3] trace: fix undefined behavior in register Date: Thu, 30 Jan 2025 15:58:49 +0100 Message-ID: <20250130145849.82003-3-david.marchand@redhat.com> In-Reply-To: <20250130145849.82003-1-david.marchand@redhat.com> References: <20250124161408.310581-1-david.marchand@redhat.com> <20250130145849.82003-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 4kCfOPCbWXsCOtVnqW-lvM4p2eNYKfdZAsO1xNHzB20_1738249150 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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 Registering a tracepoint handler was resulting so far in undefined behavior at runtime. The RTE_TRACE_POINT_REGISTER() macro was casting the tracepoint handler (which expects arguments) to a void (*)(void). At runtime, calling this handler while registering resulted in reading the current stack with no relation to this function prototype. Instead, declare an additional inline _register() handler for each tracepoint and make sure that the emitting macros in rte_trace_point_register.h only work on arguments name and type. The original tracepoint handler prototype is adjusted by adding a __rte_unused for each argument (since emitting macros do nothing with them). This last part introduces an implementation limit of 15 arguments. With this change in place, the workaround in dmadev tracepoints can be removed. Signed-off-by: David Marchand --- lib/dmadev/rte_dmadev_trace.h | 12 ------- lib/dmadev/rte_dmadev_trace_fp.h | 14 -------- lib/eal/include/rte_trace_point.h | 4 +++ lib/eal/include/rte_trace_point_register.h | 42 +++++++++++++++++++--- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/lib/dmadev/rte_dmadev_trace.h b/lib/dmadev/rte_dmadev_trace.h index ddf60b9649..9de9b54aad 100644 --- a/lib/dmadev/rte_dmadev_trace.h +++ b/lib/dmadev/rte_dmadev_trace.h @@ -22,10 +22,6 @@ extern "C" { RTE_TRACE_POINT( rte_dma_trace_info_get, RTE_TRACE_POINT_ARGS(int16_t dev_id, struct rte_dma_info *dev_info), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - struct rte_dma_info __dev_info = {0}; - dev_info = &__dev_info; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_string(dev_info->dev_name); rte_trace_point_emit_u64(dev_info->dev_capa); @@ -42,10 +38,6 @@ RTE_TRACE_POINT( rte_dma_trace_configure, RTE_TRACE_POINT_ARGS(int16_t dev_id, const struct rte_dma_conf *dev_conf, int ret), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - const struct rte_dma_conf __dev_conf = {0}; - dev_conf = &__dev_conf; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_u16(dev_conf->nb_vchans); rte_trace_point_emit_u16(dev_conf->priority); @@ -78,10 +70,6 @@ RTE_TRACE_POINT( rte_dma_trace_vchan_setup, RTE_TRACE_POINT_ARGS(int16_t dev_id, uint16_t vchan, const struct rte_dma_vchan_conf *conf, int ret), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - const struct rte_dma_vchan_conf __conf = {0}; - conf = &__conf; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_u16(vchan); rte_trace_point_emit_int(conf->direction); diff --git a/lib/dmadev/rte_dmadev_trace_fp.h b/lib/dmadev/rte_dmadev_trace_fp.h index 4950f58cd2..106eac24be 100644 --- a/lib/dmadev/rte_dmadev_trace_fp.h +++ b/lib/dmadev/rte_dmadev_trace_fp.h @@ -33,10 +33,6 @@ RTE_TRACE_POINT_FP( rte_dma_trace_vchan_status, RTE_TRACE_POINT_ARGS(int16_t dev_id, uint16_t vchan, enum rte_dma_vchan_status *status, int ret), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - enum rte_dma_vchan_status __status = 0; - status = &__status; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_u16(vchan); rte_trace_point_emit_int(*status); @@ -100,12 +96,6 @@ RTE_TRACE_POINT_FP( RTE_TRACE_POINT_ARGS(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx, bool *has_error, uint16_t ret), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - uint16_t __last_idx = 0; - bool __has_error = false; - last_idx = &__last_idx; - has_error = &__has_error; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_u16(vchan); rte_trace_point_emit_u16(nb_cpls); @@ -119,10 +109,6 @@ RTE_TRACE_POINT_FP( RTE_TRACE_POINT_ARGS(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx, enum rte_dma_status_code *status, uint16_t ret), -#ifdef _RTE_TRACE_POINT_REGISTER_H_ - uint16_t __last_idx = 0; - last_idx = &__last_idx; -#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ rte_trace_point_emit_i16(dev_id); rte_trace_point_emit_u16(vchan); rte_trace_point_emit_u16(nb_cpls); diff --git a/lib/eal/include/rte_trace_point.h b/lib/eal/include/rte_trace_point.h index a162502002..444175f238 100644 --- a/lib/eal/include/rte_trace_point.h +++ b/lib/eal/include/rte_trace_point.h @@ -36,6 +36,8 @@ extern "C" { /** The tracepoint object. */ typedef RTE_ATOMIC(uint64_t) rte_trace_point_t; +#ifndef _RTE_TRACE_POINT_REGISTER_H_ + /** * Macro to define the tracepoint arguments in RTE_TRACE_POINT macro. @@ -53,6 +55,8 @@ _tp _args \ __VA_ARGS__ \ } +#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ + /** * Create a tracepoint. * diff --git a/lib/eal/include/rte_trace_point_register.h b/lib/eal/include/rte_trace_point_register.h index 1d6198b32f..ea69daa086 100644 --- a/lib/eal/include/rte_trace_point_register.h +++ b/lib/eal/include/rte_trace_point_register.h @@ -18,6 +18,43 @@ extern "C" { RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz); +#define RTE_TRACE_POINT_ARGS_COUNT_(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,N, ...) \ + N +#define RTE_TRACE_POINT_ARGS_COUNT(...) \ + RTE_TRACE_POINT_ARGS_COUNT_(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) + +#define RTE_TRACE_POINT_ARGS_1(a) __rte_unused a +#define RTE_TRACE_POINT_ARGS_2(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_1(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_3(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_2(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_4(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_3(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_5(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_4(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_6(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_5(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_7(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_6(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_8(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_7(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_9(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_8(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_10(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_9(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_11(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_10(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_12(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_11(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_13(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_12(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_14(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_13(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_15(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_14(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_FUNC(a) RTE_TRACE_POINT_ARGS_ ## a +#define RTE_TRACE_POINT_ARGS_EXPAND(...) __VA_ARGS__ +#define RTE_TRACE_POINT_ARGS_(N, ...) \ + RTE_TRACE_POINT_ARGS_EXPAND(RTE_TRACE_POINT_ARGS_FUNC(N))(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS(...) \ + (RTE_TRACE_POINT_ARGS_(RTE_TRACE_POINT_ARGS_COUNT(0, __VA_ARGS__), __VA_ARGS__)) + +#define __RTE_TRACE_POINT(_mode, _tp, _args, ...) \ +extern rte_trace_point_t __##_tp; \ +static __rte_always_inline void _tp _args { } \ +static __rte_always_inline void \ +_tp ## _register (void) \ +{ \ + __rte_trace_point_emit_header_##_mode(&__##_tp); \ + __VA_ARGS__ \ +} + #define RTE_TRACE_POINT_REGISTER(trace, name) \ rte_trace_point_t __rte_section("__rte_trace_point") __##trace; \ static const char __##trace##_name[] = RTE_STR(name); \ @@ -26,7 +63,7 @@ RTE_INIT(trace##_init) \ if (!rte_trace_feature_is_enabled()) \ return; \ __rte_trace_point_register(&__##trace, __##trace##_name, \ - (void (*)(void)) trace); \ + trace ## _register); \ } #define __rte_trace_point_emit_header_generic(t) \ @@ -37,21 +74,18 @@ RTE_INIT(trace##_init) \ #define __rte_trace_point_emit(in, type) \ do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit_field(sizeof(type), RTE_STR(in), \ RTE_STR(type)); \ } while (0) #define rte_trace_point_emit_string(in) \ do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit_field(__RTE_TRACE_EMIT_STRING_LEN_MAX, \ RTE_STR(in)"[32]", "string_bounded_t"); \ } while (0) #define rte_trace_point_emit_blob(in, len) \ do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit(len, uint8_t); \ __rte_trace_point_emit_field(RTE_TRACE_BLOB_LEN_MAX, \ RTE_STR(in)"[" RTE_STR(RTE_TRACE_BLOB_LEN_MAX)"]", \ -- 2.48.1