History

vdso/gettimeofday: Add support for auxiliary clocks

Expose the auxiliary clocks through the vDSO. Architectures not using the generic vDSO time framework, namely SPARC64, are not supported.

Thomas Weißschuh committed 1 year ago

Commit cd3557a1 parent 380b84e2 files · +50 −1Browse files

Unified · Split

2 files
  1. include/vdso/datapage.h +2 −0
  2. lib/vdso/gettimeofday.c +48 −1
include/vdso/datapage.h+2−0
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 #ifndef __ASSEMBLY__
66
77 #include <linux/compiler.h>
8+#include <uapi/linux/bits.h>
89 #include <uapi/linux/time.h>
910 #include <uapi/linux/types.h>
1011 #include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data { · 35 unmodified lines
4647 #define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
4748 BIT(CLOCK_MONOTONIC_COARSE))
4849 #define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
50+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
4951
5052 #define CS_HRES_COARSE 0
5153 #define CS_RAW 1
lib/vdso/gettimeofday.c+48−1
@@ -2,6 +2,7 @@ · 1 unmodified line
22 /*
33 * Generic userspace implementations of gettimeofday() and similar.
44 */
5+#include <vdso/auxclock.h>
56 #include <vdso/datapage.h>
67 #include <vdso/helpers.h>
78
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles) · 66 unmodified lines
7475 static __always_inline bool vdso_clockid_valid(clockid_t clock)
7576 {
7677 /* Check for negative values or invalid clocks */
77− return likely((u32) clock < MAX_CLOCKS);
78+ return likely((u32) clock <= CLOCK_AUX_LAST);
7879 }
7980
8081 /*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc, · 187 unmodified lines
268269 return true;
269270 }
270271
272+static __always_inline
273+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
274+{
275+ const struct vdso_clock *vc;
276+ u32 seq, idx;
277+ u64 sec, ns;
278+
279+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
280+ return false;
281+
282+ idx = clock - CLOCK_AUX;
283+ vc = &vd->aux_clock_data[idx];
284+
285+ do {
286+ /*
287+ * Open coded function vdso_read_begin() to handle
288+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
289+ */
290+ while ((seq = READ_ONCE(vc->seq)) & 1) {
291+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
292+ vd = __arch_get_vdso_u_timens_data(vd);
293+ vc = &vd->aux_clock_data[idx];
294+ /* Re-read from the real time data page */
295+ continue;
296+ }
297+ cpu_relax();
298+ }
299+ smp_rmb();
300+
301+ /* Auxclock disabled? */
302+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
303+ return false;
304+
305+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
306+ return false;
307+ } while (unlikely(vdso_read_retry(vc, seq)));
308+
309+ vdso_set_timespec(ts, sec, ns);
310+
311+ return true;
312+}
313+
271314 static __always_inline bool
272315 __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
273316 struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock, · 15 unmodified lines
289332 return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
290333 else if (msk & VDSO_RAW)
291334 vc = &vc[CS_RAW];
335+ else if (msk & VDSO_AUX)
336+ return do_aux(vd, clock, ts);
292337 else
293338 return false;
294339
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc · 138 unmodified lines
433478 * Preserves the behaviour of posix_get_coarse_res().
434479 */
435480 ns = LOW_RES_NSEC;
481+ } else if (msk & VDSO_AUX) {
482+ ns = aux_clock_resolution_ns();
436483 } else {
437484 return false;
438485 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t