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 A42AE41B9E; Wed, 1 Feb 2023 13:50:24 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3BF09406A2; Wed, 1 Feb 2023 13:50:24 +0100 (CET) Received: from smartserver.smartsharesystems.com (smartserver.smartsharesystems.com [77.243.40.215]) by mails.dpdk.org (Postfix) with ESMTP id 8FC364021F for ; Wed, 1 Feb 2023 13:50:23 +0100 (CET) X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Subject: RE: [PATCH v7 4/4] eal: add nonnull and access function attributes Date: Wed, 1 Feb 2023 13:50:21 +0100 Message-ID: <98CBD80474FA8B44BF855DF32C47DC35D876E6@smartserver.smartshare.dk> In-Reply-To: <3659208.MHq7AAxBmi@thomas> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [PATCH v7 4/4] eal: add nonnull and access function attributes Thread-Index: Adk1xrFxincTNgwYS4ORo1Fn2TiT1AAasp8A References: <20221202153432.131023-1-mb@smartsharesystems.com> <98CBD80474FA8B44BF855DF32C47DC35D876DA@smartserver.smartshare.dk> <20230131182613.GB11223@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net> <3659208.MHq7AAxBmi@thomas> From: =?iso-8859-1?Q?Morten_Br=F8rup?= To: "Thomas Monjalon" , "Tyler Retzlaff" , "David Marchand" Cc: , "Ferruh Yigit" , , , , , , , , , , , 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 > From: Thomas Monjalon [mailto:thomas@monjalon.net] > Sent: Tuesday, 31 January 2023 23.52 >=20 > 31/01/2023 19:26, Tyler Retzlaff: > > On Tue, Jan 31, 2023 at 01:23:34PM +0100, Morten Br=F8rup wrote: > > > > From: David Marchand [mailto:david.marchand@redhat.com] > > > > Sent: Tuesday, 31 January 2023 12.15 > > > > > > > > On Wed, Jan 18, 2023 at 9:31 AM Morten Br=F8rup > > > > wrote: > > > > > > > > > > +To: Thomas & David, you probably have some opinions on this > too! > > > > > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > Sent: Tuesday, 17 January 2023 22.17 > > > > > > > > > > > > On Tue, Jan 17, 2023 at 09:19:22AM +0100, Morten Br=F8rup > wrote: > > > > > > > > From: Ferruh Yigit [mailto:ferruh.yigit@amd.com] > > > > > > > > Sent: Monday, 16 January 2023 18.02 > > > > > > > > > > > > > > > > On 1/16/2023 1:07 PM, Morten Br=F8rup wrote: > > > > > > > > > Add nonnull function attribute to help the compiler > detect a > > > > NULL > > > > > > > > > pointer being passed to a function not accepting NULL > > > > pointers as > > > > > > an > > > > > > > > > argument at build time. > > > > > > > > > > > > > > > > > > Add access function attributes to tell the compiler = how > a > > > > > > function > > > > > > > > > accesses memory pointed to by its pointer arguments. > > > > > > > > > > > > > > > > > > Add these attributes to the rte_memcpy() function, as > the > > > > first > > > > > > in > > > > > > > > > hopefully many to come. > > > > > > > > > > > > > > > > > > Signed-off-by: Morten Br=F8rup = > > > > > > > > > Acked-by: Tyler Retzlaff = > > > > > > > > > Reviewed-by: Ruifeng Wang > > > > > > > > > --- > > > > > > > > > > > > > > [...] > > > > > > > > > > > > > > > > +/** > > > > > > > > > + * Tells compiler that the pointer arguments must be > non- > > > > null. > > > > > > > > > + * > > > > > > > > > + * @param ... > > > > > > > > > + * Comma separated list of parameter indexes of > pointer > > > > > > > > arguments. > > > > > > > > > + */ > > > > > > > > > +#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG) > > > > > > > > > +#define __rte_nonnull_params(...) \ > > > > > > > > > + __attribute__((nonnull(__VA_ARGS__))) > > > > > > > > > +#else > > > > > > > > > +#define __rte_nonnull_params(...) > > > > > > > > > +#endif > > > > > > > > > + > > > > > > > > > > > > > > > > What do you think to have a namespace for macros like > > > > > > > > '__rte_param_xxx', > > > > > > > > so name macros as: > > > > > > > > __rte_param_nonull > > > > > > > > __rte_param_read_only > > > > > > > > __rte_param_write_only > > > > > > > > > > > > > > > > No strong opinion, it just feels tidier this way >=20 > I tend to prefer this kind of namespace as well. > Let's compare different naming proposals, > taking into account what we already have for some annotations, > and what is proposed to be added in this patch and David's patch > for lock annotations. David's lock annotations don't use a dedicated naming convention, but = simply replaces __attribute__(name(params)) with __rte_name(params), = e.g.: #define __rte_guarded_by(...) \ __attribute__((guarded_by(__VA_ARGS__))) #define __rte_exclusive_locks_required(...) \ __attribute__((exclusive_locks_required(__VA_ARGS__))) #define __rte_assert_exclusive_lock(...) \ __attribute__((assert_exclusive_lock(__VA_ARGS__))) This follows the existing convention in rte_common.h, which is easily = readable, because they directly translate to GCC attribute names, e.g.: #define __rte_warn_unused_result __attribute__((warn_unused_result)) #define __rte_always_inline inline __attribute__((always_inline)) #define __rte_noinline __attribute__((noinline)) #define __rte_hot __attribute__((hot)) #define __rte_cold __attribute__((cold)) I could follow this convention too, e.g.: #define __rte_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) #define __rte_access_read_only(...) \ __attribute__((access(read_only, __VA_ARGS__))) #define __rte_access_write_only(...) \ __attribute__((access(write_only, __VA_ARGS__))) >=20 > > > > > > > Being a proponent of the world_country_city naming scheme > myself, > > > > I > > > > > > would usually agree with this proposal. > > > > > > > > > > > > > > However, in the future, we might add macros without _param > for > > > > use > > > > > > along with the function parameters, e.g.: > > > > > > > > > > > > > > int foo(int bar __rte_nonnull __rte_read_only); > > > > > > > > > > > > > > So I decided for this order in the names (treating > > > > > > nonnull/access_mode as "country" and param/params as = "city"), > also > > > > > > somewhat looking at the __rte_deprecated and > > > > __rte_deprecated_msg(msg) > > > > > > macros. > > > > > > > > > > > > > > I have no strong preference either, so if anyone does, > please > > > > speak > > > > > > up. > > > > > > > > > > > > > > Slightly related, also note this: > > > > > > > > > > > > > > The nonnull macro is plural (_params), because it can take > > > > multiple > > > > > > pointer parameter indexes. > > > > > > > The access mode macros are singular (_param), because they > only > > > > take > > > > > > one pointer parameter index, and the optional size parameter > index. > > > > > > > > > > > > > > I considered splitting up the access mode macros even = more, > > > > making > > > > > > two variants of each, e.g. __rte_read_only_param(ptr_index) > and > > > > > > __rte_read_only_param_size(ptr_index, size_index), but > concluded > > > > that > > > > > > it would be excruciatingly verbose. The only purpose would = be > to > > > > reduce > > > > > > the risk of using them incorrectly. I decided against it, > thinking > > > > that > > > > > > any developer clever enough to use these macros is also > clever > > > > enough > > > > > > to understand how to use them (or at least read their > parameter > > > > > > descriptions to learn how). >=20 > Longer macro names may be better for code readers. You have a good point here, Thomas. It will also prevent using the = access mode attribute macros incorrectly. Let's proceed with two macros (without and with size parameter) instead = of the combined macros (with optional size parameter). Referring to the existing convention in rte_common.h, what do you think = about naming the new macros as follows? __rte_access_read_only(ptr_index) __rte_access_read_only_size(ptr_index, size_index) Or just: __rte_read_only(ptr_index) __rte_read_only_size(ptr_index, size_index) >=20 >=20 > > > > > > microsoft also has a tool & annotation vehicle for this type > of > > > > stuff. > > > > > > this discussion has caused me to wonder what happens if we > would > > > > like > > > > > > to > > > > > > add additional annotations for other tools. just load on the > > > > > > annotations > > > > > > and expand them empty conditionally? > > > > > > > > > > > > = https://learn.microsoft.com/en-us/cpp/code-quality/using-sal- > > > > > > annotations-to-reduce-c-cpp-code-defects?view=3Dmsvc-170 > > > > > > > > > > > > anyway, just a thought. no serious response required here. > > > > > > > > > > Excellent input, Tyler! > > > > > > > > > > If we want DPDK to be considered truly cross-platform, and not > treat > > > > non-Linux/non-GCC as second class citizens, we need to discuss > this. > > > > > > > > > > Microsoft's Source Code Annotation Language (SAL) seems very > good, > > > > based on its finer granularity than GCC's attributes (which in > > > > comparison seem added as an afterthought, not cleanly structured > like > > > > SAL). I have only skimmed the documentation, but that is my > immediate > > > > impression of it. > > > > > > > > > > SAL uses a completely different syntax than GCC attributes, = and > > > > Microsoft happens to also use memcpy() as an example in the > > > > documentation referred to: > > > > > > > > > > void * memcpy( > > > > > _Out_writes_bytes_all_(count) void *dest, > > > > > _In_reads_bytes_(count) const void *src, > > > > > size_t count > > > > > ); > > > > > > Stephen had bad experiences with SAL, so let's just consider the > SAL memcpy() example a reference only, showing how the syntax of > annotations can differ very much between build systems. > > > > yes, if we are in a position to use annotations today that work with > > clang/gcc then let's do that even if they aren't compatible with = SAL. > > so long as they expand empty when not using clang/gcc we can defer > discussion > > about other tools like SAL. >=20 > Yes of course it must expand empty for compilers not supporting the > annotation. > Anyway I don't think we need to support all compilers with annotation. > The main goal of annotation is to do more checks in the CI, > so supporting one compiler should be enough. There is also a secondary goal of increased performance. When the = compiler knows more about a function's behavior, it can optimize more = around it. E.g. knowing that a function doesn't modify something already = held in a register (or other local memory) allows the compiler to reuse = the local copy (in the register) without fetching the original again. >=20 >=20 > > > > > Going back to how we can handle this in DPDK, we can either: > > > > > > > > > > 1. Not annotate the functions at all, and miss out on finding > the > > > > errors for us. > > > > > > > > Seeing how clang safety checks helped me catch bugs, that would > be a > > > > pity. > > > > > > > > > > > > > > 2. Invent our own language (or find something existing) for > function > > > > headers, and use a parser to convert them to compiler specific > C/C++ > > > > headers when building the code. > > > > > > > > Argh, no. > > > > > > > > > > > > > > 3a. Keep loading on attributes, with empty macros for > unsupported > > > > compilers. > > > > > > > > > > 3b. Keep loading on attributes, with empty macros for > unsupported > > > > compilers. But limit ourselves to GCC/Clang style attributes. > > > > > > > > > > 3c. Keep loading on attributes, with empty macros for > unsupported > > > > compilers. But limit ourselves to Microsoft SAL style = attributes. > > > > > > > > > > 3d. Keep loading on attributes, with empty macros for > unsupported > > > > compilers. But limit ourselves to the most relevant attributes, > using > > > > performance and/or bug detection as criteria when considering > > > > relevance. > > > > > > > > > > I am strongly against both 1 and 2. > > > > > > > > > > If bug detection is the primary driver, we could stick with > either 3b > > > > or 3c (i.e. only target one specific build environment) and rely > on the > > > > DPDK CI for detecting bugs. But then application developers = would > not > > > > benefit, because they don't run their code through the DPDK CI. > So I am > > > > also against this. > > > > > > > > > > I think 3d (keep loading on attributes, but only the most > relevant > > > > ones) is the best choice. > > > > > > > > > > GCC/Clang style attributes are already supported as macros > prefixed > > > > by __rte, so let's not change the way we do that. > > > > > > > > > > Regarding the Microsoft SAL, I suppose Microsoft already chose > > > > annotation names to avoid collisions, so we could consider using > those > > > > exact names (i.e. without __rte prefix), and define empty macros > for > > > > non-Microsoft compilers. This would allow using Microsoft SAL > > > > annotations directly in the DPDK code. > > > > > > > > > > > > > I have a bit of trouble understanding the difference between 3a > and > > > > 3d.. 3a would be about accepting any annotation? > > > > > > Correct. > > > > > > > > > > > 3d is the best option as it is not changing anything to what we > were > > > > doing so far: we evaluate the pros and cons of each > annotations/tools, > > > > case per case. > > > > > > Agree! >=20 > I am for 3d as well. > We should focus on clang for using compilation checks. Clang doesn't support the access mode attribute (yet?). It is only = supported by GCC. The CI also uses GCC, so let's not limit ourselves to what clang can do. = Using the access mode attribute with GCC is still useful for the CI to = reveal bugs. I agree with you on the principle: We don't need to add the same = bug-finding attributes to all compiler environments; adding them to one = CI supported compiler environment should suffice. However, performance-enhancing attributes would be useful to support in = multiple compiler environments. >=20 >=20 > Another question about annotations is how much we want to use them. > I think we should use such check for critical code only. Agree. And this includes some fast path code, where they might benefit = performance. > Adding annotations everywhere is not always worth making the code > uglier. I agree. I suppose Stephen stressed the same point when referring his = experience working with SAL. It will be impossible to define a criteria for when to use or not use = such attributes, but we can probably agree on this: When adding new = functions to DPDK, adding such attributes is not a requirement. This = should make it up to the contributor to decide if she wants to add them = or not, which can be discussed on a case by case basis if the maintainer = disagrees. This principle should limit the big discussions to which attributes we = want to allow into rte_common.h; like these and the ones in David's lock = annotation patch.