* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
[not found] <20181105204000.129023-1-bvanassche@acm.org>
@ 2018-11-05 21:13 ` Andrew Morton
2018-11-05 21:48 ` Bart Van Assche
2018-11-06 9:45 ` William Kucharski
[not found] ` <62188a351f2249188ce654ee03c894b1@AcuMS.aculab.com>
1 sibling, 2 replies; 13+ messages in thread
From: Andrew Morton @ 2018-11-05 21:13 UTC (permalink / raw)
To: Bart Van Assche
Cc: linux-kernel, Vlastimil Babka, Mel Gorman, Christoph Lameter,
Roman Gushchin, Pekka Enberg, David Rientjes, Joonsoo Kim,
linux-mm
On Mon, 5 Nov 2018 12:40:00 -0800 Bart Van Assche <bvanassche@acm.org> wrote:
> This patch suppresses the following sparse warning:
>
> ./include/linux/slab.h:332:43: warning: dubious: x & !y
>
> ...
>
> --- a/include/linux/slab.h
> +++ b/include/linux/slab.h
> @@ -329,7 +329,7 @@ static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> */
> - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> + return type_dma + is_reclaimable * !is_dma * KMALLOC_RECLAIM;
> }
>
> /*
I suppose so.
That function seems too clever for its own good :(. I wonder if these
branch-avoiding tricks are really worthwhile.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 21:13 ` [PATCH] slab.h: Avoid using & for logical and of booleans Andrew Morton
@ 2018-11-05 21:48 ` Bart Van Assche
2018-11-05 22:14 ` Rasmus Villemoes
2018-11-06 9:45 ` William Kucharski
1 sibling, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2018-11-05 21:48 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Vlastimil Babka, Mel Gorman, Christoph Lameter,
Roman Gushchin, Pekka Enberg, David Rientjes, Joonsoo Kim,
linux-mm
On Mon, 2018-11-05 at 13:13 -0800, Andrew Morton wrote:
> On Mon, 5 Nov 2018 12:40:00 -0800 Bart Van Assche <bvanassche@acm.org> wrote:
>
> > This patch suppresses the following sparse warning:
> >
> > ./include/linux/slab.h:332:43: warning: dubious: x & !y
> >
> > ...
> >
> > --- a/include/linux/slab.h
> > +++ b/include/linux/slab.h
> > @@ -329,7 +329,7 @@ static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> > * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> > * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> > */
> > - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> > + return type_dma + is_reclaimable * !is_dma * KMALLOC_RECLAIM;
> > }
> >
> > /*
>
> I suppose so.
>
> That function seems too clever for its own good :(. I wonder if these
> branch-avoiding tricks are really worthwhile.
>From what I have seen in gcc disassembly it seems to me like gcc uses the
cmov instruction to implement e.g. the ternary operator (?:). So I think none
of the cleverness in kmalloc_type() is really necessary to avoid conditional
branches. I think this function would become much more readable when using a
switch statement or when rewriting it as follows (untested):
static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
{
- int is_dma = 0;
- int type_dma = 0;
- int is_reclaimable;
-
-#ifdef CONFIG_ZONE_DMA
- is_dma = !!(flags & __GFP_DMA);
- type_dma = is_dma * KMALLOC_DMA;
-#endif
-
- is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
-
/*
* If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
* KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
*/
- return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
+ static const enum kmalloc_cache_type flags_to_type[2][2] = {
+ { 0, KMALLOC_RECLAIM },
+ { KMALLOC_DMA, KMALLOC_DMA },
+ };
+#ifdef CONFIG_ZONE_DMA
+ bool is_dma = !!(flags & __GFP_DMA);
+#endif
+ bool is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
+
+ return flags_to_type[is_dma][is_reclaimable];
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 21:48 ` Bart Van Assche
@ 2018-11-05 22:14 ` Rasmus Villemoes
2018-11-05 22:40 ` Bart Van Assche
0 siblings, 1 reply; 13+ messages in thread
From: Rasmus Villemoes @ 2018-11-05 22:14 UTC (permalink / raw)
To: Bart Van Assche, Andrew Morton
Cc: linux-kernel, Vlastimil Babka, Mel Gorman, Christoph Lameter,
Roman Gushchin, Pekka Enberg, David Rientjes, Joonsoo Kim,
linux-mm
On 2018-11-05 22:48, Bart Van Assche wrote:
> On Mon, 2018-11-05 at 13:13 -0800, Andrew Morton wrote:
>> On Mon, 5 Nov 2018 12:40:00 -0800 Bart Van Assche <bvanassche@acm.org> wrote:
>>
>>> This patch suppresses the following sparse warning:
>>>
>>> ./include/linux/slab.h:332:43: warning: dubious: x & !y
>>>
>>> ...
>>>
>>> --- a/include/linux/slab.h
>>> +++ b/include/linux/slab.h
>>> @@ -329,7 +329,7 @@ static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
>>> * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
>>> * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
>>> */
>>> - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
>>> + return type_dma + is_reclaimable * !is_dma * KMALLOC_RECLAIM;
>>> }
>>>
>>> /*
>>
>> I suppose so.
>>
>> That function seems too clever for its own good :(. I wonder if these
>> branch-avoiding tricks are really worthwhile.
>
> From what I have seen in gcc disassembly it seems to me like gcc uses the
> cmov instruction to implement e.g. the ternary operator (?:). So I think none
> of the cleverness in kmalloc_type() is really necessary to avoid conditional
> branches. I think this function would become much more readable when using a
> switch statement or when rewriting it as follows (untested):
>
> static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> {
> - int is_dma = 0;
> - int type_dma = 0;
> - int is_reclaimable;
> -
> -#ifdef CONFIG_ZONE_DMA
> - is_dma = !!(flags & __GFP_DMA);
> - type_dma = is_dma * KMALLOC_DMA;
> -#endif
> -
> - is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
> -
> /*
> * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> */
> - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> + static const enum kmalloc_cache_type flags_to_type[2][2] = {
> + { 0, KMALLOC_RECLAIM },
> + { KMALLOC_DMA, KMALLOC_DMA },
> + };
> +#ifdef CONFIG_ZONE_DMA
> + bool is_dma = !!(flags & __GFP_DMA);
> +#endif
> + bool is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
> +
> + return flags_to_type[is_dma][is_reclaimable];
> }
>
Won't that pessimize the cases where gfp is a constant to actually do
the table lookup, and add 16 bytes to every translation unit?
Another option is to add a fake KMALLOC_DMA_RECLAIM so the
kmalloc_caches[] array has size 4, then assign the same dma
kmalloc_cache pointer to [2][i] and [3][i] (so that costs perhaps a
dozen pointers in .data), and then just compute kmalloc_type() as
((flags & __GFP_RECLAIMABLE) >> someshift) | ((flags & __GFP_DMA) >>
someothershift).
Perhaps one could even shuffle the GFP flags so the two shifts are the same.
Rasmus
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 22:14 ` Rasmus Villemoes
@ 2018-11-05 22:40 ` Bart Van Assche
2018-11-05 22:48 ` Alexander Duyck
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2018-11-05 22:40 UTC (permalink / raw)
To: Rasmus Villemoes, Andrew Morton
Cc: linux-kernel, Vlastimil Babka, Mel Gorman, Christoph Lameter,
Roman Gushchin, Pekka Enberg, David Rientjes, Joonsoo Kim,
linux-mm
On Mon, 2018-11-05 at 23:14 +0100, Rasmus Villemoes wrote:
> Won't that pessimize the cases where gfp is a constant to actually do
> the table lookup, and add 16 bytes to every translation unit?
>
> Another option is to add a fake KMALLOC_DMA_RECLAIM so the
> kmalloc_caches[] array has size 4, then assign the same dma
> kmalloc_cache pointer to [2][i] and [3][i] (so that costs perhaps a
> dozen pointers in .data), and then just compute kmalloc_type() as
>
> ((flags & __GFP_RECLAIMABLE) >> someshift) | ((flags & __GFP_DMA) >>
> someothershift).
>
> Perhaps one could even shuffle the GFP flags so the two shifts are the same.
How about this version, still untested? My compiler is able to evaluate
the switch expression if the argument is constant.
static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
{
- int is_dma = 0;
- int type_dma = 0;
- int is_reclaimable;
+ unsigned int dr = !!(flags & __GFP_RECLAIMABLE);
#ifdef CONFIG_ZONE_DMA
- is_dma = !!(flags & __GFP_DMA);
- type_dma = is_dma * KMALLOC_DMA;
+ dr |= !!(flags & __GFP_DMA) << 1;
#endif
- is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
-
/*
* If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
* KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
*/
- return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
+ switch (dr) {
+ default:
+ case 0:
+ return 0;
+ case 1:
+ return KMALLOC_RECLAIM;
+ case 2:
+ case 3:
+ return KMALLOC_DMA;
+ }
}
Bart.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 22:40 ` Bart Van Assche
@ 2018-11-05 22:48 ` Alexander Duyck
2018-11-06 0:01 ` Bart Van Assche
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Duyck @ 2018-11-05 22:48 UTC (permalink / raw)
To: bvanassche
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Mon, Nov 5, 2018 at 2:41 PM Bart Van Assche <bvanassche@acm.org> wrote:
>
> On Mon, 2018-11-05 at 23:14 +0100, Rasmus Villemoes wrote:
> > Won't that pessimize the cases where gfp is a constant to actually do
> > the table lookup, and add 16 bytes to every translation unit?
> >
> > Another option is to add a fake KMALLOC_DMA_RECLAIM so the
> > kmalloc_caches[] array has size 4, then assign the same dma
> > kmalloc_cache pointer to [2][i] and [3][i] (so that costs perhaps a
> > dozen pointers in .data), and then just compute kmalloc_type() as
> >
> > ((flags & __GFP_RECLAIMABLE) >> someshift) | ((flags & __GFP_DMA) >>
> > someothershift).
> >
> > Perhaps one could even shuffle the GFP flags so the two shifts are the same.
>
> How about this version, still untested? My compiler is able to evaluate
> the switch expression if the argument is constant.
>
> static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> {
> - int is_dma = 0;
> - int type_dma = 0;
> - int is_reclaimable;
> + unsigned int dr = !!(flags & __GFP_RECLAIMABLE);
>
> #ifdef CONFIG_ZONE_DMA
> - is_dma = !!(flags & __GFP_DMA);
> - type_dma = is_dma * KMALLOC_DMA;
> + dr |= !!(flags & __GFP_DMA) << 1;
> #endif
>
> - is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
> -
> /*
> * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> */
> - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> + switch (dr) {
> + default:
> + case 0:
> + return 0;
> + case 1:
> + return KMALLOC_RECLAIM;
> + case 2:
> + case 3:
> + return KMALLOC_DMA;
> + }
> }
>
> Bart.
Doesn't this defeat the whole point of the code which I thought was to
avoid conditional jumps and branches? Also why would you bother with
the "dr" value when you could just mask the flags value and switch on
that directly?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 22:48 ` Alexander Duyck
@ 2018-11-06 0:01 ` Bart Van Assche
2018-11-06 0:11 ` Alexander Duyck
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2018-11-06 0:01 UTC (permalink / raw)
To: Alexander Duyck
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Mon, 2018-11-05 at 14:48 -0800, Alexander Duyck wrote:
> On Mon, Nov 5, 2018 at 2:41 PM Bart Van Assche <bvanassche@acm.org> wrote:
> > How about this version, still untested? My compiler is able to evaluate
> > the switch expression if the argument is constant.
> >
> > static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> > {
> > - int is_dma = 0;
> > - int type_dma = 0;
> > - int is_reclaimable;
> > + unsigned int dr = !!(flags & __GFP_RECLAIMABLE);
> >
> > #ifdef CONFIG_ZONE_DMA
> > - is_dma = !!(flags & __GFP_DMA);
> > - type_dma = is_dma * KMALLOC_DMA;
> > + dr |= !!(flags & __GFP_DMA) << 1;
> > #endif
> >
> > - is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
> > -
> > /*
> > * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> > * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> > */
> > - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> > + switch (dr) {
> > + default:
> > + case 0:
> > + return 0;
> > + case 1:
> > + return KMALLOC_RECLAIM;
> > + case 2:
> > + case 3:
> > + return KMALLOC_DMA;
> > + }
> > }
>
> Doesn't this defeat the whole point of the code which I thought was to
> avoid conditional jumps and branches? Also why would you bother with
> the "dr" value when you could just mask the flags value and switch on
> that directly?
Storing the relevant bits of 'flags' in the 'dr' variable avoids that the
bit selection expressions have to be repeated and allows to use a switch
statement instead of multiple if / else statements.
Most kmalloc() calls pass a constant to the gfp argument. That allows the
compiler to evaluate kmalloc_type() at compile time. So the conditional jumps
and branches only appear when the gfp argument is not a constant. What makes
you think it is important to optimize for that case?
Bart.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-06 0:01 ` Bart Van Assche
@ 2018-11-06 0:11 ` Alexander Duyck
2018-11-06 0:32 ` Bart Van Assche
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Duyck @ 2018-11-06 0:11 UTC (permalink / raw)
To: bvanassche
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Mon, Nov 5, 2018 at 4:01 PM Bart Van Assche <bvanassche@acm.org> wrote:
>
> On Mon, 2018-11-05 at 14:48 -0800, Alexander Duyck wrote:
> > On Mon, Nov 5, 2018 at 2:41 PM Bart Van Assche <bvanassche@acm.org> wrote:
> > > How about this version, still untested? My compiler is able to evaluate
> > > the switch expression if the argument is constant.
> > >
> > > static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
> > > {
> > > - int is_dma = 0;
> > > - int type_dma = 0;
> > > - int is_reclaimable;
> > > + unsigned int dr = !!(flags & __GFP_RECLAIMABLE);
> > >
> > > #ifdef CONFIG_ZONE_DMA
> > > - is_dma = !!(flags & __GFP_DMA);
> > > - type_dma = is_dma * KMALLOC_DMA;
> > > + dr |= !!(flags & __GFP_DMA) << 1;
> > > #endif
> > >
> > > - is_reclaimable = !!(flags & __GFP_RECLAIMABLE);
> > > -
> > > /*
> > > * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return
> > > * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE
> > > */
> > > - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
> > > + switch (dr) {
> > > + default:
> > > + case 0:
> > > + return 0;
> > > + case 1:
> > > + return KMALLOC_RECLAIM;
> > > + case 2:
> > > + case 3:
> > > + return KMALLOC_DMA;
> > > + }
> > > }
> >
> > Doesn't this defeat the whole point of the code which I thought was to
> > avoid conditional jumps and branches? Also why would you bother with
> > the "dr" value when you could just mask the flags value and switch on
> > that directly?
>
> Storing the relevant bits of 'flags' in the 'dr' variable avoids that the
> bit selection expressions have to be repeated and allows to use a switch
> statement instead of multiple if / else statements.
Really they shouldn't have to be repeated. You essentially have just 3
cases. 0, __GFP_RECLAIMABLE, and the default case.
> Most kmalloc() calls pass a constant to the gfp argument. That allows the
> compiler to evaluate kmalloc_type() at compile time. So the conditional jumps
> and branches only appear when the gfp argument is not a constant. What makes
> you think it is important to optimize for that case?
>
> Bart.
I didn't really think it was all that important to optimize, but I
thought that was what you were trying to maintain with the earlier
patch since it was converting things to a table lookup.
If we really don't care then why even bother with the switch statement
anyway? It seems like you could just do one ternary operator and be
done with it. Basically all you need is:
return (defined(CONFIG_ZONE_DMA) && (flags & __GFP_DMA)) ? KMALLOC_DMA :
(flags & __GFP_RECLAIMABLE) ? KMALLOC_RECLAIM : 0;
Why bother with all the extra complexity of the switch statement?
Thanks.
- Alex
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-06 0:11 ` Alexander Duyck
@ 2018-11-06 0:32 ` Bart Van Assche
2018-11-06 17:20 ` Alexander Duyck
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2018-11-06 0:32 UTC (permalink / raw)
To: Alexander Duyck
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Mon, 2018-11-05 at 16:11 -0800, Alexander Duyck wrote:
> If we really don't care then why even bother with the switch statement
> anyway? It seems like you could just do one ternary operator and be
> done with it. Basically all you need is:
> return (defined(CONFIG_ZONE_DMA) && (flags & __GFP_DMA)) ? KMALLOC_DMA :
> (flags & __GFP_RECLAIMABLE) ? KMALLOC_RECLAIM : 0;
>
> Why bother with all the extra complexity of the switch statement?
I don't think that defined() can be used in a C expression. Hence the
IS_ENABLED() macro. If you fix that, leave out four superfluous parentheses,
test your patch, post that patch and cc me then I will add my Reviewed-by.
Bart.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-05 21:13 ` [PATCH] slab.h: Avoid using & for logical and of booleans Andrew Morton
2018-11-05 21:48 ` Bart Van Assche
@ 2018-11-06 9:45 ` William Kucharski
1 sibling, 0 replies; 13+ messages in thread
From: William Kucharski @ 2018-11-06 9:45 UTC (permalink / raw)
To: Andrew Morton
Cc: Bart Van Assche, linux-kernel, Vlastimil Babka, Mel Gorman,
Christoph Lameter, Roman Gushchin, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
> On Nov 5, 2018, at 14:13, Andrew Morton <akpm@linux-foundation.org> wrote:
>
>> On Mon, 5 Nov 2018 12:40:00 -0800 Bart Van Assche <bvanassche@acm.org> wrote:
>> - return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM;
>> + return type_dma + is_reclaimable * !is_dma * KMALLOC_RECLAIM;
>> }
>>
>> /*
>
> I suppose so.
>
> That function seems too clever for its own good :(. I wonder if these
> branch-avoiding tricks are really worthwhile.
At the very least I'd like to see some comments added as to why that approach was taken for the sake of future maintainers.
William Kucharski
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-06 0:32 ` Bart Van Assche
@ 2018-11-06 17:20 ` Alexander Duyck
2018-11-06 17:48 ` Bart Van Assche
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Duyck @ 2018-11-06 17:20 UTC (permalink / raw)
To: bvanassche
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Mon, Nov 5, 2018 at 4:32 PM Bart Van Assche <bvanassche@acm.org> wrote:
>
> On Mon, 2018-11-05 at 16:11 -0800, Alexander Duyck wrote:
> > If we really don't care then why even bother with the switch statement
> > anyway? It seems like you could just do one ternary operator and be
> > done with it. Basically all you need is:
> > return (defined(CONFIG_ZONE_DMA) && (flags & __GFP_DMA)) ? KMALLOC_DMA :
> > (flags & __GFP_RECLAIMABLE) ? KMALLOC_RECLAIM : 0;
> >
> > Why bother with all the extra complexity of the switch statement?
>
> I don't think that defined() can be used in a C expression. Hence the
> IS_ENABLED() macro. If you fix that, leave out four superfluous parentheses,
> test your patch, post that patch and cc me then I will add my Reviewed-by.
>
> Bart.
Actually the defined macro is used multiple spots in if statements
throughout the kernel.
The reason for IS_ENABLED is to address the fact that we can be
dealing with macros that indicate if they are built in or a module
since those end up being two different defines depending on if you
select 'y' or 'm'.
Thanks.
- Alex
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-06 17:20 ` Alexander Duyck
@ 2018-11-06 17:48 ` Bart Van Assche
2018-11-06 18:17 ` Alexander Duyck
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2018-11-06 17:48 UTC (permalink / raw)
To: Alexander Duyck
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Tue, 2018-11-06 at 09:20 -0800, Alexander Duyck wrote:
> On Mon, Nov 5, 2018 at 4:32 PM Bart Van Assche <bvanassche@acm.org> wrote:
> >
> > On Mon, 2018-11-05 at 16:11 -0800, Alexander Duyck wrote:
> > > If we really don't care then why even bother with the switch statement
> > > anyway? It seems like you could just do one ternary operator and be
> > > done with it. Basically all you need is:
> > > return (defined(CONFIG_ZONE_DMA) && (flags & __GFP_DMA)) ? KMALLOC_DMA :
> > > (flags & __GFP_RECLAIMABLE) ? KMALLOC_RECLAIM : 0;
> > >
> > > Why bother with all the extra complexity of the switch statement?
> >
> > I don't think that defined() can be used in a C expression. Hence the
> > IS_ENABLED() macro. If you fix that, leave out four superfluous parentheses,
> > test your patch, post that patch and cc me then I will add my Reviewed-by.
>
> Actually the defined macro is used multiple spots in if statements
> throughout the kernel.
The only 'if (defined(' matches I found in the kernel tree that are not
preprocessor statements occur in Perl code. Maybe I overlooked something?
> The reason for IS_ENABLED is to address the fact that we can be
> dealing with macros that indicate if they are built in or a module
> since those end up being two different defines depending on if you
> select 'y' or 'm'.
>From Documentation/process/coding-style.rst:
Within code, where possible, use the IS_ENABLED macro to convert a Kconfig
symbol into a C boolean expression, and use it in a normal C conditional:
.. code-block:: c
if (IS_ENABLED(CONFIG_SOMETHING)) {
...
}
Bart.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
2018-11-06 17:48 ` Bart Van Assche
@ 2018-11-06 18:17 ` Alexander Duyck
0 siblings, 0 replies; 13+ messages in thread
From: Alexander Duyck @ 2018-11-06 18:17 UTC (permalink / raw)
To: bvanassche
Cc: linux, Andrew Morton, LKML, Vlastimil Babka, Mel Gorman,
Christoph Lameter, guro, Pekka Enberg, David Rientjes,
Joonsoo Kim, linux-mm
On Tue, Nov 6, 2018 at 9:48 AM Bart Van Assche <bvanassche@acm.org> wrote:
>
> On Tue, 2018-11-06 at 09:20 -0800, Alexander Duyck wrote:
> > On Mon, Nov 5, 2018 at 4:32 PM Bart Van Assche <bvanassche@acm.org> wrote:
> > >
> > > On Mon, 2018-11-05 at 16:11 -0800, Alexander Duyck wrote:
> > > > If we really don't care then why even bother with the switch statement
> > > > anyway? It seems like you could just do one ternary operator and be
> > > > done with it. Basically all you need is:
> > > > return (defined(CONFIG_ZONE_DMA) && (flags & __GFP_DMA)) ? KMALLOC_DMA :
> > > > (flags & __GFP_RECLAIMABLE) ? KMALLOC_RECLAIM : 0;
> > > >
> > > > Why bother with all the extra complexity of the switch statement?
> > >
> > > I don't think that defined() can be used in a C expression. Hence the
> > > IS_ENABLED() macro. If you fix that, leave out four superfluous parentheses,
> > > test your patch, post that patch and cc me then I will add my Reviewed-by.
> >
> > Actually the defined macro is used multiple spots in if statements
> > throughout the kernel.
>
> The only 'if (defined(' matches I found in the kernel tree that are not
> preprocessor statements occur in Perl code. Maybe I overlooked something?
You may be right. I think I was thinking of "__is_defined", not "defined".
> > The reason for IS_ENABLED is to address the fact that we can be
> > dealing with macros that indicate if they are built in or a module
> > since those end up being two different defines depending on if you
> > select 'y' or 'm'.
>
> From Documentation/process/coding-style.rst:
>
> Within code, where possible, use the IS_ENABLED macro to convert a Kconfig
> symbol into a C boolean expression, and use it in a normal C conditional:
>
> .. code-block:: c
>
> if (IS_ENABLED(CONFIG_SOMETHING)) {
> ...
> }
>
> Bart.
Right. Part of the reason for suggesting that is that depending on how
you define "CONFIG_SOMETHING" it can actually be defined as
"CONFIG_SOMETHING" or "CONFIG_SOMETHING_MODULE". I was operating
under the assumption that CONFIG_ZONE_DMA wasn't ever going to be
built as a module.
Thanks.
- Alex
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] slab.h: Avoid using & for logical and of booleans
[not found] ` <aa5975b6-58ed-5a3e-7de1-4b1384f88457@suse.cz>
@ 2018-11-21 13:22 ` Vlastimil Babka
0 siblings, 0 replies; 13+ messages in thread
From: Vlastimil Babka @ 2018-11-21 13:22 UTC (permalink / raw)
To: David Laight, Andrew Morton
Cc: 'Bart Van Assche',
linux-kernel, Mel Gorman, Christoph Lameter, Roman Gushchin,
Darryl T. Agostinelli, linux-mm, Masahiro Yamada, Dan Carpenter
On 11/13/18 7:22 PM, Vlastimil Babka wrote:
> On 11/12/18 10:55 AM, David Laight wrote:
>> From: Vlastimil Babka [mailto:vbabka@suse.cz]
>>> Sent: 09 November 2018 19:16
>> ...
>>> This? Not terribly elegant, but I don't see a nicer way right now...
>>
>> Maybe just have two copies of the function body?
>>
>> static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags)
>> {
>> #ifndef CONFIG_ZONE_DMA
>> return flags & __GFP_RECLAIMABLE ? KMALLOC_RECLAIM : KMALLOC_NORMAL;
>> #else
>> if (likely((flags & (__GFP_DMA | __GFP_RECLAIMABLE)) == 0))
>> return KMALLOC_NORMAL;
>> return flags & __GFP_DMA ? KMALLOC_DMA : KMALLOC_RECLAIM;
>> #endif
>> }
>
> OK that's probably the most straightforward to follow, thanks.
> Note that for CONFIG_ZONE_DMA=n the result is identical to original code and
> all other attempts. flags & __GFP_DMA is converted to 1/0 index without branches
> or cmovs or whatnot.
Ping? Seems like people will report duplicates until the sparse warning
is gone in mainline...
Also CC linux-mm which was somehow lost.
----8<----
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2018-11-21 13:22 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20181105204000.129023-1-bvanassche@acm.org>
2018-11-05 21:13 ` [PATCH] slab.h: Avoid using & for logical and of booleans Andrew Morton
2018-11-05 21:48 ` Bart Van Assche
2018-11-05 22:14 ` Rasmus Villemoes
2018-11-05 22:40 ` Bart Van Assche
2018-11-05 22:48 ` Alexander Duyck
2018-11-06 0:01 ` Bart Van Assche
2018-11-06 0:11 ` Alexander Duyck
2018-11-06 0:32 ` Bart Van Assche
2018-11-06 17:20 ` Alexander Duyck
2018-11-06 17:48 ` Bart Van Assche
2018-11-06 18:17 ` Alexander Duyck
2018-11-06 9:45 ` William Kucharski
[not found] ` <62188a351f2249188ce654ee03c894b1@AcuMS.aculab.com>
[not found] ` <e44e6c8b-e4e4-e7cb-a5ca-88e9559eb0d7@suse.cz>
[not found] ` <3c9adab0f1f74c46a60b3d4401030337@AcuMS.aculab.com>
[not found] ` <60deb90d-e521-39e5-5072-fc9efb98e365@suse.cz>
[not found] ` <9af3ac1d43bb422cb3c41e7e8e422e6e@AcuMS.aculab.com>
[not found] ` <cbc1fc52-dc8c-aa38-8f29-22da8bcd91c1@suse.cz>
[not found] ` <20181109110019.c82fba8125d4e2891fbe4a6c@linux-foundation.org>
[not found] ` <b8ffd59b-0d15-9c98-b9ea-ad71e4c0c734@suse.cz>
[not found] ` <bf7c2a6b801a4430bf842fc20e826db6@AcuMS.aculab.com>
[not found] ` <aa5975b6-58ed-5a3e-7de1-4b1384f88457@suse.cz>
2018-11-21 13:22 ` Vlastimil Babka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox