]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mlxsw: spectrum_acl_bloom_filter: Workaround for some LLVM versions
authorWangYuli <wangyuli@uniontech.com>
Tue, 18 Mar 2025 10:36:54 +0000 (18:36 +0800)
committerJakub Kicinski <kuba@kernel.org>
Mon, 24 Mar 2025 22:17:21 +0000 (15:17 -0700)
This is a workaround to mitigate a compiler anomaly.

During LLVM toolchain compilation of this driver on s390x architecture, an
unreasonable __write_overflow_field warning occurs.

Contextually, chunk_index is restricted to 0, 1 or 2. By expanding these
possibilities, the compile warning is suppressed.

Fix follow error with clang-19 when -Werror:
  In file included from drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c:5:
  In file included from ./include/linux/gfp.h:7:
  In file included from ./include/linux/mmzone.h:8:
  In file included from ./include/linux/spinlock.h:63:
  In file included from ./include/linux/lockdep.h:14:
  In file included from ./include/linux/smp.h:13:
  In file included from ./include/linux/cpumask.h:12:
  In file included from ./include/linux/bitmap.h:13:
  In file included from ./include/linux/string.h:392:
  ./include/linux/fortify-string.h:571:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
    571 |                         __write_overflow_field(p_size_field, size);
        |                         ^
  1 error generated.

According to the testing, we can be fairly certain that this is a clang
compiler bug, impacting only clang-19 and below. Clang versions 20 and
21 do not exhibit this behavior.

Link: https://lore.kernel.org/all/484364B641C901CD+20250311141025.1624528-1-wangyuli@uniontech.com/
Fixes: 7585cacdb978 ("mlxsw: spectrum_acl: Add Bloom filter handling")
Co-developed-by: Zijian Chen <czj2441@163.com>
Signed-off-by: Zijian Chen <czj2441@163.com>
Co-developed-by: Wentao Guan <guanwentao@uniontech.com>
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Co-developed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: WangYuli <wangyuli@uniontech.com>
Signed-off-by: WangYuli <wangyuli@uniontech.com>
Link: https://patch.msgid.link/A1858F1D36E653E0+20250318103654.708077-1-wangyuli@uniontech.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c

index a54eedb69a3f5be356b47a4eb215b8da223ccff7..067f0055a55af81620f92c2579ffd105c33bbbf6 100644 (file)
@@ -212,7 +212,22 @@ static const u8 mlxsw_sp4_acl_bf_crc6_tab[256] = {
  * This array defines key offsets for easy access when copying key blocks from
  * entry key to Bloom filter chunk.
  */
-static const u8 chunk_key_offsets[MLXSW_BLOOM_KEY_CHUNKS] = {2, 20, 38};
+static char *
+mlxsw_sp_acl_bf_enc_key_get(struct mlxsw_sp_acl_atcam_entry *aentry,
+                           u8 chunk_index)
+{
+       switch (chunk_index) {
+       case 0:
+               return &aentry->ht_key.enc_key[2];
+       case 1:
+               return &aentry->ht_key.enc_key[20];
+       case 2:
+               return &aentry->ht_key.enc_key[38];
+       default:
+               WARN_ON_ONCE(1);
+               return &aentry->ht_key.enc_key[0];
+       }
+}
 
 static u16 mlxsw_sp2_acl_bf_crc16_byte(u16 crc, u8 c)
 {
@@ -235,9 +250,10 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
                             u8 key_offset, u8 chunk_key_len, u8 chunk_len)
 {
        struct mlxsw_afk_key_info *key_info = aregion->region->key_info;
-       u8 chunk_index, chunk_count, block_count;
+       u8 chunk_index, chunk_count;
        char *chunk = output;
        __be16 erp_region_id;
+       u32 block_count;
 
        block_count = mlxsw_afk_key_info_blocks_count_get(key_info);
        chunk_count = 1 + ((block_count - 1) >> 2);
@@ -245,12 +261,13 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
                                   (aregion->region->id << 4));
        for (chunk_index = max_chunks - chunk_count; chunk_index < max_chunks;
             chunk_index++) {
+               char *enc_key;
+
                memset(chunk, 0, pad_bytes);
                memcpy(chunk + pad_bytes, &erp_region_id,
                       sizeof(erp_region_id));
-               memcpy(chunk + key_offset,
-                      &aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]],
-                      chunk_key_len);
+               enc_key = mlxsw_sp_acl_bf_enc_key_get(aentry, chunk_index);
+               memcpy(chunk + key_offset, enc_key, chunk_key_len);
                chunk += chunk_len;
        }
        *len = chunk_count * chunk_len;