| From: Christophe de Dinechin <dinechin@redhat.com> |
| Subject: nodemask.h: fix compilation error with GCC12 |
| Date: Thu, 14 Apr 2022 17:08:54 +0200 |
| |
| With gcc version 12.0.1 20220401 (Red Hat 12.0.1-0), building with |
| defconfig results in the following compilation error: |
| |
| | CC mm/swapfile.o |
| | mm/swapfile.c: In function `setup_swap_info': |
| | mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds |
| | of `struct plist_node[]' [-Werror=array-bounds] |
| | 2291 | p->avail_lists[i].prio = 1; |
| | | ~~~~~~~~~~~~~~^~~ |
| | In file included from mm/swapfile.c:16: |
| | ./include/linux/swap.h:292:27: note: while referencing `avail_lists' |
| | 292 | struct plist_node avail_lists[]; /* |
| | | ^~~~~~~~~~~ |
| |
| This is due to the compiler detecting that the mask in |
| node_states[__state] could theoretically be zero, which would lead to |
| first_node() returning -1 through find_first_bit. |
| |
| I believe that the warning/error is legitimate. I first tried adding a |
| test to check that the node mask is not emtpy, since a similar test exists |
| in the case where MAX_NUMNODES == 1. |
| |
| However, adding the if statement causes other warnings to appear in |
| for_each_cpu_node_but, because it introduces a dangling else ambiguity. |
| And unfortunately, GCC is not smart enough to detect that the added test |
| makes the case where (node) == -1 impossible, so it still complains with |
| the same message. |
| |
| This is why I settled on replacing that with a harmless, but relatively |
| useless (node) >= 0 test. Based on the warning for the dangling else, I |
| also decided to fix the case where MAX_NUMNODES == 1 by moving the |
| condition inside the for loop. It will still only be tested once. This |
| ensures that the meaning of an else following for_each_node_mask or |
| derivatives would not silently have a different meaning depending on the |
| configuration. |
| |
| Link: https://lkml.kernel.org/r/20220414150855.2407137-3-dinechin@redhat.com |
| Signed-off-by: Christophe de Dinechin <christophe@dinechin.org> |
| Signed-off-by: Christophe de Dinechin <dinechin@redhat.com> |
| Reviewed-by: Andrew Morton <akpm@linux-foundation.org> |
| Cc: Ben Segall <bsegall@google.com> |
| Cc: "Michael S. Tsirkin" <mst@redhat.com> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: Mel Gorman <mgorman@suse.de> |
| Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> |
| Cc: Vincent Guittot <vincent.guittot@linaro.org> |
| Cc: Paolo Bonzini <pbonzini@redhat.com> |
| Cc: Daniel Bristot de Oliveira <bristot@redhat.com> |
| Cc: Jason Wang <jasowang@redhat.com> |
| Cc: Zhen Lei <thunder.leizhen@huawei.com> |
| Cc: Juri Lelli <juri.lelli@redhat.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/nodemask.h | 13 ++++++------- |
| 1 file changed, 6 insertions(+), 7 deletions(-) |
| |
| --- a/include/linux/nodemask.h~nodemaskh-fix-compilation-error-with-gcc12 |
| +++ a/include/linux/nodemask.h |
| @@ -375,14 +375,13 @@ static inline void __nodes_fold(nodemask |
| } |
| |
| #if MAX_NUMNODES > 1 |
| -#define for_each_node_mask(node, mask) \ |
| - for ((node) = first_node(mask); \ |
| - (node) < MAX_NUMNODES; \ |
| - (node) = next_node((node), (mask))) |
| +#define for_each_node_mask(node, mask) \ |
| + for ((node) = first_node(mask); \ |
| + (node >= 0) && (node) < MAX_NUMNODES; \ |
| + (node) = next_node((node), (mask))) |
| #else /* MAX_NUMNODES == 1 */ |
| -#define for_each_node_mask(node, mask) \ |
| - if (!nodes_empty(mask)) \ |
| - for ((node) = 0; (node) < 1; (node)++) |
| +#define for_each_node_mask(node, mask) \ |
| + for ((node) = 0; (node) < 1 && !nodes_empty(mask); (node)++) |
| #endif /* MAX_NUMNODES */ |
| |
| /* |
| _ |