linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used.
@ 2011-11-22 18:14 David Daney
  2011-11-22 18:14 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Daney
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: David Daney @ 2011-11-22 18:14 UTC (permalink / raw)
  To: ralf, Linus Torvalds, Andrew Morton, David Rientjes, DM
  Cc: linux-kernel, linux-arch, David Daney

From: David Daney <david.daney@cavium.com>

New for v2:

As suggested by 'DM', call the macro BUILD_BUG() instead of
BUILD_BUG_ON_USED().  Linus seemed satisfied with this, so if it still
looks good, can we put it in some linux-next tree (Perhaps Andrew
Morton's) to cook for a while?

The second patch now covers linux/huge_mm.h too.

>From v1:

   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() macro.
  hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions.

 include/linux/compiler-gcc4.h |    1 +
 include/linux/compiler.h      |    4 +++-
 include/linux/huge_mm.h       |    8 ++++----
 include/linux/hugetlb.h       |   14 +++++++-------
 include/linux/kernel.h        |   16 ++++++++++++++++
 5 files changed, 31 insertions(+), 12 deletions(-)

-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro.
  2011-11-22 18:14 [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
@ 2011-11-22 18:14 ` David Daney
  2011-11-23  1:34   ` David Rientjes
  2011-11-22 18:14 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Daney
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: David Daney @ 2011-11-22 18:14 UTC (permalink / raw)
  To: ralf, Linus Torvalds, Andrew Morton, David Rientjes, DM
  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() expands to the undefined function __build_bug_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..e30002f 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() (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 - 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()						\
+	do {							\
+		extern void __build_bug_failed(void)		\
+			__linktime_error("BUILD_BUG failed");	\
+		__build_bug_failed();				\
+	} while (0)
+
 #endif	/* __CHECKER__ */
 
 /* Trap pasters of __FUNCTION__ at compile-time */
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions.
  2011-11-22 18:14 [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
  2011-11-22 18:14 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Daney
@ 2011-11-22 18:14 ` David Daney
  2011-11-23  1:35   ` David Rientjes
  2011-11-23 11:11 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Howells
  2011-11-23 11:11 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Howells
  3 siblings, 1 reply; 7+ messages in thread
From: David Daney @ 2011-11-22 18:14 UTC (permalink / raw)
  To: ralf, Linus Torvalds, Andrew Morton, David Rientjes, DM
  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

or

    #ifdef CONFIG_TRANSPARENT_HUGEPAGE

If there were any misuse of these symbols, the only symptom would be
an OOPS at runtime.  Change the BUG() to BUILD_BUG() to catch
any such abuse at compile time instead.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 include/linux/huge_mm.h |    8 ++++----
 include/linux/hugetlb.h |   14 +++++++-------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index a9ace9c..33e47d8 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -145,10 +145,10 @@ static inline struct page *compound_trans_head(struct page *page)
 	}
 	return page;
 }
-#else /* CONFIG_TRANSPARENT_HUGEPAGE */
-#define HPAGE_PMD_SHIFT ({ BUG(); 0; })
-#define HPAGE_PMD_MASK ({ BUG(); 0; })
-#define HPAGE_PMD_SIZE ({ BUG(); 0; })
+#else /* !CONFIG_TRANSPARENT_HUGEPAGE */
+#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
+#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
+#define HPAGE_PMD_SIZE ({ BUILD_BUG(); 0; })
 
 #define hpage_nr_pages(x) 1
 
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d9d6c86..1289937 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(); 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(); 0; })
+#define hugetlb_prefault(mapping, vma)		({ BUILD_BUG(); 0; })
+#define unmap_hugepage_range(vma, start, end, page)	BUILD_BUG()
 static inline void hugetlb_report_meminfo(struct seq_file *m)
 {
 }
@@ -100,8 +100,8 @@ 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, f, c) ({BUILD_BUG(); 0; })
+#define hugetlb_fault(mm, vma, addr, flags)	({ BUILD_BUG(); 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 +186,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()
 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] 7+ messages in thread

* Re: [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro.
  2011-11-22 18:14 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Daney
@ 2011-11-23  1:34   ` David Rientjes
  0 siblings, 0 replies; 7+ messages in thread
From: David Rientjes @ 2011-11-23  1:34 UTC (permalink / raw)
  To: David Daney
  Cc: ralf, Linus Torvalds, Andrew Morton, DM, linux-kernel,
	linux-arch, David Daney

On Tue, 22 Nov 2011, David Daney wrote:

> 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() expands to the undefined function __build_bug_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>

Acked-by: David Rientjes <rientjes@google.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions.
  2011-11-22 18:14 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Daney
@ 2011-11-23  1:35   ` David Rientjes
  0 siblings, 0 replies; 7+ messages in thread
From: David Rientjes @ 2011-11-23  1:35 UTC (permalink / raw)
  To: David Daney
  Cc: ralf, Linus Torvalds, Andrew Morton, DM, linux-kernel,
	linux-arch, David Daney

On Tue, 22 Nov 2011, David Daney wrote:

> 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
> 
> or
> 
>     #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> 
> If there were any misuse of these symbols, the only symptom would be
> an OOPS at runtime.  Change the BUG() to BUILD_BUG() to catch
> any such abuse at compile time instead.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Acked-by: David Rientjes <rientjes@google.com>

> @@ -186,7 +186,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()
>  static inline struct file *hugetlb_file_setup(const char *name, size_t size,
>  		vm_flags_t acctflag, struct user_struct **user, int creat_flags)
>  {

Looks like this symbol can just be removed entirely, it's not referenced 
anywhere.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro.
  2011-11-22 18:14 [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
  2011-11-22 18:14 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Daney
  2011-11-22 18:14 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Daney
@ 2011-11-23 11:11 ` David Howells
  2011-11-23 11:11 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Howells
  3 siblings, 0 replies; 7+ messages in thread
From: David Howells @ 2011-11-23 11:11 UTC (permalink / raw)
  To: David Daney
  Cc: dhowells, ralf, Linus Torvalds, Andrew Morton, David Rientjes,
	DM, linux-kernel, linux-arch, David Daney

David Daney <ddaney.cavm@gmail.com> wrote:

> 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() expands to the undefined function __build_bug_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>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions.
  2011-11-22 18:14 [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
                   ` (2 preceding siblings ...)
  2011-11-23 11:11 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Howells
@ 2011-11-23 11:11 ` David Howells
  3 siblings, 0 replies; 7+ messages in thread
From: David Howells @ 2011-11-23 11:11 UTC (permalink / raw)
  To: David Daney
  Cc: dhowells, ralf, Linus Torvalds, Andrew Morton, David Rientjes,
	DM, linux-kernel, linux-arch, David Daney

David Daney <ddaney.cavm@gmail.com> wrote:

> 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
> 
> or
> 
>     #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> 
> If there were any misuse of these symbols, the only symptom would be
> an OOPS at runtime.  Change the BUG() to BUILD_BUG() to catch
> any such abuse at compile time instead.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-11-23 11:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-22 18:14 [PATCH v2 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
2011-11-22 18:14 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Daney
2011-11-23  1:34   ` David Rientjes
2011-11-22 18:14 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Daney
2011-11-23  1:35   ` David Rientjes
2011-11-23 11:11 ` [PATCH v2 1/2] kernel.h: Add BUILD_BUG() macro David Howells
2011-11-23 11:11 ` [PATCH v2 2/2] hugetlb: Replace BUG() with BUILD_BUG() for dummy definitions David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).