* [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used.
@ 2011-11-22 1:31 David Daney
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: David Daney @ 2011-11-22 1:31 UTC (permalink / raw)
To: ralf, Linus Torvalds, Andrew Morton, David Rientjes
Cc: linux-kernel, linux-arch, David Daney
From: David Daney <david.daney@cavium.com>
After some, perhaps justified, reluctance to merge dummy symbol
definitions containing BUG() into header files, I propose these patches
instead.
We define a new compile time assertion BUILD_BUG_ON_USED() that can be
used in places were we expect the compiler's dead code elimination to
get rid of code. This happens mostly in code dealing with huge pages,
but in other places as well.
The first patch adds BUILD_BUG_ON_USED(), the second gets rid of one
of the main abusers of BUG().
David Daney (2):
kernel.h: Add BUILD_BUG_ON_USED() macro.
hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy
definitions.
include/linux/compiler-gcc4.h | 1 +
include/linux/compiler.h | 4 +++-
include/linux/hugetlb.h | 15 ++++++++-------
include/linux/kernel.h | 16 ++++++++++++++++
4 files changed, 28 insertions(+), 8 deletions(-)
--
1.7.2.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro.
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
@ 2011-11-22 1:31 ` David Daney
2011-11-22 4:35 ` Linus Torvalds
2011-11-22 1:31 ` [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions David Daney
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
2 siblings, 1 reply; 6+ messages in thread
From: David Daney @ 2011-11-22 1:31 UTC (permalink / raw)
To: ralf, Linus Torvalds, Andrew Morton, David Rientjes
Cc: linux-kernel, linux-arch, David Daney
From: David Daney <david.daney@cavium.com>
We can place this in definitions that we expect the compiler to remove
by dead code elimination. If this assertion fails, we get a nice
error message at build time.
The GCC function attribute error("message") was added in version 4.3,
so we define a new macro __linktime_error(message) to expand to this
for GCC-4.3 and later. This will give us an error diagnostic from the
compiler on the line that fails. For other compilers
__linktime_error(message) expands to nothing, and we have to be
content with a link time error, but at least we will still get a build
error.
BUILD_BUG_ON_USED() expands to the undefined function
__build_bug_on_used_failed() and will fail at link time if the
compiler ever emits code for it. On GCC-4.3 and later,
attribute((error())) is used so that the failure will be noted at compile
time instead.
Signed-off-by: David Daney <david.daney@cavium.com>
---
include/linux/compiler-gcc4.h | 1 +
include/linux/compiler.h | 4 +++-
include/linux/kernel.h | 16 ++++++++++++++++
3 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index dfadc96..2f40791 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -29,6 +29,7 @@
the kernel context */
#define __cold __attribute__((__cold__))
+#define __linktime_error(message) __attribute__((__error__(message)))
#if __GNUC_MINOR__ >= 5
/*
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 320d6c9..4a24354 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -293,7 +293,9 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#ifndef __compiletime_error
# define __compiletime_error(message)
#endif
-
+#ifndef __linktime_error
+# define __linktime_error(message)
+#endif
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b93c66e..ebe54515 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -666,6 +666,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
#define BUILD_BUG_ON_ZERO(e) (0)
#define BUILD_BUG_ON_NULL(e) ((void*)0)
#define BUILD_BUG_ON(condition)
+#define BUILD_BUG_ON_USED() (0)
#else /* __CHECKER__ */
/* Force a compilation error if a constant expression is not a power of 2 */
@@ -704,6 +705,21 @@ extern int __build_bug_on_failed;
if (condition) __build_bug_on_failed = 1; \
} while(0)
#endif
+
+/**
+ * BUILD_BUG_ON_USED - break compile if used.
+ *
+ * If you have some code that you expect the compiler to eliminate at
+ * build time, you should use BUILD_BUG_ON_USED to detect if it is
+ * unexpectedly used.
+ */
+#define BUILD_BUG_ON_USED() \
+ do { \
+ extern void __build_bug_on_used_failed(void) \
+ __linktime_error("BUILD_BUG_ON_USED failed"); \
+ __build_bug_on_used_failed(); \
+ } while (0)
+
#endif /* __CHECKER__ */
/* Trap pasters of __FUNCTION__ at compile-time */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions.
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
@ 2011-11-22 1:31 ` David Daney
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
2 siblings, 0 replies; 6+ messages in thread
From: David Daney @ 2011-11-22 1:31 UTC (permalink / raw)
To: ralf, Linus Torvalds, Andrew Morton, David Rientjes
Cc: linux-kernel, linux-arch, David Daney
From: David Daney <david.daney@cavium.com>
The file linux/hugetlb.h has many places where dummy symbols were
defined so that the main source code would contain fewer:
#ifdef CONFIG_HUGETLBFS
If there were any misuse of these symbols, the only symptom would be
an OOPS at runtime. Change the BUG() to BUILD_BUG_ON_USED() to catch
any such abuse at compile time instead.
Signed-off-by: David Daney <david.daney@cavium.com>
---
include/linux/hugetlb.h | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d9d6c86..0067191 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -85,11 +85,11 @@ static inline unsigned long hugetlb_total_pages(void)
return 0;
}
-#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; })
+#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUILD_BUG_ON_USED(); 0; })
#define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
-#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
-#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
-#define unmap_hugepage_range(vma, start, end, page) BUG()
+#define copy_hugetlb_page_range(src, dst, vma) ({ BUILD_BUG_ON_USED(); 0; })
+#define hugetlb_prefault(mapping, vma) ({ BUILD_BUG_ON_USED(); 0; })
+#define unmap_hugepage_range(vma, start, end, page) BUILD_BUG_ON_USED()
static inline void hugetlb_report_meminfo(struct seq_file *m)
{
}
@@ -100,8 +100,9 @@ static inline void hugetlb_report_meminfo(struct seq_file *m)
#define pmd_huge(x) 0
#define pud_huge(x) 0
#define is_hugepage_only_range(mm, addr, len) 0
-#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; })
-#define hugetlb_fault(mm, vma, addr, flags) ({ BUG(); 0; })
+#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
+ ({BUILD_BUG_ON_USED(); 0; })
+#define hugetlb_fault(mm, vma, addr, flags) ({ BUILD_BUG_ON_USED(); 0; })
#define huge_pte_offset(mm, address) 0
#define dequeue_hwpoisoned_huge_page(page) 0
static inline void copy_huge_page(struct page *dst, struct page *src)
@@ -186,7 +187,7 @@ static inline void set_file_hugepages(struct file *file)
#else /* !CONFIG_HUGETLBFS */
#define is_file_hugepages(file) 0
-#define set_file_hugepages(file) BUG()
+#define set_file_hugepages(file) BUILD_BUG_ON_USED()
static inline struct file *hugetlb_file_setup(const char *name, size_t size,
vm_flags_t acctflag, struct user_struct **user, int creat_flags)
{
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro.
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
@ 2011-11-22 4:35 ` Linus Torvalds
0 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2011-11-22 4:35 UTC (permalink / raw)
To: David Daney
Cc: ralf, Andrew Morton, David Rientjes, linux-kernel, linux-arch,
David Daney
On Mon, Nov 21, 2011 at 5:31 PM, David Daney <ddaney.cavm@gmail.com> wrote:
>
> The GCC function attribute error("message") was added in version 4.3,
> so we define a new macro __linktime_error(message) to expand to this
> for GCC-4.3 and later. This will give us an error diagnostic from the
> compiler on the line that fails. For other compilers
> __linktime_error(message) expands to nothing, and we have to be
> content with a link time error, but at least we will still get a build
> error.
Ok. This looks quite reasonable, and I suspect we could replace some
of the other cases that currently use link-time errors with this and
get slightly better error reporting. It also looks like we should use
this __attribute__((__error__())) approach for our current
BUILD_BUG_ON() thing, instead of playing with the whole "negative
array size" thing.
And it does seem like glibc already uses this thing heavily, so we can
even expect it to work.
That said, I'm still not comfy actually applying these patches during
the -rc series. But for the next merge window, no problem.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used.
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
2011-11-22 1:31 ` [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions David Daney
@ 2011-11-22 8:42 ` DM
2011-11-22 17:13 ` Linus Torvalds
2 siblings, 1 reply; 6+ messages in thread
From: DM @ 2011-11-22 8:42 UTC (permalink / raw)
To: David Daney
Cc: ralf, Linus Torvalds, Andrew Morton, David Rientjes, linux-kernel,
linux-arch, David Daney
On 2011-11-22 02:31, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
>
> After some, perhaps justified, reluctance to merge dummy symbol
> definitions containing BUG() into header files, I propose these patches
> instead.
>
> We define a new compile time assertion BUILD_BUG_ON_USED() that can be
> used in places were we expect the compiler's dead code elimination to
> get rid of code. This happens mostly in code dealing with huge pages,
> but in other places as well.
>
> The first patch adds BUILD_BUG_ON_USED(), the second gets rid of one
> of the main abusers of BUG().
>
Perhaps BUILD_BUG() is a more consistent name for this?
We would then have BUG() and BUG_ON(x) for run-time vs BUILD_BUG() and BUILD_BUG_ON(x) for compile-time.
/DM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used.
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
@ 2011-11-22 17:13 ` Linus Torvalds
0 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2011-11-22 17:13 UTC (permalink / raw)
To: DM
Cc: David Daney, ralf, Andrew Morton, David Rientjes, linux-kernel,
linux-arch, David Daney
On Tue, Nov 22, 2011 at 12:42 AM, DM <dm.n9107@gmail.com> wrote:
>
> Perhaps BUILD_BUG() is a more consistent name for this?
>
> We would then have BUG() and BUG_ON(x) for run-time vs BUILD_BUG() and BUILD_BUG_ON(x) for compile-time.
Yeah, that probably would be nicer naming. The "BUILD_BUG_ON_USED()"
is kind of about the implementation, not the intention of the thing.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-11-22 17:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
2011-11-22 4:35 ` Linus Torvalds
2011-11-22 1:31 ` [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions David Daney
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
2011-11-22 17:13 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox