posix-timers: Document sys_clock_getres() correctly
authorThomas Gleixner <tglx@linutronix.de>
Tue, 25 Apr 2023 18:49:11 +0000 (20:49 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Sun, 18 Jun 2023 20:41:50 +0000 (22:41 +0200)
The decades old comment about Posix clock resolution is confusing at best.

Remove it and add a proper explanation to sys_clock_getres().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20230425183313.356427330@linutronix.de
kernel/time/posix-timers.c

index 6ac693331df99cc5984e505f346609229cd54e43..1acdd04e5d26d28c273c13a364bb501c53623df8 100644 (file)
@@ -67,14 +67,6 @@ static const struct k_clock clock_realtime, clock_monotonic;
  *         to implement others.  This structure defines the various
  *         clocks.
  *
- * RESOLUTION: Clock resolution is used to round up timer and interval
- *         times, NOT to report clock times, which are reported with as
- *         much resolution as the system can muster.  In some cases this
- *         resolution may depend on the underlying clock hardware and
- *         may not be quantifiable until run time, and only then is the
- *         necessary code is written.  The standard says we should say
- *         something about this issue in the documentation...
- *
  * FUNCTIONS: The CLOCKs structure defines possible functions to
  *         handle various clock functions.
  *
@@ -1198,6 +1190,79 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
        return err;
 }
 
+/**
+ * sys_clock_getres - Get the resolution of a clock
+ * @which_clock:       The clock to get the resolution for
+ * @tp:                        Pointer to a a user space timespec64 for storage
+ *
+ * POSIX defines:
+ *
+ * "The clock_getres() function shall return the resolution of any
+ * clock. Clock resolutions are implementation-defined and cannot be set by
+ * a process. If the argument res is not NULL, the resolution of the
+ * specified clock shall be stored in the location pointed to by res. If
+ * res is NULL, the clock resolution is not returned. If the time argument
+ * of clock_settime() is not a multiple of res, then the value is truncated
+ * to a multiple of res."
+ *
+ * Due to the various hardware constraints the real resolution can vary
+ * wildly and even change during runtime when the underlying devices are
+ * replaced. The kernel also can use hardware devices with different
+ * resolutions for reading the time and for arming timers.
+ *
+ * The kernel therefore deviates from the POSIX spec in various aspects:
+ *
+ * 1) The resolution returned to user space
+ *
+ *    For CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_TAI,
+ *    CLOCK_REALTIME_ALARM, CLOCK_BOOTTIME_ALAREM and CLOCK_MONOTONIC_RAW
+ *    the kernel differentiates only two cases:
+ *
+ *    I)  Low resolution mode:
+ *
+ *       When high resolution timers are disabled at compile or runtime
+ *       the resolution returned is nanoseconds per tick, which represents
+ *       the precision at which timers expire.
+ *
+ *    II) High resolution mode:
+ *
+ *       When high resolution timers are enabled the resolution returned
+ *       is always one nanosecond independent of the actual resolution of
+ *       the underlying hardware devices.
+ *
+ *       For CLOCK_*_ALARM the actual resolution depends on system
+ *       state. When system is running the resolution is the same as the
+ *       resolution of the other clocks. During suspend the actual
+ *       resolution is the resolution of the underlying RTC device which
+ *       might be way less precise than the clockevent device used during
+ *       running state.
+ *
+ *   For CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE the resolution
+ *   returned is always nanoseconds per tick.
+ *
+ *   For CLOCK_PROCESS_CPUTIME and CLOCK_THREAD_CPUTIME the resolution
+ *   returned is always one nanosecond under the assumption that the
+ *   underlying scheduler clock has a better resolution than nanoseconds
+ *   per tick.
+ *
+ *   For dynamic POSIX clocks (PTP devices) the resolution returned is
+ *   always one nanosecond.
+ *
+ * 2) Affect on sys_clock_settime()
+ *
+ *    The kernel does not truncate the time which is handed in to
+ *    sys_clock_settime(). The kernel internal timekeeping is always using
+ *    nanoseconds precision independent of the clocksource device which is
+ *    used to read the time from. The resolution of that device only
+ *    affects the presicion of the time returned by sys_clock_gettime().
+ *
+ * Returns:
+ *     0               Success. @tp contains the resolution
+ *     -EINVAL         @which_clock is not a valid clock ID
+ *     -EFAULT         Copying the resolution to @tp faulted
+ *     -ENODEV         Dynamic POSIX clock is not backed by a device
+ *     -EOPNOTSUPP     Dynamic POSIX clock does not support getres()
+ */
 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
                struct __kernel_timespec __user *, tp)
 {