sched.h, timer.h and TASK_COMM_LEN -- circularity of definition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  just ran into an interesting circular header file issue.  first,
from <linux/timer.h>:

=====
struct timer_list {
        struct list_head entry;
        unsigned long expires;

        void (*function)(unsigned long);
        unsigned long data;

        struct tvec_base *base;
#ifdef CONFIG_TIMER_STATS
        void *start_site;
        char start_comm[16];           <--- note hard-coded "16"
        int start_pid;
#endif
=====

  now pop over to kernel/timer.c:

=====
void init_timer(struct timer_list *timer)
{
        timer->entry.next = NULL;
        timer->base = __raw_get_cpu_var(tvec_bases);
#ifdef CONFIG_TIMER_STATS
        timer->start_site = NULL;
        timer->start_pid = -1;
        memset(timer->start_comm, 0, TASK_COMM_LEN);
                                     ^^^^^^^^^^^^^ ???
#endif
}
=====

  it certainly seems that calling init_timer() will clear that array
of 16 bytes, but timer.c uses the flexible macro definition
TASK_COMM_LEN.  why doesn't timer.h?  so let's make that change to
timer.h and, to get the macro definition of TASK_COMM_LEN in timer.h,
we need to include <linux/sched.h> where it's defined:

/* Task command name length */
#define TASK_COMM_LEN 16

  then try to "make":
...
  CC      arch/x86/kernel/asm-offsets.s
In file included from include/linux/sched.h:341,
                 from include/linux/timer.h:7,
                 from include/linux/workqueue.h:8,
                 from include/linux/slub_def.h:11,
                 from include/linux/slab.h:118,
                 from include/linux/percpu.h:5,
                 from include/asm/local.h:4,
                 from include/linux/module.h:19,
                 from include/linux/crypto.h:21,
                 from arch/x86/kernel/asm-offsets_32.c:7,
                 from arch/x86/kernel/asm-offsets.c:2:
include/linux/aio.h:202: error: field ʽwqʼ has incomplete type
In file included from include/linux/timer.h:7,
                 from include/linux/workqueue.h:8,
                 from include/linux/slub_def.h:11,
                 from include/linux/slab.h:118,
                 from include/linux/percpu.h:5,
                 from include/asm/local.h:4,
                 from include/linux/module.h:19,
                 from include/linux/crypto.h:21,
                 from arch/x86/kernel/asm-offsets_32.c:7,
                 from arch/x86/kernel/asm-offsets.c:2:
include/linux/sched.h:598: error: field ʽworkʼ has incomplete type
make[1]: *** [arch/x86/kernel/asm-offsets.s] Error 1
make: *** [prepare0] Error 2
$

  the problem appears to be that timer.h includes sched.h, but sched.h
conversely includes timer.h.  so timer.h includes sched.h early
(before the definition of "struct timer_list" can be defined).
sched.h then tries to include timer.h, but can't since multiple
inclusion protection of timer.h prevents that.  at which point, later
on in sched.h, *something* badly needs the definition of struct
timer_list but doesn't have it.  whoops.

  thoughts?  it would seem that, for cleanliness, if timer.h and
timer.c really should match in that array length, then they *both*
should be using the more general "TASK_COMM_LEN".  but, under the
circumstances, that can't be done as long as that macro is defined in
sched.h.

  thoughts?

rday
--


========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
    Have classroom, will lecture.

http://crashcourse.ca                          Waterloo, Ontario, CANADA
========================================================================

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux