History

Merge tag 'timers-ptp-2026-06-13' of gitolite.kernel.org:pub/scm/linux/kernel/git/tip/tip

Pull timekeeping updates from Thomas Gleixner: "Updates for NTP/timekeeping and PTP: - Expand timekeeping snapshot mechanisms The various snapshot functions are mostly used for PTP to collect "atomic" snapshots of various involved clocks. They lack support for the recently introduced AUX clocks and do not provide the underlying counter value (e.g. TSC) to user space. Exposing the counter value snapshot allows for better control and steering. Convert the hard wired ktime_get_snapshot() to take a clock ID, which allows the caller to select the clock ID to be captured along with CLOCK_MONONOTONIC_RAW. Additionally capture the underlying hardware counter value and the clock source ID of the counter. Expand the hardware based snapshot capture where devices provide a mechanism to snapshot the hardware PTP clock and the system counter (usually via PCI/PTM) to support AUX clocks and also provide the captured counter value back to the caller and not only the clock timestamps derived from it. - Add a new optional read_snapshot() callback to clocksources That is required to capture atomic snapshots from clocksources which are derived from TSC with a scaling mechanism (e.g. Hyper-V, KVMclock). The value pair is handed back in the snapshot structure to the callers, so they can do the necessary correlations in a more precise way. This touches usage sites of the affected functions and data structure all over the tree, but stays fully backwards compatible for the existing user space exposed interfaces. New PTP IOCTLs will provide access to the extended functionality in later kernel versions" * tag 'timers-ptp-2026-06-13' of gitolite.kernel.org:pub/scm/linux/kernel/git/tip/tip: (28 commits) ptp: vmclock: Use hw_cycles from snapshot for precise TSC pairing x86/kvmclock: Implement read_snapshot() for kvmclock clocksource clocksource/hyperv: Implement read_snapshot() for TSC page clocksource timekeeping: Add clocksource read_snapshot() method and hw_cycles to snapshot ptp: Switch to ktime_get_snapshot_id() for pre/post timestamps timekeeping: Add support for AUX clock cross timestamping timekeeping: Remove system_device_crosststamp::sys_realtime ALSA: hda/common: Use system_device_crosststamp::sys_systime wifi: iwlwifi: Use system_device_crosststamp::sys_systime ptp: Use system_device_crosststamp::sys_systime timekeeping: Prepare for cross timestamps on arbitrary clock IDs timekeeping: Remove ktime_get_snapshot() virtio_rtc: Use provided clock ID for history snapshot net/mlx5: Use provided clock ID for history snapshot igc: Use provided clock ID for history snapshot ice/ptp: Use provided clock ID for history snapshot wifi: iwlwifi: Adopt PTP cross timestamps to core changes timekeeping: Add CLOCK ID to system_device_crosststamp timekeeping: Add system_counterval_t to struct system_device_crosststamp timekeeping: Add CLOCK_AUX support for ktime_get_snapshot_id() ...

Linus Torvalds committed 5 months ago

Commit 2d6d57f2 parents a53fcff bc484a523 files · +348 −194Browse files

Unified · Split

23 files
  1. arch/arm64/kvm/hyp_trace.c +4 −4
  2. arch/arm64/kvm/hypercalls.c +3 −3
  3. arch/x86/kernel/kvmclock.c +29 −7
  4. drivers/clocksource/hyperv_timer.c +27 −10
  5. drivers/net/dsa/sja1105/sja1105_main.c +4 −4
  6. drivers/net/ethernet/intel/ice/ice_ptp.c +4 −1
  7. drivers/net/ethernet/intel/igc/igc.h +1 −0
  8. drivers/net/ethernet/intel/igc/igc_ptp.c +3 −1
  9. drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +2 −2
  10. drivers/net/wireless/intel/iwlwifi/mld/ptp.c +3 −2
  11. drivers/net/wireless/intel/iwlwifi/mvm/ptp.c +4 −3
  12. drivers/pps/generators/pps_gen-dummy.c +1 −5
  13. drivers/pps/generators/pps_gen_tio.c +1 −5
  14. drivers/ptp/ptp_chardev.c +11 −7
  15. drivers/ptp/ptp_ocp.c +4 −7
  16. drivers/ptp/ptp_vmclock.c +12 −17
  17. drivers/virtio/virtio_rtc_ptp.c +1 −1
  18. include/linux/clocksource.h +24 −0
  19. include/linux/pps_kernel.h +6 −4
  20. include/linux/ptp_clock_kernel.h +8 −7
  21. include/linux/timekeeping.h +36 −25
  22. kernel/time/timekeeping.c +158 −77
  23. sound/hda/common/controller.c +2 −2
arch/arm64/kvm/hyp_trace.c+4−4
@@ -51,8 +51,8 @@ static void __hyp_clock_work(struct work_struct *work) · 50 unmodified lines
5151
5252 hyp_clock = container_of(dwork, struct hyp_trace_clock, work);
5353
54− ktime_get_snapshot(&snap);
55− boot = ktime_to_ns(snap.boot);
54+ ktime_get_snapshot_id(CLOCK_BOOTTIME, &snap);
55+ boot = ktime_to_ns(snap.systime);
5656
5757 delta_boot = boot - hyp_clock->boot;
5858 delta_cycles = snap.cycles - hyp_clock->cycles;
@@ -118,9 +118,9 @@ static void hyp_trace_clock_enable(struct hyp_trace_clock *hyp_clock, bool enabl · 59 unmodified lines
118118 hyp_clock->running = false;
119119 }
120120
121− ktime_get_snapshot(&snap);
121+ ktime_get_snapshot_id(CLOCK_BOOTTIME, &snap);
122122
123− hyp_clock->boot = ktime_to_ns(snap.boot);
123+ hyp_clock->boot = ktime_to_ns(snap.systime);
124124 hyp_clock->cycles = snap.cycles;
125125 hyp_clock->mult = 0;
126126
arch/arm64/kvm/hypercalls.c+3−3
@@ -28,7 +28,7 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) · 27 unmodified lines
2828 * system time and counter value must captured at the same
2929 * time to keep consistency and precision.
3030 */
31− ktime_get_snapshot(&systime_snapshot);
31+ ktime_get_snapshot_id(CLOCK_REALTIME, &systime_snapshot);
3232
3333 /*
3434 * This is only valid if the current clocksource is the
@@ -61,8 +61,8 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) · 26 unmodified lines
6161 * in the future (about 292 years from 1970, and at that stage
6262 * nobody will give a damn about it).
6363 */
64− val[0] = upper_32_bits(systime_snapshot.real);
65− val[1] = lower_32_bits(systime_snapshot.real);
64+ val[0] = upper_32_bits(systime_snapshot.systime);
65+ val[1] = lower_32_bits(systime_snapshot.systime);
6666 val[2] = upper_32_bits(cycles);
6767 val[3] = lower_32_bits(cycles);
6868 }
arch/x86/kernel/kvmclock.c+29−7
@@ -87,6 +87,27 @@ static u64 kvm_clock_get_cycles(struct clocksource *cs) · 86 unmodified lines
8787 return kvm_clock_read();
8888 }
8989
90+static u64 kvm_clock_get_cycles_snapshot(struct clocksource *cs,
91+ struct clocksource_hw_snapshot *chs)
92+{
93+ struct pvclock_vcpu_time_info *src;
94+ unsigned version;
95+ u64 ret, tsc;
96+
97+ preempt_disable_notrace();
98+ src = this_cpu_pvti();
99+ do {
100+ version = pvclock_read_begin(src);
101+ tsc = rdtsc_ordered();
102+ ret = __pvclock_read_cycles(src, tsc);
103+ } while (pvclock_read_retry(src, version));
104+ preempt_enable_notrace();
105+
106+ chs->hw_cycles = tsc;
107+ chs->hw_csid = CSID_X86_TSC;
108+ return ret;
109+}
110+
90111 static noinstr u64 kvm_sched_clock_read(void)
91112 {
92113 return pvclock_clocksource_read_nowd(this_cpu_pvti()) - kvm_sched_clock_offset;
@@ -156,13 +177,14 @@ static int kvm_cs_enable(struct clocksource *cs) · 63 unmodified lines
156177 }
157178
158179 static struct clocksource kvm_clock = {
159− .name = "kvm-clock",
160− .read = kvm_clock_get_cycles,
161− .rating = 400,
162− .mask = CLOCKSOURCE_MASK(64),
163− .flags = CLOCK_SOURCE_IS_CONTINUOUS,
164− .id = CSID_X86_KVM_CLK,
165− .enable = kvm_cs_enable,
180+ .name = "kvm-clock",
181+ .read = kvm_clock_get_cycles,
182+ .read_snapshot = kvm_clock_get_cycles_snapshot,
183+ .rating = 400,
184+ .mask = CLOCKSOURCE_MASK(64),
185+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
186+ .id = CSID_X86_KVM_CLK,
187+ .enable = kvm_cs_enable,
166188 };
167189
168190 static void kvm_register_clock(char *txt)
drivers/clocksource/hyperv_timer.c+27−10
@@ -444,6 +444,22 @@ static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg) · 443 unmodified lines
444444 return read_hv_clock_tsc();
445445 }
446446
447+static u64 notrace read_hv_clock_tsc_cs_snapshot(struct clocksource *arg,
448+ struct clocksource_hw_snapshot *chs)
449+{
450+ u64 time;
451+
452+ if (hv_read_tsc_page_tsc(tsc_page, &chs->hw_cycles, &time)) {
453+ chs->hw_csid = CSID_X86_TSC;
454+ } else {
455+ chs->hw_cycles = 0;
456+ chs->hw_csid = CSID_GENERIC;
457+ time = read_hv_clock_msr();
458+ }
459+
460+ return time;
461+}
462+
447463 static u64 noinstr read_hv_sched_clock_tsc(void)
448464 {
449465 return (read_hv_clock_tsc() - hv_sched_clock_offset) *
@@ -492,18 +508,19 @@ static int hv_cs_enable(struct clocksource *cs) · 42 unmodified lines
492508 #endif
493509
494510 static struct clocksource hyperv_cs_tsc = {
495− .name = "hyperv_clocksource_tsc_page",
496− .rating = 500,
497− .read = read_hv_clock_tsc_cs,
498− .mask = CLOCKSOURCE_MASK(64),
499− .flags = CLOCK_SOURCE_IS_CONTINUOUS,
500− .suspend= suspend_hv_clock_tsc,
501− .resume = resume_hv_clock_tsc,
511+ .name = "hyperv_clocksource_tsc_page",
512+ .rating = 500,
513+ .read = read_hv_clock_tsc_cs,
514+ .read_snapshot = read_hv_clock_tsc_cs_snapshot,
515+ .mask = CLOCKSOURCE_MASK(64),
516+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
517+ .suspend = suspend_hv_clock_tsc,
518+ .resume = resume_hv_clock_tsc,
502519 #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
503− .enable = hv_cs_enable,
504− .vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
520+ .enable = hv_cs_enable,
521+ .vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
505522 #else
506− .vdso_clock_mode = VDSO_CLOCKMODE_NONE,
523+ .vdso_clock_mode = VDSO_CLOCKMODE_NONE,
507524 #endif
508525 };
509526
drivers/net/dsa/sja1105/sja1105_main.c+4−4
@@ -2310,10 +2310,10 @@ int sja1105_static_config_reload(struct sja1105_private *priv, · 2309 unmodified lines
23102310 goto out;
23112311 }
23122312
2313− t1 = timespec64_to_ns(&ptp_sts_before.pre_ts);
2314− t2 = timespec64_to_ns(&ptp_sts_before.post_ts);
2315− t3 = timespec64_to_ns(&ptp_sts_after.pre_ts);
2316− t4 = timespec64_to_ns(&ptp_sts_after.post_ts);
2313+ t1 = ktime_to_ns(ptp_sts_before.pre_sts.systime);
2314+ t2 = ktime_to_ns(ptp_sts_before.post_sts.systime);
2315+ t3 = ktime_to_ns(ptp_sts_after.pre_sts.systime);
2316+ t4 = ktime_to_ns(ptp_sts_after.post_sts.systime);
23172317 /* Mid point, corresponds to pre-reset PTPCLKVAL */
23182318 t12 = t1 + (t2 - t1) / 2;
23192319 /* Mid point, corresponds to post-reset PTPCLKVAL, aka 0 */
drivers/net/ethernet/intel/ice/ice_ptp.c+4−1
@@ -2065,11 +2065,13 @@ static const struct ice_crosststamp_cfg ice_crosststamp_cfg_e830 = { · 2064 unmodified lines
20652065 /**
20662066 * struct ice_crosststamp_ctx - Device cross timestamp context
20672067 * @snapshot: snapshot of system clocks for historic interpolation
2068+ * @snapshot_clock_id: System clock ID for @snapshot
20682069 * @pf: pointer to the PF private structure
20692070 * @cfg: pointer to hardware configuration for cross timestamp
20702071 */
20712072 struct ice_crosststamp_ctx {
20722073 struct system_time_snapshot snapshot;
2074+ clockid_t snapshot_clock_id;
20732075 struct ice_pf *pf;
20742076 const struct ice_crosststamp_cfg *cfg;
20752077 };
@@ -2115,7 +2117,7 @@ static int ice_capture_crosststamp(ktime_t *device, · 39 unmodified lines
21152117 }
21162118
21172119 /* Snapshot system time for historic interpolation */
2118− ktime_get_snapshot(&ctx->snapshot);
2120+ ktime_get_snapshot_id(ctx->snapshot_clock_id, &ctx->snapshot);
21192121
21202122 /* Program cmd to master timer */
21212123 ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
@@ -2176,6 +2178,7 @@ static int ice_ptp_getcrosststamp(struct ptp_clock_info *info, · 54 unmodified lines
21762178 {
21772179 struct ice_pf *pf = ptp_info_to_pf(info);
21782180 struct ice_crosststamp_ctx ctx = {
2181+ .snapshot_clock_id = cts->clock_id,
21792182 .pf = pf,
21802183 };
21812184
drivers/net/ethernet/intel/igc/igc.h+1−0
@@ -326,6 +326,7 @@ struct igc_adapter { · 325 unmodified lines
326326 struct timespec64 prev_ptp_time; /* Pre-reset PTP clock */
327327 ktime_t ptp_reset_start; /* Reset time in clock mono */
328328 struct system_time_snapshot snapshot;
329+ clockid_t snapshot_clock_id;
329330 struct mutex ptm_lock; /* Only allow one PTM transaction at a time */
330331
331332 char fw_version[32];
drivers/net/ethernet/intel/igc/igc_ptp.c+3−1
@@ -1049,7 +1049,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device, · 1048 unmodified lines
10491049 */
10501050 do {
10511051 /* Get a snapshot of system clocks to use as historic value. */
1052− ktime_get_snapshot(&adapter->snapshot);
1052+ ktime_get_snapshot_id(adapter->snapshot_clock_id, &adapter->snapshot);
10531053
10541054 igc_ptm_trigger(hw);
10551055
@@ -1103,6 +1103,8 @@ static int igc_ptp_getcrosststamp(struct ptp_clock_info *ptp, · 47 unmodified lines
11031103 /* This blocks until any in progress PTM transactions complete */
11041104 mutex_lock(&adapter->ptm_lock);
11051105
1106+ adapter->snapshot_clock_id = cts->clock_id;
1107+
11061108 ret = get_device_system_crosststamp(igc_phc_get_syncdevicetime,
11071109 adapter, &adapter->snapshot, cts);
11081110 mutex_unlock(&adapter->ptm_lock);
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c+2−2
@@ -340,7 +340,7 @@ static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp, · 339 unmodified lines
340340 goto unlock;
341341 }
342342
343− ktime_get_snapshot(&history_begin);
343+ ktime_get_snapshot_id(cts->clock_id, &history_begin);
344344
345345 err = get_device_system_crosststamp(mlx5_mtctr_syncdevicetime, mdev,
346346 &history_begin, cts);
@@ -366,7 +366,7 @@ static int mlx5_ptp_getcrosscycles(struct ptp_clock_info *ptp, · 19 unmodified lines
366366 goto unlock;
367367 }
368368
369− ktime_get_snapshot(&history_begin);
369+ ktime_get_snapshot_id(cts->clock_id, &history_begin);
370370
371371 err = get_device_system_crosststamp(mlx5_mtctr_syncdevicecyclestime,
372372 mdev, &history_begin, cts);
drivers/net/wireless/intel/iwlwifi/mld/ptp.c+3−2
@@ -250,7 +250,8 @@ iwl_mld_phc_get_crosstimestamp(struct ptp_clock_info *ptp, · 249 unmodified lines
250250 /* System (wall) time */
251251 ktime_t sys_time;
252252
253− memset(xtstamp, 0, sizeof(struct system_device_crosststamp));
253+ if (xtstamp->clock_id != CLOCK_REALTIME)
254+ return -ENOTSUPP;
254255
255256 ret = iwl_mld_get_crosstimestamp_fw(mld, &gp2, &sys_time);
256257 if (ret) {
@@ -270,7 +271,7 @@ iwl_mld_phc_get_crosstimestamp(struct ptp_clock_info *ptp, · 13 unmodified lines
270271
271272 /* System monotonic raw time is not used */
272273 xtstamp->device = ns_to_ktime(gp2_ns);
273− xtstamp->sys_realtime = sys_time;
274+ xtstamp->sys_systime = sys_time;
274275
275276 return ret;
276277 }
drivers/net/wireless/intel/iwlwifi/mvm/ptp.c+4−3
@@ -160,13 +160,14 @@ iwl_mvm_phc_get_crosstimestamp(struct ptp_clock_info *ptp, · 159 unmodified lines
160160 /* System (wall) time */
161161 ktime_t sys_time;
162162
163− memset(xtstamp, 0, sizeof(struct system_device_crosststamp));
164−
165163 if (!mvm->ptp_data.ptp_clock) {
166164 IWL_ERR(mvm, "No PHC clock registered\n");
167165 return -ENODEV;
168166 }
169167
168+ if (xtstamp->clock_id != CLOCK_REALTIME)
169+ return -ENOTSUPP;
170+
170171 mutex_lock(&mvm->mutex);
171172 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SYNCED_TIME)) {
172173 ret = iwl_mvm_get_crosstimestamp_fw(mvm, &gp2, &sys_time);
@@ -184,7 +185,7 @@ iwl_mvm_phc_get_crosstimestamp(struct ptp_clock_info *ptp, · 11 unmodified lines
184185
185186 /* System monotonic raw time is not used */
186187 xtstamp->device = (ktime_t)gp2_ns;
187− xtstamp->sys_realtime = sys_time;
188+ xtstamp->sys_systime = sys_time;
188189
189190 out:
190191 mutex_unlock(&mvm->mutex);
drivers/pps/generators/pps_gen-dummy.c+1−5
@@ -39,11 +39,7 @@ static void pps_gen_ktimer_event(struct timer_list *unused) · 38 unmodified lines
3939 static int pps_gen_dummy_get_time(struct pps_gen_device *pps_gen,
4040 struct timespec64 *time)
4141 {
42− struct system_time_snapshot snap;
43−
44− ktime_get_snapshot(&snap);
45− *time = ktime_to_timespec64(snap.real);
46−
42+ ktime_get_real_ts64(time);
4743 return 0;
4844 }
4945
drivers/pps/generators/pps_gen_tio.c+1−5
@@ -189,11 +189,7 @@ static int pps_tio_gen_enable(struct pps_gen_device *pps_gen, bool enable) · 188 unmodified lines
189189 static int pps_tio_get_time(struct pps_gen_device *pps_gen,
190190 struct timespec64 *time)
191191 {
192− struct system_time_snapshot snap;
193−
194− ktime_get_snapshot(&snap);
195− *time = ktime_to_timespec64(snap.real);
196−
192+ ktime_get_real_ts64(time);
197193 return 0;
198194 }
199195
drivers/ptp/ptp_chardev.c+11−7
@@ -317,8 +317,8 @@ typedef int (*ptp_crosststamp_fn)(struct ptp_clock_info *, · 316 unmodified lines
317317 static long ptp_sys_offset_precise(struct ptp_clock *ptp, void __user *arg,
318318 ptp_crosststamp_fn crosststamp_fn)
319319 {
320+ struct system_device_crosststamp xtstamp = { .clock_id = CLOCK_REALTIME };
320321 struct ptp_sys_offset_precise precise_offset;
321− struct system_device_crosststamp xtstamp;
322322 struct timespec64 ts;
323323 int err;
324324
@@ -333,7 +333,7 @@ static long ptp_sys_offset_precise(struct ptp_clock *ptp, void __user *arg, · 8 unmodified lines
333333 ts = ktime_to_timespec64(xtstamp.device);
334334 precise_offset.device.sec = ts.tv_sec;
335335 precise_offset.device.nsec = ts.tv_nsec;
336− ts = ktime_to_timespec64(xtstamp.sys_realtime);
336+ ts = ktime_to_timespec64(xtstamp.sys_systime);
337337 precise_offset.sys_realtime.sec = ts.tv_sec;
338338 precise_offset.sys_realtime.nsec = ts.tv_nsec;
339339 ts = ktime_to_timespec64(xtstamp.sys_monoraw);
@@ -386,15 +386,19 @@ static long ptp_sys_offset_extended(struct ptp_clock *ptp, void __user *arg, · 46 unmodified lines
386386 return err;
387387
388388 /* Filter out disabled or unavailable clocks */
389− if (sts.pre_ts.tv_sec < 0 || sts.post_ts.tv_sec < 0)
389+ if (!sts.pre_sts.valid || !sts.post_sts.valid)
390390 return -EINVAL;
391391
392− extoff->ts[i][0].sec = sts.pre_ts.tv_sec;
393− extoff->ts[i][0].nsec = sts.pre_ts.tv_nsec;
394392 extoff->ts[i][1].sec = ts.tv_sec;
395393 extoff->ts[i][1].nsec = ts.tv_nsec;
396− extoff->ts[i][2].sec = sts.post_ts.tv_sec;
397− extoff->ts[i][2].nsec = sts.post_ts.tv_nsec;
394+
395+ ts = ktime_to_timespec64(sts.pre_sts.systime);
396+ extoff->ts[i][0].sec = ts.tv_sec;
397+ extoff->ts[i][0].nsec = ts.tv_nsec;
398+
399+ ts = ktime_to_timespec64(sts.post_sts.systime);
400+ extoff->ts[i][2].sec = ts.tv_sec;
401+ extoff->ts[i][2].nsec = ts.tv_nsec;
398402 }
399403
400404 return copy_to_user(arg, extoff, sizeof(*extoff)) ? -EFAULT : 0;
drivers/ptp/ptp_ocp.c+4−7
@@ -1491,11 +1491,8 @@ __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts, · 1490 unmodified lines
14911491 }
14921492 ptp_read_system_postts(sts);
14931493
1494− if (sts && bp->ts_window_adjust) {
1495− s64 ns = timespec64_to_ns(&sts->post_ts);
1496−
1497− sts->post_ts = ns_to_timespec64(ns - bp->ts_window_adjust);
1498− }
1494+ if (sts && bp->ts_window_adjust)
1495+ sts->post_sts.systime -= bp->ts_window_adjust;
14991496
15001497 time_ns = ioread32(&bp->reg->time_ns);
15011498 time_sec = ioread32(&bp->reg->time_sec);
@@ -4600,8 +4597,8 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) · 3098 unmodified lines
46004597 struct timespec64 sys_ts;
46014598 s64 pre_ns, post_ns, ns;
46024599
4603− pre_ns = timespec64_to_ns(&sts.pre_ts);
4604− post_ns = timespec64_to_ns(&sts.post_ts);
4600+ pre_ns = ktime_to_ns(sts.pre_sts.systime);
4601+ post_ns = ktime_to_ns(sts.post_sts.systime);
46054602 ns = (pre_ns + post_ns) / 2;
46064603 ns += (s64)bp->utc_tai_offset * NSEC_PER_SEC;
46074604 sys_ts = ns_to_timespec64(ns);
drivers/ptp/ptp_vmclock.c+12−17
@@ -101,7 +101,6 @@ static int vmclock_get_crosststamp(struct vmclock_state *st, · 100 unmodified lines
101101 struct timespec64 *tspec)
102102 {
103103 ktime_t deadline = ktime_add(ktime_get(), VMCLOCK_MAX_WAIT);
104− struct system_time_snapshot systime_snapshot;
105104 uint64_t cycle, delta, seq, frac_sec;
106105
107106 #ifdef CONFIG_X86
@@ -132,17 +131,19 @@ static int vmclock_get_crosststamp(struct vmclock_state *st, · 24 unmodified lines
132131 * will be derived from the *same* counter value.
133132 *
134133 * If the system isn't using the same counter, then the value
135− * from ktime_get_snapshot() will still be used as pre_ts, and
136− * ptp_read_system_postts() is called to populate postts after
137− * calling get_cycles().
138− *
139− * The conversion to timespec64 happens further down, outside
140− * the seq_count loop.
134+ * from ptp_read_system_prets() will still be used as pre_ts,
135+ * and ptp_read_system_postts() is called to populate postts
136+ * after calling get_cycles().
141137 */
142138 if (sts) {
143− ktime_get_snapshot(&systime_snapshot);
144− if (systime_snapshot.cs_id == st->cs_id) {
145− cycle = systime_snapshot.cycles;
139+ ptp_read_system_prets(sts);
140+ if (sts->pre_sts.cs_id == st->cs_id) {
141+ cycle = sts->pre_sts.cycles;
142+ sts->post_sts = sts->pre_sts;
143+ } else if (sts->pre_sts.hw_csid == st->cs_id &&
144+ sts->pre_sts.hw_cycles) {
145+ cycle = sts->pre_sts.hw_cycles;
146+ sts->post_sts = sts->pre_sts;
146147 } else {
147148 cycle = get_cycles();
148149 ptp_read_system_postts(sts);
@@ -180,12 +181,6 @@ static int vmclock_get_crosststamp(struct vmclock_state *st, · 31 unmodified lines
180181 system_counter->cs_id = st->cs_id;
181182 }
182183
183− if (sts) {
184− sts->pre_ts = ktime_to_timespec64(systime_snapshot.real);
185− if (systime_snapshot.cs_id == st->cs_id)
186− sts->post_ts = sts->pre_ts;
187− }
188−
189184 return 0;
190185 }
191186
@@ -272,7 +267,7 @@ static int ptp_vmclock_getcrosststamp(struct ptp_clock_info *ptp, · 80 unmodified lines
272267 if (ret == -ENODEV) {
273268 struct system_time_snapshot systime_snapshot;
274269
275− ktime_get_snapshot(&systime_snapshot);
270+ ktime_get_snapshot_id(CLOCK_REALTIME, &systime_snapshot);
276271
277272 if (systime_snapshot.cs_id == CSID_X86_TSC ||
278273 systime_snapshot.cs_id == CSID_X86_KVM_CLK) {
drivers/virtio/virtio_rtc_ptp.c+1−1
@@ -139,7 +139,7 @@ static int viortc_ptp_getcrosststamp(struct ptp_clock_info *ptp, · 138 unmodified lines
139139 if (ret)
140140 return ret;
141141
142− ktime_get_snapshot(&history_begin);
142+ ktime_get_snapshot_id(xtstamp->clock_id, &history_begin);
143143 if (history_begin.cs_id != cs_id)
144144 return -EOPNOTSUPP;
145145
include/linux/clocksource.h+24−0
@@ -31,6 +31,21 @@ struct module; · 30 unmodified lines
3131
3232 #include <vdso/clocksource.h>
3333
34+/**
35+ * struct clocksource_hw_snapshot - Snapshot for the underlying hardware counter of derived
36+ * clocksources like kvmclock or Hyper-V scaled TSC
37+ * @hw_cycles: The hardware counter value
38+ * @hw_csid: Clocksource ID of the hardware counter
39+ *
40+ * Such clocksources must implement the read_snapshot() callback and fill in the
41+ * hardware counter value, the clocksource ID of the hardware counter and derive
42+ * the actual clocksource cycles from @hw_cycles to provide an atomic snapshot
43+ */
44+struct clocksource_hw_snapshot {
45+ u64 hw_cycles;
46+ enum clocksource_ids hw_csid;
47+};
48+
3449 /**
3550 * struct clocksource - hardware abstraction for a free running counter
3651 * Provides mostly state-free accessors to the underlying hardware.
@@ -72,6 +87,14 @@ struct module; · 35 unmodified lines
7287 * @flags: Flags describing special properties
7388 * @base: Hardware abstraction for clock on which a clocksource
7489 * is based
90+ * @read_snapshot: Extended @read() function for clocksources such as
91+ * kvmclock or the Hyper-V scaled TSC where the actual
92+ * clocksource value for timekeeping is calculated from an
93+ * underlying hardware counter. Returns the timekeeping
94+ * relevant cycle value and stores the raw value of the
95+ * underlying counter from which it was calculated
96+ * including the clocksource ID of that counter in the
97+ * clocksource hardware snapshot.
7598 * @enable: Optional function to enable the clocksource
7699 * @disable: Optional function to disable the clocksource
77100 * @suspend: Optional suspend function for the clocksource
@@ -113,6 +136,7 @@ struct clocksource { · 35 unmodified lines
113136 unsigned long flags;
114137 struct clocksource_base *base;
115138
139+ u64 (*read_snapshot)(struct clocksource *cs, struct clocksource_hw_snapshot *chs);
116140 int (*enable)(struct clocksource *cs);
117141 void (*disable)(struct clocksource *cs);
118142 void (*suspend)(struct clocksource *cs);
include/linux/pps_kernel.h+6−4
@@ -99,12 +99,14 @@ static inline void timespec_to_pps_ktime(struct pps_ktime *kt, · 98 unmodified lines
9999
100100 static inline void pps_get_ts(struct pps_event_time *ts)
101101 {
102+#ifdef CONFIG_NTP_PPS
102103 struct system_time_snapshot snap;
103104
104− ktime_get_snapshot(&snap);
105− ts->ts_real = ktime_to_timespec64(snap.real);
106−#ifdef CONFIG_NTP_PPS
107− ts->ts_raw = ktime_to_timespec64(snap.raw);
105+ ktime_get_snapshot_id(CLOCK_REALTIME, &snap);
106+ ts->ts_real = ktime_to_timespec64(snap.systime);
107+ ts->ts_raw = ktime_to_timespec64(snap.monoraw);
108+#else
109+ ktime_get_real_ts64(&ts->ts_real);
108110 #endif
109111 }
110112
include/linux/ptp_clock_kernel.h+8−7
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/pps_kernel.h>
1313 #include <linux/ptp_clock.h>
1414 #include <linux/timecounter.h>
15+#include <linux/timekeeping.h>
1516 #include <linux/skbuff.h>
1617
1718 #define PTP_CLOCK_NAME_LEN 32
@@ -45,13 +46,13 @@ struct system_device_crosststamp; · 27 unmodified lines
4546
4647 /**
4748 * struct ptp_system_timestamp - system time corresponding to a PHC timestamp
48− * @pre_ts: system timestamp before capturing PHC
49− * @post_ts: system timestamp after capturing PHC
50− * @clockid: clock-base used for capturing the system timestamps
49+ * @pre_sts: system time snapshot before capturing PHC
50+ * @post_sts: system time snapshot after capturing PHC
51+ * @clockid: clock-base used for capturing the system timestamps
5152 */
5253 struct ptp_system_timestamp {
53− struct timespec64 pre_ts;
54− struct timespec64 post_ts;
54+ struct system_time_snapshot pre_sts;
55+ struct system_time_snapshot post_sts;
5556 clockid_t clockid;
5657 };
5758
@@ -510,13 +511,13 @@ static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, · 452 unmodified lines
510511 static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts)
511512 {
512513 if (sts)
513− ktime_get_clock_ts64(sts->clockid, &sts->pre_ts);
514+ ktime_get_snapshot_id(sts->clockid, &sts->pre_sts);
514515 }
515516
516517 static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
517518 {
518519 if (sts)
519− ktime_get_clock_ts64(sts->clockid, &sts->post_ts);
520+ ktime_get_snapshot_id(sts->clockid, &sts->post_sts);
520521 }
521522
522523 #endif
include/linux/timekeeping.h+36−25
@@ -276,37 +276,30 @@ static inline bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt) { ret · 275 unmodified lines
276276 #endif
277277
278278 /**
279− * struct system_time_snapshot - simultaneous raw/real time capture with
280− * counter value
281− * @cycles: Clocksource counter value to produce the system times
282− * @real: Realtime system time
283− * @boot: Boot time
284− * @raw: Monotonic raw system time
285− * @cs_id: Clocksource ID
279+ * struct system_time_snapshot - Simultaneous time capture of CLOCK_MONOTONIC_RAW,
280+ * a selected CLOCK_* and the clocksource counter value
281+ * @cycles: Clocksource counter value to produce the system times
282+ * @hw_cycles: For derived clocksources, the hardware counter value from
283+ * which @cycles was derived
284+ * @systime: The system time of the selected CLOCK ID
285+ * @monoraw: Monotonic raw system time
286+ * @cs_id: Clocksource ID
287+ * @hw_csid: Clocksource ID of the underlying hardware counter for derived
288+ * clocksources which implement the read_snapshot() callback.
286289 * @clock_was_set_seq: The sequence number of clock-was-set events
287290 * @cs_was_changed_seq: The sequence number of clocksource change events
291+ * @valid: True if the snapshot is valid
288292 */
289293 struct system_time_snapshot {
290294 u64 cycles;
291− ktime_t real;
292− ktime_t boot;
293− ktime_t raw;
295+ u64 hw_cycles;
296+ ktime_t systime;
297+ ktime_t monoraw;
294298 enum clocksource_ids cs_id;
299+ enum clocksource_ids hw_csid;
295300 unsigned int clock_was_set_seq;
296301 u8 cs_was_changed_seq;
297−};
298−
299−/**
300− * struct system_device_crosststamp - system/device cross-timestamp
301− * (synchronized capture)
302− * @device: Device time
303− * @sys_realtime: Realtime simultaneous with device time
304− * @sys_monoraw: Monotonic raw simultaneous with device time
305− */
306−struct system_device_crosststamp {
307− ktime_t device;
308− ktime_t sys_realtime;
309− ktime_t sys_monoraw;
302+ u8 valid;
310303 };
311304
312305 /**
@@ -325,6 +318,23 @@ struct system_counterval_t { · 12 unmodified lines
325318 bool use_nsecs;
326319 };
327320
321+/**
322+ * struct system_device_crosststamp - system/device cross-timestamp
323+ * (synchronized capture)
324+ * @clock_id: System time Clock ID to capture
325+ * @device: Device time
326+ * @sys_counter: Clocksource counter value simultaneous with device time
327+ * @sys_systime: System time for @clock_id
328+ * @sys_monoraw: Monotonic raw simultaneous with device time
329+ */
330+struct system_device_crosststamp {
331+ clockid_t clock_id;
332+ ktime_t device;
333+ struct system_counterval_t sys_counter;
334+ ktime_t sys_systime;
335+ ktime_t sys_monoraw;
336+};
337+
328338 extern bool ktime_real_to_base_clock(ktime_t treal,
329339 enum clocksource_ids base_id, u64 *cycles);
330340 extern bool timekeeping_clocksource_has_base(enum clocksource_ids id);
@@ -341,9 +351,10 @@ extern int get_device_system_crosststamp( · 10 unmodified lines
341351 struct system_device_crosststamp *xtstamp);
342352
343353 /*
344− * Simultaneously snapshot realtime and monotonic raw clocks
354+ * Simultaneously snapshot a given clock with MONOTONIC_RAW and the underlying
355+ * clocksource counter value.
345356 */
346−extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);
357+extern void ktime_get_snapshot_id(clockid_t clock_id, struct system_time_snapshot *systime_snapshot);
347358
348359 /*
349360 * Persistent clock related interfaces
kernel/time/timekeeping.c+158−77
@@ -67,6 +67,7 @@ static inline bool tk_is_aux(const struct timekeeper *tk) · 66 unmodified lines
6767 {
6868 return tk->id >= TIMEKEEPER_AUX_FIRST && tk->id <= TIMEKEEPER_AUX_LAST;
6969 }
70+static inline struct tk_data *aux_get_tk_data(clockid_t id);
7071 #else
7172 static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
7273 {
@@ -77,6 +78,10 @@ static inline bool tk_is_aux(const struct timekeeper *tk) · 4 unmodified lines
7778 {
7879 return false;
7980 }
81+static inline struct tk_data *aux_get_tk_data(clockid_t id)
82+{
83+ return NULL;
84+}
8085 #endif
8186
8287 static inline void tk_update_aux_offs(struct timekeeper *tk, ktime_t offs)
@@ -315,6 +320,7 @@ static __always_inline u64 tk_clock_read(const struct tk_read_base *tkr) · 232 unmodified lines
315320
316321 return clock->read(clock);
317322 }
323+
318324 static inline void clocksource_disable_inline_read(void) { }
319325 static inline void clocksource_enable_inline_read(void) { }
320326 #endif
@@ -1182,44 +1188,107 @@ noinstr time64_t __ktime_get_real_seconds(void) · 861 unmodified lines
11821188 return tk->xtime_sec;
11831189 }
11841190
1185−/**
1186− * ktime_get_snapshot - snapshots the realtime/monotonic raw clocks with counter
1187− * @systime_snapshot: pointer to struct receiving the system time snapshot
1188− */
1189−void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
1191+static inline u64 tk_clock_read_snapshot(const struct tk_read_base *tkr,
1192+ struct clocksource_hw_snapshot *chs)
11901193 {
1191− struct timekeeper *tk = &tk_core.timekeeper;
1194+ struct clocksource *clock = READ_ONCE(tkr->clock);
1195+
1196+ if (unlikely(clock->read_snapshot))
1197+ return clock->read_snapshot(clock, chs);
1198+
1199+ return clock->read(clock);
1200+}
1201+
1202+
1203+/**
1204+ * ktime_get_snapshot_id - Simultaneously snapshot a given clock ID with
1205+ * CLOCK_MONOTONIC_RAW and the underlying
1206+ * clocksource counter value.
1207+ * @clock_id: The clock ID to snapshot
1208+ * @systime_snapshot: Pointer to struct receiving the system time snapshot
1209+ */
1210+void ktime_get_snapshot_id(clockid_t clock_id, struct system_time_snapshot *systime_snapshot)
1211+{
1212+ ktime_t base_raw, base_sys, offs_sys, *offs, offs_zero = 0;
1213+ u64 nsec_raw, nsec_sys, now;
1214+ struct timekeeper *tk;
1215+ struct tk_data *tkd;
11921216 unsigned int seq;
1193− ktime_t base_raw;
1194− ktime_t base_real;
1195− ktime_t base_boot;
1196− u64 nsec_raw;
1197− u64 nsec_real;
1198− u64 now;
11991217
1200− WARN_ON_ONCE(timekeeping_suspended);
1218+ /* Invalidate the snapshot for all failure cases */
1219+ systime_snapshot->valid = false;
1220+
1221+ if (WARN_ON_ONCE(timekeeping_suspended))
1222+ return;
1223+
1224+ switch (clock_id) {
1225+ case CLOCK_REALTIME:
1226+ tkd = &tk_core;
1227+ offs = &tk_core.timekeeper.offs_real;
1228+ break;
1229+ /* Map RAW to MONOTONIC so the loop below is trivial */
1230+ case CLOCK_MONOTONIC_RAW:
1231+ case CLOCK_MONOTONIC:
1232+ tkd = &tk_core;
1233+ offs = &offs_zero;
1234+ break;
1235+ case CLOCK_BOOTTIME:
1236+ tkd = &tk_core;
1237+ offs = &tk_core.timekeeper.offs_boot;
1238+ break;
1239+ case CLOCK_AUX ... CLOCK_AUX_LAST:
1240+ tkd = aux_get_tk_data(clock_id);
1241+ if (!tkd)
1242+ return;
1243+ offs = &tkd->timekeeper.offs_aux;
1244+ break;
1245+ default:
1246+ WARN_ON_ONCE(1);
1247+ return;
1248+ }
1249+
1250+ tk = &tkd->timekeeper;
12011251
12021252 do {
1203− seq = read_seqcount_begin(&tk_core.seq);
1204− now = tk_clock_read(&tk->tkr_mono);
1253+ struct clocksource_hw_snapshot chs = { };
1254+
1255+ seq = read_seqcount_begin(&tkd->seq);
1256+
1257+ /* Aux clocks can be invalid */
1258+ if (!tk->clock_valid)
1259+ return;
1260+
1261+ now = tk_clock_read_snapshot(&tk->tkr_mono, &chs);
12051262 systime_snapshot->cs_id = tk->tkr_mono.clock->id;
1263+
1264+ systime_snapshot->hw_cycles = chs.hw_cycles;
1265+ systime_snapshot->hw_csid = chs.hw_csid;
1266+
12061267 systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq;
12071268 systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq;
1208− base_real = ktime_add(tk->tkr_mono.base,
1209− tk_core.timekeeper.offs_real);
1210− base_boot = ktime_add(tk->tkr_mono.base,
1211− tk_core.timekeeper.offs_boot);
1269+
1270+ base_sys = tk->tkr_mono.base;
1271+ offs_sys = *offs;
12121272 base_raw = tk->tkr_raw.base;
1213− nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, now);
1214− nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, now);
1215− } while (read_seqcount_retry(&tk_core.seq, seq));
1273+
1274+ nsec_sys = timekeeping_cycles_to_ns(&tk->tkr_mono, now);
1275+ nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, now);
1276+ } while (read_seqcount_retry(&tkd->seq, seq));
12161277
12171278 systime_snapshot->cycles = now;
1218− systime_snapshot->real = ktime_add_ns(base_real, nsec_real);
1219− systime_snapshot->boot = ktime_add_ns(base_boot, nsec_real);
1220− systime_snapshot->raw = ktime_add_ns(base_raw, nsec_raw);
1279+ systime_snapshot->systime = ktime_add_ns(base_sys, offs_sys + nsec_sys);
1280+ systime_snapshot->monoraw = ktime_add_ns(base_raw, nsec_raw);
1281+
1282+ /*
1283+ * Special case for PTP. Just transfer the raw time into sys,
1284+ * so the call sites can consistently use snap::systime.
1285+ */
1286+ if (clock_id == CLOCK_MONOTONIC_RAW)
1287+ systime_snapshot->systime = systime_snapshot->monoraw;
1288+ /* Tell the consumer that this snapshot is valid */
1289+ systime_snapshot->valid = true;
12211290 }
1222−EXPORT_SYMBOL_GPL(ktime_get_snapshot);
1291+EXPORT_SYMBOL_GPL(ktime_get_snapshot_id);
12231292
12241293 /* Scale base by mult/div checking for overflow */
12251294 static int scale64_check_overflow(u64 mult, u64 div, u64 *base)
@@ -1262,7 +1331,7 @@ static int adjust_historical_crosststamp(struct system_time_snapshot *history, · 36 unmodified lines
12621331 struct system_device_crosststamp *ts)
12631332 {
12641333 struct timekeeper *tk = &tk_core.timekeeper;
1265− u64 corr_raw, corr_real;
1334+ u64 corr_raw, corr_sys;
12661335 bool interp_forward;
12671336 int ret;
12681337
@@ -1279,8 +1348,7 @@ static int adjust_historical_crosststamp(struct system_time_snapshot *history, · 10 unmodified lines
12791348 * Scale the monotonic raw time delta by:
12801349 * partial_history_cycles / total_history_cycles
12811350 */
1282− corr_raw = (u64)ktime_to_ns(
1283− ktime_sub(ts->sys_monoraw, history->raw));
1351+ corr_raw = (u64)ktime_to_ns(ktime_sub(ts->sys_monoraw, history->monoraw));
12841352 ret = scale64_check_overflow(partial_history_cycles,
12851353 total_history_cycles, &corr_raw);
12861354 if (ret)
@@ -1288,30 +1356,29 @@ static int adjust_historical_crosststamp(struct system_time_snapshot *history, · 1 unmodified line
12881356
12891357 /*
12901358 * If there is a discontinuity in the history, scale monotonic raw
1291− * correction by:
1292− * mult(real)/mult(raw) yielding the realtime correction
1293− * Otherwise, calculate the realtime correction similar to monotonic
1294− * raw calculation
1359+ * correction by:
1360+ * mult(sys)/mult(raw) yielding the system time correction
1361+ *
1362+ * Otherwise, calculate the system time correction similar to monotonic
1363+ * raw calculation
12951364 */
12961365 if (discontinuity) {
1297− corr_real = mul_u64_u32_div
1298− (corr_raw, tk->tkr_mono.mult, tk->tkr_raw.mult);
1366+ corr_sys = mul_u64_u32_div(corr_raw, tk->tkr_mono.mult, tk->tkr_raw.mult);
12991367 } else {
1300− corr_real = (u64)ktime_to_ns(
1301− ktime_sub(ts->sys_realtime, history->real));
1302− ret = scale64_check_overflow(partial_history_cycles,
1303− total_history_cycles, &corr_real);
1368+ corr_sys = (u64)ktime_to_ns(ktime_sub(ts->sys_systime, history->systime));
1369+ ret = scale64_check_overflow(partial_history_cycles, total_history_cycles,
1370+ &corr_sys);
13041371 if (ret)
13051372 return ret;
13061373 }
13071374
1308− /* Fixup monotonic raw and real time time values */
1375+ /* Fixup monotonic raw and system time time values */
13091376 if (interp_forward) {
1310− ts->sys_monoraw = ktime_add_ns(history->raw, corr_raw);
1311− ts->sys_realtime = ktime_add_ns(history->real, corr_real);
1377+ ts->sys_monoraw = ktime_add_ns(history->monoraw, corr_raw);
1378+ ts->sys_systime = ktime_add_ns(history->systime, corr_sys);
13121379 } else {
13131380 ts->sys_monoraw = ktime_sub_ns(ts->sys_monoraw, corr_raw);
1314− ts->sys_realtime = ktime_sub_ns(ts->sys_realtime, corr_real);
1381+ ts->sys_systime = ktime_sub_ns(ts->sys_systime, corr_sys);
13151382 }
13161383
13171384 return 0;
@@ -1368,6 +1435,8 @@ static bool convert_base_to_cs(struct system_counterval_t *scv) · 50 unmodified lines
13681435 return false;
13691436
13701437 scv->cycles += base->offset;
1438+ /* Set the clocksource ID as scv::cycles is now clocksource based */
1439+ scv->cs_id = cs->id;
13711440 return true;
13721441 }
13731442
@@ -1435,11 +1504,11 @@ EXPORT_SYMBOL_GPL(ktime_real_to_base_clock); · 61 unmodified lines
14351504
14361505 /**
14371506 * get_device_system_crosststamp - Synchronously capture system/device timestamp
1438− * @get_time_fn: Callback to get simultaneous device time and
1439− * system counter from the device driver
1507+ * @get_time_fn: Callback to get simultaneous device time and system counter
1508+ * from the device driver
14401509 * @ctx: Context passed to get_time_fn()
1441− * @history_begin: Historical reference point used to interpolate system
1442− * time when counter provided by the driver is before the current interval
1510+ * @history_begin: Historical reference point used to interpolate system time when
1511+ * the counter value provided by the driver is before the current interval
14431512 * @xtstamp: Receives simultaneously captured system and device time
14441513 *
14451514 * Reads a timestamp from a device and correlates it to system time
@@ -1452,36 +1521,54 @@ int get_device_system_crosststamp(int (*get_time_fn) · 6 unmodified lines
14521521 struct system_time_snapshot *history_begin,
14531522 struct system_device_crosststamp *xtstamp)
14541523 {
1455− struct system_counterval_t system_counterval = {};
1456− struct timekeeper *tk = &tk_core.timekeeper;
1457− u64 cycles, now, interval_start;
1458− unsigned int clock_was_set_seq = 0;
1459− ktime_t base_real, base_raw;
1460− u64 nsec_real, nsec_raw;
1524+ u64 syscnt_cycles, cycles, now, interval_start;
1525+ unsigned int seq, clock_was_set_seq = 0;
1526+ ktime_t base_sys, base_raw, *offs;
1527+ u64 nsec_sys, nsec_raw;
14611528 u8 cs_was_changed_seq;
1462− unsigned int seq;
14631529 bool do_interp;
1530+ struct timekeeper *tk;
1531+ struct tk_data *tkd;
14641532 int ret;
14651533
1534+ switch (xtstamp->clock_id) {
1535+ case CLOCK_REALTIME:
1536+ tkd = &tk_core;
1537+ offs = &tk_core.timekeeper.offs_real;
1538+ break;
1539+ case CLOCK_AUX ... CLOCK_AUX_LAST:
1540+ tkd = aux_get_tk_data(xtstamp->clock_id);
1541+ if (!tkd)
1542+ return -ENODEV;
1543+ offs = &tkd->timekeeper.offs_aux;
1544+ break;
1545+ default:
1546+ WARN_ON_ONCE(1);
1547+ return -ENODEV;
1548+ }
1549+
1550+ tk = &tkd->timekeeper;
1551+
14661552 do {
1467− seq = read_seqcount_begin(&tk_core.seq);
1553+ seq = read_seqcount_begin(&tkd->seq);
14681554 /*
14691555 * Try to synchronously capture device time and a system
14701556 * counter value calling back into the device driver
14711557 */
1472− ret = get_time_fn(&xtstamp->device, &system_counterval, ctx);
1558+ ret = get_time_fn(&xtstamp->device, &xtstamp->sys_counter, ctx);
14731559 if (ret)
14741560 return ret;
14751561
14761562 /*
14771563 * Verify that the clocksource ID associated with the captured
14781564 * system counter value is the same as for the currently
1479− * installed timekeeper clocksource
1565+ * installed timekeeper clocksource and convert to it.
14801566 */
1481− if (system_counterval.cs_id == CSID_GENERIC ||
1482− !convert_base_to_cs(&system_counterval))
1567+ if (xtstamp->sys_counter.cs_id == CSID_GENERIC ||
1568+ !convert_base_to_cs(&xtstamp->sys_counter))
14831569 return -ENODEV;
1484− cycles = system_counterval.cycles;
1570+
1571+ cycles = syscnt_cycles = xtstamp->sys_counter.cycles;
14851572
14861573 /*
14871574 * Check whether the system counter value provided by the
@@ -1498,15 +1585,14 @@ int get_device_system_crosststamp(int (*get_time_fn) · 10 unmodified lines
14981585 do_interp = false;
14991586 }
15001587
1501− base_real = ktime_add(tk->tkr_mono.base,
1502− tk_core.timekeeper.offs_real);
1588+ base_sys = ktime_add(tk->tkr_mono.base, *offs);
15031589 base_raw = tk->tkr_raw.base;
15041590
1505− nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, cycles);
1591+ nsec_sys = timekeeping_cycles_to_ns(&tk->tkr_mono, cycles);
15061592 nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, cycles);
1507− } while (read_seqcount_retry(&tk_core.seq, seq));
1593+ } while (read_seqcount_retry(&tkd->seq, seq));
15081594
1509− xtstamp->sys_realtime = ktime_add_ns(base_real, nsec_real);
1595+ xtstamp->sys_systime = ktime_add_ns(base_sys, nsec_sys);
15101596 xtstamp->sys_monoraw = ktime_add_ns(base_raw, nsec_raw);
15111597
15121598 /*
@@ -1523,24 +1609,19 @@ int get_device_system_crosststamp(int (*get_time_fn) · 10 unmodified lines
15231609 * clocksource change
15241610 */
15251611 if (!history_begin ||
1526− !timestamp_in_interval(history_begin->cycles,
1527− cycles, system_counterval.cycles) ||
1612+ !timestamp_in_interval(history_begin->cycles, cycles, syscnt_cycles) ||
15281613 history_begin->cs_was_changed_seq != cs_was_changed_seq)
15291614 return -EINVAL;
1530− partial_history_cycles = cycles - system_counterval.cycles;
1615+
1616+ partial_history_cycles = cycles - syscnt_cycles;
15311617 total_history_cycles = cycles - history_begin->cycles;
1532− discontinuity =
1533− history_begin->clock_was_set_seq != clock_was_set_seq;
1618+ discontinuity = history_begin->clock_was_set_seq != clock_was_set_seq;
15341619
1535− ret = adjust_historical_crosststamp(history_begin,
1536− partial_history_cycles,
1537− total_history_cycles,
1538− discontinuity, xtstamp);
1539− if (ret)
1540− return ret;
1620+ ret = adjust_historical_crosststamp(history_begin, partial_history_cycles,
1621+ total_history_cycles, discontinuity, xtstamp);
15411622 }
15421623
1543− return 0;
1624+ return ret;
15441625 }
15451626 EXPORT_SYMBOL_GPL(get_device_system_crosststamp);
15461627
sound/hda/common/controller.c+2−2
@@ -491,9 +491,9 @@ static int azx_get_time_info(struct snd_pcm_substream *substream, · 490 unmodified lines
491491 struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
492492 struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
493493 {
494+ struct system_device_crosststamp xtstamp = { .clock_id = CLOCK_REALTIME };
494495 struct azx_dev *azx_dev = get_azx_dev(substream);
495496 struct snd_pcm_runtime *runtime = substream->runtime;
496− struct system_device_crosststamp xtstamp;
497497 int ret;
498498 u64 nsec;
499499
@@ -527,7 +527,7 @@ static int azx_get_time_info(struct snd_pcm_substream *substream, · 27 unmodified lines
527527 break;
528528
529529 default:
530− *system_ts = ktime_to_timespec64(xtstamp.sys_realtime);
530+ *system_ts = ktime_to_timespec64(xtstamp.sys_systime);
531531 break;
532532
533533 }

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