| From haveblue@us.ibm.com Thu Mar 16 17:30:46 2006 |
| From: Dave Hansen <haveblue@us.ibm.com> |
| Subject: warn when statically-allocated kobjects are used |
| Cc: gregkh@suse.de, Dave Hansen <haveblue@us.ibm.com> |
| Date: Thu, 16 Mar 2006 17:30:16 -0800 |
| Message-Id: <20060317013016.5C643E69@localhost.localdomain> |
| |
| |
| One of the top ten sysfs problems is that users use statically |
| allocated kobjects. This patch reminds them that this is a |
| naughty thing. |
| |
| One _really_ nice thing this patch does, is us the kallsyms |
| mechanism to print out exactly which symbol is being complained |
| about: |
| |
| The kobject at, or inside devices_subsys+0x14/0x60 is not dynamically allocated. |
| |
| There are not very many architectures that actually place a |
| _sdata or _data symbol in their vmlinux.lds.S. This patch |
| causes link errors in all these cases. Is there an |
| alternative symbol that we can use, or can we use weak |
| symbols and detect them, so that they are at least skipped? |
| |
| Does kernel/kallsyms.c:is_kernel() do the trick, so that we |
| don't need to use the asm-generic/sections.h variables at all? |
| |
| |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| |
| --- |
| arch/i386/kernel/vmlinux.lds.S | 2 + |
| lib/kobject.c | 43 +++++++++++++++++++++++++++++++++++++++++ |
| 2 files changed, 45 insertions(+) |
| |
| --- a/arch/i386/kernel/vmlinux.lds.S |
| +++ b/arch/i386/kernel/vmlinux.lds.S |
| @@ -61,6 +61,8 @@ SECTIONS |
| __stop___ex_table = .; |
| } |
| |
| + _sdata = .; /* End of text section */ |
| + |
| RODATA |
| |
| BUG_TABLE |
| --- a/lib/kobject.c |
| +++ b/lib/kobject.c |
| @@ -15,6 +15,8 @@ |
| #include <linux/module.h> |
| #include <linux/stat.h> |
| #include <linux/slab.h> |
| +#include <linux/kallsyms.h> |
| +#include <asm-generic/sections.h> |
| |
| /** |
| * populate_dir - populate directory with attributes. |
| @@ -121,6 +123,46 @@ char *kobject_get_path(struct kobject *k |
| } |
| EXPORT_SYMBOL_GPL(kobject_get_path); |
| |
| +#ifdef CONFIG_X86_32 |
| +static int ptr_in_range(void *ptr, void *start, void *end) |
| +{ |
| + /* |
| + * This should hopefully get rid of causing warnings |
| + * if the architecture did not set one of the section |
| + * variables up. |
| + */ |
| + if (start >= end) |
| + return 0; |
| + |
| + if ((ptr >= start) && (ptr < end)) |
| + return 1; |
| + return 0; |
| +} |
| + |
| +static void verify_dynamic_kobject_allocation(struct kobject *kobj) |
| +{ |
| + if (ptr_in_range(kobj, &_sdata[0], &_edata[0])) |
| + goto warn; |
| + if (ptr_in_range(kobj, &__bss_start[0], &__bss_stop[0])) |
| + goto warn; |
| + return; |
| +warn: |
| + pr_debug("---- begin silly warning ----\n"); |
| + pr_debug("This is a janitorial warning, not a kernel bug.\n"); |
| +#ifdef CONFIG_DEBUG_KOBJECT |
| + print_symbol("The kobject at, or inside %s is not dynamically allocated.\n", |
| + (unsigned long)kobj); |
| +#endif |
| + pr_debug("kobjects must be dynamically allocated, not static\n"); |
| + /* dump_stack(); */ |
| + pr_debug("---- end silly warning ----\n"); |
| +} |
| +#else |
| +static void verify_dynamic_kobject_allocation(struct kobject *kobj) |
| +{ |
| +} |
| +#endif |
| + |
| /** |
| * kobject_init - initialize object. |
| * @kobj: object in question. |
| @@ -130,6 +172,7 @@ void kobject_init(struct kobject * kobj) |
| if (!kobj) |
| return; |
| WARN_ON(atomic_read(&kobj->kref.refcount)); |
| + verify_dynamic_kobject_allocation(kobj); |
| kref_init(&kobj->kref); |
| INIT_LIST_HEAD(&kobj->entry); |
| init_waitqueue_head(&kobj->poll); |