>-----Original Message----- >From: Ferruh Yigit <ferruh.yi...@amd.com> >Sent: Wednesday, January 25, 2023 9:40 PM >To: Ankur Dwivedi <adwiv...@marvell.com>; dev@dpdk.org >Cc: tho...@monjalon.net; david.march...@redhat.com; m...@ashroe.eu; >or...@nvidia.com; ch...@att.com; humi...@huawei.com; >linvi...@tuxdriver.com; ciara.lof...@intel.com; qi.z.zh...@intel.com; >m...@semihalf.com; m...@semihalf.com; shaib...@amazon.com; >evge...@amazon.com; igo...@amazon.com; cha...@amd.com; Igor >Russkikh <irussk...@marvell.com>; shepard.sie...@atomicrules.com; >ed.cz...@atomicrules.com; john.mil...@atomicrules.com; >ajit.khapa...@broadcom.com; somnath.ko...@broadcom.com; Jerin Jacob >Kollanukkaran <jer...@marvell.com>; Maciej Czekaj [C] ><mcze...@marvell.com>; Shijith Thotton <sthot...@marvell.com>; >Srisivasubramanian Srinivasan <sriniva...@marvell.com>; Harman Kalra ><hka...@marvell.com>; rahul.lakkire...@chelsio.com; johnd...@cisco.com; >hyon...@cisco.com; liudongdo...@huawei.com; >yisen.zhu...@huawei.com; xuanziya...@huawei.com; >cloud.wangxiao...@huawei.com; zhouguoy...@huawei.com; >simei...@intel.com; wenjun1...@intel.com; qiming.y...@intel.com; >yuying.zh...@intel.com; beilei.x...@intel.com; xiao.w.w...@intel.com; >jingjing...@intel.com; junfeng....@intel.com; rosen...@intel.com; Nithin >Kumar Dabilpuram <ndabilpu...@marvell.com>; Kiran Kumar Kokkilagadda ><kirankum...@marvell.com>; Sunil Kumar Kori <sk...@marvell.com>; Satha >Koteswara Rao Kottidi <skotesh...@marvell.com>; Liron Himi ><lir...@marvell.com>; z...@semihalf.com; Radha Chintakuntla ><rad...@marvell.com>; Veerasenareddy Burru <vbu...@marvell.com>; >Sathesh B Edara <sed...@marvell.com>; ma...@nvidia.com; >viachesl...@nvidia.com; lon...@microsoft.com; spin...@cesnet.cz; >chaoyong...@corigine.com; niklas.soderl...@corigine.com; >hemant.agra...@nxp.com; sachin.sax...@oss.nxp.com; g.si...@nxp.com; >apeksha.gu...@nxp.com; sachin.sax...@nxp.com; abo...@pensando.io; >Rasesh Mody <rm...@marvell.com>; Shahed Shaikh ><shsha...@marvell.com>; Devendra Singh Rawat ><dsinghra...@marvell.com>; andrew.rybche...@oktetlabs.ru; >jiawe...@trustnetic.com; jianw...@trustnetic.com; >jbehr...@vmware.com; maxime.coque...@redhat.com; >chenbo....@intel.com; steven.webs...@windriver.com; >matt.pet...@windriver.com; bruce.richard...@intel.com; >mtetsu...@gmail.com; gr...@u256.net; jasvinder.si...@intel.com; >cristian.dumitre...@intel.com; jgraj...@cisco.com; >m...@smartsharesystems.com >Subject: Re: [EXT] Re: [PATCH v6 1/6] eal: trace: add trace point emit for blob > >On 1/25/2023 3:02 PM, Ankur Dwivedi wrote: >> >>> >>> --------------------------------------------------------------------- >>> - On 1/20/2023 8:40 AM, Ankur Dwivedi wrote: >>>> Adds a trace point emit function for capturing a blob. The blob >>>> captures the length passed by the application followed by the array. >>>> >>>> The maximum blob bytes which can be captured is bounded by >>>> RTE_TRACE_BLOB_LEN_MAX macro. The value for max blob length macro >is >>>> 64 bytes. If the length is less than 64 the remaining trailing bytes >>>> are set to zero. >>>> >>>> This patch also adds test case for emit blob tracepoint function. >>>> >>>> Signed-off-by: Ankur Dwivedi <adwiv...@marvell.com> >>>> --- >>>> app/test/test_trace.c | 11 ++++++++ >>>> doc/guides/prog_guide/trace_lib.rst | 12 ++++++++ >>>> lib/eal/common/eal_common_trace_points.c | 2 ++ >>>> lib/eal/include/rte_eal_trace.h | 6 ++++ >>>> lib/eal/include/rte_trace_point.h | 32 ++++++++++++++++++++++ >>>> lib/eal/include/rte_trace_point_register.h | 9 ++++++ >>>> lib/eal/version.map | 3 ++ >>>> 7 files changed, 75 insertions(+) >>>> >>>> diff --git a/app/test/test_trace.c b/app/test/test_trace.c index >>>> 6bedf14024..ad4a394a29 100644 >>>> --- a/app/test/test_trace.c >>>> +++ b/app/test/test_trace.c >>>> @@ -4,6 +4,7 @@ >>>> >>>> #include <rte_eal_trace.h> >>>> #include <rte_lcore.h> >>>> +#include <rte_random.h> >>>> #include <rte_trace.h> >>>> >>>> #include "test.h" >>>> @@ -177,7 +178,12 @@ test_fp_trace_points(void) static int >>>> test_generic_trace_points(void) >>>> { >>>> + uint8_t arr[RTE_TRACE_BLOB_LEN_MAX]; >>>> int tmp; >>>> + int i; >>>> + >>>> + for (i = 0; i < RTE_TRACE_BLOB_LEN_MAX; i++) >>>> + arr[i] = i; >>>> >>>> rte_eal_trace_generic_void(); >>>> rte_eal_trace_generic_u64(0x10000000000000); >>>> @@ -195,6 +201,11 @@ test_generic_trace_points(void) >>>> rte_eal_trace_generic_ptr(&tmp); >>>> rte_eal_trace_generic_str("my string"); >>>> rte_eal_trace_generic_size_t(sizeof(void *)); >>>> + rte_eal_trace_generic_blob(arr, 0); >>>> + rte_eal_trace_generic_blob(arr, 17); >>>> + rte_eal_trace_generic_blob(arr, RTE_TRACE_BLOB_LEN_MAX); >>>> + rte_eal_trace_generic_blob(arr, rte_rand() % >>>> + RTE_TRACE_BLOB_LEN_MAX); >>>> RTE_EAL_TRACE_GENERIC_FUNC; >>>> >>>> return TEST_SUCCESS; >>>> diff --git a/doc/guides/prog_guide/trace_lib.rst >>>> b/doc/guides/prog_guide/trace_lib.rst >>>> index 9a8f38073d..3e0ea5835c 100644 >>>> --- a/doc/guides/prog_guide/trace_lib.rst >>>> +++ b/doc/guides/prog_guide/trace_lib.rst >>>> @@ -352,3 +352,15 @@ event ID. >>>> The ``packet.header`` and ``packet.context`` will be written in the >>>> slow path at the time of trace memory creation. The >>>> ``trace.header`` and trace payload will be emitted when the tracepoint >function is invoked. >>>> + >>>> +Limitations >>>> +----------- >>>> + >>>> +- The ``rte_trace_point_emit_blob()`` function can capture a >>>> +maximum blob of >>>> + length ``RTE_TRACE_BLOB_LEN_MAX`` bytes. The application can call >>>> + ``rte_trace_point_emit_blob()`` multiple times with length less >>>> +than or equal to >>>> + ``RTE_TRACE_BLOB_LEN_MAX``, if it needs to capture more than >>>> +``RTE_TRACE_BLOB_LEN_MAX`` >>>> + bytes. >>>> +- If the length passed to the ``rte_trace_point_emit_blob()`` is >>>> +less than >>>> + ``RTE_TRACE_BLOB_LEN_MAX``, then the trailing >>>> +``(RTE_TRACE_BLOB_LEN_MAX - len)`` >>>> + bytes in the trace are set to zero. >>>> diff --git a/lib/eal/common/eal_common_trace_points.c >>>> b/lib/eal/common/eal_common_trace_points.c >>>> index 0b0b254615..051f89809c 100644 >>>> --- a/lib/eal/common/eal_common_trace_points.c >>>> +++ b/lib/eal/common/eal_common_trace_points.c >>>> @@ -40,6 +40,8 @@ >>> RTE_TRACE_POINT_REGISTER(rte_eal_trace_generic_size_t, >>>> lib.eal.generic.size_t) >>>> RTE_TRACE_POINT_REGISTER(rte_eal_trace_generic_func, >>>> lib.eal.generic.func) >>>> +RTE_TRACE_POINT_REGISTER(rte_eal_trace_generic_blob, >>>> + lib.eal.generic.blob) >>>> >>>> RTE_TRACE_POINT_REGISTER(rte_eal_trace_alarm_set, >>>> lib.eal.alarm.set) >>>> diff --git a/lib/eal/include/rte_eal_trace.h >>>> b/lib/eal/include/rte_eal_trace.h index 5ef4398230..e0b836eb2f >>>> 100644 >>>> --- a/lib/eal/include/rte_eal_trace.h >>>> +++ b/lib/eal/include/rte_eal_trace.h >>>> @@ -143,6 +143,12 @@ RTE_TRACE_POINT( >>>> rte_trace_point_emit_string(func); >>>> ) >>>> >>>> +RTE_TRACE_POINT( >>>> + rte_eal_trace_generic_blob, >>>> + RTE_TRACE_POINT_ARGS(void *in, uint8_t len), >>>> + rte_trace_point_emit_blob(in, len); >>>> +) >>>> + >>>> #define RTE_EAL_TRACE_GENERIC_FUNC >>>> rte_eal_trace_generic_func(__func__) >>>> >>>> /* Interrupt */ >>>> diff --git a/lib/eal/include/rte_trace_point.h >>>> b/lib/eal/include/rte_trace_point.h >>>> index 0f8700974f..aca8344dbf 100644 >>>> --- a/lib/eal/include/rte_trace_point.h >>>> +++ b/lib/eal/include/rte_trace_point.h >>>> @@ -144,6 +144,16 @@ _tp _args \ >>>> #define rte_trace_point_emit_ptr(val) >>>> /** Tracepoint function payload for string datatype */ #define >>>> rte_trace_point_emit_string(val) >>>> +/** >>>> + * Tracepoint function to capture a blob. >>>> + * >>>> + * @param val >>>> + * Pointer to the array to be captured. >>>> + * @param len >>>> + * Length to be captured. The maximum supported length is >>>> + * RTE_TRACE_BLOB_LEN_MAX bytes. >>>> + */ >>>> +#define rte_trace_point_emit_blob(val, len) >>>> >>> >>> This is just for doxygen right, why doxygen comments are not above >>> the actual macros but there is a separate #if block for it? >> >> The actual macro is within a #ifndef __DOXYGEN__ block. I think that >> is the reason for including Doxygen comments here. > >Thanks for confirming. > >Why comments are not as part of actual macro, but there is a separate '#ifdef >__DOXYGEN__' block?
The actual rte_trace_point_emit_blob macro containing the definition, is inside a #ifdef ALLOW_EXPERIMENTAL_API block, so the doxygen will not get generated for rte_trace_point_emit_blob unless ALLOW_EXPERIMENTAL_API is defined in doxygen config. Putting the macro in #ifdef __DOXYGEN__ generates doxygen for the macro, even if ALLOW_EXPERIMENTAL_API is not defined. > >>> >>>> #endif /* __DOXYGEN__ */ >>>> >>>> @@ -152,6 +162,9 @@ _tp _args \ >>>> /** @internal Macro to define event header size. */ #define >>>> __RTE_TRACE_EVENT_HEADER_SZ sizeof(uint64_t) >>>> >>>> +/** Macro to define maximum emit length of blob. */ #define >>>> +RTE_TRACE_BLOB_LEN_MAX 64 >>>> + >>>> /** >>>> * Enable recording events of the given tracepoint in the trace buffer. >>>> * >>>> @@ -374,12 +387,31 @@ do { \ >>>> mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX); >>> \ } while >>>> (0) >>>> >>>> +#define rte_trace_point_emit_blob(in, len) \ do { \ >>>> + if (unlikely(in == NULL)) \ >>>> + return; \ >>>> + if (len > RTE_TRACE_BLOB_LEN_MAX) \ >>>> + len = RTE_TRACE_BLOB_LEN_MAX; \ >>>> + __rte_trace_point_emit(len, uint8_t); \ >>>> + memcpy(mem, in, len); \ >>>> + mem = RTE_PTR_ADD(mem, len); \ >>>> + memset(mem, 0, RTE_TRACE_BLOB_LEN_MAX - len); \ >>>> + mem = RTE_PTR_ADD(mem, RTE_TRACE_BLOB_LEN_MAX - len); \ >>> >>> >>> Is first memset later memcpy not done because of performance concerns? >> >> The memset sets to 0 the unused bytes (RTE_TRACE_BLOB_LEN_MAX - len). >So memset is done after memcpy. > >yep, I can see what is done. > >Question is, you can do more simply: >memset(mem, 0, RTE_TRACE_BLOB_LEN_MAX); >memcpy(mem, in, len); >mem = RTE_PTR_ADD(mem, RTE_TRACE_BLOB_LEN_MAX - len); > >Why did you prefer the implementation you did, intentionally? If so what is >the intention, performance concerns? Yes performance is a concern. If memset is done before memcpy, then, 64 <= number of bytes written <= 128, depending on length value from 0 to 64. But in memset after memcpy, always 64 bytes will be written. > >btw, I want to remind that size of the 'len' can be max 64 bytes. > >>> >>>> +} while (0) >>>> + >>>> #else >>>> >>>> #define __rte_trace_point_emit_header_generic(t) RTE_SET_USED(t) >>>> #define __rte_trace_point_emit_header_fp(t) RTE_SET_USED(t) #define >>>> __rte_trace_point_emit(in, type) RTE_SET_USED(in) #define >>>> rte_trace_point_emit_string(in) RTE_SET_USED(in) >>>> +#define rte_trace_point_emit_blob(in, len) \ do { \ >>>> + RTE_SET_USED(in); \ >>>> + RTE_SET_USED(len); \ >>>> +} while (0) >>>> + >>>> >>>> #endif /* ALLOW_EXPERIMENTAL_API */ #endif /* >>>> _RTE_TRACE_POINT_REGISTER_H_ */ diff --git >>>> a/lib/eal/include/rte_trace_point_register.h >>>> b/lib/eal/include/rte_trace_point_register.h >>>> index a32f4d731b..7efbac8a72 100644 >>>> --- a/lib/eal/include/rte_trace_point_register.h >>>> +++ b/lib/eal/include/rte_trace_point_register.h >>>> @@ -47,6 +47,15 @@ do { \ >>>> 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)"]", \ >>>> + RTE_STR(uint8_t)); \ >>>> +} while (0) >>>> + >>> >>> Why this macro defined here again, it is also defined in 'rte_trace_point.h' >>> already? >>> Is it because of 'register_fn()' in '__rte_trace_point_register()'? >> >> Yes the register happens in this function. > >You are not really answering questions. > >There are three copy of '#define rte_trace_point_emit_blob(in, len)' one of >them is for doxygen comment, please explain why there are two more copies >of it? > The rte_trace_point_emit_blob is used when ALLOW_EXPERIMENTAL_API is defined. One definition is for that. The other is basically a null definition when ALLOW_EXPERIMENTAL_API is not defined. >>> >>>> #ifdef __cplusplus >>>> } >>>> #endif >>>> diff --git a/lib/eal/version.map b/lib/eal/version.map index >>>> 7ad12a7dc9..67be24686a 100644 >>>> --- a/lib/eal/version.map >>>> +++ b/lib/eal/version.map >>>> @@ -440,6 +440,9 @@ EXPERIMENTAL { >>>> rte_thread_detach; >>>> rte_thread_equal; >>>> rte_thread_join; >>>> + >>>> + # added in 23.03 >>>> + __rte_eal_trace_generic_blob; >>> >>> This is not a function but a trace object. >>> I guess it was agreed that trace object not need to be exported, and >>> trace can be found by name? >> >> Yes the export in version.map can be removed. Will remove it in next patch >series. > >ack. > >Will there be a separate patch to remove existing symbols? Although I am not >sure if it will be ABI break. I will send a separate patch to remove existing tracepoint symbols.