Re: WARNING: modpost: vmlinux.o(.text.unlikely+0x2c44): Section mismatch in reference from the function trace_define_generic_fields() to the variable .init.data:initcall_level_names
From: Steven Rostedt
Date: Mon Jan 10 2022 - 18:51:05 EST
On Tue, 21 Dec 2021 01:12:12 +0800
kernel test robot <lkp@xxxxxxxxx> wrote:
> All warnings (new ones prefixed by >>, old ones prefixed by <<):
>
> >> WARNING: modpost: vmlinux.o(.text.unlikely+0x2c44): Section mismatch in reference from the function trace_define_generic_fields() to the variable .init.data:initcall_level_names
> The function trace_define_generic_fields() references
> the variable __initdata initcall_level_names.
> This is often because trace_define_generic_fields lacks a __initdata
> annotation or the annotation of initcall_level_names is wrong.
I keep getting this, and it looks like a bug in the compiler not the kernel
code.
We have:
int filter_assign_type(const char *type)
{
if (strstr(type, "__data_loc") && strstr(type, "char"))
return FILTER_DYN_STRING;
if (strstr(type, "__rel_loc") && strstr(type, "char"))
return FILTER_RDYN_STRING;
if (strchr(type, '[') && strstr(type, "char"))
return FILTER_STATIC_STRING;
if (strcmp(type, "char *") == 0 || strcmp(type, "const char *") == 0)
return FILTER_PTR_STRING;
return FILTER_OTHER;
}
static int __trace_define_field(struct list_head *head, const char *type,
const char *name, int offset, int size,
int is_signed, int filter_type)
{
struct ftrace_event_field *field;
field = kmem_cache_alloc(field_cachep, GFP_TRACE);
if (!field)
return -ENOMEM;
field->name = name;
field->type = type;
if (filter_type == FILTER_OTHER)
field->filter_type = filter_assign_type(type);
else
field->filter_type = filter_type;
field->offset = offset;
field->size = size;
field->is_signed = is_signed;
list_add(&field->link, head);
return 0;
}
#define is_signed_type(type) (((type)(-1)) < (type)1)
static LIST_HEAD(ftrace_generic_fields);
#define __generic_field(type, item, filter_type) \
ret = __trace_define_field(&ftrace_generic_fields, #type, \
#item, 0, 0, is_signed_type(type), \
filter_type); \
if (ret) \
return ret;
static int trace_define_generic_fields(void)
{
int ret;
__generic_field(int, CPU, FILTER_CPU);
__generic_field(int, cpu, FILTER_CPU);
__generic_field(char *, COMM, FILTER_COMM);
__generic_field(char *, comm, FILTER_COMM);
return ret;
}
Please tell me where initcall_level_names is being referenced?
Either fix the compiler or tell me exactly what the bug is. Otherwise, stop
sending me this.
-- Steve