Tick and interrupt handling

To provide the programming interface, the clock device generating the ticks is abstracted through the structure struct clock_event_device, defined in include/linux/clockchips.h:

struct clock_event_device {
        void                    (*event_handler)(struct clock_event_device *);
        int                     (*set_next_event)(unsigned long evt, struct clock_event_device *);
        int                     (*set_next_ktime)(ktime_t expires, struct clock_event_device *);
        ktime_t                  next_event;
        u64                      max_delta_ns;
        u64                      min_delta_ns;
        u32                      mult;
        u32                      shift;
        enum clock_event_state    state_use_accessors;
        unsigned int            features;
        unsigned long           retries;

        int                     (*set_state_periodic)(struct  clock_event_device *);
        int                     (*set_state_oneshot)(struct clock_event_device *);
        int                     (*set_state_oneshot_stopped)(struct clock_event_device *);
        int                     (*set_state_shutdown)(struct clock_event_device *);
        int                     (*tick_resume)(struct clock_event_device *);

        void                    (*broadcast)(const struct cpumask *mask);
        void                    (*suspend)(struct clock_event_device *);
        void                    (*resume)(struct clock_event_device *);
        unsigned long           min_delta_ticks;
        unsigned long           max_delta_ticks;

        const char               *name;
        int                     rating;
        int                     irq;
        int                     bound_on;
        const struct cpumask       *cpumask;
        struct list_head  list;
        struct module             *owner;
} ____cacheline_aligned;

Here, event_handler is the appropriate routine, assigned by the framework to be called by the low-level handler to run the tick. Depending on the configuration, this clock_event_device could be periodic, one-shot, or ktime based. Out of these three, the appropriate operating mode for the tick device is set through the unsigned int features field, using any of these macros:

#define CLOCK_EVT_FEAT_PERIODIC 0x000001
#define CLOCK_EVT_FEAT_ONESHOT 0x000002
#define CLOCK_EVT_FEAT_KTIME 0x000004

Periodic mode configures the hardware generate the tick once every 1/HZ seconds, while one-shot mode makes the hardware generate the tick after the passage of a specific number of cycles from the current time.

Depending on the use cases and the operating mode, event_handler could be any of these three routines:

  • tick_handle_periodic(), which is the default handler for periodic ticks and is defined in kernel/time/tick-common.c.
  • tick_nohz_handler() is the low-resolution interrupt handler, used in low res mode. It's defined in kernel/time/tick-sched.c.
  • hrtimer_interrupt() is used in high res mode and is defined in kernel/time/hrtimer.c. Interrupts are disabled when it's called.

A clock event device is configured and registered through the routine clockevents_config_and_register(), defined in kernel/time/clockevents.c.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.29.89