~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/time/tick-oneshot.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * This file contains functions which manage high resolution tick
  4  * related events.
  5  *
  6  * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
  7  * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
  8  * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
  9  */
 10 #include <linux/cpu.h>
 11 #include <linux/err.h>
 12 #include <linux/hrtimer.h>
 13 #include <linux/interrupt.h>
 14 #include <linux/percpu.h>
 15 #include <linux/profile.h>
 16 #include <linux/sched.h>
 17 
 18 #include "tick-internal.h"
 19 
 20 /**
 21  * tick_program_event - program the CPU local timer device for the next event
 22  */
 23 int tick_program_event(ktime_t expires, int force)
 24 {
 25         struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
 26 
 27         if (unlikely(expires == KTIME_MAX)) {
 28                 /*
 29                  * We don't need the clock event device any more, stop it.
 30                  */
 31                 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED);
 32                 dev->next_event = KTIME_MAX;
 33                 return 0;
 34         }
 35 
 36         if (unlikely(clockevent_state_oneshot_stopped(dev))) {
 37                 /*
 38                  * We need the clock event again, configure it in ONESHOT mode
 39                  * before using it.
 40                  */
 41                 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
 42         }
 43 
 44         return clockevents_program_event(dev, expires, force);
 45 }
 46 
 47 /**
 48  * tick_resume_oneshot - resume oneshot mode
 49  */
 50 void tick_resume_oneshot(void)
 51 {
 52         struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
 53 
 54         clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
 55         clockevents_program_event(dev, ktime_get(), true);
 56 }
 57 
 58 /**
 59  * tick_setup_oneshot - setup the event device for oneshot mode (hres or nohz)
 60  */
 61 void tick_setup_oneshot(struct clock_event_device *newdev,
 62                         void (*handler)(struct clock_event_device *),
 63                         ktime_t next_event)
 64 {
 65         newdev->event_handler = handler;
 66         clockevents_switch_state(newdev, CLOCK_EVT_STATE_ONESHOT);
 67         clockevents_program_event(newdev, next_event, true);
 68 }
 69 
 70 /**
 71  * tick_switch_to_oneshot - switch to oneshot mode
 72  */
 73 int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
 74 {
 75         struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
 76         struct clock_event_device *dev = td->evtdev;
 77 
 78         if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) ||
 79                     !tick_device_is_functional(dev)) {
 80 
 81                 pr_info("Clockevents: could not switch to one-shot mode:");
 82                 if (!dev) {
 83                         pr_cont(" no tick device\n");
 84                 } else {
 85                         if (!tick_device_is_functional(dev))
 86                                 pr_cont(" %s is not functional.\n", dev->name);
 87                         else
 88                                 pr_cont(" %s does not support one-shot mode.\n",
 89                                         dev->name);
 90                 }
 91                 return -EINVAL;
 92         }
 93 
 94         td->mode = TICKDEV_MODE_ONESHOT;
 95         dev->event_handler = handler;
 96         clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
 97         tick_broadcast_switch_to_oneshot();
 98         return 0;
 99 }
100 
101 /**
102  * tick_oneshot_mode_active - check whether the system is in oneshot mode
103  *
104  * returns 1 when either nohz or highres are enabled. otherwise 0.
105  */
106 int tick_oneshot_mode_active(void)
107 {
108         unsigned long flags;
109         int ret;
110 
111         local_irq_save(flags);
112         ret = __this_cpu_read(tick_cpu_device.mode) == TICKDEV_MODE_ONESHOT;
113         local_irq_restore(flags);
114 
115         return ret;
116 }
117 
118 #ifdef CONFIG_HIGH_RES_TIMERS
119 /**
120  * tick_init_highres - switch to high resolution mode
121  *
122  * Called with interrupts disabled.
123  */
124 int tick_init_highres(void)
125 {
126         return tick_switch_to_oneshot(hrtimer_interrupt);
127 }
128 #endif
129 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php