linux/kernel/time/clocksource.c
<<
>>
Prefs
   1/*
   2 * linux/kernel/time/clocksource.c
   3 *
   4 * This file contains the functions which manage clocksource drivers.
   5 *
   6 * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21 *
  22 * TODO WishList:
  23 *   o Allow clocksource drivers to be unregistered
  24 *   o get rid of clocksource_jiffies extern
  25 */
  26
  27#include <linux/clocksource.h>
  28#include <linux/sysdev.h>
  29#include <linux/init.h>
  30#include <linux/module.h>
  31#include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */
  32#include <linux/tick.h>
  33
  34/* XXX - Would like a better way for initializing curr_clocksource */
  35extern struct clocksource clocksource_jiffies;
  36
  37/*[Clocksource internal variables]---------
  38 * curr_clocksource:
  39 *      currently selected clocksource. Initialized to clocksource_jiffies.
  40 * next_clocksource:
  41 *      pending next selected clocksource.
  42 * clocksource_list:
  43 *      linked list with the registered clocksources
  44 * clocksource_lock:
  45 *      protects manipulations to curr_clocksource and next_clocksource
  46 *      and the clocksource_list
  47 * override_name:
  48 *      Name of the user-specified clocksource.
  49 */
  50static struct clocksource *curr_clocksource = &clocksource_jiffies;
  51static struct clocksource *next_clocksource;
  52static struct clocksource *clocksource_override;
  53static LIST_HEAD(clocksource_list);
  54static DEFINE_SPINLOCK(clocksource_lock);
  55static char override_name[32];
  56static int finished_booting;
  57
  58/* clocksource_done_booting - Called near the end of core bootup
  59 *
  60 * Hack to avoid lots of clocksource churn at boot time.
  61 * We use fs_initcall because we want this to start before
  62 * device_initcall but after subsys_initcall.
  63 */
  64static int __init clocksource_done_booting(void)
  65{
  66        finished_booting = 1;
  67        return 0;
  68}
  69fs_initcall(clocksource_done_booting);
  70
  71#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
  72static LIST_HEAD(watchdog_list);
  73static struct clocksource *watchdog;
  74static struct timer_list watchdog_timer;
  75static DEFINE_SPINLOCK(watchdog_lock);
  76static cycle_t watchdog_last;
  77static unsigned long watchdog_resumed;
  78
  79/*
  80 * Interval: 0.5sec Threshold: 0.0625s
  81 */
  82#define WATCHDOG_INTERVAL (HZ >> 1)
  83#define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
  84
  85static void clocksource_ratewd(struct clocksource *cs, int64_t delta)
  86{
  87        if (delta > -WATCHDOG_THRESHOLD && delta < WATCHDOG_THRESHOLD)
  88                return;
  89
  90        printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)\n",
  91               cs->name, delta);
  92        cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
  93        clocksource_change_rating(cs, 0);
  94        list_del(&cs->wd_list);
  95}
  96
  97static void clocksource_watchdog(unsigned long data)
  98{
  99        struct clocksource *cs, *tmp;
 100        cycle_t csnow, wdnow;
 101        int64_t wd_nsec, cs_nsec;
 102        int resumed;
 103
 104        spin_lock(&watchdog_lock);
 105
 106        resumed = test_and_clear_bit(0, &watchdog_resumed);
 107
 108        wdnow = watchdog->read();
 109        wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask);
 110        watchdog_last = wdnow;
 111
 112        list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
 113                csnow = cs->read();
 114
 115                if (unlikely(resumed)) {
 116                        cs->wd_last = csnow;
 117                        continue;
 118                }
 119
 120                /* Initialized ? */
 121                if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
 122                        if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
 123                            (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
 124                                cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 125                                /*
 126                                 * We just marked the clocksource as
 127                                 * highres-capable, notify the rest of the
 128                                 * system as well so that we transition
 129                                 * into high-res mode:
 130                                 */
 131                                tick_clock_notify();
 132                        }
 133                        cs->flags |= CLOCK_SOURCE_WATCHDOG;
 134                        cs->wd_last = csnow;
 135                } else {
 136                        cs_nsec = cyc2ns(cs, (csnow - cs->wd_last) & cs->mask);
 137                        cs->wd_last = csnow;
 138                        /* Check the delta. Might remove from the list ! */
 139                        clocksource_ratewd(cs, cs_nsec - wd_nsec);
 140                }
 141        }
 142
 143        if (!list_empty(&watchdog_list)) {
 144                /*
 145                 * Cycle through CPUs to check if the CPUs stay
 146                 * synchronized to each other.
 147                 */
 148                int next_cpu = next_cpu_nr(raw_smp_processor_id(), cpu_online_map);
 149
 150                if (next_cpu >= nr_cpu_ids)
 151                        next_cpu = first_cpu(cpu_online_map);
 152                watchdog_timer.expires += WATCHDOG_INTERVAL;
 153                add_timer_on(&watchdog_timer, next_cpu);
 154        }
 155        spin_unlock(&watchdog_lock);
 156}
 157static void clocksource_resume_watchdog(void)
 158{
 159        set_bit(0, &watchdog_resumed);
 160}
 161
 162static void clocksource_check_watchdog(struct clocksource *cs)
 163{
 164        struct clocksource *cse;
 165        unsigned long flags;
 166
 167        spin_lock_irqsave(&watchdog_lock, flags);
 168        if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
 169                int started = !list_empty(&watchdog_list);
 170
 171                list_add(&cs->wd_list, &watchdog_list);
 172                if (!started && watchdog) {
 173                        watchdog_last = watchdog->read();
 174                        watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
 175                        add_timer_on(&watchdog_timer,
 176                                     first_cpu(cpu_online_map));
 177                }
 178        } else {
 179                if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 180                        cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 181
 182                if (!watchdog || cs->rating > watchdog->rating) {
 183                        if (watchdog)
 184                                del_timer(&watchdog_timer);
 185                        watchdog = cs;
 186                        init_timer(&watchdog_timer);
 187                        watchdog_timer.function = clocksource_watchdog;
 188
 189                        /* Reset watchdog cycles */
 190                        list_for_each_entry(cse, &watchdog_list, wd_list)
 191                                cse->flags &= ~CLOCK_SOURCE_WATCHDOG;
 192                        /* Start if list is not empty */
 193                        if (!list_empty(&watchdog_list)) {
 194                                watchdog_last = watchdog->read();
 195                                watchdog_timer.expires =
 196                                        jiffies + WATCHDOG_INTERVAL;
 197                                add_timer_on(&watchdog_timer,
 198                                             first_cpu(cpu_online_map));
 199                        }
 200                }
 201        }
 202        spin_unlock_irqrestore(&watchdog_lock, flags);
 203}
 204#else
 205static void clocksource_check_watchdog(struct clocksource *cs)
 206{
 207        if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 208                cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 209}
 210
 211static inline void clocksource_resume_watchdog(void) { }
 212#endif
 213
 214/**
 215 * clocksource_resume - resume the clocksource(s)
 216 */
 217void clocksource_resume(void)
 218{
 219        struct clocksource *cs;
 220        unsigned long flags;
 221
 222        spin_lock_irqsave(&clocksource_lock, flags);
 223
 224        list_for_each_entry(cs, &clocksource_list, list) {
 225                if (cs->resume)
 226                        cs->resume();
 227        }
 228
 229        clocksource_resume_watchdog();
 230
 231        spin_unlock_irqrestore(&clocksource_lock, flags);
 232}
 233
 234/**
 235 * clocksource_touch_watchdog - Update watchdog
 236 *
 237 * Update the watchdog after exception contexts such as kgdb so as not
 238 * to incorrectly trip the watchdog.
 239 *
 240 */
 241void clocksource_touch_watchdog(void)
 242{
 243        clocksource_resume_watchdog();
 244}
 245
 246/**
 247 * clocksource_get_next - Returns the selected clocksource
 248 *
 249 */
 250struct clocksource *clocksource_get_next(void)
 251{
 252        unsigned long flags;
 253
 254        spin_lock_irqsave(&clocksource_lock, flags);
 255        if (next_clocksource && finished_booting) {
 256                curr_clocksource = next_clocksource;
 257                next_clocksource = NULL;
 258        }
 259        spin_unlock_irqrestore(&clocksource_lock, flags);
 260
 261        return curr_clocksource;
 262}
 263
 264/**
 265 * select_clocksource - Selects the best registered clocksource.
 266 *
 267 * Private function. Must hold clocksource_lock when called.
 268 *
 269 * Select the clocksource with the best rating, or the clocksource,
 270 * which is selected by userspace override.
 271 */
 272static struct clocksource *select_clocksource(void)
 273{
 274        struct clocksource *next;
 275
 276        if (list_empty(&clocksource_list))
 277                return NULL;
 278
 279        if (clocksource_override)
 280                next = clocksource_override;
 281        else
 282                next = list_entry(clocksource_list.next, struct clocksource,
 283                                  list);
 284
 285        if (next == curr_clocksource)
 286                return NULL;
 287
 288        return next;
 289}
 290
 291/*
 292 * Enqueue the clocksource sorted by rating
 293 */
 294static int clocksource_enqueue(struct clocksource *c)
 295{
 296        struct list_head *tmp, *entry = &clocksource_list;
 297
 298        list_for_each(tmp, &clocksource_list) {
 299                struct clocksource *cs;
 300
 301                cs = list_entry(tmp, struct clocksource, list);
 302                if (cs == c)
 303                        return -EBUSY;
 304                /* Keep track of the place, where to insert */
 305                if (cs->rating >= c->rating)
 306                        entry = tmp;
 307        }
 308        list_add(&c->list, entry);
 309
 310        if (strlen(c->name) == strlen(override_name) &&
 311            !strcmp(c->name, override_name))
 312                clocksource_override = c;
 313
 314        return 0;
 315}
 316
 317/**
 318 * clocksource_register - Used to install new clocksources
 319 * @t:          clocksource to be registered
 320 *
 321 * Returns -EBUSY if registration fails, zero otherwise.
 322 */
 323int clocksource_register(struct clocksource *c)
 324{
 325        unsigned long flags;
 326        int ret;
 327
 328        /* save mult_orig on registration */
 329        c->mult_orig = c->mult;
 330
 331        spin_lock_irqsave(&clocksource_lock, flags);
 332        ret = clocksource_enqueue(c);
 333        if (!ret)
 334                next_clocksource = select_clocksource();
 335        spin_unlock_irqrestore(&clocksource_lock, flags);
 336        if (!ret)
 337                clocksource_check_watchdog(c);
 338        return ret;
 339}
 340EXPORT_SYMBOL(clocksource_register);
 341
 342/**
 343 * clocksource_change_rating - Change the rating of a registered clocksource
 344 *
 345 */
 346void clocksource_change_rating(struct clocksource *cs, int rating)
 347{
 348        unsigned long flags;
 349
 350        spin_lock_irqsave(&clocksource_lock, flags);
 351        list_del(&cs->list);
 352        cs->rating = rating;
 353        clocksource_enqueue(cs);
 354        next_clocksource = select_clocksource();
 355        spin_unlock_irqrestore(&clocksource_lock, flags);
 356}
 357
 358/**
 359 * clocksource_unregister - remove a registered clocksource
 360 */
 361void clocksource_unregister(struct clocksource *cs)
 362{
 363        unsigned long flags;
 364
 365        spin_lock_irqsave(&clocksource_lock, flags);
 366        list_del(&cs->list);
 367        if (clocksource_override == cs)
 368                clocksource_override = NULL;
 369        next_clocksource = select_clocksource();
 370        spin_unlock_irqrestore(&clocksource_lock, flags);
 371}
 372
 373#ifdef CONFIG_SYSFS
 374/**
 375 * sysfs_show_current_clocksources - sysfs interface for current clocksource
 376 * @dev:        unused
 377 * @buf:        char buffer to be filled with clocksource list
 378 *
 379 * Provides sysfs interface for listing current clocksource.
 380 */
 381static ssize_t
 382sysfs_show_current_clocksources(struct sys_device *dev,
 383                                struct sysdev_attribute *attr, char *buf)
 384{
 385        ssize_t count = 0;
 386
 387        spin_lock_irq(&clocksource_lock);
 388        count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name);
 389        spin_unlock_irq(&clocksource_lock);
 390
 391        return count;
 392}
 393
 394/**
 395 * sysfs_override_clocksource - interface for manually overriding clocksource
 396 * @dev:        unused
 397 * @buf:        name of override clocksource
 398 * @count:      length of buffer
 399 *
 400 * Takes input from sysfs interface for manually overriding the default
 401 * clocksource selction.
 402 */
 403static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 404                                          struct sysdev_attribute *attr,
 405                                          const char *buf, size_t count)
 406{
 407        struct clocksource *ovr = NULL;
 408        size_t ret = count;
 409        int len;
 410
 411        /* strings from sysfs write are not 0 terminated! */
 412        if (count >= sizeof(override_name))
 413                return -EINVAL;
 414
 415        /* strip of \n: */
 416        if (buf[count-1] == '\n')
 417                count--;
 418
 419        spin_lock_irq(&clocksource_lock);
 420
 421        if (count > 0)
 422                memcpy(override_name, buf, count);
 423        override_name[count] = 0;
 424
 425        len = strlen(override_name);
 426        if (len) {
 427                struct clocksource *cs;
 428
 429                ovr = clocksource_override;
 430                /* try to select it: */
 431                list_for_each_entry(cs, &clocksource_list, list) {
 432                        if (strlen(cs->name) == len &&
 433                            !strcmp(cs->name, override_name))
 434                                ovr = cs;
 435                }
 436        }
 437
 438        /* Reselect, when the override name has changed */
 439        if (ovr != clocksource_override) {
 440                clocksource_override = ovr;
 441                next_clocksource = select_clocksource();
 442        }
 443
 444        spin_unlock_irq(&clocksource_lock);
 445
 446        return ret;
 447}
 448
 449/**
 450 * sysfs_show_available_clocksources - sysfs interface for listing clocksource
 451 * @dev:        unused
 452 * @buf:        char buffer to be filled with clocksource list
 453 *
 454 * Provides sysfs interface for listing registered clocksources
 455 */
 456static ssize_t
 457sysfs_show_available_clocksources(struct sys_device *dev,
 458                                  struct sysdev_attribute *attr,
 459                                  char *buf)
 460{
 461        struct clocksource *src;
 462        ssize_t count = 0;
 463
 464        spin_lock_irq(&clocksource_lock);
 465        list_for_each_entry(src, &clocksource_list, list) {
 466                count += snprintf(buf + count,
 467                                  max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
 468                                  "%s ", src->name);
 469        }
 470        spin_unlock_irq(&clocksource_lock);
 471
 472        count += snprintf(buf + count,
 473                          max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
 474
 475        return count;
 476}
 477
 478/*
 479 * Sysfs setup bits:
 480 */
 481static SYSDEV_ATTR(current_clocksource, 0644, sysfs_show_current_clocksources,
 482                   sysfs_override_clocksource);
 483
 484static SYSDEV_ATTR(available_clocksource, 0444,
 485                   sysfs_show_available_clocksources, NULL);
 486
 487static struct sysdev_class clocksource_sysclass = {
 488        .name = "clocksource",
 489};
 490
 491static struct sys_device device_clocksource = {
 492        .id     = 0,
 493        .cls    = &clocksource_sysclass,
 494};
 495
 496static int __init init_clocksource_sysfs(void)
 497{
 498        int error = sysdev_class_register(&clocksource_sysclass);
 499
 500        if (!error)
 501                error = sysdev_register(&device_clocksource);
 502        if (!error)
 503                error = sysdev_create_file(
 504                                &device_clocksource,
 505                                &attr_current_clocksource);
 506        if (!error)
 507                error = sysdev_create_file(
 508                                &device_clocksource,
 509                                &attr_available_clocksource);
 510        return error;
 511}
 512
 513device_initcall(init_clocksource_sysfs);
 514#endif /* CONFIG_SYSFS */
 515
 516/**
 517 * boot_override_clocksource - boot clock override
 518 * @str:        override name
 519 *
 520 * Takes a clocksource= boot argument and uses it
 521 * as the clocksource override name.
 522 */
 523static int __init boot_override_clocksource(char* str)
 524{
 525        unsigned long flags;
 526        spin_lock_irqsave(&clocksource_lock, flags);
 527        if (str)
 528                strlcpy(override_name, str, sizeof(override_name));
 529        spin_unlock_irqrestore(&clocksource_lock, flags);
 530        return 1;
 531}
 532
 533__setup("clocksource=", boot_override_clocksource);
 534
 535/**
 536 * boot_override_clock - Compatibility layer for deprecated boot option
 537 * @str:        override name
 538 *
 539 * DEPRECATED! Takes a clock= boot argument and uses it
 540 * as the clocksource override name
 541 */
 542static int __init boot_override_clock(char* str)
 543{
 544        if (!strcmp(str, "pmtmr")) {
 545                printk("Warning: clock=pmtmr is deprecated. "
 546                        "Use clocksource=acpi_pm.\n");
 547                return boot_override_clocksource("acpi_pm");
 548        }
 549        printk("Warning! clock= boot option is deprecated. "
 550                "Use clocksource=xyz\n");
 551        return boot_override_clocksource(str);
 552}
 553
 554__setup("clock=", boot_override_clock);
 555