[PATCH 1/1] block: prevent calls to should_fail_bio() optimized by gcc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When CONFIG_FAIL_MAKE_REQUEST is not enabled, gcc may optimize out
calls to should_fail_bio() because the content of should_fail_bio()
is empty returning always 'false'. The gcc compiler then detects
the function call to should_fail_bio() being empty and optimizes
out the call to it. This prevents block I/O error injection programs
attached to it from working. The compiler is not aware of the side
effect of calling this probe function.

This issue is seen with gcc compiler version 14. Previous versions
of gcc compiler (checked 9, 11, 12, 13) don't have this optimization.

Clang compiler (seen with version 18.1.18) has the same issue of
optimizing out calls to should_fail_bio().

Adding the compiler attribute __attribute__((noipa)) to should_fail_bio()
function avoids this optimization. This attribute is available starting
from gcc compiler version 8.1. Adding this attribute avoids the issue
and only side effect is the slight increase in the code size of the
binary blk-core.o (e.g. 16 bytes with gcc version 11 and 48 bytes
with gcc version 14) as expected.

For Clang case, 'noipa' attribute is not available but it has a similar
attribute, 'optnone', with the same effect and fixes the issue. So, the
patch adds either 'noipa' attribute for gcc case or 'optnone' for
Clang case.

Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Prasad Singamsetty <prasad.singamsetty@xxxxxxxxxx>
---
 block/blk-core.c                    |  2 +-
 include/linux/compiler_attributes.h | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index e8cc270a453f..fb1da9ea92bb 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -539,7 +539,7 @@ static inline void bio_check_ro(struct bio *bio)
 	}
 }
 
-static noinline int should_fail_bio(struct bio *bio)
+static noipa noinline int should_fail_bio(struct bio *bio)
 {
 	if (should_fail_request(bdev_whole(bio->bi_bdev), bio->bi_iter.bi_size))
 		return -EIO;
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
index c16d4199bf92..9d4726c3426e 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -230,6 +230,21 @@
  */
 #define   noinline                      __attribute__((__noinline__))
 
+/*
+ * Optional: only supported since gcc >= 8
+ * Optional: Not supported by clang. "optnone" is used to
+ *	     disable all otipmizations
+ *
+ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noipa-function-attribute
+ */
+#if __has_attribute(__noipa__)
+#define   noipa                      __attribute__((__noipa__))
+#elif __has_attribute(__optnone__)
+#define   noipa                      __attribute__((__optnone__))
+#else
+#define   noipa
+#endif
+
 /*
  * Optional: only supported since gcc >= 8
  * Optional: not supported by clang

base-commit: 1a1d569a75f3ab2923cb62daf356d102e4df2b86
-- 
2.43.5





[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux