LCOV - code coverage report
Current view: top level - kernel/time - jiffies.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 20 30.0 %
Date: 2023-04-06 08:38:28 Functions: 3 4 75.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * This file contains the jiffies based clocksource.
       4             :  *
       5             :  * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
       6             :  */
       7             : #include <linux/clocksource.h>
       8             : #include <linux/jiffies.h>
       9             : #include <linux/module.h>
      10             : #include <linux/init.h>
      11             : 
      12             : #include "timekeeping.h"
      13             : #include "tick-internal.h"
      14             : 
      15             : 
      16         149 : static u64 jiffies_read(struct clocksource *cs)
      17             : {
      18         149 :         return (u64) jiffies;
      19             : }
      20             : 
      21             : /*
      22             :  * The Jiffies based clocksource is the lowest common
      23             :  * denominator clock source which should function on
      24             :  * all systems. It has the same coarse resolution as
      25             :  * the timer interrupt frequency HZ and it suffers
      26             :  * inaccuracies caused by missed or lost timer
      27             :  * interrupts and the inability for the timer
      28             :  * interrupt hardware to accurately tick at the
      29             :  * requested HZ value. It is also not recommended
      30             :  * for "tick-less" systems.
      31             :  */
      32             : static struct clocksource clocksource_jiffies = {
      33             :         .name                   = "jiffies",
      34             :         .rating                 = 1, /* lowest valid rating*/
      35             :         .uncertainty_margin     = 32 * NSEC_PER_MSEC,
      36             :         .read                   = jiffies_read,
      37             :         .mask                   = CLOCKSOURCE_MASK(32),
      38             :         .mult                   = TICK_NSEC << JIFFIES_SHIFT, /* details above */
      39             :         .shift                  = JIFFIES_SHIFT,
      40             :         .max_cycles             = 10,
      41             : };
      42             : 
      43             : __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(jiffies_lock);
      44             : __cacheline_aligned_in_smp seqcount_raw_spinlock_t jiffies_seq =
      45             :         SEQCNT_RAW_SPINLOCK_ZERO(jiffies_seq, &jiffies_lock);
      46             : 
      47             : #if (BITS_PER_LONG < 64)
      48             : u64 get_jiffies_64(void)
      49             : {
      50             :         unsigned int seq;
      51             :         u64 ret;
      52             : 
      53             :         do {
      54             :                 seq = read_seqcount_begin(&jiffies_seq);
      55             :                 ret = jiffies_64;
      56             :         } while (read_seqcount_retry(&jiffies_seq, seq));
      57             :         return ret;
      58             : }
      59             : EXPORT_SYMBOL(get_jiffies_64);
      60             : #endif
      61             : 
      62             : EXPORT_SYMBOL(jiffies);
      63             : 
      64           1 : static int __init init_jiffies_clocksource(void)
      65             : {
      66           1 :         return __clocksource_register(&clocksource_jiffies);
      67             : }
      68             : 
      69             : core_initcall(init_jiffies_clocksource);
      70             : 
      71           2 : struct clocksource * __init __weak clocksource_default_clock(void)
      72             : {
      73           2 :         return &clocksource_jiffies;
      74             : }
      75             : 
      76             : static struct clocksource refined_jiffies;
      77             : 
      78           0 : int register_refined_jiffies(long cycles_per_second)
      79             : {
      80             :         u64 nsec_per_tick, shift_hz;
      81             :         long cycles_per_tick;
      82             : 
      83             : 
      84             : 
      85           0 :         refined_jiffies = clocksource_jiffies;
      86           0 :         refined_jiffies.name = "refined-jiffies";
      87           0 :         refined_jiffies.rating++;
      88             : 
      89             :         /* Calc cycles per tick */
      90           0 :         cycles_per_tick = (cycles_per_second + HZ/2)/HZ;
      91             :         /* shift_hz stores hz<<8 for extra accuracy */
      92           0 :         shift_hz = (u64)cycles_per_second << 8;
      93           0 :         shift_hz += cycles_per_tick/2;
      94           0 :         do_div(shift_hz, cycles_per_tick);
      95             :         /* Calculate nsec_per_tick using shift_hz */
      96           0 :         nsec_per_tick = (u64)NSEC_PER_SEC << 8;
      97           0 :         nsec_per_tick += (u32)shift_hz/2;
      98           0 :         do_div(nsec_per_tick, (u32)shift_hz);
      99             : 
     100           0 :         refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
     101             : 
     102           0 :         __clocksource_register(&refined_jiffies);
     103           0 :         return 0;
     104             : }

Generated by: LCOV version 1.14