This is bulk deletion of preprocessor include guards and conversion
to #pragma once directive.
See [PATCH 11/11] and [PATCH 12/11] for the script and rationale.
Everything else is trivial stuff.
From c17ac63e1334c742686cd411736699c1d34d45a7 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Wed, 10 Feb 2021 21:07:45 +0300
Subject: [PATCH 01/11] pragma once: delete include/linux/atm_suni.h
This file has been empty since 2.3.99-pre3!
Delete it instead of converting to #pragma once.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
drivers/atm/fore200e.c | 1 -
drivers/atm/suni.c | 1 -
include/linux/atm_suni.h | 12 ------------
3 files changed, 14 deletions(-)
delete mode 100644 include/linux/atm_suni.h
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 9a70bee84125..0b9c99c3d218 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -21,7 +21,6 @@
#include <linux/module.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
-#include <linux/atm_suni.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/firmware.h>
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
index c920a8c52925..21e5acc766b8 100644
--- a/drivers/atm/suni.c
+++ b/drivers/atm/suni.c
@@ -21,7 +21,6 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/capability.h>
-#include <linux/atm_suni.h>
#include <linux/slab.h>
#include <asm/param.h>
#include <linux/uaccess.h>
diff --git a/include/linux/atm_suni.h b/include/linux/atm_suni.h
deleted file mode 100644
index 84f3aab54468..000000000000
--- a/include/linux/atm_suni.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* atm_suni.h - Driver-specific declarations of the SUNI driver (for use by
- driver-specific utilities) */
-
-/* Written 1998,2000 by Werner Almesberger, EPFL ICA */
-
-
-#ifndef LINUX_ATM_SUNI_H
-#define LINUX_ATM_SUNI_H
-
-/* everything obsoleted */
-
-#endif
--
2.29.2
From 45622ce1e4db512ad603dd90f959e61285b7541a Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 14:43:52 +0300
Subject: [PATCH 03/11] pragma once: convert arch/s390/tools/gen_facilities.c
Generate arch/s390/include/generated/asm/facility-defs.h without include
guard.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
arch/s390/tools/gen_facilities.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c
index 61ce5b59b828..cd5055994206 100644
--- a/arch/s390/tools/gen_facilities.c
+++ b/arch/s390/tools/gen_facilities.c
@@ -157,8 +157,7 @@ static void print_facility_lists(void)
int main(int argc, char **argv)
{
- printf("#ifndef __ASM_S390_FACILITY_DEFS__\n");
- printf("#define __ASM_S390_FACILITY_DEFS__\n");
+ printf("#pragma once\n");
printf("/*\n");
printf(" * DO NOT MODIFY.\n");
printf(" *\n");
@@ -166,6 +165,6 @@ int main(int argc, char **argv)
printf(" */\n\n");
printf("#include <linux/const.h>\n\n");
print_facility_lists();
- printf("\n#endif\n");
+ printf("\n");
return 0;
}
--
2.29.2
From 72842f89ae91a4d02ea29604f87c373052bd3f64 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 14:37:40 +0300
Subject: [PATCH 02/11] pragma once: convert arch/arm/tools/gen-mach-types
Generate arch/arm/include/generated/asm/mach-types.h without include
guard.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
arch/arm/tools/gen-mach-types | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types
index cbe1c33bb871..c28cd4b50f76 100644
--- a/arch/arm/tools/gen-mach-types
+++ b/arch/arm/tools/gen-mach-types
@@ -23,12 +23,11 @@ NF == 3 {
END {
+ printf("#pragma once\n");
printf("/*\n");
printf(" * This was automagically generated from %s!\n", FILENAME);
printf(" * Do NOT edit\n");
- printf(" */\n\n");
- printf("#ifndef __ASM_ARM_MACH_TYPE_H\n");
- printf("#define __ASM_ARM_MACH_TYPE_H\n\n");
+ printf(" */\n");
printf("#ifndef __ASSEMBLY__\n");
printf("/* The type of machine we're running on */\n");
printf("extern unsigned int __machine_arch_type;\n");
@@ -68,6 +67,5 @@ END {
printf("\n#ifndef machine_arch_type\n");
printf("#define machine_arch_type\t__machine_arch_type\n");
- printf("#endif\n\n");
printf("#endif\n");
}
--
2.29.2
From 1c4107e55b322dada46879837d4d64841bc5f150 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 16:56:54 +0300
Subject: [PATCH 06/11] pragma once: convert include/linux/cb710.h
This file is concatenation of two files with two include guards.
Convert it manually.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
include/linux/cb710.h | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/include/linux/cb710.h b/include/linux/cb710.h
index 405657a9a0d5..f3055e9442db 100644
--- a/include/linux/cb710.h
+++ b/include/linux/cb710.h
@@ -1,12 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#pragma once
/*
* cb710/cb710.h
*
* Copyright by Michał Mirosław, 2008-2009
*/
-#ifndef LINUX_CB710_DRIVER_H
-#define LINUX_CB710_DRIVER_H
-
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
@@ -121,15 +119,11 @@ void cb710_dump_regs(struct cb710_chip *chip, unsigned dump);
#define CB710_DUMP_ACCESS_ALL 0x700
#define CB710_DUMP_ACCESS_MASK 0x700
-#endif /* LINUX_CB710_DRIVER_H */
/*
* cb710/sgbuf2.h
*
* Copyright by Michał Mirosław, 2008-2009
*/
-#ifndef LINUX_CB710_SG_H
-#define LINUX_CB710_SG_H
-
#include <linux/highmem.h>
#include <linux/scatterlist.h>
@@ -197,5 +191,3 @@ static inline void cb710_sg_dwiter_read_to_io(struct sg_mapping_iter *miter,
while (count-- > 0)
iowrite32(cb710_sg_dwiter_read_next_block(miter), port);
}
-
-#endif /* LINUX_CB710_SG_H */
--
2.29.2
From e428633ff0df5fe8501aaf785c6961fc766344b2 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 00:31:23 +0300
Subject: [PATCH 07/11] pragma once: convert kernel/time/timeconst.bc
Generate include/generated/timeconst.h without include guard.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
kernel/time/timeconst.bc | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/kernel/time/timeconst.bc b/kernel/time/timeconst.bc
index 7ed0e0fb5831..42b3a542e5f5 100644
--- a/kernel/time/timeconst.bc
+++ b/kernel/time/timeconst.bc
@@ -41,12 +41,9 @@ define fmuls(b,n,d) {
}
define timeconst(hz) {
+ print "#pragma once\n"
print "/* Automatically generated by kernel/time/timeconst.bc */\n"
print "/* Time conversion constants for HZ == ", hz, " */\n"
- print "\n"
-
- print "#ifndef KERNEL_TIMECONST_H\n"
- print "#define KERNEL_TIMECONST_H\n\n"
print "#include <linux/param.h>\n"
print "#include <linux/types.h>\n\n"
@@ -106,9 +103,6 @@ define timeconst(hz) {
print "#define HZ_TO_NSEC_DEN\t\t", hz/cd, "\n"
print "#define NSEC_TO_HZ_NUM\t\t", hz/cd, "\n"
print "#define NSEC_TO_HZ_DEN\t\t", 1000000000/cd, "\n"
- print "\n"
-
- print "#endif /* KERNEL_TIMECONST_H */\n"
}
halt
}
--
2.29.2
From 251ca5673886b5bb0a42004944290b9d2b267a4a Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Fri, 19 Feb 2021 13:37:24 +0300
Subject: [PATCH 10/11] pragma once: delete few backslashes
Some macros contain one backslash too many and end up being the last
macro in a header file. When #pragma once conversion script truncates
the last #endif and whitespace before it, such backslash triggers
a warning about "OMG file ends up in a backslash-newline".
Needless to say I don't want to handle another case in my script,
so delete useless backslashes instead.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
arch/arc/include/asm/cacheflush.h | 2 +-
drivers/net/ethernet/mellanox/mlxsw/item.h | 2 +-
include/linux/once.h | 2 +-
include/media/drv-intf/exynos-fimc.h | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
index e201b4b1655a..46704c341b17 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -112,6 +112,6 @@ do { \
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len); \
+ memcpy(dst, src, len)
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/item.h b/drivers/net/ethernet/mellanox/mlxsw/item.h
index e92cadc98128..cc0133401dd1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/item.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/item.h
@@ -504,6 +504,6 @@ mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val) \
return __mlxsw_item_bit_array_set(buf, \
&__ITEM_NAME(_type, _cname, _iname), \
index, val); \
-} \
+}
#endif
diff --git a/include/linux/once.h b/include/linux/once.h
index 9225ee6d96c7..0af450ff94a5 100644
--- a/include/linux/once.h
+++ b/include/linux/once.h
@@ -55,6 +55,6 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
#define get_random_once(buf, nbytes) \
DO_ONCE(get_random_bytes, (buf), (nbytes))
#define get_random_once_wait(buf, nbytes) \
- DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \
+ DO_ONCE(get_random_bytes_wait, (buf), (nbytes))
#endif /* _LINUX_ONCE_H */
diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
index 6b9ef631d6bb..6c5fbdacf4b5 100644
--- a/include/media/drv-intf/exynos-fimc.h
+++ b/include/media/drv-intf/exynos-fimc.h
@@ -152,6 +152,6 @@ static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
#define fimc_pipeline_call(ent, op, args...) \
((!(ent) || !(ent)->pipe) ? -ENOENT : \
(((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
- (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \
+ (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))
#endif /* S5P_FIMC_H_ */
--
2.29.2
From fe8504a1a0b5352cbc676b933c3dbb79ae9f59c9 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 16:50:24 +0300
Subject: [PATCH 04/11] pragma once: convert drivers/gpu/drm/pl111/pl111_nomadik.h
This file has broken include guard, convert it manually.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
drivers/gpu/drm/pl111/pl111_nomadik.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/pl111/pl111_nomadik.h b/drivers/gpu/drm/pl111/pl111_nomadik.h
index 47ccf5c839fc..00592a38c7d8 100644
--- a/drivers/gpu/drm/pl111/pl111_nomadik.h
+++ b/drivers/gpu/drm/pl111/pl111_nomadik.h
@@ -1,9 +1,5 @@
// SPDX-License-Identifier: GPL-2.0+
-
-#ifndef PL111_NOMADIK_H
-#define PL111_NOMADIK_H
-#endif
-
+#pragma once
struct device;
#ifdef CONFIG_ARCH_NOMADIK
--
2.29.2
From 1f58b4923ca9bfb8b1e73554d3793ee98ab58a77 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 17:14:25 +0300
Subject: [PATCH 05/11] pragma once: convert drivers/scsi/qla2xxx/qla_target.h
This file has broken include guard which is not obvious just by looking
at the code. Convert it manually. I think I got #endif right.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
drivers/scsi/qla2xxx/qla_target.h | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 10e5e6c8087d..923910dd1809 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -15,10 +15,7 @@
* This is the global def file that is useful for including from the
* target portion.
*/
-
-#ifndef __QLA_TARGET_H
-#define __QLA_TARGET_H
-
+#pragma once
#include "qla_def.h"
#include "qla_dsd.h"
@@ -116,7 +113,6 @@
(min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \
QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0))
#endif
-#endif
#define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \
? le16_to_cpu((iocb)->u.isp2x.target.extended) \
@@ -244,6 +240,7 @@ struct ctio_to_2xxx {
#ifndef CTIO_RET_TYPE
#define CTIO_RET_TYPE 0x17 /* CTIO return entry */
#define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */
+#endif
struct fcp_hdr {
uint8_t r_ctl;
@@ -1082,5 +1079,3 @@ extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t,
uint8_t, uint8_t, uint8_t);
-
-#endif /* __QLA_TARGET_H */
--
2.29.2
From f10fe79897fa9600f144c76bc5df52dba28b7a66 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 01:37:55 +0300
Subject: [PATCH 08/11] pragma once: convert scripts/atomic/
Generate atomic headers without include guards.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
include/asm-generic/atomic-instrumented.h | 9 ++-------
include/asm-generic/atomic-long.h | 9 ++-------
include/linux/atomic-arch-fallback.h | 9 ++-------
include/linux/atomic-fallback.h | 9 ++-------
scripts/atomic/gen-atomic-fallback.sh | 10 +---------
scripts/atomic/gen-atomic-instrumented.sh | 10 +---------
scripts/atomic/gen-atomic-long.sh | 7 +------
7 files changed, 11 insertions(+), 52 deletions(-)
diff --git a/include/asm-generic/atomic-instrumented.h b/include/asm-generic/atomic-instrumented.h
index 888b6cfeed91..7c50dc944da4 100644
--- a/include/asm-generic/atomic-instrumented.h
+++ b/include/asm-generic/atomic-instrumented.h
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by scripts/atomic/gen-atomic-instrumented.sh
// DO NOT MODIFY THIS FILE DIRECTLY
@@ -14,9 +14,6 @@
* arch_ variants (i.e. arch_atomic_read()/arch_atomic_cmpxchg()) to avoid
* double instrumentation.
*/
-#ifndef _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
-#define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
-
#include <linux/build_bug.h>
#include <linux/compiler.h>
#include <linux/instrumented.h>
@@ -1828,6 +1825,4 @@ atomic64_dec_if_positive(atomic64_t *v)
instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \
arch_cmpxchg_double_local(__ai_ptr, __VA_ARGS__); \
})
-
-#endif /* _ASM_GENERIC_ATOMIC_INSTRUMENTED_H */
-// 4bec382e44520f4d8267e42620054db26a659ea3
+// d4532f98463d7403bde1d3199c19ef660be362a4
diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h
index 073cf40f431b..99627cd42f32 100644
--- a/include/asm-generic/atomic-long.h
+++ b/include/asm-generic/atomic-long.h
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by scripts/atomic/gen-atomic-long.sh
// DO NOT MODIFY THIS FILE DIRECTLY
-
-#ifndef _ASM_GENERIC_ATOMIC_LONG_H
-#define _ASM_GENERIC_ATOMIC_LONG_H
-
#include <linux/compiler.h>
#include <asm/types.h>
@@ -1010,5 +1006,4 @@ atomic_long_dec_if_positive(atomic_long_t *v)
}
#endif /* CONFIG_64BIT */
-#endif /* _ASM_GENERIC_ATOMIC_LONG_H */
-// a624200981f552b2c6be4f32fe44da8289f30d87
+// d6f8dde6d86814728f0671cfc505c9a3361a70a0
diff --git a/include/linux/atomic-arch-fallback.h b/include/linux/atomic-arch-fallback.h
index a3dba31df01e..477c53f3a4d6 100644
--- a/include/linux/atomic-arch-fallback.h
+++ b/include/linux/atomic-arch-fallback.h
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by scripts/atomic/gen-atomic-fallback.sh
// DO NOT MODIFY THIS FILE DIRECTLY
-
-#ifndef _LINUX_ATOMIC_FALLBACK_H
-#define _LINUX_ATOMIC_FALLBACK_H
-
#include <linux/compiler.h>
#ifndef arch_xchg_relaxed
@@ -2357,5 +2353,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v)
#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
#endif
-#endif /* _LINUX_ATOMIC_FALLBACK_H */
-// cca554917d7ea73d5e3e7397dd70c484cad9b2c4
+// 97eae5341271dde782071fb73ff76f4b7bfa4808
diff --git a/include/linux/atomic-fallback.h b/include/linux/atomic-fallback.h
index 2a3f55d98be9..eecc9ee88af6 100644
--- a/include/linux/atomic-fallback.h
+++ b/include/linux/atomic-fallback.h
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by scripts/atomic/gen-atomic-fallback.sh
// DO NOT MODIFY THIS FILE DIRECTLY
-
-#ifndef _LINUX_ATOMIC_FALLBACK_H
-#define _LINUX_ATOMIC_FALLBACK_H
-
#include <linux/compiler.h>
#ifndef xchg_relaxed
@@ -2591,5 +2587,4 @@ atomic64_dec_if_positive(atomic64_t *v)
#define atomic64_dec_if_positive atomic64_dec_if_positive
#endif
-#endif /* _LINUX_ATOMIC_FALLBACK_H */
-// d78e6c293c661c15188f0ec05bce45188c8d5892
+// a697a2a982652cdb954bc317199caba6ae5c3ed9
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh
index 317a6cec76e1..27a63ae3a458 100755
--- a/scripts/atomic/gen-atomic-fallback.sh
+++ b/scripts/atomic/gen-atomic-fallback.sh
@@ -223,13 +223,9 @@ gen_try_cmpxchg_fallbacks()
cat << EOF
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by $0
// DO NOT MODIFY THIS FILE DIRECTLY
-
-#ifndef _LINUX_ATOMIC_FALLBACK_H
-#define _LINUX_ATOMIC_FALLBACK_H
-
#include <linux/compiler.h>
EOF
@@ -254,7 +250,3 @@ EOF
grep '^[a-z]' "$1" | while read name meta args; do
gen_proto "${meta}" "${name}" "${ARCH}" "atomic64" "s64" ${args}
done
-
-cat <<EOF
-#endif /* _LINUX_ATOMIC_FALLBACK_H */
-EOF
diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh
index 5766ffcec7c5..b00f5ed4d62c 100755
--- a/scripts/atomic/gen-atomic-instrumented.sh
+++ b/scripts/atomic/gen-atomic-instrumented.sh
@@ -154,7 +154,7 @@ gen_optional_xchg()
cat << EOF
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by $0
// DO NOT MODIFY THIS FILE DIRECTLY
@@ -169,9 +169,6 @@ cat << EOF
* arch_ variants (i.e. arch_atomic_read()/arch_atomic_cmpxchg()) to avoid
* double instrumentation.
*/
-#ifndef _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
-#define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
-
#include <linux/build_bug.h>
#include <linux/compiler.h>
#include <linux/instrumented.h>
@@ -202,8 +199,3 @@ gen_xchg "cmpxchg_double" "2 * "
printf "\n\n"
gen_xchg "cmpxchg_double_local" "2 * "
-
-cat <<EOF
-
-#endif /* _ASM_GENERIC_ATOMIC_INSTRUMENTED_H */
-EOF
diff --git a/scripts/atomic/gen-atomic-long.sh b/scripts/atomic/gen-atomic-long.sh
index e318d3f92e53..4a707ba62048 100755
--- a/scripts/atomic/gen-atomic-long.sh
+++ b/scripts/atomic/gen-atomic-long.sh
@@ -57,13 +57,9 @@ EOF
cat << EOF
// SPDX-License-Identifier: GPL-2.0
-
+#pragma once
// Generated by $0
// DO NOT MODIFY THIS FILE DIRECTLY
-
-#ifndef _ASM_GENERIC_ATOMIC_LONG_H
-#define _ASM_GENERIC_ATOMIC_LONG_H
-
#include <linux/compiler.h>
#include <asm/types.h>
@@ -98,5 +94,4 @@ done
cat <<EOF
#endif /* CONFIG_64BIT */
-#endif /* _ASM_GENERIC_ATOMIC_LONG_H */
EOF
--
2.29.2
From 097f2c8b2af7d9e88cff59376ea0ad51b95341cb Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 00:39:23 +0300
Subject: [PATCH 09/11] pragma once: convert scripts/selinux/genheaders/genheaders.c
Generate security/selinux/flask.h and security/selinux/av_permissions.h
without include guards.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
scripts/selinux/genheaders/genheaders.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
index f355b3e0e968..e13ee4221993 100644
--- a/scripts/selinux/genheaders/genheaders.c
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -74,8 +74,8 @@ int main(int argc, char *argv[])
initial_sid_to_string[i] = stoupperx(s);
}
+ fprintf(fout, "#pragma once\n");
fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
- fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
@@ -109,7 +109,6 @@ int main(int argc, char *argv[])
fprintf(fout, "\treturn sock;\n");
fprintf(fout, "}\n");
- fprintf(fout, "\n#endif\n");
fclose(fout);
fout = fopen(argv[2], "w");
@@ -119,8 +118,8 @@ int main(int argc, char *argv[])
exit(4);
}
+ fprintf(fout, "#pragma once\n");
fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
- fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
@@ -136,7 +135,6 @@ int main(int argc, char *argv[])
}
}
- fprintf(fout, "\n#endif\n");
fclose(fout);
exit(0);
}
--
2.29.2
From 2bffcdfec69a8d28e9cb2c535724fbba8e12b820 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <[email protected]>
Date: Tue, 9 Feb 2021 14:47:34 +0300
Subject: [PATCH 11/11] pragma once: conversion script (in Python 2)
Script accepts list of files to be converted from the command line,
strips include guard if any and inserts "#pragma once" directive in
the beginning.
The following patterns are recognised:
#ifndef FOO_H #ifndef FOO_H
#define FOO_H #ifndef FOO_H 1
#endif
#endif // comment
#endif /* one line comment */
This is how almost all include guards look like.
Scripts doesn't pretend to be a compiler. For example, comments inside
preprocessor directive aren't recognised because people don't write code
like this:
# /*
* legal C
*/ def\
ine FOO /*
* no, we don't care
*/
Trailing multiline comments aren't recognised as well.
Script can cut through SPDX comments:
/* SPDX-License-Identifier: xxx
* <=== pragma once will be inserted here
* Copyright ...
*/
In other words, the script is simple but not too simple.
It cowardly exits and doesn't do anything as a safety measure in case of
an existing pragma once directive, missing/broken include guard or a bug.
Running it second time shouldn't do anything.
Signed-off-by: Alexey Dobriyan <[email protected]>
---
scripts/pragma-once.py | 159 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 159 insertions(+)
create mode 100755 scripts/pragma-once.py
diff --git a/scripts/pragma-once.py b/scripts/pragma-once.py
new file mode 100755
index 000000000000..7c8a274aad28
--- /dev/null
+++ b/scripts/pragma-once.py
@@ -0,0 +1,159 @@
+#!/usr/bin/python2
+# Copyright (c) 2021 Alexey Dobriyan <[email protected]>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Change include guard to "#pragma once" directive in place.
+import os
+import re
+import sys
+
+def read_file(filename):
+ with open(filename) as f:
+ return f.read()
+
+def write_file(filename, buf):
+ tmp = '%s.pragma-once' % filename
+ with open(tmp, 'w') as f:
+ f.write(buf)
+ os.rename(tmp, filename)
+
+def ws(c):
+ return c == ' ' or c == '\t' or c == '\n'
+
+re_ifndef = re.compile('#[ \t]*ifndef[ \t]+([A-Za-z_][A-Za-z0-9_]*)\n')
+re_define = re.compile('#[ \t]*define[ \t]+([A-Za-z_][A-Za-z0-9_]*)([ \t]+1)?\n')
+re_endif1 = re.compile('#[ \t]*endif[ \t]*//')
+re_endif2 = re.compile('#[ \t]*endif[ \t]*/\*')
+
+def pragma_once(c):
+ i = 0
+
+ # skip leading whitespace and comments
+ while i < len(c):
+ if ws(c[i]):
+ i += 1
+ elif c[i] == '/' and c[i + 1] == '*':
+ i = c.index('*/', i + 2) + 2
+ elif c[i] == '/' and c[i + 1] == '/':
+ i = c.index('\n', i + 2) + 1
+ else:
+ break;
+
+ # find #ifndef
+ ifndef_start = i
+ match = re_ifndef.match(c, i)
+ guard = match.group(1)
+ i = match.end()
+
+ # find #define
+ match = re_define.match(c, i)
+ if match.group(1) != guard:
+ raise
+ i = match.end()
+
+ while ws(c[i]):
+ i += 1
+
+ define_end = i
+
+ # trim whitespace before #ifndef
+ i = ifndef_start
+ while i > 0 and ws(c[i - 1]):
+ i -= 1
+ if c[i] == '\n':
+ i += 1
+ ifndef_start = i
+
+ #print repr(c[ifndef_start:define_end])
+
+ # find #endif
+ i = c.rindex('\n#endif', i) + 1
+ endif_start = i
+
+ match = None
+ if match is None:
+ match = re_endif1.match(c, i)
+ if match:
+ try:
+ i = c.index('\n', match.end()) + 1
+ except ValueError:
+ i = len(c)
+
+ if match is None:
+ match = re_endif2.match(c, i)
+ if match:
+ try:
+ i = c.index('*/', match.end()) + 2
+ except ValueError:
+ i = len(c)
+
+ if match is None:
+ i = endif_start + len('#endif')
+
+ while i < len(c) and ws(c[i]):
+ i += 1
+ if i != len(c):
+ raise
+
+ endif_end = i
+
+ # trim whitespace before #endif
+ i = endif_start
+ while i > 0 and ws(c[i - 1]):
+ i -= 1
+ if c[i] == '\n':
+ i += 1
+ endif_start = i
+
+ #print repr(c[endif_start:endif_end])
+
+ if define_end > endif_start:
+ raise
+
+ spdx_end = None
+ pragma_once = '#pragma once\n'
+ cut_comment = False
+ if c.startswith('/* SPDX'):
+ spdx_end = c.index('\n') + 1
+ if not (c[spdx_end - 3] == '*' and c[spdx_end - 2] == '/'):
+ cut_comment = True
+ elif c.startswith('// SPDX') or c.startswith('//SPDX'):
+ spdx_end = c.index('\n') + 1
+
+ if spdx_end is None:
+ l = [pragma_once, c[0:ifndef_start]]
+ elif cut_comment:
+ l = [c[0:spdx_end - 1], ' */\n', pragma_once, '/*\n', c[spdx_end:ifndef_start]]
+ else:
+ l = [c[0:spdx_end], pragma_once, c[spdx_end:ifndef_start]]
+
+ l.append(c[define_end:endif_start])
+ l.append(c[endif_end:])
+ return ''.join(l)
+
+def main():
+ for filename in sys.argv[1:]:
+ s = ''
+ try:
+ buf = read_file(filename)
+ if buf.find('#pragma once') == -1:
+ write_file(filename, pragma_once(buf))
+ else:
+ s = 'skip '
+ except:
+ pass
+ print '#pragma once: %s%s' % (s, filename)
+
+if __name__ == '__main__':
+ main()
--
2.29.2
On Sun, Feb 28, 2021 at 8:57 AM Alexey Dobriyan <[email protected]> wrote:
>
> This is bulk deletion of preprocessor include guards and conversion
> to #pragma once directive.
So as mentioned earlier, I'm not 100% convinced about the advantage of
#pragma once.
But I decided to actually test it, and it turns out that it causes
problems for at least sparse.
Sparse *does* support pragma once, but it does it purely based on
pathname equality. So a simple test-program like this:
File 'pragma.h':
#pragma once
#include "header.h"
works fine. But this doesn't work at all:
#pragma once
#include "./header.h"
because it causes the filename to be different every time, and you
eventually end up with trying to open "././....../pragma.h" and it
causes ENAMETOOLONG.
So at least sparse isn't ready for this.
I guess sparse could always simplify the name, but that's non-trivial.
And honestly, using st_dev/st_ino is problematic too, since
(a) they can easily be re-used for generated files
(b) you'd have to actually open/fstat the filename to use it, which
obviates one of the optimizations
Trying the same on gcc, you don't get that endless "add "./" behavior"
that sparse did, but a quick test shows that it actually opens the
file and reads it three times: once for "pramga.h", once for
"./pragma.h" and a third time for "pragma.h". It only seems to
_expand_ it once, though.
I have no idea what gcc does. Maybe it does some "different name, so
let's open and read it, and then does st_dev/st_ino again". But if so,
why the _third_ time? Is it some guard against "st_ino might have been
re-used, so I'll open the original name and re-verify"?
End result: #pragma is fundamentally less reliable than the
traditional #ifdef guard. The #ifdef guard works fine even if you
re-read the file for whatever reason, while #pragma relies on some
kind of magical behavior.
I'm adding Luc in case he has any ideas of what the magical behavior might be.
Honestly, I think #pragma once is complete garbage. It's really is
fundamenetally more complicated than the #ifdef guard, and it has
absolutely zero upsides.
I'm not taking this pramga series unless somebody can explain why it's
a good thing. Because all I see are downsides.
Linus
On Sun, Feb 28, 2021 at 12:04 PM Alexey Dobriyan <[email protected]> wrote:
>
> From 097f2c8b2af7d9e88cff59376ea0ad51b95341cb Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Tue, 9 Feb 2021 00:39:23 +0300
> Subject: [PATCH 09/11] pragma once: convert scripts/selinux/genheaders/genheaders.c
>
> Generate security/selinux/flask.h and security/selinux/av_permissions.h
> without include guards.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
> ---
> scripts/selinux/genheaders/genheaders.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
My LKML subscription must have died at some point due to mail bounces,
or maybe I dopped it (?), because I'm not seeing the rest of this
patchset for context.
However, unless the rest of the kernel transitions to this, or there
is some other big win that I'm missing, I don't see much of a reason
for this; can you provide some compelling reason for why we should
make this change? A quick search on "#pragma once" seems to indicate
it is non-standard, so why replace the simple #ifdef/#define solution
for this?
> diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
> index f355b3e0e968..e13ee4221993 100644
> --- a/scripts/selinux/genheaders/genheaders.c
> +++ b/scripts/selinux/genheaders/genheaders.c
> @@ -74,8 +74,8 @@ int main(int argc, char *argv[])
> initial_sid_to_string[i] = stoupperx(s);
> }
>
> + fprintf(fout, "#pragma once\n");
> fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
> - fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
>
> for (i = 0; secclass_map[i].name; i++) {
> struct security_class_mapping *map = &secclass_map[i];
> @@ -109,7 +109,6 @@ int main(int argc, char *argv[])
> fprintf(fout, "\treturn sock;\n");
> fprintf(fout, "}\n");
>
> - fprintf(fout, "\n#endif\n");
> fclose(fout);
>
> fout = fopen(argv[2], "w");
> @@ -119,8 +118,8 @@ int main(int argc, char *argv[])
> exit(4);
> }
>
> + fprintf(fout, "#pragma once\n");
> fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
> - fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
>
> for (i = 0; secclass_map[i].name; i++) {
> struct security_class_mapping *map = &secclass_map[i];
> @@ -136,7 +135,6 @@ int main(int argc, char *argv[])
> }
> }
>
> - fprintf(fout, "\n#endif\n");
> fclose(fout);
> exit(0);
> }
> --
> 2.29.2
--
paul moore
http://www.paul-moore.com
On Sun, Feb 28, 2021 at 09:46:17AM -0800, Linus Torvalds wrote:
> On Sun, Feb 28, 2021 at 8:57 AM Alexey Dobriyan <[email protected]> wrote:
> >
> > This is bulk deletion of preprocessor include guards and conversion
> > to #pragma once directive.
>
> So as mentioned earlier, I'm not 100% convinced about the advantage of
> #pragma once.
>
> But I decided to actually test it, and it turns out that it causes
> problems for at least sparse.
Oh no.
> Sparse *does* support pragma once, but it does it purely based on
> pathname equality.
Doing what gcc or clang does seems like a smart thing to do.
> So a simple test-program like this:
>
> File 'pragma.h':
>
> #pragma once
> #include "header.h"
>
> works fine. But this doesn't work at all:
>
> #pragma once
> #include "./header.h"
>
> because it causes the filename to be different every time, and you
> eventually end up with trying to open "././....../pragma.h" and it
> causes ENAMETOOLONG.
>
> So at least sparse isn't ready for this.
>
> I guess sparse could always simplify the name, but that's non-trivial.
>
> And honestly, using st_dev/st_ino is problematic too, since
>
> (a) they can easily be re-used for generated files
>
> (b) you'd have to actually open/fstat the filename to use it, which
> obviates one of the optimizations
fstat is more or less necessary anyway to allocate just enough memory
for 1 read. fstat is not a problem, read is (and subsequent parsing).
> Trying the same on gcc, you don't get that endless "add "./" behavior"
> that sparse did, but a quick test shows that it actually opens the
> file and reads it three times: once for "pramga.h", once for
> "./pragma.h" and a third time for "pragma.h". It only seems to
> _expand_ it once, though.
>
> I have no idea what gcc does. Maybe it does some "different name, so
> let's open and read it, and then does st_dev/st_ino again". But if so,
> why the _third_ time? Is it some guard against "st_ino might have been
> re-used, so I'll open the original name and re-verify"?
>
> End result: #pragma is fundamentally less reliable than the
> traditional #ifdef guard. The #ifdef guard works fine even if you
> re-read the file for whatever reason, while #pragma relies on some
> kind of magical behavior.
>
> I'm adding Luc in case he has any ideas of what the magical behavior might be.
gcc does
open "/" + "whatever between quotes"
fstat
so that "1.h" and "./1.h" differ
https://github.com/gcc-mirror/gcc/blob/master/libcpp/files.c#L377
clang does better:
"./" + "whatever between quotes"
open
fstat
normalise pathname via readlink /proc/*/fd
I think it is quite hard to break something with double inclusion
without trying to actually break stuff. Macros has to be token
for token identical or compiler warn. Types definition too.
Function prototypes and so on.
This is how I found half of the exception list.
The "no leading ./ in includes is trivially enforced with checkpatch.pl
or even grep! And it will optimise the build now that gcc behaviour has
been uncovered.
Include guards aren't without problems.
We have at least 1 identical include guard in the tree for two
completely unrelated headers (allmodconfig of some fringe arch found it)
Nobody complains because only defconfigs are run apparently.
Developer can typo it disabling double inclusion.
#ifndef FOO_H
#define FOO_h
#endif
I've seen a reference to a static checker checking for such stuff
so this problem exists.
Invisibly broken inlcude guards (see qla2xxx patch in the series).
On Sun, Feb 28, 2021 at 11:34 AM Alexey Dobriyan <[email protected]> wrote:
>
> >
> > End result: #pragma is fundamentally less reliable than the
> > traditional #ifdef guard. The #ifdef guard works fine even if you
> > re-read the file for whatever reason, while #pragma relies on some
> > kind of magical behavior.
You continue to not even answer this very fundamental question.
"#pragma once" doesn't seem to have a _single_ actual real advantage.
Everybody already does the optimization of not even opening - much
less reading and re-parsing - headers that have the traditional #ifdef
guard.
And even if you _don't_ do that optimization, the #ifdef guard
fundmentally semantically guarantyees the right behavior.
So the #ifdef guard is
(a) standard
(b) simple
(c) reliable
(d) traditional
and you have yet to explain a _single_ advantage of "#pragma once".
Why add this incredible churn that has no upside?
So no. We're not using #pragma once unless y9ou can come up with some
very strong argument for it
And no, having to come up with a name for the #ifdef guard is not a
strong argument. It's simply not that complicated.
Linus
On Sun, Feb 28, 2021 at 01:37:41PM -0500, Paul Moore wrote:
> On Sun, Feb 28, 2021 at 12:04 PM Alexey Dobriyan <[email protected]> wrote:
> >
> > From 097f2c8b2af7d9e88cff59376ea0ad51b95341cb Mon Sep 17 00:00:00 2001
> > From: Alexey Dobriyan <[email protected]>
> > Date: Tue, 9 Feb 2021 00:39:23 +0300
> > Subject: [PATCH 09/11] pragma once: convert scripts/selinux/genheaders/genheaders.c
> >
> > Generate security/selinux/flask.h and security/selinux/av_permissions.h
> > without include guards.
> >
> > Signed-off-by: Alexey Dobriyan <[email protected]>
> > ---
> > scripts/selinux/genheaders/genheaders.c | 6 ++----
> > 1 file changed, 2 insertions(+), 4 deletions(-)
>
> My LKML subscription must have died at some point due to mail bounces,
> or maybe I dopped it (?), because I'm not seeing the rest of this
> patchset for context.
>
> However, unless the rest of the kernel transitions to this, or there
> is some other big win that I'm missing, I don't see much of a reason
> for this; can you provide some compelling reason for why we should
> make this change? A quick search on "#pragma once" seems to indicate
> it is non-standard, so why replace the simple #ifdef/#define solution
> for this?
See https://lore.kernel.org/lkml/CAHk-=wjFWZMVWTbvUMVxQqGKvGMC_BNrahCtTkpEjxoC0k-T=A@mail.gmail.com/T/#t
On Sun, 28 Feb 2021 19:58:17 +0300 Alexey Dobriyan wrote:
> From c17ac63e1334c742686cd411736699c1d34d45a7 Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Wed, 10 Feb 2021 21:07:45 +0300
> Subject: [PATCH 01/11] pragma once: delete include/linux/atm_suni.h
>
> This file has been empty since 2.3.99-pre3!
> Delete it instead of converting to #pragma once.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
I'm guessing you want this to be merged via the networking tree?
(Guessing since you didn't CC us on the cover letter).
In that case please wait a couple of days and re-post it as a
standalone patch to netdev. Our build & validation bots can't deal
with series where we only get patches 1 and 10 on the list.
If someone else is willing to merge the entire series - consider
this patch acked.
On 2/28/21 9:01 AM, Alexey Dobriyan wrote:
> This file has broken include guard which is not obvious just by looking
> at the code. Convert it manually. I think I got #endif right.
Why do you think that the include guard is broken? Please mention this
in the patch description.
> -
> -#ifndef __QLA_TARGET_H
> -#define __QLA_TARGET_H
> -
> +#pragma once
> #include "qla_def.h"
> #include "qla_dsd.h"
Please insert a blank line between #pragma once and the #include directives.
Thanks,
Bart.
On Sun, Feb 28, 2021 at 10:34:46PM +0300, Alexey Dobriyan wrote:
>
> gcc does
>
> open "/" + "whatever between quotes"
> fstat
>
> so that "1.h" and "./1.h" differ
When I try the following with GCC 10.2:
$ cat header.h
#pragma once
#include "./header.h"
.. plenty of stuff ..
$ strace -f gcc -E header.h
I see that the file is opened 4 times (3 times with the name "header.h"
and once with "./header.h"). Each of these open is followed by a fstat().
More annoyingly, the file is also read 4 times (3 times entirely and once
only the fist 4096 bytes).
When the equivalent is done with an include guard instead, the file is
only read twice (once with each names) and read twice (entirely).
-- Luc
On Sun, Feb 28, 2021 at 08:05:14PM +0300, Alexey Dobriyan wrote:
> From 251ca5673886b5bb0a42004944290b9d2b267a4a Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Fri, 19 Feb 2021 13:37:24 +0300
> Subject: [PATCH 10/11] pragma once: delete few backslashes
>
> Some macros contain one backslash too many and end up being the last
> macro in a header file. When #pragma once conversion script truncates
> the last #endif and whitespace before it, such backslash triggers
> a warning about "OMG file ends up in a backslash-newline".
>
> Needless to say I don't want to handle another case in my script,
> so delete useless backslashes instead.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
For mlxsw:
Reviewed-by: Ido Schimmel <[email protected]>
Tested-by: Ido Schimmel <[email protected]>
Thanks
On Sun, Feb 28, 2021 at 07:59:16PM +0300, Alexey Dobriyan wrote:
> From 72842f89ae91a4d02ea29604f87c373052bd3f64 Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Tue, 9 Feb 2021 14:37:40 +0300
> Subject: [PATCH 02/11] pragma once: convert arch/arm/tools/gen-mach-types
>
> Generate arch/arm/include/generated/asm/mach-types.h without include
> guard.
The fundamental question of "why" is missing from this commit message.
Are we making this change to all kernel headers?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Sun, Feb 28, 2021 at 08:03:18PM +0300, Alexey Dobriyan wrote:
> From f10fe79897fa9600f144c76bc5df52dba28b7a66 Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Tue, 9 Feb 2021 01:37:55 +0300
> Subject: [PATCH 08/11] pragma once: convert scripts/atomic/
>
> Generate atomic headers without include guards.
-ENOCONTEXT, why ?
On Sun, Feb 28, 2021 at 6:00 PM Alexey Dobriyan <[email protected]> wrote:
> From fe8504a1a0b5352cbc676b933c3dbb79ae9f59c9 Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Tue, 9 Feb 2021 16:50:24 +0300
> Subject: [PATCH 04/11] pragma once: convert drivers/gpu/drm/pl111/pl111_nomadik.h
>
> This file has broken include guard, convert it manually.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
Yeah that's right, I wonder how this happened.
Reviewed-by: Linus Walleij <[email protected]>
Yours,
Linus Walleij
On Mon, Mar 01, 2021 at 10:19:50AM +0000, Russell King - ARM Linux admin wrote:
> On Sun, Feb 28, 2021 at 07:59:16PM +0300, Alexey Dobriyan wrote:
> > From 72842f89ae91a4d02ea29604f87c373052bd3f64 Mon Sep 17 00:00:00 2001
> > From: Alexey Dobriyan <[email protected]>
> > Date: Tue, 9 Feb 2021 14:37:40 +0300
> > Subject: [PATCH 02/11] pragma once: convert arch/arm/tools/gen-mach-types
> >
> > Generate arch/arm/include/generated/asm/mach-types.h without include
> > guard.
>
> The fundamental question of "why" is missing from this commit message.
> Are we making this change to all kernel headers?
Apparently, no. Linus doesn't like it.
On Sun, Feb 28, 2021 at 08:02:10PM +0300, Alexey Dobriyan wrote:
> From 1c4107e55b322dada46879837d4d64841bc5f150 Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Tue, 9 Feb 2021 16:56:54 +0300
> Subject: [PATCH 06/11] pragma once: convert include/linux/cb710.h
>
> This file is concatenation of two files with two include guards.
> Convert it manually.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
Acked-by: Micha? Miros?aw <[email protected]>
> (a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC
> MEANING. It's a pure optimization that doesn't actually change
> anything else. If you don't do the optimization, absolutely nothing
> changes.
And if the parser is well written the optimisation is probably
irrelevant compared to the compile time.
OTOH that probably requires using mmap(), memchr('\n') to look
for line starts, a fast search for '[ ]*#' followed by else/endif
and a final horrid backwards check for a continuation line.
That optimisation will generally speed up header file processing.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On 28/02/2021 17:05, Alexey Dobriyan wrote:
> From 251ca5673886b5bb0a42004944290b9d2b267a4a Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Fri, 19 Feb 2021 13:37:24 +0300
> Subject: [PATCH 10/11] pragma once: delete few backslashes
>
> Some macros contain one backslash too many and end up being the last
> macro in a header file. When #pragma once conversion script truncates
> the last #endif and whitespace before it, such backslash triggers
> a warning about "OMG file ends up in a backslash-newline".
>
> Needless to say I don't want to handle another case in my script,
> so delete useless backslashes instead.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
> ---
> arch/arc/include/asm/cacheflush.h | 2 +-
> drivers/net/ethernet/mellanox/mlxsw/item.h | 2 +-
> include/linux/once.h | 2 +-
> include/media/drv-intf/exynos-fimc.h | 2 +-
> 4 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
> index e201b4b1655a..46704c341b17 100644
> --- a/arch/arc/include/asm/cacheflush.h
> +++ b/arch/arc/include/asm/cacheflush.h
> @@ -112,6 +112,6 @@ do { \
> } while (0)
>
> #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> - memcpy(dst, src, len); \
> + memcpy(dst, src, len)
> This changebar also removes a semicolon.
It looks plausibly correct, but the commit message ought to mention it.
-ed
On 2/28/21 9:05 AM, Alexey Dobriyan wrote:
> From 251ca5673886b5bb0a42004944290b9d2b267a4a Mon Sep 17 00:00:00 2001
> From: Alexey Dobriyan <[email protected]>
> Date: Fri, 19 Feb 2021 13:37:24 +0300
> Subject: [PATCH 10/11] pragma once: delete few backslashes
>
> Some macros contain one backslash too many and end up being the last
> macro in a header file. When #pragma once conversion script truncates
> the last #endif and whitespace before it, such backslash triggers
> a warning about "OMG file ends up in a backslash-newline".
>
> Needless to say I don't want to handle another case in my script,
> so delete useless backslashes instead.
>
> Signed-off-by: Alexey Dobriyan <[email protected]>
Acked-by: Vineet Gupta <[email protected]> #arch/arc bits
Thx,
-Vineet
> ---
> arch/arc/include/asm/cacheflush.h | 2 +-
> drivers/net/ethernet/mellanox/mlxsw/item.h | 2 +-
> include/linux/once.h | 2 +-
> include/media/drv-intf/exynos-fimc.h | 2 +-
> 4 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
> index e201b4b1655a..46704c341b17 100644
> --- a/arch/arc/include/asm/cacheflush.h
> +++ b/arch/arc/include/asm/cacheflush.h
> @@ -112,6 +112,6 @@ do { \
> } while (0)
>
> #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> - memcpy(dst, src, len); \
> + memcpy(dst, src, len)
>
> #endif
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/item.h b/drivers/net/ethernet/mellanox/mlxsw/item.h
> index e92cadc98128..cc0133401dd1 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/item.h
> +++ b/drivers/net/ethernet/mellanox/mlxsw/item.h
> @@ -504,6 +504,6 @@ mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val) \
> return __mlxsw_item_bit_array_set(buf, \
> &__ITEM_NAME(_type, _cname, _iname), \
> index, val); \
> -} \
> +}
>
> #endif
> diff --git a/include/linux/once.h b/include/linux/once.h
> index 9225ee6d96c7..0af450ff94a5 100644
> --- a/include/linux/once.h
> +++ b/include/linux/once.h
> @@ -55,6 +55,6 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
> #define get_random_once(buf, nbytes) \
> DO_ONCE(get_random_bytes, (buf), (nbytes))
> #define get_random_once_wait(buf, nbytes) \
> - DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \
> + DO_ONCE(get_random_bytes_wait, (buf), (nbytes))
>
> #endif /* _LINUX_ONCE_H */
> diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
> index 6b9ef631d6bb..6c5fbdacf4b5 100644
> --- a/include/media/drv-intf/exynos-fimc.h
> +++ b/include/media/drv-intf/exynos-fimc.h
> @@ -152,6 +152,6 @@ static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
> #define fimc_pipeline_call(ent, op, args...) \
> ((!(ent) || !(ent)->pipe) ? -ENOENT : \
> (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
> - (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \
> + (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))
>
> #endif /* S5P_FIMC_H_ */
>
On Wed, Mar 3, 2021 at 11:46 AM Tom Tromey <[email protected]> wrote:
>
> It's also worth noting that in GCC it is slower than include guards.
> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58770
>
> It's just a bug, probably easy to fix. On the other hand, nobody has
> ever bothered to do so.
That bugzilla is actually worth reading, if only to explain how the
include guard is more robust technology compared to #pragma once.
The traditional include guarding with #ifndef/#define/#endif around
the contents has the advantage that a compiler _can_ generate the
obvious trivial optimizations of just memoizing that "oh, I've seen
this filename already, and it had that include guard pattern, so I
don't need to include it again".
But, I hear you say "that's exactly what '#pragma once' does too!".
No, it's not. There's actually two huge and very fundamental
differences between '#pragma once' and the traditional include guard
optimization:
(a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC
MEANING. It's a pure optimization that doesn't actually change
anything else. If you don't do the optimization, absolutely nothing
changes.
(b) the traditional include guard model allows for overriding and is
simply more flexible
And the GCC bugzilla talks about some of the issues with (a), and I
already mentioned one similar issue with (a) wrt sparse: exactly what
is it that "#pragma once" really protects?
Is it the filename? Is it the _canonical_ filename? What about
symbolic links or hardlinks? Is it the inode number? What about
filesystems that don't really have those concepts?
The above questions aren't some made-up example. They are literally
FUNDAMENTAL DESIGN MISTAKES in "#pragma once".
In contrast, include guards just work. You give the guard an explicit
name, and that solves all the problems above, and allows for extra
flexibility (ie the (b) issue: you can override things and include
things twice if you know you're playing games, but you can also use
the guard name to see "have I already included this file" for when you
have possible nasty circular include file issues etc).
So the traditional include guard model is simply technically the superior model.
This is why I'm NAK'ing "#pragma once". It was never a good idea, and
the alleged advantage ("faster builds by avoiding double includes")
was always pure garbage because preprocessors could do the same
optimization using the traditional include guards. In fact, because
the traditional include guards have well-defined meaning and doesn't
have any of the questions about what makes a file unique, and a missed
optimization doesn't cause any semantic differences, a compiler has a
much _easier_ time with that optimization than with the ostensibly
simpler "#pragma once".
Most #pragma things are not wonderful. But '#pragma once' is actively bad.
Linus
On Thu, Mar 4, 2021 at 5:55 AM David Laight <[email protected]> wrote:
>
> > (a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC
> > MEANING. It's a pure optimization that doesn't actually change
> > anything else. If you don't do the optimization, absolutely nothing
> > changes.
>
> And if the parser is well written the optimisation is probably
> irrelevant compared to the compile time.
That's actually surprisingly not even remotely true.
People always think that the optimization phases of a compiler are the
expensive ones. And yes, there are certain optimizations that can be
*really* expensive, and people just don't even do them because they
are _so_ expensive and are exponential in time.
And yes, there can be some patterns that expose bad scaling in some
compiler algorithms, and histyorically that has often been seen when
people use generators to automatically generate huge functions (or
huge initializers), and then the compiler has some O(n**3) thing in it
that is entirely unnoticeable for normal code written by a human, but
means that a million-entry initializer takes five hours to compile.
But in reality, on very real normal code, the *front end* of the
compiler is often the most costly thing by far. Very much just the
lexer and the simple parser. Things that are "simple" and people think
are fast.
But they are are often the slowest part in C style languages, because
you have to lex and parse _everything_. You include maybe a dozen
header files, maybe more. Those in turn often include another dozen
support header files. You easily end up tokenizing and parsing
hundreds of header files for even the simplest programs - and 99,.9%
of that isn't ever *used*, and never actually generates any code that
needs to be optimized. Think of all the complex macros and functions
and type definitions you get when you include something basic like
<stdio.h>. Trust me, it's a _lot_ of small details that get tokenixed,
parsed and memoized.
And then all you do is a 'printf("Hello world");' and the amount of
actual code generation and optimization by the back-end is basically
zero.
And C++ is about an order of magnitude worse, because you really take
this whole approach and turn it up to 11 with templates, namespaces,
STL, and a lot of all that infrastructure that is there for all the
possible cases, but that most files that include it only use a small
tiny portion of.
So in C-style (and particularly C++) languages, reading header files,
tokenizing them and parsing them can _easily_ be the bulk of your
compile time. Absolutely every single serious C/C++ compiler
integrates tbe preprocessor _into_ the compiler, because the
traditional model of having a separate "cpp" phase actually made the
tokenization problem happen _twice_: once by the pre-processor, and
then a second time by the compiler. Integrating the two phases, so
that you can use just one tokenizer, and one single set of
identifiers, actually speeds up compile speed _enormously_.
Yes, yes, tokenization and parsing really is the simple part of a
compiler. Good register allocation is _hard_. SSA makes a lot of the
basic optimizations actually fairly straightforward and simple, but
more complex transformations (loop invariant stuff, vectorization,
various things like that) are really much much much more complex than
the simple front-end.
But that simple front end is the thing that touches absolutely
_everything_, whether it actually generates code or not.
And yes, this is mainly a C-style language problem. If you have
hardcoded modules approach and not the "include files that describe
all the different interfaces", you don't end up in that situation
where you spend a lot of time parsign the possible interfaces over and
over again.
And C++ really is hugely worse, and takes this issue to another level.
You can have simple single C++ files that end up basically having to
parse hundreds of thousands of lines of fairly complex code, because
they use several complex libraries, and that's how the library header
files are set up,m with multiple levels (ie the GUI header files
depend on, and include the lower-level object header files, which in
turn depend on "simple" core libraries like STL and Boost.
This is why pretty much every compiler out there does that include
file header guard optimization. Because avoiding having to read and
parse a file multiple times really does show up as a big big win. Even
when it's all hidden behind the #ifndef/#define/#endif guarding logic,
the cost of reading the file and lexing and parsing it enough to _see_
those guards is not cheap. Doing it once is required and important,
but then you memoize the fact that "oh, all the stuff I needed to
parse was behind this macro test, so next time I see this file, if
that macro is set, I can just ignore it".
So it is actually a very important optimization. It's just that the
optimization is better done with that explicit guard memoization than
it is with '#pragma once'
Linus
From: Linus Torvalds
> Sent: 04 March 2021 20:16
>
> On Thu, Mar 4, 2021 at 5:55 AM David Laight <[email protected]> wrote:
> >
> > > (a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC
> > > MEANING. It's a pure optimization that doesn't actually change
> > > anything else. If you don't do the optimization, absolutely nothing
> > > changes.
> >
> > And if the parser is well written the optimisation is probably
> > irrelevant compared to the compile time.
>
> That's actually surprisingly not even remotely true.
The point is that you can skip the unwanted parts of
#if without having to parse the file at all.
You just need to detect the line breaks.
So yes, you need to read the file and look at every byte.
But you don't need to even start tokenising it.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Fri, Mar 5, 2021 at 1:19 AM David Laight <[email protected]> wrote:
>
> The point is that you can skip the unwanted parts of
> #if without having to parse the file at all.
> You just need to detect the line breaks.
That's not actually true AT ALL.
You still need to at the very least parse the preprocessor tokens,
looking for things like #if, #else, and #endif. Because those can -
and do - nest inside the whole thing, so you're not even looking for
the final #endif, you have to be aware that there might be new #if
statements that means that now you now have to increment the nesting
count for the endif.
And to do even just *THAT*, you need to do all the comment parsing,
and all the string parsing, because a #endif means something entirely
different if there was a "/*" or a string on a previous line that
hasn't been terminated yet (yes, unterminated strings are bad
practice, but ..).
And regardless of even _those_ issues, you still should do all the
other syntactic tokenization stuff (ie all the quoting, the the
character handling: 'a' is a valid C token, but if you see the string
"it's" outside of a comment, that's a syntax error even if it's inside
a disabled region. IOW, this is an incorrect file:
#if 0
it's a bug to do this, and the compiler should scream
#endif
because it's simply not a valid token sequence. The fact that it's
inside a "#if 0" region doesn't change that fact at all. So you did
need to do all the tokenization logic.
The same goes for all the wide string stuff, the tri-graph horrors, etc etc.
End result: you need to still do basically all of the basic lexing,
and while you can then usually quickly throw the result mostly away
(and you could possibly use a simplified lexer _because_ you throw it
away), you actually didn't really win much. Doing a specialized lexer
just for the disabled regions is probably simply a bad idea: the fact
that you need to still do all the #if nesting etc checking means that
you still do need to do a modicum of tokenization etc.
Really: the whole "trivial" front-end parsing phase of C - and
particularly C++ - is a huge huge deal. It's going to show in the
profiles of the compiler quite decisively, unless you have a compiler
that then spends absolutely insane time on optimization and tries to
do things that basically no sane compiler does (because developers
wouldn't put up with the time sink).
So yes, I've even used things like super-optimizers that chew on small
pieces of code for _days_ because they have insane exponential costs
etc. I've never done it seriously, because it really isn't realistic,
but it can be a fun exercise to try.
Outside of those kinds of super-optimizers, lexing and parsing is a
big big deal.
(And again - this is very much language-specific. The C/C++ model of
header files is very very flexible, and has a lot of conveniences, but
it's also a big part of why the front end is such a big deal. Other
language models have other trade-offs).
Linus
On Fri, Mar 5, 2021 at 10:25 PM Linus Torvalds
<[email protected]> wrote:
>
> And regardless of even _those_ issues, you still should do all the
> other syntactic tokenization stuff (ie all the quoting, the the
> character handling: 'a' is a valid C token, but if you see the string
> "it's" outside of a comment, that's a syntax error even if it's inside
> a disabled region. IOW, this is an incorrect file:
>
> #if 0
> it's a bug to do this, and the compiler should scream
> #endif
>
> because it's simply not a valid token sequence. The fact that it's
> inside a "#if 0" region doesn't change that fact at all. So you did
> need to do all the tokenization logic.
Compilers don't scream that much, only GCC seems to give a warning. I
assume it is because it is just undefined rather than a required
error/diagnostic, i.e. the "If a ’ or a " character matches the last
category, the behavior is undefined." in 6.4.
Concerning #pragma once: I actually would like to have a standard
#once directive if what is a "seen file" could be defined a bit more
precisely. Even if just says it creates a guard with something similar
to the result of `__FILE__` would be good enough for many projects out
there, and one can still use guards when flexibility is needed and/or
corner cases are expected (which, if detected, the compiler could also
warn about).
Cheers,
Miguel
On Sat, Mar 6, 2021 at 5:07 AM Miguel Ojeda
<[email protected]> wrote:
>
> Concerning #pragma once: I actually would like to have a standard
> #once directive if what is a "seen file" could be defined a bit more
> precisely.
I think it would be ok if you had something like
#pragma once IDTOKEN
which would basically act *exactly* as a "#ifndef IDTOKEN/#define
IDTOKEN" with that final #endif at the end of the file.
But even then it should have the rule that it must be the very first
thing in the file (ignoring whitespace and pure comments).
Then it would literally be just a cleaner and simpler version of the
guarding logic, with none of the semantic confusion that #pragma once
now has.
Because I cannot see any other way to define what "seen file" really means.
There's no sane "implied IDTOKEN" that I can see. It can't really be
the pathname, because pathnames are actually really hard to turn into
canonical form in user space thanks to things like symlinks. It can't
be st_ino/st_dev stat information, because the C preprocessor isn't a
"POSIX only" thing.
It could be a "Ok, #pragma once only works if you don't have multiple
ways to reach the same file, and you never have ambiguous include
paths". But that's actually not all that unusual in real projects: you
often have fairly complex include paths, you have C files that include
the header in the same directory with just "filename.h", but it
_could_ get included indirectly from _another_ header that gave a
pathname relative to the project root, etc etc.
This is not unrelated to another complete morass of horrible problems:
precompiled header files. That feature had exactly the same reason for
it as "#pragma once" - slow build speeds due to the cost of parsing
complex header file hierarchies.
And I guarantee that multiple compiler teams spent hundreds of
person-years of effort on trying to make it work. And several
compilers do support the notion. And they ALL have big warnings about
when you should enable it, and when you shouldn't, and what things
don't work if you use them, and about how it can cause really really
subtle problems.
Because it turns out that precompiled header files are a major pain
and a major mistake. Some projects still use them, because they can be
such a huge timesaver (again: particularly C++ projects that just have
a "include everything" approach to headers because trying to separate
things out is too hard). But they all come with huge warnings about
how they break the actual real semantics of a compiler, and if you do
_anything_ to change the build ("hey, I'd like to use a different
compiler option"), things may or may not work.
Linus
Hi!
> > > (a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC
> > > MEANING. It's a pure optimization that doesn't actually change
> > > anything else. If you don't do the optimization, absolutely nothing
> > > changes.
> >
> > And if the parser is well written the optimisation is probably
> > irrelevant compared to the compile time.
>
> That's actually surprisingly not even remotely true.
>
> People always think that the optimization phases of a compiler are the
> expensive ones. And yes, there are certain optimizations that can be
> *really* expensive, and people just don't even do them because they
> are _so_ expensive and are exponential in time.
Well, linux kernel can be compiled in two _seconds_ if you take
compiler optimized for fast parsing... and quick code generation.
See "SUSE Labs Conference 2018 - Compiling the Linux kernel in a
second (give or take)" on youtube.
So yes, gcc's frontend may be slow, but that does not mean job can not
be done quickly by suitable compiler.
Best regards,
Pavel
--
http://www.livejournal.com/~pavelmachek
Hi!
> > index e201b4b1655a..46704c341b17 100644
> > --- a/arch/arc/include/asm/cacheflush.h
> > +++ b/arch/arc/include/asm/cacheflush.h
> > @@ -112,6 +112,6 @@ do { \
> > } while (0)
> >
> > #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> > - memcpy(dst, src, len); \
> > + memcpy(dst, src, len)
> > This changebar also removes a semicolon.
> It looks plausibly correct, but the commit message ought to mention it.
Probably should use do{}while(0) trick.
Pavel
--
http://www.livejournal.com/~pavelmachek