2020-09-06 11:10:18

by Alejandro Colomar

[permalink] [raw]
Subject: Multiple definitions of ARRAY_SIZE(arr)

Hi all,

I was reading through kernel code, and found that there are many
definitions of `ARRAY_SIZE(arr)` all around the kernel.

Is there a reason for all of those to exist, or should they all just
include <linux/kernel.h>? If so, I would be happy to patch them.

Moreover, only the <linux/kernel.h> one is safe because of
`__must_be_array(arr)`.

Here's what I found:

$ grep -rn "define ARRAY_SIZE("
fs/orangefs/orangefs-debug.h:21:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]))
fs/unicode/mkutf8data.c:63:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
scripts/genksyms/genksyms.c:406:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]))
scripts/dtc/util.h:26:#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
scripts/mod/file2alias.c:713:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
scripts/kconfig/preprocess.c:15:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]))
scripts/kallsyms.c:28:#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
include/linux/kernel.h:47:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]) + __must_be_array(arr))
tools/gpio/gpio-utils.h:17:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]))
tools/iio/iio_utils.h:18:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof(arr[0]))
tools/virtio/linux/kernel.h:50:#define ARRAY_SIZE(x)
(sizeof(x)/sizeof(x[0]))
tools/lib/traceevent/plugins/plugin_xen.c:103:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/include/linux/kernel.h:107:#define ARRAY_SIZE(arr) (sizeof(arr) /
sizeof((arr)[0]) + __must_be_array(arr))
tools/power/cpupower/utils/cpupower.c:23:#define ARRAY_SIZE(x)
(sizeof(x)/sizeof(x[0]))
tools/usb/usbip/libsrc/usbip_device_driver.c:30:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/spi/spidev_test.c:26:#define ARRAY_SIZE(a) (sizeof(a) /
sizeof((a)[0]))
tools/testing/selftests/seccomp/seccomp_benchmark.c:17:#define
ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
tools/testing/selftests/sparc64/drivers/adi-test.c:28:# define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
tools/testing/selftests/net/reuseport_bpf.c:28:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/net/tcp_fastopen_backup_key.c:38:#define
ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/net/socket.c:34:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/net/rxtimestamp.c:21:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/kselftest_harness.h:590:#define ARRAY_SIZE(a)
(sizeof(a) / sizeof(a[0]))
tools/testing/selftests/timens/procfs.c:27:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/timens/timens.c:25:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/cgroup/cgroup_util.h:7:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/rseq/basic_percpu_ops_test.c:14:#define
ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/rseq/rseq.c:32:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/ir/ir_loopback.c:29:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/vm/va_128TBswitch.c:12:#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))
tools/testing/selftests/x86/protection_keys.c:54:#define ARRAY_SIZE(x)
(sizeof(x) / sizeof(*(x)))
tools/testing/selftests/bpf/progs/test_sysctl_loop1.c:13:#define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
tools/testing/selftests/bpf/progs/test_sysctl_loop2.c:13:#define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
tools/testing/selftests/bpf/progs/test_sysctl_prog.c:19:#define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
tools/testing/selftests/bpf/bpf_util.h:31:# define ARRAY_SIZE(x)
(sizeof(x) / sizeof((x)[0]))
tools/vm/page-types.c:209:#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
samples/seccomp/user-trap.c:24:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof(*(x)))
samples/mic/mpssd/mpssd.c:40:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
samples/bpf/cookie_uid_helper_example.c:34:#define ARRAY_SIZE(x)
(sizeof(x) / sizeof(*(x)))
arch/powerpc/boot/types.h:7:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
arch/mips/boot/tools/relocs.h:32:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
arch/um/include/shared/user.h:17:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
arch/x86/tools/insn_sanity.c:19:#define ARRAY_SIZE(a)
(sizeof(a)/sizeof(a[0]))
arch/x86/tools/relocs.h:22:#define ARRAY_SIZE(x) (sizeof(x) /
sizeof((x)[0]))
arch/x86/boot/boot.h:31:#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
Documentation/process/coding-style.rst:985: #define ARRAY_SIZE(x)
(sizeof(x) / sizeof((x)[0]))
Documentation/translations/zh_CN/process/coding-style.rst:823: #define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
Documentation/translations/it_IT/process/coding-style.rst:1001: #define
ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))


Alex


2020-09-06 11:43:22

by Alejandro Colomar

[permalink] [raw]
Subject: Re: Multiple definitions of ARRAY_SIZE(arr)

Hi all,

Here are a few more I could find using:
$ grep -rn "\/" | grep "sizeof.*sizeof" | grep -v ARRAY_SIZE | \
grep define | grep "\[0\]\|\*"

drivers/net/ethernet/huawei/hinic/hinic_ethtool.c:449:#define
ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0])))
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c:33:#define
NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c:46:#define
NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c:58:#define
NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c:52:#define
NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
scripts/dtc/libfdt/fdt_strerror.c:43:#define FDT_ERRTABSIZE
(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
include/linux/sh_intc.h:100:#define _INTC_ARRAY(a) a, __same_type(a,
NULL) ? 0 : sizeof(a)/sizeof(*a)
include/acpi/actypes.h:497:#define ACPI_ARRAY_LENGTH(x)
(sizeof(x) / sizeof((x)[0]))
tools/firewire/nosy-dump.h:5:#define array_length(array) (sizeof(array)
/ sizeof(array[0]))
tools/perf/pmu-events/json.c:144:#define LOOKUP(a, i) ((i) <
(sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
tools/perf/arch/x86/util/dwarf-regs.c:92:#define ARCH_MAX_REGS
((sizeof(regoffset_table) / sizeof(regoffset_table[0])) - 1)
tools/testing/selftests/net/hwtstamp_config.c:53:#define N_TX_TYPES
((int)(sizeof(tx_types) / sizeof(tx_types[0])))
tools/testing/selftests/net/hwtstamp_config.c:74:#define N_RX_FILTERS
((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
tools/testing/selftests/openat2/helpers.h:16:#define ARRAY_LEN(X)
(sizeof (X) / sizeof (*(X)))
tools/bpf/bpf_dbg.c:82:# define array_size(x) (sizeof(x) / sizeof((x)[0]))
samples/bpf/test_map_in_map_user.c:30:#define NR_TESTS
(sizeof(test_names) / sizeof(*test_names))


And a few more I could find using:
$ grep -rn "\/" | grep "sizeof.*sizeof" | grep -v ARRAY_SIZE | \
grep -v define | grep "\[0\]\|\*"

drivers/net/ethernet/intel/i40e/i40e_adminq.h:123: if (!((u32)aq_rc <
(sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
drivers/net/ethernet/intel/iavf/iavf_adminq.h:123: if (!((u32)aq_rc <
(sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
drivers/net/ethernet/mellanox/mlx4/qp.c:616: for (k =
MLX4_QP_TABLE_ZONE_RSS + 1; k < sizeof(*bitmap)/sizeof((*bitmap)[0]);
drivers/net/ethernet/mellanox/mlx4/qp.c:742: i <
sizeof(qp_table->zones_uids)/sizeof(qp_table->zones_uids[0]);
drivers/gpu/drm/i915/gvt/vgpu.c:127: num_types = sizeof(vgpu_types) /
sizeof(vgpu_types[0]);
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c:2372: for (k =
0; k <
sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]);
k++) {
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c:39: table_size =
sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max);
\
tools/perf/tests/bpf.c:320: sizeof(insns) / sizeof(insns[0]),
tools/perf/util/trace-event-parse.c:209: for (i = 0; i <
(int)(sizeof(flags)/sizeof(flags[0])); i++)
tools/lib/traceevent/event-parse.c:3868: for (i = 0; i <
(int)(sizeof(flags)/sizeof(flags[0])); i++)
tools/usb/usbip/src/usbipd.c:536: sizeof(sockfdlist) /
sizeof(*sockfdlist));
tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c:299: for
(i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i)
tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c:327: for
(i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i) {
tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c:367:
actual = (actual + 1)%(sizeof(iobuf)/sizeof(*iobuf));
tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c:372: for
(i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i)
tools/usb/ffs-test.c:669: for (i = 1; i < sizeof threads / sizeof
*threads; ++i)
tools/usb/ffs-test.c:672: for (i = 1; i < sizeof threads / sizeof
*threads; ++i)
tools/usb/ffs-test.c:677: for (i = 1; i < sizeof threads / sizeof
*threads; ++i)
tools/testing/scatterlist/main.c:76: assert(i == (sizeof(tests) /
sizeof(tests[0])) - 1);
tools/testing/selftests/net/psock_fanout.c:152: attr.insn_cnt =
sizeof(prog) / sizeof(prog[0]);
tools/testing/selftests/net/reuseport_bpf_numa.c:89: attr.insn_cnt =
sizeof(prog) / sizeof(prog[0]);
tools/testing/selftests/x86/test_vdso.c:267: for (int clock = 0; clock <
sizeof(clocknames) / sizeof(clocknames[0]);
tools/testing/selftests/proc/proc-pid-vm.c:371: for (i = 0; i <
sizeof(S)/sizeof(S[0]); i++) {
tools/testing/selftests/proc/proc-pid-vm.c:420: for (i = 0; i <
sizeof(S)/sizeof(S[0]); i++) {
tools/testing/selftests/bpf/progs/test_rdonly_maps.c:67: int i =
sizeof(rdonly_values.a) / sizeof(rdonly_values.a[0]);
tools/testing/selftests/bpf/prog_tests/obj_name.c:23: for (i = 0; i <
sizeof(tests) / sizeof(tests[0]); i++) {
tools/testing/selftests/bpf/prog_tests/global_data.c:31: for (i = 0; i <
sizeof(tests) / sizeof(tests[0]); i++) {
tools/testing/selftests/bpf/prog_tests/global_data.c:60: for (i = 0; i <
sizeof(tests) / sizeof(tests[0]); i++) {
tools/testing/selftests/bpf/prog_tests/global_data.c:94: for (i = 0; i <
sizeof(tests) / sizeof(tests[0]); i++) {
tools/testing/selftests/bpf/test_lru_map.c:883: for (f = 0; f <
sizeof(map_flags) / sizeof(*map_flags); f++) {
tools/testing/selftests/bpf/test_lru_map.c:887: for (t = 0; t <
sizeof(map_types) / sizeof(*map_types); t++) {
samples/seccomp/bpf-fancy.c:83: .len = (unsigned
short)(sizeof(filter)/sizeof(filter[0])),
samples/seccomp/bpf-fancy.c:86: bpf_resolve_jumps(&l, filter,
sizeof(filter)/sizeof(*filter));
samples/seccomp/dropper.c:42: .len = (unsigned
short)(sizeof(filter)/sizeof(filter[0])),
samples/seccomp/bpf-direct.c:146: .len = (unsigned
short)(sizeof(filter)/sizeof(filter[0])),
samples/timers/hpet_example.c:64: for (i = 0; i < (sizeof (hpet_command)
/ sizeof (hpet_command[0])); i++)
samples/bpf/tracex5_user.c:22: .len = (unsigned
short)(sizeof(filter)/sizeof(filter[0])),
samples/bpf/test_lru_dist.c:527: for (f = 0; f < sizeof(map_flags) /
sizeof(*map_flags); f++) {
arch/powerpc/xmon/ppc-opc.c:6972: sizeof (powerpc_opcodes) / sizeof
(powerpc_opcodes[0]);
arch/powerpc/xmon/ppc-opc.c:7211: sizeof (vle_opcodes) / sizeof
(vle_opcodes[0]);
arch/powerpc/xmon/ppc-opc.c:7280: sizeof (powerpc_macros) / sizeof
(powerpc_macros[0]);
arch/powerpc/kernel/traps.c:2298: for (i = 0; i <
sizeof(ppc_emulated)/sizeof(*entries); i++) {
arch/s390/tools/gen_facilities.c:154: for (i = 0; i <
sizeof(facility_defs) / sizeof(facility_defs[0]); i++)
arch/s390/tools/gen_opcode_table.c:141: for (i = 0; i <
sizeof(insn_type_table) / sizeof(insn_type_table[0]); i++) {
arch/um/kernel/config.c.in:17: for (i = 0; i <
sizeof(config)/sizeof(config[0]); i++)
arch/x86/entry/vdso/vdso2c.h:119: for (i = 0; i < sizeof(special_pages)
/ sizeof(special_pages[0]); i++) {


There were a more entries on these, but looked like noise,
or were in a more obfuscated form that should be examined
case by case. Might look deeper at them later.


Alex