diff mbox

[v4,3/4] kernel hacking: new config CC_OPTIMIZE_FOR_DEBUGGING to apply GCC -Og optimization

Message ID 1525855396-7908-4-git-send-email-changbin.du@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Du, Changbin May 9, 2018, 8:43 a.m. UTC
From: Changbin Du <changbin.du@intel.com>

This will apply GCC '-Og' optimization level which is supported
since GCC 4.8. This optimization level offers a reasonable level
of optimization while maintaining fast compilation and a good
debugging experience. It is similar to '-O1' while perferring
to keep debug ability over runtime speed.

If enabling this option breaks your kernel, you should either
disable this or find a fix (mostly in the arch code). Currently
this option has only been tested on x86_64 and arm platform.

This option can satisfy people who was searching for a method
to disable compiler optimizations so to achieve better kernel
debugging experience with kgdb or qemu.

The main problem of '-Og' is we must not use __attribute__((error(msg))).
The compiler will report error though the call to error function
still can be optimize out. So we must fallback to array tricky.

Comparison of vmlinux size: a bit smaller.

    w/o CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
    $ size vmlinux
       text    data     bss     dec     hex filename
    22665554   9709674  2920908 35296136        21a9388 vmlinux

    w/ CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
    $ size vmlinux
       text    data     bss     dec     hex filename
    21499032   10102758 2920908 34522698        20ec64a vmlinux

Comparison of system performance: a bit drop (~6%).
    This benchmark of kernel compilation is suggested by Ingo Molnar.
    https://lkml.org/lkml/2018/5/2/74

    Preparation: Set cpufreq to 'performance'.
    for ((cpu=0; cpu<120; cpu++)); do
      G=/sys/devices/system/cpu/cpu$cpu/cpufreq/scaling_governor
      [ -f $G ] && echo performance > $G
    done

    w/o CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
    $ perf stat --repeat 5 --null --pre                 '\
        cp -a kernel ../kernel.copy.$(date +%s);         \
        rm -rf *;                                        \
        git checkout .;                                  \
        echo 1 > /proc/sys/vm/drop_caches;               \
        find ../kernel* -type f | xargs cat >/dev/null;  \
        make -j kernel >/dev/null;                       \
        make clean >/dev/null 2>&1;                      \
        sync                                            '\
                                                         \
        make -j8 >/dev/null

    Performance counter stats for 'make -j8' (5 runs):

        219.764246652 seconds time elapsed                   ( +-  0.78% )

    w/ CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
    $ perf stat --repeat 5 --null --pre                 '\
        cp -a kernel ../kernel.copy.$(date +%s);         \
        rm -rf *;                                        \
        git checkout .;                                  \
        echo 1 > /proc/sys/vm/drop_caches;               \
        find ../kernel* -type f | xargs cat >/dev/null;  \
        make -j kernel >/dev/null;                       \
        make clean >/dev/null 2>&1;                      \
        sync                                            '\
                                                         \
        make -j8 >/dev/null

    Performance counter stats for 'make -j8' (5 runs):

         233.574187771 seconds time elapsed                  ( +-  0.19% )

Signed-off-by: Changbin Du <changbin.du@intel.com>

---
v3:
  o Rename DEBUG_EXPERIENCE to CC_OPTIMIZE_FOR_DEBUGGING
  o Move new configuration item to "General setup->Compiler optimization level"
v2:
  o Improve performance benchmark as suggested by Ingo.
  o Grammar updates in description. (Randy Dunlap)
---
 Makefile                     |  4 ++++
 include/linux/compiler-gcc.h |  2 +-
 include/linux/compiler.h     |  2 +-
 init/Kconfig                 | 19 +++++++++++++++++++
 4 files changed, 25 insertions(+), 2 deletions(-)

Comments

kernel test robot May 10, 2018, 8:59 p.m. UTC | #1
Hi Changbin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-rc4 next-20180510]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/changbin-du-intel-com/kernel-hacking-GCC-optimization-for-better-debug-experience-Og/20180509-213955
config: x86_64-randconfig-s1-05100951 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_freq':
>> drivers//net/wireless/zydas/zd1201.c:939:10: warning: 'channel' may be used uninitialized in this function [-Wmaybe-uninitialized]
     freq->m = channel;
     ~~~~~~~~^~~~~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_mode':
>> drivers//net/wireless/zydas/zd1201.c:1016:2: warning: 'porttype' may be used uninitialized in this function [-Wmaybe-uninitialized]
     switch(porttype) {
     ^~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_rate':
>> drivers//net/wireless/zydas/zd1201.c:1282:2: warning: 'rate' may be used uninitialized in this function [-Wmaybe-uninitialized]
     switch(rate) {
     ^~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_rts':
>> drivers//net/wireless/zydas/zd1201.c:1334:13: warning: 'rtst' may be used uninitialized in this function [-Wmaybe-uninitialized]
     rts->value = rtst;
     ~~~~~~~~~~~^~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_frag':
>> drivers//net/wireless/zydas/zd1201.c:1372:14: warning: 'fragt' may be used uninitialized in this function [-Wmaybe-uninitialized]
     frag->value = fragt;
     ~~~~~~~~~~~~^~~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_set_power':
>> drivers//net/wireless/zydas/zd1201.c:1503:28: warning: 'duration' may be used uninitialized in this function [-Wmaybe-uninitialized]
       level = vwrq->value * 4 / duration;
               ~~~~~~~~~~~~~~~~^~~~~~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_power':
   drivers//net/wireless/zydas/zd1201.c:1542:27: warning: 'duration' may be used uninitialized in this function [-Wmaybe-uninitialized]
       vwrq->value = duration * level / 4;
                     ~~~~~~~~~^~~~~~~
>> drivers//net/wireless/zydas/zd1201.c:1547:15: warning: 'level' may be used uninitialized in this function [-Wmaybe-uninitialized]
      if (enabled && level)
          ~~~~~~~~^~~~~~~~
>> drivers//net/wireless/zydas/zd1201.c:1547:6: warning: 'enabled' may be used uninitialized in this function [-Wmaybe-uninitialized]
      if (enabled && level)
         ^
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_hostauth':
>> drivers//net/wireless/zydas/zd1201.c:1631:13: warning: 'hostauth' may be used uninitialized in this function [-Wmaybe-uninitialized]
     rrq->value = hostauth;
     ~~~~~~~~~~~^~~~~~~~~~
   drivers//net/wireless/zydas/zd1201.c: In function 'zd1201_get_maxassoc':
>> drivers//net/wireless/zydas/zd1201.c:1681:13: warning: 'maxassoc' may be used uninitialized in this function [-Wmaybe-uninitialized]
     rrq->value = maxassoc;
     ~~~~~~~~~~~^~~~~~~~~~
--
   drivers/rtc/rtc-da9052.c: In function 'da9052_read_alarm':
>> drivers/rtc/rtc-da9052.c:25:3: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
      dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
      ^~~~~~~
   In file included from drivers/rtc/rtc-da9052.c:21:0:
   include/linux/mfd/da9052/da9052.h:157:6: note: 'ret' was declared here
     int ret;
         ^~~
>> drivers/rtc/rtc-da9052.c:25:3: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
      dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
      ^~~~~~~
   In file included from drivers/rtc/rtc-da9052.c:21:0:
   include/linux/mfd/da9052/da9052.h:157:6: note: 'ret' was declared here
     int ret;
         ^~~
   drivers/rtc/rtc-da9052.c: In function 'da9052_rtc_read_time':
>> drivers/rtc/rtc-da9052.c:25:3: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
      dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
      ^~~~~~~
   In file included from drivers/rtc/rtc-da9052.c:21:0:
   include/linux/mfd/da9052/da9052.h:157:6: note: 'ret' was declared here
     int ret;
         ^~~
>> drivers/rtc/rtc-da9052.c:25:3: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
      dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
      ^~~~~~~
   In file included from drivers/rtc/rtc-da9052.c:21:0:
   include/linux/mfd/da9052/da9052.h:157:6: note: 'ret' was declared here
     int ret;
         ^~~
--
   net/bluetooth/mgmt.c: In function 'read_local_oob_ext_data_complete':
>> net/bluetooth/mgmt.c:5669:27: warning: 'r256' may be used uninitialized in this function [-Wmaybe-uninitialized]
     u8 *h192, *r192, *h256, *r256;
                              ^~~~
--
   In file included from drivers//net/wireless/zydas/zd1211rw/zd_usb.c:28:0:
   drivers//net/wireless/zydas/zd1211rw/zd_usb.c: In function 'eject_installer':
>> include/linux/usb.h:1922:23: warning: 'bulk_out_ep' may be used uninitialized in this function [-Wmaybe-uninitialized]
     ((PIPE_BULK << 30) | __create_pipe(dev, endpoint))
                          ^~~~~~~~~~~~~
   drivers//net/wireless/zydas/zd1211rw/zd_usb.c:1278:5: note: 'bulk_out_ep' was declared here
     u8 bulk_out_ep;
        ^~~~~~~~~~~
--
   drivers/slimbus/messaging.c: In function 'slim_do_transfer':
>> drivers/slimbus/messaging.c:126:4: warning: 'tid' may be used uninitialized in this function [-Wmaybe-uninitialized]
       idr_remove(&ctrl->tid_idr, tid);
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   drivers//staging/comedi/drivers/serial2002.c: In function 'serial2002_setup_subdevs':
>> drivers//staging/comedi/drivers/serial2002.c:497:7: warning: 'cfg' may be used uninitialized in this function [-Wmaybe-uninitialized]
      if (serial2002_setup_subdevice(s, cfg, range, mapping, kind))
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from drivers/net/wireless/zydas/zd1211rw/zd_usb.c:28:0:
   drivers/net/wireless/zydas/zd1211rw/zd_usb.c: In function 'eject_installer':
>> include/linux/usb.h:1922:23: warning: 'bulk_out_ep' may be used uninitialized in this function [-Wmaybe-uninitialized]
     ((PIPE_BULK << 30) | __create_pipe(dev, endpoint))
                          ^~~~~~~~~~~~~
   drivers/net/wireless/zydas/zd1211rw/zd_usb.c:1278:5: note: 'bulk_out_ep' was declared here
     u8 bulk_out_ep;
        ^~~~~~~~~~~
--
   drivers//regulator/max8925-regulator.c: In function 'max8925_regulator_probe':
>> drivers//regulator/max8925-regulator.c:315:3: warning: 'ri' may be used uninitialized in this function [-Wmaybe-uninitialized]
      dev_err(&pdev->dev, "failed to register regulator %s\n",
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ri->desc.name);
        ~~~~~~~~~~~~~~
--
   drivers//bcma/sprom.c: In function 'bcma_sprom_get':
>> drivers//bcma/sprom.c:642:3: warning: 'sprom' may be used uninitialized in this function [-Wmaybe-uninitialized]
      kfree(sprom);
      ^~~~~~~~~~~~
--
   drivers//block/rbd.c: In function 'rbd_v2_snap_id_by_name':
>> drivers//block/rbd.c:4797:25: warning: 'snap_id' may be used uninitialized in this function [-Wmaybe-uninitialized]
     return found ? snap_id : CEPH_NOSNAP;
                             
   drivers//block/rbd.c: In function 'rbd_dev_image_id':
>> drivers//block/rbd.c:5349:27: warning: 'image_id' may be used uninitialized in this function [-Wmaybe-uninitialized]
      rbd_dev->spec->image_id = image_id;
      ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
--
   drivers//firmware/qemu_fw_cfg.c: In function 'fw_cfg_build_symlink':
>> drivers//firmware/qemu_fw_cfg.c:557:9: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
     return ret;
            ^~~
..

vim +/seq +33 include/linux/compiler.h

1f0d69a9 Steven Rostedt          2008-11-12  22  
d45ae1f7 Steven Rostedt (VMware  2017-01-17  23) #define __branch_check__(x, expect, is_constant) ({			\
1f0d69a9 Steven Rostedt          2008-11-12  24  			int ______r;					\
134e6a03 Steven Rostedt (VMware  2017-01-19  25) 			static struct ftrace_likely_data		\
1f0d69a9 Steven Rostedt          2008-11-12  26  				__attribute__((__aligned__(4)))		\
45b79749 Steven Rostedt          2008-11-21  27  				__attribute__((section("_ftrace_annotated_branch"))) \
1f0d69a9 Steven Rostedt          2008-11-12  28  				______f = {				\
134e6a03 Steven Rostedt (VMware  2017-01-19  29) 				.data.func = __func__,			\
134e6a03 Steven Rostedt (VMware  2017-01-19  30) 				.data.file = __FILE__,			\
134e6a03 Steven Rostedt (VMware  2017-01-19  31) 				.data.line = __LINE__,			\
1f0d69a9 Steven Rostedt          2008-11-12  32  			};						\
d45ae1f7 Steven Rostedt (VMware  2017-01-17 @33) 			______r = __builtin_expect(!!(x), expect);	\
d45ae1f7 Steven Rostedt (VMware  2017-01-17  34) 			ftrace_likely_update(&______f, ______r,		\
d45ae1f7 Steven Rostedt (VMware  2017-01-17  35) 					     expect, is_constant);	\
1f0d69a9 Steven Rostedt          2008-11-12  36  			______r;					\
1f0d69a9 Steven Rostedt          2008-11-12  37  		})
1f0d69a9 Steven Rostedt          2008-11-12  38  

:::::: The code at line 33 was first introduced by commit
:::::: d45ae1f7041ac52ade6c5ec76d96bbed765d67aa tracing: Process constants for (un)likely() profiler

:::::: TO: Steven Rostedt (VMware) <rostedt@goodmis.org>
:::::: CC: Steven Rostedt (VMware) <rostedt@goodmis.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot May 11, 2018, 3:18 a.m. UTC | #2
Hi Changbin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-rc4 next-20180510]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/changbin-du-intel-com/kernel-hacking-GCC-optimization-for-better-debug-experience-Og/20180509-213955
config: x86_64-randconfig-s1-05100951 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   lib/test_firmware.c: In function 'trigger_batched_requests_async_store':
>> lib/test_firmware.c:779:31: warning: 'rc' may be used uninitialized in this function [-Wmaybe-uninitialized]
      test_fw_config->test_result = rc;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
--
   kernel/futex.c: In function 'futex_atomic_op_inuser':
>> kernel/futex.c:1604:17: warning: 'oldval' may be used uninitialized in this function [-Wmaybe-uninitialized]
      return oldval > cmparg;
             ~~~~~~~^~~~~~~~
--
   kernel/kexec_file.c: In function 'kexec_apply_relocations':
>> kernel/kexec_file.c:896:6: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
      if (ret)
         ^
--
   mm/swap_state.c: In function '__add_to_swap_cache':
>> mm/swap_state.c:156:9: warning: 'error' may be used uninitialized in this function [-Wmaybe-uninitialized]
     return error;
            ^~~~~
--
   mm/swapfile.c: In function 'setup_swap_map_and_extents':
>> mm/swapfile.c:3061:10: warning: 'nr_extents' may be used uninitialized in this function [-Wmaybe-uninitialized]
      return nr_extents;
             ^~~~~~~~~~
--
   mm/ksm.c: In function 'stable_node_dup':
>> mm/ksm.c:1365:15: warning: 'found_rmap_hlist_len' may be used uninitialized in this function [-Wmaybe-uninitialized]
       if (!found ||
           ~~~~~~~^~
           dup->rmap_hlist_len > found_rmap_hlist_len) {
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   mm/huge_memory.c: In function 'do_huge_pmd_wp_page':
>> mm/huge_memory.c:1318:15: warning: 'huge_gfp' may be used uninitialized in this function [-Wmaybe-uninitialized]
     if (unlikely(mem_cgroup_try_charge(new_page, vma->vm_mm,
                  ^~~~~~~~~~~~~~~~~~~~~
--
   fs/splice.c: In function 'iter_file_splice_write':
>> fs/splice.c:694:10: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
     ssize_t ret;
             ^~~
--
   In file included from include/asm-generic/bug.h:5:0,
                    from arch/x86/include/asm/bug.h:83,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/gfp.h:5,
                    from include/linux/slab.h:15,
                    from ipc/sem.c:73:
   ipc/sem.c: In function 'find_alloc_undo':
>> include/linux/compiler.h:215:31: warning: 'ulp' may be used uninitialized in this function [-Wmaybe-uninitialized]
     case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
             ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
   ipc/sem.c:1843:24: note: 'ulp' was declared here
     struct sem_undo_list *ulp;
                           ^~~
--
   block/blk-merge.c: In function '__blk_recalc_rq_segments':
>> block/blk-merge.c:284:21: warning: 'bbio' may be used uninitialized in this function [-Wmaybe-uninitialized]
     if (seg_size > bbio->bi_seg_back_size)
                    ~~~~^~~~~~~~~~~~~~~~~~

vim +/ulp +215 include/linux/compiler.h

230fa253 Christian Borntraeger 2014-11-25  208  
43239cbe Christian Borntraeger 2015-01-13  209  static __always_inline void __write_once_size(volatile void *p, void *res, int size)
230fa253 Christian Borntraeger 2014-11-25  210  {
230fa253 Christian Borntraeger 2014-11-25  211  	switch (size) {
230fa253 Christian Borntraeger 2014-11-25  212  	case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
230fa253 Christian Borntraeger 2014-11-25  213  	case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
230fa253 Christian Borntraeger 2014-11-25  214  	case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
230fa253 Christian Borntraeger 2014-11-25 @215  	case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
230fa253 Christian Borntraeger 2014-11-25  216  	default:
230fa253 Christian Borntraeger 2014-11-25  217  		barrier();
230fa253 Christian Borntraeger 2014-11-25  218  		__builtin_memcpy((void *)p, (const void *)res, size);
230fa253 Christian Borntraeger 2014-11-25  219  		barrier();
230fa253 Christian Borntraeger 2014-11-25  220  	}
230fa253 Christian Borntraeger 2014-11-25  221  }
230fa253 Christian Borntraeger 2014-11-25  222  

:::::: The code at line 215 was first introduced by commit
:::::: 230fa253df6352af12ad0a16128760b5cb3f92df kernel: Provide READ_ONCE and ASSIGN_ONCE

:::::: TO: Christian Borntraeger <borntraeger@de.ibm.com>
:::::: CC: Christian Borntraeger <borntraeger@de.ibm.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/Makefile b/Makefile
index 6720c40..977418a 100644
--- a/Makefile
+++ b/Makefile
@@ -639,6 +639,9 @@  KBUILD_CFLAGS	+= $(call cc-disable-warning, format-truncation)
 KBUILD_CFLAGS	+= $(call cc-disable-warning, format-overflow)
 KBUILD_CFLAGS	+= $(call cc-disable-warning, int-in-bool-context)
 
+ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUGGING
+KBUILD_CFLAGS	+= $(call cc-option, -Og)
+else
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS	+= $(call cc-option,-Oz,-Os)
 KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
@@ -649,6 +652,7 @@  else
 KBUILD_CFLAGS   += -O2
 endif
 endif
+endif
 
 KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \
 			$(call cc-disable-warning,maybe-uninitialized,))
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index b4bf73f..586ed11 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -192,7 +192,7 @@ 
 
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
 
-#ifndef __CHECKER__
+#if !defined(__CHECKER__) && !defined(CONFIG_CC_OPTIMIZE_FOR_DEBUGGING)
 # define __compiletime_warning(message) __attribute__((warning(message)))
 # define __compiletime_error(message) __attribute__((error(message)))
 #endif /* __CHECKER__ */
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index ab4711c..e97caf4 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -301,7 +301,7 @@  unsigned long read_word_at_a_time(const void *addr)
  * sparse see a constant array size without breaking compiletime_assert on old
  * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
  */
-# ifndef __CHECKER__
+# if !defined(__CHECKER__) && !defined(CONFIG_CC_OPTIMIZE_FOR_DEBUGGING)
 #  define __compiletime_error_fallback(condition) \
 	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
 # endif
diff --git a/init/Kconfig b/init/Kconfig
index f013afc..aa52535 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1036,6 +1036,25 @@  config CC_OPTIMIZE_FOR_SIZE
 
 	  If unsure, say N.
 
+config CC_OPTIMIZE_FOR_DEBUGGING
+	bool "Optimize for better debugging experience (-Og)"
+	select NO_AUTO_INLINE
+	help
+	  This will apply GCC '-Og' optimization level which is supported
+	  since GCC 4.8. This optimization level offers a reasonable level
+	  of optimization while maintaining fast compilation and a good
+	  debugging experience. It is similar to '-O1' while preferring to
+	  keep debug ability over runtime speed. The overall performance
+	  will drop a bit (~6%).
+
+	  Use only if you want to debug the kernel, especially if you want
+	  to have better kernel debugging experience with gdb facilities
+	  like kgdb or qemu. If enabling this option breaks your kernel,
+	  you should either disable this or find a fix (mostly in the arch
+	  code).
+
+	  If unsure, select N.
+
 endchoice
 
 config SYSCTL