<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Clock sources, Clock events, sched_clock() and delay timers — The Linux Kernel documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=3918102e" />
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Delay and sleep mechanisms" href="delay_sleep_functions.html" />
<link rel="prev" title="NO_HZ: Reducing Scheduling-Clock Ticks" href="no_hz.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.svg" alt="Logo of The Linux Kernel"/>
</a></p>
<h1 class="logo"><a href="../index.html">The Linux Kernel</a></h1>
<p class="blurb">6.18.50</p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>
<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="../subsystem-apis.html#core-subsystems">Core subsystems</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../core-api/index.html">Core API Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../driver-api/index.html">Driver implementer’s API guide</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mm/index.html">Memory Management Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../power/index.html">Power Management</a></li>
<li class="toctree-l3"><a class="reference internal" href="../scheduler/index.html">Scheduler</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="index.html">Timers</a></li>
<li class="toctree-l3"><a class="reference internal" href="../locking/index.html">Locking</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#human-interfaces">Human interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#networking-interfaces">Networking interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#other-subsystems">Other subsystems</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../translations/index.html">Translations</a></li>
</ul>
</div>
<script type="text/javascript"> <!--
var sbar = document.getElementsByClassName("sphinxsidebar")[0];
let currents = document.getElementsByClassName("current")
if (currents.length) {
sbar.scrollTop = currents[currents.length - 1].offsetTop;
}
--> </script>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/timers/timekeeping.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
</div>
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="clock-sources-clock-events-sched-clock-and-delay-timers">
<h1>Clock sources, Clock events, sched_clock() and delay timers<a class="headerlink" href="#clock-sources-clock-events-sched-clock-and-delay-timers" title="Link to this heading">¶</a></h1>
<p>This document tries to briefly explain some basic kernel timekeeping
abstractions. It partly pertains to the drivers usually found in
drivers/clocksource in the kernel tree, but the code may be spread out
across the kernel.</p>
<p>If you grep through the kernel source you will find a number of architecture-
specific implementations of clock sources, clockevents and several likewise
architecture-specific overrides of the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> function and some
delay timers.</p>
<p>To provide timekeeping for your platform, the clock source provides
the basic timeline, whereas clock events shoot interrupts on certain points
on this timeline, providing facilities such as high-resolution timers.
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> is used for scheduling and timestamping, and delay timers
provide an accurate delay source using hardware counters.</p>
<section id="clock-sources">
<h2>Clock sources<a class="headerlink" href="#clock-sources" title="Link to this heading">¶</a></h2>
<p>The purpose of the clock source is to provide a timeline for the system that
tells you where you are in time. For example issuing the command ‘date’ on
a Linux system will eventually read the clock source to determine exactly
what time it is.</p>
<p>Typically the clock source is a monotonic, atomic counter which will provide
n bits which count from 0 to (2^n)-1 and then wraps around to 0 and start over.
It will ideally NEVER stop ticking as long as the system is running. It
may stop during system suspend.</p>
<p>The clock source shall have as high resolution as possible, and the frequency
shall be as stable and correct as possible as compared to a real-world wall
clock. It should not move unpredictably back and forth in time or miss a few
cycles here and there.</p>
<p>It must be immune to the kind of effects that occur in hardware where e.g.
the counter register is read in two phases on the bus lowest 16 bits first
and the higher 16 bits in a second bus cycle with the counter bits
potentially being updated in between leading to the risk of very strange
values from the counter.</p>
<p>When the wall-clock accuracy of the clock source isn’t satisfactory, there
are various quirks and layers in the timekeeping code for e.g. synchronizing
the user-visible time to RTC clocks in the system or against networked time
servers using NTP, but all they do basically is update an offset against
the clock source, which provides the fundamental timeline for the system.
These measures does not affect the clock source per se, they only adapt the
system to the shortcomings of it.</p>
<p>The clock source <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">shall</span></code> provide means to translate the provided counter
into a nanosecond value as an unsigned long long (unsigned 64 bit) number.
Since this operation may be invoked very often, doing this in a strict
mathematical sense is not desirable: instead the number is taken as close as
possible to a nanosecond value using only the arithmetic operations
multiply and shift, so in <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_cyc2ns()</span></code> you find:</p>
<blockquote>
<div><p>ns ~= (clocksource * mult) >> shift</p>
</div></blockquote>
<p>You will find a number of helper functions in the clock source code intended
to aid in providing these mult and shift values, such as
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_khz2mult()</span></code>, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_hz2mult()</span></code> that help determine the
mult factor from a fixed shift, and <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_register_hz()</span></code> and
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_register_khz()</span></code> which will help out assigning both shift and mult
factors using the frequency of the clock source as the only input.</p>
<p>For real simple clock sources accessed from a single I/O memory location
there is nowadays even <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">clocksource_mmio_init()</span></code> which will take a memory
location, bit width, a parameter telling whether the counter in the
register counts up or down, and the timer clock rate, and then conjure all
necessary parameters.</p>
<p>Since a 32-bit counter at say 100 MHz will wrap around to zero after some 43
seconds, the code handling the clock source will have to compensate for this.
That is the reason why the clock source <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">also</span></code> contains a ‘mask’
member telling how many bits of the source are valid. This way the timekeeping
code knows when the counter will wrap around and can insert the necessary
compensation code on both sides of the wrap point so that the system timeline
remains monotonic.</p>
</section>
<section id="clock-events">
<h2>Clock events<a class="headerlink" href="#clock-events" title="Link to this heading">¶</a></h2>
<p>Clock events are the conceptual reverse of clock sources: they take a
desired time specification value and calculate the values to poke into
hardware timer registers.</p>
<p>Clock events are orthogonal to clock sources. The same hardware
and register range may be used for the clock event, but it is essentially
a different thing. The hardware driving clock events has to be able to
fire interrupts, so as to trigger events on the system timeline. On an SMP
system, it is ideal (and customary) to have one such event driving timer per
CPU core, so that each core can trigger events independently of any other
core.</p>
<p>You will notice that the clock event device code is based on the same basic
idea about translating counters to nanoseconds using mult and shift
arithmetic, and you find the same family of helper functions again for
assigning these values. The clock event driver does not need a ‘mask’
attribute however: the system will not try to plan events beyond the time
horizon of the clock event.</p>
</section>
<section id="sched-clock">
<h2>sched_clock()<a class="headerlink" href="#sched-clock" title="Link to this heading">¶</a></h2>
<p>In addition to the clock sources and clock events there is a special weak
function in the kernel called <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code>. This function shall return the
number of nanoseconds since the system was started. An architecture may or
may not provide an implementation of <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> on its own. If a local
implementation is not provided, the system jiffy counter will be used as
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code>.</p>
<p>As the name suggests, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> is used for scheduling the system,
determining the absolute timeslice for a certain process in the CFS scheduler
for example. It is also used for printk timestamps when you have selected to
include time information in printk for things like bootcharts.</p>
<p>Compared to clock sources, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> has to be very fast: it is called
much more often, especially by the scheduler. If you have to do trade-offs
between accuracy compared to the clock source, you may sacrifice accuracy
for speed in <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code>. It however requires some of the same basic
characteristics as the clock source, i.e. it should be monotonic.</p>
<p>The <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> function may wrap only on unsigned long long boundaries,
i.e. after 64 bits. Since this is a nanosecond value this will mean it wraps
after circa 585 years. (For most practical systems this means “never”.)</p>
<p>If an architecture does not provide its own implementation of this function,
it will fall back to using jiffies, making its maximum resolution 1/HZ of the
jiffy frequency for the architecture. This will affect scheduling accuracy
and will likely show up in system benchmarks.</p>
<p>The clock driving <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> may stop or reset to zero during system
suspend/sleep. This does not matter to the function it serves of scheduling
events on the system. However it may result in interesting timestamps in
<a class="reference internal" href="../core-api/printk-basics.html#c.printk" title="printk"><code class="xref c c-func docutils literal notranslate"><span class="pre">printk()</span></code></a>.</p>
<p>The <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> function should be callable in any context, IRQ- and
NMI-safe and return a sane value in any context.</p>
<p>Some architectures may have a limited set of time sources and lack a nice
counter to derive a 64-bit nanosecond value, so for example on the ARM
architecture, special helper functions have been created to provide a
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> nanosecond base from a 16- or 32-bit counter. Sometimes the
same counter that is also used as clock source is used for this purpose.</p>
<p>On SMP systems, it is crucial for performance that <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> can be called
independently on each CPU without any synchronization performance hits.
Some hardware (such as the x86 TSC) will cause the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> function to
drift between the CPUs on the system. The kernel can work around this by
enabling the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option. This is another aspect
that makes <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sched_clock()</span></code> different from the ordinary clock source.</p>
</section>
<section id="delay-timers-some-architectures-only">
<h2>Delay timers (some architectures only)<a class="headerlink" href="#delay-timers-some-architectures-only" title="Link to this heading">¶</a></h2>
<p>On systems with variable CPU frequency, the various kernel <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">delay()</span></code> functions
will sometimes behave strangely. Basically these delays usually use a hard
loop to delay a certain number of jiffy fractions using a “lpj” (loops per
jiffy) value, calibrated on boot.</p>
<p>Let’s hope that your system is running on maximum frequency when this value
is calibrated: as an effect when the frequency is geared down to half the
full frequency, any <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">delay()</span></code> will be twice as long. Usually this does not
hurt, as you’re commonly requesting that amount of delay <em>or more</em>. But
basically the semantics are quite unpredictable on such systems.</p>
<p>Enter timer-based delays. Using these, a timer read may be used instead of
a hard-coded loop for providing the desired delay.</p>
<p>This is done by declaring a <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">delay_timer</span></code> and assigning the appropriate
function pointers and rate settings for this delay timer.</p>
<p>This is available on some architectures like OpenRISC or ARM.</p>
</section>
</section>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
©The kernel development community.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
& <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/timers/timekeeping.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>