lkml.org 
[lkml]   [2017]   [May]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:timers/core] posix-timers: Make posix_clocks immutable
    Commit-ID:  d3ba5a9a345b1243276f8a982e1bce557c2504fd
    Gitweb: http://git.kernel.org/tip/d3ba5a9a345b1243276f8a982e1bce557c2504fd
    Author: Christoph Hellwig <hch@lst.de>
    AuthorDate: Fri, 26 May 2017 12:03:11 +0300
    Committer: Thomas Gleixner <tglx@linutronix.de>
    CommitDate: Sat, 27 May 2017 09:46:35 +0200

    posix-timers: Make posix_clocks immutable

    There are no more modular users providing a posix clock. The register
    function is now pointless so the posix clock array can be initialized
    statically at compile time and the array including the various k_clock
    structs can be marked 'const'.

    Inspired by changes in the Grsecurity patch set, but done proper.

    [ tglx: Massaged changelog and fixed the POSIX_TIMER=n case ]

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Cc: Mike Travis <mike.travis@hpe.com>
    Cc: Dimitri Sivanich <sivanich@hpe.com>
    Link: http://lkml.kernel.org/r/20170526090311.3377-3-hch@lst.de
    ---
    include/linux/posix-timers.h | 9 +-
    kernel/time/alarmtimer.c | 89 ++++++++++---------
    kernel/time/posix-clock.c | 2 +-
    kernel/time/posix-cpu-timers.c | 34 +++-----
    kernel/time/posix-timers.c | 191 +++++++++++++++++++----------------------
    5 files changed, 151 insertions(+), 174 deletions(-)

    diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
    index 8c1e43a..b313ef2 100644
    --- a/include/linux/posix-timers.h
    +++ b/include/linux/posix-timers.h
    @@ -105,10 +105,11 @@ struct k_clock {
    struct itimerspec64 *cur_setting);
    };

    -extern struct k_clock clock_posix_cpu;
    -extern struct k_clock clock_posix_dynamic;
    -
    -void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock);
    +extern const struct k_clock clock_posix_cpu;
    +extern const struct k_clock clock_posix_dynamic;
    +extern const struct k_clock clock_process;
    +extern const struct k_clock clock_thread;
    +extern const struct k_clock alarm_clock;

    /* function to call to trigger timer event */
    int posix_timer_event(struct k_itimer *timr, int si_private);
    diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
    index 5cb5b00..4f4cc35 100644
    --- a/kernel/time/alarmtimer.c
    +++ b/kernel/time/alarmtimer.c
    @@ -307,38 +307,6 @@ static int alarmtimer_resume(struct device *dev)
    }
    #endif

    -static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
    -{
    - struct alarm_base *base;
    - unsigned long flags;
    - ktime_t delta;
    -
    - switch(type) {
    - case ALARM_REALTIME:
    - base = &alarm_bases[ALARM_REALTIME];
    - type = ALARM_REALTIME_FREEZER;
    - break;
    - case ALARM_BOOTTIME:
    - base = &alarm_bases[ALARM_BOOTTIME];
    - type = ALARM_BOOTTIME_FREEZER;
    - break;
    - default:
    - WARN_ONCE(1, "Invalid alarm type: %d\n", type);
    - return;
    - }
    -
    - delta = ktime_sub(absexp, base->gettime());
    -
    - spin_lock_irqsave(&freezer_delta_lock, flags);
    - if (!freezer_delta || (delta < freezer_delta)) {
    - freezer_delta = delta;
    - freezer_expires = absexp;
    - freezer_alarmtype = type;
    - }
    - spin_unlock_irqrestore(&freezer_delta_lock, flags);
    -}
    -
    -
    /**
    * alarm_init - Initialize an alarm structure
    * @alarm: ptr to alarm to be initialized
    @@ -488,6 +456,38 @@ u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
    }
    EXPORT_SYMBOL_GPL(alarm_forward_now);

    +#ifdef CONFIG_POSIX_TIMERS
    +
    +static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
    +{
    + struct alarm_base *base;
    + unsigned long flags;
    + ktime_t delta;
    +
    + switch(type) {
    + case ALARM_REALTIME:
    + base = &alarm_bases[ALARM_REALTIME];
    + type = ALARM_REALTIME_FREEZER;
    + break;
    + case ALARM_BOOTTIME:
    + base = &alarm_bases[ALARM_BOOTTIME];
    + type = ALARM_BOOTTIME_FREEZER;
    + break;
    + default:
    + WARN_ONCE(1, "Invalid alarm type: %d\n", type);
    + return;
    + }
    +
    + delta = ktime_sub(absexp, base->gettime());
    +
    + spin_lock_irqsave(&freezer_delta_lock, flags);
    + if (!freezer_delta || (delta < freezer_delta)) {
    + freezer_delta = delta;
    + freezer_expires = absexp;
    + freezer_alarmtype = type;
    + }
    + spin_unlock_irqrestore(&freezer_delta_lock, flags);
    +}

    /**
    * clock2alarm - helper that converts from clockid to alarmtypes
    @@ -846,6 +846,17 @@ out:
    return ret;
    }

    +const struct k_clock alarm_clock = {
    + .clock_getres = alarm_clock_getres,
    + .clock_get = alarm_clock_get,
    + .timer_create = alarm_timer_create,
    + .timer_set = alarm_timer_set,
    + .timer_del = alarm_timer_del,
    + .timer_get = alarm_timer_get,
    + .nsleep = alarm_timer_nsleep,
    +};
    +#endif /* CONFIG_POSIX_TIMERS */
    +

    /* Suspend hook structures */
    static const struct dev_pm_ops alarmtimer_pm_ops = {
    @@ -871,23 +882,9 @@ static int __init alarmtimer_init(void)
    struct platform_device *pdev;
    int error = 0;
    int i;
    - struct k_clock alarm_clock = {
    - .clock_getres = alarm_clock_getres,
    - .clock_get = alarm_clock_get,
    - .timer_create = alarm_timer_create,
    - .timer_set = alarm_timer_set,
    - .timer_del = alarm_timer_del,
    - .timer_get = alarm_timer_get,
    - .nsleep = alarm_timer_nsleep,
    - };

    alarmtimer_rtc_timer_init();

    - if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
    - posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);
    - posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);
    - }
    -
    /* Initialize alarm bases */
    alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME;
    alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real;
    diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
    index 31d588d..7e45300 100644
    --- a/kernel/time/posix-clock.c
    +++ b/kernel/time/posix-clock.c
    @@ -434,7 +434,7 @@ static int pc_timer_settime(struct k_itimer *kit, int flags,
    return err;
    }

    -struct k_clock clock_posix_dynamic = {
    +const struct k_clock clock_posix_dynamic = {
    .clock_getres = pc_clock_getres,
    .clock_set = pc_clock_settime,
    .clock_get = pc_clock_gettime,
    diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
    index 1370f06..1a522b3 100644
    --- a/kernel/time/posix-cpu-timers.c
    +++ b/kernel/time/posix-cpu-timers.c
    @@ -1413,7 +1413,7 @@ static int thread_cpu_timer_create(struct k_itimer *timer)
    return posix_cpu_timer_create(timer);
    }

    -struct k_clock clock_posix_cpu = {
    +const struct k_clock clock_posix_cpu = {
    .clock_getres = posix_cpu_clock_getres,
    .clock_set = posix_cpu_clock_set,
    .clock_get = posix_cpu_clock_get,
    @@ -1425,24 +1425,16 @@ struct k_clock clock_posix_cpu = {
    .timer_get = posix_cpu_timer_get,
    };

    -static __init int init_posix_cpu_timers(void)
    -{
    - struct k_clock process = {
    - .clock_getres = process_cpu_clock_getres,
    - .clock_get = process_cpu_clock_get,
    - .timer_create = process_cpu_timer_create,
    - .nsleep = process_cpu_nsleep,
    - .nsleep_restart = process_cpu_nsleep_restart,
    - };
    - struct k_clock thread = {
    - .clock_getres = thread_cpu_clock_getres,
    - .clock_get = thread_cpu_clock_get,
    - .timer_create = thread_cpu_timer_create,
    - };
    -
    - posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
    - posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread);
    +const struct k_clock clock_process = {
    + .clock_getres = process_cpu_clock_getres,
    + .clock_get = process_cpu_clock_get,
    + .timer_create = process_cpu_timer_create,
    + .nsleep = process_cpu_nsleep,
    + .nsleep_restart = process_cpu_nsleep_restart,
    +};

    - return 0;
    -}
    -__initcall(init_posix_cpu_timers);
    +const struct k_clock clock_thread = {
    + .clock_getres = thread_cpu_clock_getres,
    + .clock_get = thread_cpu_clock_get,
    + .timer_create = thread_cpu_timer_create,
    +};
    diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
    index 4d7b2ce..0c0cccf 100644
    --- a/kernel/time/posix-timers.c
    +++ b/kernel/time/posix-timers.c
    @@ -125,8 +125,6 @@ static DEFINE_SPINLOCK(hash_lock);
    * which we beg off on and pass to do_sys_settimeofday().
    */

    -static struct k_clock posix_clocks[MAX_CLOCKS];
    -
    /*
    * These ones are defined below.
    */
    @@ -280,74 +278,87 @@ static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec64 *tp)
    return 0;
    }

    +
    +static const struct k_clock clock_realtime = {
    + .clock_getres = posix_get_hrtimer_res,
    + .clock_get = posix_clock_realtime_get,
    + .clock_set = posix_clock_realtime_set,
    + .clock_adj = posix_clock_realtime_adj,
    + .nsleep = common_nsleep,
    + .nsleep_restart = hrtimer_nanosleep_restart,
    + .timer_create = common_timer_create,
    + .timer_set = common_timer_set,
    + .timer_get = common_timer_get,
    + .timer_del = common_timer_del,
    +};
    +
    +static const struct k_clock clock_monotonic = {
    + .clock_getres = posix_get_hrtimer_res,
    + .clock_get = posix_ktime_get_ts,
    + .nsleep = common_nsleep,
    + .nsleep_restart = hrtimer_nanosleep_restart,
    + .timer_create = common_timer_create,
    + .timer_set = common_timer_set,
    + .timer_get = common_timer_get,
    + .timer_del = common_timer_del,
    +};
    +
    +static const struct k_clock clock_monotonic_raw = {
    + .clock_getres = posix_get_hrtimer_res,
    + .clock_get = posix_get_monotonic_raw,
    +};
    +
    +static const struct k_clock clock_realtime_coarse = {
    + .clock_getres = posix_get_coarse_res,
    + .clock_get = posix_get_realtime_coarse,
    +};
    +
    +static const struct k_clock clock_monotonic_coarse = {
    + .clock_getres = posix_get_coarse_res,
    + .clock_get = posix_get_monotonic_coarse,
    +};
    +
    +static const struct k_clock clock_tai = {
    + .clock_getres = posix_get_hrtimer_res,
    + .clock_get = posix_get_tai,
    + .nsleep = common_nsleep,
    + .nsleep_restart = hrtimer_nanosleep_restart,
    + .timer_create = common_timer_create,
    + .timer_set = common_timer_set,
    + .timer_get = common_timer_get,
    + .timer_del = common_timer_del,
    +};
    +
    +static const struct k_clock clock_boottime = {
    + .clock_getres = posix_get_hrtimer_res,
    + .clock_get = posix_get_boottime,
    + .nsleep = common_nsleep,
    + .nsleep_restart = hrtimer_nanosleep_restart,
    + .timer_create = common_timer_create,
    + .timer_set = common_timer_set,
    + .timer_get = common_timer_get,
    + .timer_del = common_timer_del,
    +};
    +
    +static const struct k_clock * const posix_clocks[] = {
    + [CLOCK_REALTIME] = &clock_realtime,
    + [CLOCK_MONOTONIC] = &clock_monotonic,
    + [CLOCK_PROCESS_CPUTIME_ID] = &clock_process,
    + [CLOCK_THREAD_CPUTIME_ID] = &clock_thread,
    + [CLOCK_MONOTONIC_RAW] = &clock_monotonic_raw,
    + [CLOCK_REALTIME_COARSE] = &clock_realtime_coarse,
    + [CLOCK_MONOTONIC_COARSE] = &clock_monotonic_coarse,
    + [CLOCK_BOOTTIME] = &clock_boottime,
    + [CLOCK_REALTIME_ALARM] = &alarm_clock,
    + [CLOCK_BOOTTIME_ALARM] = &alarm_clock,
    + [CLOCK_TAI] = &clock_tai,
    +};
    +
    /*
    * Initialize everything, well, just everything in Posix clocks/timers ;)
    */
    static __init int init_posix_timers(void)
    {
    - struct k_clock clock_realtime = {
    - .clock_getres = posix_get_hrtimer_res,
    - .clock_get = posix_clock_realtime_get,
    - .clock_set = posix_clock_realtime_set,
    - .clock_adj = posix_clock_realtime_adj,
    - .nsleep = common_nsleep,
    - .nsleep_restart = hrtimer_nanosleep_restart,
    - .timer_create = common_timer_create,
    - .timer_set = common_timer_set,
    - .timer_get = common_timer_get,
    - .timer_del = common_timer_del,
    - };
    - struct k_clock clock_monotonic = {
    - .clock_getres = posix_get_hrtimer_res,
    - .clock_get = posix_ktime_get_ts,
    - .nsleep = common_nsleep,
    - .nsleep_restart = hrtimer_nanosleep_restart,
    - .timer_create = common_timer_create,
    - .timer_set = common_timer_set,
    - .timer_get = common_timer_get,
    - .timer_del = common_timer_del,
    - };
    - struct k_clock clock_monotonic_raw = {
    - .clock_getres = posix_get_hrtimer_res,
    - .clock_get = posix_get_monotonic_raw,
    - };
    - struct k_clock clock_realtime_coarse = {
    - .clock_getres = posix_get_coarse_res,
    - .clock_get = posix_get_realtime_coarse,
    - };
    - struct k_clock clock_monotonic_coarse = {
    - .clock_getres = posix_get_coarse_res,
    - .clock_get = posix_get_monotonic_coarse,
    - };
    - struct k_clock clock_tai = {
    - .clock_getres = posix_get_hrtimer_res,
    - .clock_get = posix_get_tai,
    - .nsleep = common_nsleep,
    - .nsleep_restart = hrtimer_nanosleep_restart,
    - .timer_create = common_timer_create,
    - .timer_set = common_timer_set,
    - .timer_get = common_timer_get,
    - .timer_del = common_timer_del,
    - };
    - struct k_clock clock_boottime = {
    - .clock_getres = posix_get_hrtimer_res,
    - .clock_get = posix_get_boottime,
    - .nsleep = common_nsleep,
    - .nsleep_restart = hrtimer_nanosleep_restart,
    - .timer_create = common_timer_create,
    - .timer_set = common_timer_set,
    - .timer_get = common_timer_get,
    - .timer_del = common_timer_del,
    - };
    -
    - posix_timers_register_clock(CLOCK_REALTIME, &clock_realtime);
    - posix_timers_register_clock(CLOCK_MONOTONIC, &clock_monotonic);
    - posix_timers_register_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
    - posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
    - posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
    - posix_timers_register_clock(CLOCK_BOOTTIME, &clock_boottime);
    - posix_timers_register_clock(CLOCK_TAI, &clock_tai);
    -
    posix_timers_cache = kmem_cache_create("posix_timers_cache",
    sizeof (struct k_itimer), 0, SLAB_PANIC,
    NULL);
    @@ -521,30 +532,6 @@ static struct pid *good_sigevent(sigevent_t * event)
    return task_pid(rtn);
    }

    -void posix_timers_register_clock(const clockid_t clock_id,
    - struct k_clock *new_clock)
    -{
    - if ((unsigned) clock_id >= MAX_CLOCKS) {
    - printk(KERN_WARNING "POSIX clock register failed for clock_id %d\n",
    - clock_id);
    - return;
    - }
    -
    - if (!new_clock->clock_get) {
    - printk(KERN_WARNING "POSIX clock id %d lacks clock_get()\n",
    - clock_id);
    - return;
    - }
    - if (!new_clock->clock_getres) {
    - printk(KERN_WARNING "POSIX clock id %d lacks clock_getres()\n",
    - clock_id);
    - return;
    - }
    -
    - posix_clocks[clock_id] = *new_clock;
    -}
    -EXPORT_SYMBOL_GPL(posix_timers_register_clock);
    -
    static struct k_itimer * alloc_posix_timer(void)
    {
    struct k_itimer *tmr;
    @@ -581,15 +568,15 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
    call_rcu(&tmr->it.rcu, k_itimer_rcu_free);
    }

    -static struct k_clock *clockid_to_kclock(const clockid_t id)
    +static const struct k_clock *clockid_to_kclock(const clockid_t id)
    {
    if (id < 0)
    return (id & CLOCKFD_MASK) == CLOCKFD ?
    &clock_posix_dynamic : &clock_posix_cpu;

    - if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres)
    + if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
    return NULL;
    - return &posix_clocks[id];
    + return posix_clocks[id];
    }

    static int common_timer_create(struct k_itimer *new_timer)
    @@ -604,7 +591,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
    struct sigevent __user *, timer_event_spec,
    timer_t __user *, created_timer_id)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct k_itimer *new_timer;
    int error, new_timer_id;
    sigevent_t event;
    @@ -781,7 +768,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
    struct itimerspec64 cur_setting64;
    struct itimerspec cur_setting;
    struct k_itimer *timr;
    - struct k_clock *kc;
    + const struct k_clock *kc;
    unsigned long flags;
    int ret = 0;

    @@ -890,7 +877,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
    struct itimerspec new_spec, old_spec;
    struct k_itimer *timr;
    unsigned long flag;
    - struct k_clock *kc;
    + const struct k_clock *kc;
    int error = 0;

    if (!new_setting)
    @@ -939,7 +926,7 @@ static int common_timer_del(struct k_itimer *timer)

    static inline int timer_delete_hook(struct k_itimer *timer)
    {
    - struct k_clock *kc = clockid_to_kclock(timer->it_clock);
    + const struct k_clock *kc = clockid_to_kclock(timer->it_clock);

    if (WARN_ON_ONCE(!kc || !kc->timer_del))
    return -EINVAL;
    @@ -1018,7 +1005,7 @@ void exit_itimers(struct signal_struct *sig)
    SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
    const struct timespec __user *, tp)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct timespec64 new_tp64;
    struct timespec new_tp;

    @@ -1035,7 +1022,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
    SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
    struct timespec __user *,tp)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct timespec64 kernel_tp64;
    struct timespec kernel_tp;
    int error;
    @@ -1055,7 +1042,7 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
    SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
    struct timex __user *, utx)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct timex ktx;
    int err;

    @@ -1078,7 +1065,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
    SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
    struct timespec __user *, tp)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct timespec64 rtn_tp64;
    struct timespec rtn_tp;
    int error;
    @@ -1110,7 +1097,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
    const struct timespec __user *, rqtp,
    struct timespec __user *, rmtp)
    {
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);
    struct timespec64 t64;
    struct timespec t;

    @@ -1136,7 +1123,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
    long clock_nanosleep_restart(struct restart_block *restart_block)
    {
    clockid_t which_clock = restart_block->nanosleep.clockid;
    - struct k_clock *kc = clockid_to_kclock(which_clock);
    + const struct k_clock *kc = clockid_to_kclock(which_clock);

    if (WARN_ON_ONCE(!kc || !kc->nsleep_restart))
    return -EINVAL;
    \
     
     \ /
      Last update: 2017-05-27 09:53    [W:2.383 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site