mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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()
...
This commit is contained in:
@@ -51,8 +51,8 @@ static void __hyp_clock_work(struct work_struct *work)
|
||||
|
||||
hyp_clock = container_of(dwork, struct hyp_trace_clock, work);
|
||||
|
||||
ktime_get_snapshot(&snap);
|
||||
boot = ktime_to_ns(snap.boot);
|
||||
ktime_get_snapshot_id(CLOCK_BOOTTIME, &snap);
|
||||
boot = ktime_to_ns(snap.systime);
|
||||
|
||||
delta_boot = boot - hyp_clock->boot;
|
||||
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
|
||||
hyp_clock->running = false;
|
||||
}
|
||||
|
||||
ktime_get_snapshot(&snap);
|
||||
ktime_get_snapshot_id(CLOCK_BOOTTIME, &snap);
|
||||
|
||||
hyp_clock->boot = ktime_to_ns(snap.boot);
|
||||
hyp_clock->boot = ktime_to_ns(snap.systime);
|
||||
hyp_clock->cycles = snap.cycles;
|
||||
hyp_clock->mult = 0;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
|
||||
* system time and counter value must captured at the same
|
||||
* time to keep consistency and precision.
|
||||
*/
|
||||
ktime_get_snapshot(&systime_snapshot);
|
||||
ktime_get_snapshot_id(CLOCK_REALTIME, &systime_snapshot);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
* in the future (about 292 years from 1970, and at that stage
|
||||
* nobody will give a damn about it).
|
||||
*/
|
||||
val[0] = upper_32_bits(systime_snapshot.real);
|
||||
val[1] = lower_32_bits(systime_snapshot.real);
|
||||
val[0] = upper_32_bits(systime_snapshot.systime);
|
||||
val[1] = lower_32_bits(systime_snapshot.systime);
|
||||
val[2] = upper_32_bits(cycles);
|
||||
val[3] = lower_32_bits(cycles);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,27 @@ static u64 kvm_clock_get_cycles(struct clocksource *cs)
|
||||
return kvm_clock_read();
|
||||
}
|
||||
|
||||
static u64 kvm_clock_get_cycles_snapshot(struct clocksource *cs,
|
||||
struct clocksource_hw_snapshot *chs)
|
||||
{
|
||||
struct pvclock_vcpu_time_info *src;
|
||||
unsigned version;
|
||||
u64 ret, tsc;
|
||||
|
||||
preempt_disable_notrace();
|
||||
src = this_cpu_pvti();
|
||||
do {
|
||||
version = pvclock_read_begin(src);
|
||||
tsc = rdtsc_ordered();
|
||||
ret = __pvclock_read_cycles(src, tsc);
|
||||
} while (pvclock_read_retry(src, version));
|
||||
preempt_enable_notrace();
|
||||
|
||||
chs->hw_cycles = tsc;
|
||||
chs->hw_csid = CSID_X86_TSC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinstr u64 kvm_sched_clock_read(void)
|
||||
{
|
||||
return pvclock_clocksource_read_nowd(this_cpu_pvti()) - kvm_sched_clock_offset;
|
||||
@@ -156,13 +177,14 @@ static int kvm_cs_enable(struct clocksource *cs)
|
||||
}
|
||||
|
||||
static struct clocksource kvm_clock = {
|
||||
.name = "kvm-clock",
|
||||
.read = kvm_clock_get_cycles,
|
||||
.rating = 400,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.id = CSID_X86_KVM_CLK,
|
||||
.enable = kvm_cs_enable,
|
||||
.name = "kvm-clock",
|
||||
.read = kvm_clock_get_cycles,
|
||||
.read_snapshot = kvm_clock_get_cycles_snapshot,
|
||||
.rating = 400,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.id = CSID_X86_KVM_CLK,
|
||||
.enable = kvm_cs_enable,
|
||||
};
|
||||
|
||||
static void kvm_register_clock(char *txt)
|
||||
|
||||
@@ -444,6 +444,22 @@ static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
|
||||
return read_hv_clock_tsc();
|
||||
}
|
||||
|
||||
static u64 notrace read_hv_clock_tsc_cs_snapshot(struct clocksource *arg,
|
||||
struct clocksource_hw_snapshot *chs)
|
||||
{
|
||||
u64 time;
|
||||
|
||||
if (hv_read_tsc_page_tsc(tsc_page, &chs->hw_cycles, &time)) {
|
||||
chs->hw_csid = CSID_X86_TSC;
|
||||
} else {
|
||||
chs->hw_cycles = 0;
|
||||
chs->hw_csid = CSID_GENERIC;
|
||||
time = read_hv_clock_msr();
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
static u64 noinstr read_hv_sched_clock_tsc(void)
|
||||
{
|
||||
return (read_hv_clock_tsc() - hv_sched_clock_offset) *
|
||||
@@ -492,18 +508,19 @@ static int hv_cs_enable(struct clocksource *cs)
|
||||
#endif
|
||||
|
||||
static struct clocksource hyperv_cs_tsc = {
|
||||
.name = "hyperv_clocksource_tsc_page",
|
||||
.rating = 500,
|
||||
.read = read_hv_clock_tsc_cs,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.suspend= suspend_hv_clock_tsc,
|
||||
.resume = resume_hv_clock_tsc,
|
||||
.name = "hyperv_clocksource_tsc_page",
|
||||
.rating = 500,
|
||||
.read = read_hv_clock_tsc_cs,
|
||||
.read_snapshot = read_hv_clock_tsc_cs_snapshot,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.suspend = suspend_hv_clock_tsc,
|
||||
.resume = resume_hv_clock_tsc,
|
||||
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
|
||||
.enable = hv_cs_enable,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
|
||||
.enable = hv_cs_enable,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
|
||||
#else
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_NONE,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_NONE,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -2310,10 +2310,10 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
|
||||
goto out;
|
||||
}
|
||||
|
||||
t1 = timespec64_to_ns(&ptp_sts_before.pre_ts);
|
||||
t2 = timespec64_to_ns(&ptp_sts_before.post_ts);
|
||||
t3 = timespec64_to_ns(&ptp_sts_after.pre_ts);
|
||||
t4 = timespec64_to_ns(&ptp_sts_after.post_ts);
|
||||
t1 = ktime_to_ns(ptp_sts_before.pre_sts.systime);
|
||||
t2 = ktime_to_ns(ptp_sts_before.post_sts.systime);
|
||||
t3 = ktime_to_ns(ptp_sts_after.pre_sts.systime);
|
||||
t4 = ktime_to_ns(ptp_sts_after.post_sts.systime);
|
||||
/* Mid point, corresponds to pre-reset PTPCLKVAL */
|
||||
t12 = t1 + (t2 - t1) / 2;
|
||||
/* Mid point, corresponds to post-reset PTPCLKVAL, aka 0 */
|
||||
|
||||
@@ -2065,11 +2065,13 @@ static const struct ice_crosststamp_cfg ice_crosststamp_cfg_e830 = {
|
||||
/**
|
||||
* struct ice_crosststamp_ctx - Device cross timestamp context
|
||||
* @snapshot: snapshot of system clocks for historic interpolation
|
||||
* @snapshot_clock_id: System clock ID for @snapshot
|
||||
* @pf: pointer to the PF private structure
|
||||
* @cfg: pointer to hardware configuration for cross timestamp
|
||||
*/
|
||||
struct ice_crosststamp_ctx {
|
||||
struct system_time_snapshot snapshot;
|
||||
clockid_t snapshot_clock_id;
|
||||
struct ice_pf *pf;
|
||||
const struct ice_crosststamp_cfg *cfg;
|
||||
};
|
||||
@@ -2115,7 +2117,7 @@ static int ice_capture_crosststamp(ktime_t *device,
|
||||
}
|
||||
|
||||
/* Snapshot system time for historic interpolation */
|
||||
ktime_get_snapshot(&ctx->snapshot);
|
||||
ktime_get_snapshot_id(ctx->snapshot_clock_id, &ctx->snapshot);
|
||||
|
||||
/* Program cmd to master timer */
|
||||
ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
|
||||
@@ -2176,6 +2178,7 @@ static int ice_ptp_getcrosststamp(struct ptp_clock_info *info,
|
||||
{
|
||||
struct ice_pf *pf = ptp_info_to_pf(info);
|
||||
struct ice_crosststamp_ctx ctx = {
|
||||
.snapshot_clock_id = cts->clock_id,
|
||||
.pf = pf,
|
||||
};
|
||||
|
||||
|
||||
@@ -326,6 +326,7 @@ struct igc_adapter {
|
||||
struct timespec64 prev_ptp_time; /* Pre-reset PTP clock */
|
||||
ktime_t ptp_reset_start; /* Reset time in clock mono */
|
||||
struct system_time_snapshot snapshot;
|
||||
clockid_t snapshot_clock_id;
|
||||
struct mutex ptm_lock; /* Only allow one PTM transaction at a time */
|
||||
|
||||
char fw_version[32];
|
||||
|
||||
@@ -1049,7 +1049,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
|
||||
*/
|
||||
do {
|
||||
/* Get a snapshot of system clocks to use as historic value. */
|
||||
ktime_get_snapshot(&adapter->snapshot);
|
||||
ktime_get_snapshot_id(adapter->snapshot_clock_id, &adapter->snapshot);
|
||||
|
||||
igc_ptm_trigger(hw);
|
||||
|
||||
@@ -1103,6 +1103,8 @@ static int igc_ptp_getcrosststamp(struct ptp_clock_info *ptp,
|
||||
/* This blocks until any in progress PTM transactions complete */
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
|
||||
adapter->snapshot_clock_id = cts->clock_id;
|
||||
|
||||
ret = get_device_system_crosststamp(igc_phc_get_syncdevicetime,
|
||||
adapter, &adapter->snapshot, cts);
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
|
||||
@@ -340,7 +340,7 @@ static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ktime_get_snapshot(&history_begin);
|
||||
ktime_get_snapshot_id(cts->clock_id, &history_begin);
|
||||
|
||||
err = get_device_system_crosststamp(mlx5_mtctr_syncdevicetime, mdev,
|
||||
&history_begin, cts);
|
||||
@@ -366,7 +366,7 @@ static int mlx5_ptp_getcrosscycles(struct ptp_clock_info *ptp,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ktime_get_snapshot(&history_begin);
|
||||
ktime_get_snapshot_id(cts->clock_id, &history_begin);
|
||||
|
||||
err = get_device_system_crosststamp(mlx5_mtctr_syncdevicecyclestime,
|
||||
mdev, &history_begin, cts);
|
||||
|
||||
@@ -250,7 +250,8 @@ iwl_mld_phc_get_crosstimestamp(struct ptp_clock_info *ptp,
|
||||
/* System (wall) time */
|
||||
ktime_t sys_time;
|
||||
|
||||
memset(xtstamp, 0, sizeof(struct system_device_crosststamp));
|
||||
if (xtstamp->clock_id != CLOCK_REALTIME)
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = iwl_mld_get_crosstimestamp_fw(mld, &gp2, &sys_time);
|
||||
if (ret) {
|
||||
@@ -270,7 +271,7 @@ iwl_mld_phc_get_crosstimestamp(struct ptp_clock_info *ptp,
|
||||
|
||||
/* System monotonic raw time is not used */
|
||||
xtstamp->device = ns_to_ktime(gp2_ns);
|
||||
xtstamp->sys_realtime = sys_time;
|
||||
xtstamp->sys_systime = sys_time;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -160,13 +160,14 @@ iwl_mvm_phc_get_crosstimestamp(struct ptp_clock_info *ptp,
|
||||
/* System (wall) time */
|
||||
ktime_t sys_time;
|
||||
|
||||
memset(xtstamp, 0, sizeof(struct system_device_crosststamp));
|
||||
|
||||
if (!mvm->ptp_data.ptp_clock) {
|
||||
IWL_ERR(mvm, "No PHC clock registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (xtstamp->clock_id != CLOCK_REALTIME)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SYNCED_TIME)) {
|
||||
ret = iwl_mvm_get_crosstimestamp_fw(mvm, &gp2, &sys_time);
|
||||
@@ -184,7 +185,7 @@ iwl_mvm_phc_get_crosstimestamp(struct ptp_clock_info *ptp,
|
||||
|
||||
/* System monotonic raw time is not used */
|
||||
xtstamp->device = (ktime_t)gp2_ns;
|
||||
xtstamp->sys_realtime = sys_time;
|
||||
xtstamp->sys_systime = sys_time;
|
||||
|
||||
out:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
@@ -39,11 +39,7 @@ static void pps_gen_ktimer_event(struct timer_list *unused)
|
||||
static int pps_gen_dummy_get_time(struct pps_gen_device *pps_gen,
|
||||
struct timespec64 *time)
|
||||
{
|
||||
struct system_time_snapshot snap;
|
||||
|
||||
ktime_get_snapshot(&snap);
|
||||
*time = ktime_to_timespec64(snap.real);
|
||||
|
||||
ktime_get_real_ts64(time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,11 +189,7 @@ static int pps_tio_gen_enable(struct pps_gen_device *pps_gen, bool enable)
|
||||
static int pps_tio_get_time(struct pps_gen_device *pps_gen,
|
||||
struct timespec64 *time)
|
||||
{
|
||||
struct system_time_snapshot snap;
|
||||
|
||||
ktime_get_snapshot(&snap);
|
||||
*time = ktime_to_timespec64(snap.real);
|
||||
|
||||
ktime_get_real_ts64(time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -317,8 +317,8 @@ typedef int (*ptp_crosststamp_fn)(struct ptp_clock_info *,
|
||||
static long ptp_sys_offset_precise(struct ptp_clock *ptp, void __user *arg,
|
||||
ptp_crosststamp_fn crosststamp_fn)
|
||||
{
|
||||
struct system_device_crosststamp xtstamp = { .clock_id = CLOCK_REALTIME };
|
||||
struct ptp_sys_offset_precise precise_offset;
|
||||
struct system_device_crosststamp xtstamp;
|
||||
struct timespec64 ts;
|
||||
int err;
|
||||
|
||||
@@ -333,7 +333,7 @@ static long ptp_sys_offset_precise(struct ptp_clock *ptp, void __user *arg,
|
||||
ts = ktime_to_timespec64(xtstamp.device);
|
||||
precise_offset.device.sec = ts.tv_sec;
|
||||
precise_offset.device.nsec = ts.tv_nsec;
|
||||
ts = ktime_to_timespec64(xtstamp.sys_realtime);
|
||||
ts = ktime_to_timespec64(xtstamp.sys_systime);
|
||||
precise_offset.sys_realtime.sec = ts.tv_sec;
|
||||
precise_offset.sys_realtime.nsec = ts.tv_nsec;
|
||||
ts = ktime_to_timespec64(xtstamp.sys_monoraw);
|
||||
@@ -386,15 +386,19 @@ static long ptp_sys_offset_extended(struct ptp_clock *ptp, void __user *arg,
|
||||
return err;
|
||||
|
||||
/* Filter out disabled or unavailable clocks */
|
||||
if (sts.pre_ts.tv_sec < 0 || sts.post_ts.tv_sec < 0)
|
||||
if (!sts.pre_sts.valid || !sts.post_sts.valid)
|
||||
return -EINVAL;
|
||||
|
||||
extoff->ts[i][0].sec = sts.pre_ts.tv_sec;
|
||||
extoff->ts[i][0].nsec = sts.pre_ts.tv_nsec;
|
||||
extoff->ts[i][1].sec = ts.tv_sec;
|
||||
extoff->ts[i][1].nsec = ts.tv_nsec;
|
||||
extoff->ts[i][2].sec = sts.post_ts.tv_sec;
|
||||
extoff->ts[i][2].nsec = sts.post_ts.tv_nsec;
|
||||
|
||||
ts = ktime_to_timespec64(sts.pre_sts.systime);
|
||||
extoff->ts[i][0].sec = ts.tv_sec;
|
||||
extoff->ts[i][0].nsec = ts.tv_nsec;
|
||||
|
||||
ts = ktime_to_timespec64(sts.post_sts.systime);
|
||||
extoff->ts[i][2].sec = ts.tv_sec;
|
||||
extoff->ts[i][2].nsec = ts.tv_nsec;
|
||||
}
|
||||
|
||||
return copy_to_user(arg, extoff, sizeof(*extoff)) ? -EFAULT : 0;
|
||||
|
||||
@@ -1491,11 +1491,8 @@ __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts,
|
||||
}
|
||||
ptp_read_system_postts(sts);
|
||||
|
||||
if (sts && bp->ts_window_adjust) {
|
||||
s64 ns = timespec64_to_ns(&sts->post_ts);
|
||||
|
||||
sts->post_ts = ns_to_timespec64(ns - bp->ts_window_adjust);
|
||||
}
|
||||
if (sts && bp->ts_window_adjust)
|
||||
sts->post_sts.systime -= bp->ts_window_adjust;
|
||||
|
||||
time_ns = ioread32(&bp->reg->time_ns);
|
||||
time_sec = ioread32(&bp->reg->time_sec);
|
||||
@@ -4600,8 +4597,8 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
|
||||
struct timespec64 sys_ts;
|
||||
s64 pre_ns, post_ns, ns;
|
||||
|
||||
pre_ns = timespec64_to_ns(&sts.pre_ts);
|
||||
post_ns = timespec64_to_ns(&sts.post_ts);
|
||||
pre_ns = ktime_to_ns(sts.pre_sts.systime);
|
||||
post_ns = ktime_to_ns(sts.post_sts.systime);
|
||||
ns = (pre_ns + post_ns) / 2;
|
||||
ns += (s64)bp->utc_tai_offset * NSEC_PER_SEC;
|
||||
sys_ts = ns_to_timespec64(ns);
|
||||
|
||||
+12
-17
@@ -101,7 +101,6 @@ static int vmclock_get_crosststamp(struct vmclock_state *st,
|
||||
struct timespec64 *tspec)
|
||||
{
|
||||
ktime_t deadline = ktime_add(ktime_get(), VMCLOCK_MAX_WAIT);
|
||||
struct system_time_snapshot systime_snapshot;
|
||||
uint64_t cycle, delta, seq, frac_sec;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
@@ -132,17 +131,19 @@ static int vmclock_get_crosststamp(struct vmclock_state *st,
|
||||
* will be derived from the *same* counter value.
|
||||
*
|
||||
* If the system isn't using the same counter, then the value
|
||||
* from ktime_get_snapshot() will still be used as pre_ts, and
|
||||
* ptp_read_system_postts() is called to populate postts after
|
||||
* calling get_cycles().
|
||||
*
|
||||
* The conversion to timespec64 happens further down, outside
|
||||
* the seq_count loop.
|
||||
* from ptp_read_system_prets() will still be used as pre_ts,
|
||||
* and ptp_read_system_postts() is called to populate postts
|
||||
* after calling get_cycles().
|
||||
*/
|
||||
if (sts) {
|
||||
ktime_get_snapshot(&systime_snapshot);
|
||||
if (systime_snapshot.cs_id == st->cs_id) {
|
||||
cycle = systime_snapshot.cycles;
|
||||
ptp_read_system_prets(sts);
|
||||
if (sts->pre_sts.cs_id == st->cs_id) {
|
||||
cycle = sts->pre_sts.cycles;
|
||||
sts->post_sts = sts->pre_sts;
|
||||
} else if (sts->pre_sts.hw_csid == st->cs_id &&
|
||||
sts->pre_sts.hw_cycles) {
|
||||
cycle = sts->pre_sts.hw_cycles;
|
||||
sts->post_sts = sts->pre_sts;
|
||||
} else {
|
||||
cycle = get_cycles();
|
||||
ptp_read_system_postts(sts);
|
||||
@@ -180,12 +181,6 @@ static int vmclock_get_crosststamp(struct vmclock_state *st,
|
||||
system_counter->cs_id = st->cs_id;
|
||||
}
|
||||
|
||||
if (sts) {
|
||||
sts->pre_ts = ktime_to_timespec64(systime_snapshot.real);
|
||||
if (systime_snapshot.cs_id == st->cs_id)
|
||||
sts->post_ts = sts->pre_ts;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -272,7 +267,7 @@ static int ptp_vmclock_getcrosststamp(struct ptp_clock_info *ptp,
|
||||
if (ret == -ENODEV) {
|
||||
struct system_time_snapshot systime_snapshot;
|
||||
|
||||
ktime_get_snapshot(&systime_snapshot);
|
||||
ktime_get_snapshot_id(CLOCK_REALTIME, &systime_snapshot);
|
||||
|
||||
if (systime_snapshot.cs_id == CSID_X86_TSC ||
|
||||
systime_snapshot.cs_id == CSID_X86_KVM_CLK) {
|
||||
|
||||
@@ -139,7 +139,7 @@ static int viortc_ptp_getcrosststamp(struct ptp_clock_info *ptp,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ktime_get_snapshot(&history_begin);
|
||||
ktime_get_snapshot_id(xtstamp->clock_id, &history_begin);
|
||||
if (history_begin.cs_id != cs_id)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
|
||||
@@ -31,6 +31,21 @@ struct module;
|
||||
|
||||
#include <vdso/clocksource.h>
|
||||
|
||||
/**
|
||||
* struct clocksource_hw_snapshot - Snapshot for the underlying hardware counter of derived
|
||||
* clocksources like kvmclock or Hyper-V scaled TSC
|
||||
* @hw_cycles: The hardware counter value
|
||||
* @hw_csid: Clocksource ID of the hardware counter
|
||||
*
|
||||
* Such clocksources must implement the read_snapshot() callback and fill in the
|
||||
* hardware counter value, the clocksource ID of the hardware counter and derive
|
||||
* the actual clocksource cycles from @hw_cycles to provide an atomic snapshot
|
||||
*/
|
||||
struct clocksource_hw_snapshot {
|
||||
u64 hw_cycles;
|
||||
enum clocksource_ids hw_csid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clocksource - hardware abstraction for a free running counter
|
||||
* Provides mostly state-free accessors to the underlying hardware.
|
||||
@@ -72,6 +87,14 @@ struct module;
|
||||
* @flags: Flags describing special properties
|
||||
* @base: Hardware abstraction for clock on which a clocksource
|
||||
* is based
|
||||
* @read_snapshot: Extended @read() function for clocksources such as
|
||||
* kvmclock or the Hyper-V scaled TSC where the actual
|
||||
* clocksource value for timekeeping is calculated from an
|
||||
* underlying hardware counter. Returns the timekeeping
|
||||
* relevant cycle value and stores the raw value of the
|
||||
* underlying counter from which it was calculated
|
||||
* including the clocksource ID of that counter in the
|
||||
* clocksource hardware snapshot.
|
||||
* @enable: Optional function to enable the clocksource
|
||||
* @disable: Optional function to disable the clocksource
|
||||
* @suspend: Optional suspend function for the clocksource
|
||||
@@ -113,6 +136,7 @@ struct clocksource {
|
||||
unsigned long flags;
|
||||
struct clocksource_base *base;
|
||||
|
||||
u64 (*read_snapshot)(struct clocksource *cs, struct clocksource_hw_snapshot *chs);
|
||||
int (*enable)(struct clocksource *cs);
|
||||
void (*disable)(struct clocksource *cs);
|
||||
void (*suspend)(struct clocksource *cs);
|
||||
|
||||
@@ -99,12 +99,14 @@ static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
|
||||
|
||||
static inline void pps_get_ts(struct pps_event_time *ts)
|
||||
{
|
||||
#ifdef CONFIG_NTP_PPS
|
||||
struct system_time_snapshot snap;
|
||||
|
||||
ktime_get_snapshot(&snap);
|
||||
ts->ts_real = ktime_to_timespec64(snap.real);
|
||||
#ifdef CONFIG_NTP_PPS
|
||||
ts->ts_raw = ktime_to_timespec64(snap.raw);
|
||||
ktime_get_snapshot_id(CLOCK_REALTIME, &snap);
|
||||
ts->ts_real = ktime_to_timespec64(snap.systime);
|
||||
ts->ts_raw = ktime_to_timespec64(snap.monoraw);
|
||||
#else
|
||||
ktime_get_real_ts64(&ts->ts_real);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/pps_kernel.h>
|
||||
#include <linux/ptp_clock.h>
|
||||
#include <linux/timecounter.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#define PTP_CLOCK_NAME_LEN 32
|
||||
@@ -45,13 +46,13 @@ struct system_device_crosststamp;
|
||||
|
||||
/**
|
||||
* struct ptp_system_timestamp - system time corresponding to a PHC timestamp
|
||||
* @pre_ts: system timestamp before capturing PHC
|
||||
* @post_ts: system timestamp after capturing PHC
|
||||
* @clockid: clock-base used for capturing the system timestamps
|
||||
* @pre_sts: system time snapshot before capturing PHC
|
||||
* @post_sts: system time snapshot after capturing PHC
|
||||
* @clockid: clock-base used for capturing the system timestamps
|
||||
*/
|
||||
struct ptp_system_timestamp {
|
||||
struct timespec64 pre_ts;
|
||||
struct timespec64 post_ts;
|
||||
struct system_time_snapshot pre_sts;
|
||||
struct system_time_snapshot post_sts;
|
||||
clockid_t clockid;
|
||||
};
|
||||
|
||||
@@ -510,13 +511,13 @@ static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp,
|
||||
static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts)
|
||||
{
|
||||
if (sts)
|
||||
ktime_get_clock_ts64(sts->clockid, &sts->pre_ts);
|
||||
ktime_get_snapshot_id(sts->clockid, &sts->pre_sts);
|
||||
}
|
||||
|
||||
static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
|
||||
{
|
||||
if (sts)
|
||||
ktime_get_clock_ts64(sts->clockid, &sts->post_ts);
|
||||
ktime_get_snapshot_id(sts->clockid, &sts->post_sts);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user