mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
timekeeping: Add system_counterval_t to struct system_device_crosststamp
An upcoming extension to the PTP IOCTL requires to return the system counter value and the clocksource ID to user space. get_device_system_crosststamp() has this information already. Extend struct system_device_crosststamp with a system_counterval_t member and fill in the data. Signed-off-by: Thomas Gleixner <tglx@kernel.org> Tested-by: David Woodhouse <dwmw@amazon.co.uk> Tested-by: Arthur Kiyanovski <akiyano@amazon.com> Reviewed-by: David Woodhouse <dwmw@amazon.co.uk> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260529195557.429406675@kernel.org
This commit is contained in:
@@ -296,19 +296,6 @@ struct system_time_snapshot {
|
||||
u8 valid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct system_device_crosststamp - system/device cross-timestamp
|
||||
* (synchronized capture)
|
||||
* @device: Device time
|
||||
* @sys_realtime: Realtime simultaneous with device time
|
||||
* @sys_monoraw: Monotonic raw simultaneous with device time
|
||||
*/
|
||||
struct system_device_crosststamp {
|
||||
ktime_t device;
|
||||
ktime_t sys_realtime;
|
||||
ktime_t sys_monoraw;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct system_counterval_t - system counter value with the ID of the
|
||||
* corresponding clocksource
|
||||
@@ -325,6 +312,21 @@ struct system_counterval_t {
|
||||
bool use_nsecs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct system_device_crosststamp - system/device cross-timestamp
|
||||
* (synchronized capture)
|
||||
* @device: Device time
|
||||
* @sys_counter: Clocksource counter value simultaneous with device time
|
||||
* @sys_realtime: Realtime simultaneous with device time
|
||||
* @sys_monoraw: Monotonic raw simultaneous with device time
|
||||
*/
|
||||
struct system_device_crosststamp {
|
||||
ktime_t device;
|
||||
struct system_counterval_t sys_counter;
|
||||
ktime_t sys_realtime;
|
||||
ktime_t sys_monoraw;
|
||||
};
|
||||
|
||||
extern bool ktime_real_to_base_clock(ktime_t treal,
|
||||
enum clocksource_ids base_id, u64 *cycles);
|
||||
extern bool timekeeping_clocksource_has_base(enum clocksource_ids id);
|
||||
|
||||
@@ -1418,6 +1418,8 @@ static bool convert_base_to_cs(struct system_counterval_t *scv)
|
||||
return false;
|
||||
|
||||
scv->cycles += base->offset;
|
||||
/* Set the clocksource ID as scv::cycles is now clocksource based */
|
||||
scv->cs_id = cs->id;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1485,11 +1487,11 @@ EXPORT_SYMBOL_GPL(ktime_real_to_base_clock);
|
||||
|
||||
/**
|
||||
* get_device_system_crosststamp - Synchronously capture system/device timestamp
|
||||
* @get_time_fn: Callback to get simultaneous device time and
|
||||
* system counter from the device driver
|
||||
* @get_time_fn: Callback to get simultaneous device time and system counter
|
||||
* from the device driver
|
||||
* @ctx: Context passed to get_time_fn()
|
||||
* @history_begin: Historical reference point used to interpolate system
|
||||
* time when counter provided by the driver is before the current interval
|
||||
* @history_begin: Historical reference point used to interpolate system time when
|
||||
* the counter value provided by the driver is before the current interval
|
||||
* @xtstamp: Receives simultaneously captured system and device time
|
||||
*
|
||||
* Reads a timestamp from a device and correlates it to system time
|
||||
@@ -1502,14 +1504,12 @@ int get_device_system_crosststamp(int (*get_time_fn)
|
||||
struct system_time_snapshot *history_begin,
|
||||
struct system_device_crosststamp *xtstamp)
|
||||
{
|
||||
struct system_counterval_t system_counterval = {};
|
||||
u64 syscnt_cycles, cycles, now, interval_start;
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
u64 cycles, now, interval_start;
|
||||
unsigned int clock_was_set_seq = 0;
|
||||
unsigned int seq, clock_was_set_seq = 0;
|
||||
ktime_t base_real, base_raw;
|
||||
u64 nsec_real, nsec_raw;
|
||||
u8 cs_was_changed_seq;
|
||||
unsigned int seq;
|
||||
bool do_interp;
|
||||
int ret;
|
||||
|
||||
@@ -1519,19 +1519,20 @@ int get_device_system_crosststamp(int (*get_time_fn)
|
||||
* Try to synchronously capture device time and a system
|
||||
* counter value calling back into the device driver
|
||||
*/
|
||||
ret = get_time_fn(&xtstamp->device, &system_counterval, ctx);
|
||||
ret = get_time_fn(&xtstamp->device, &xtstamp->sys_counter, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Verify that the clocksource ID associated with the captured
|
||||
* system counter value is the same as for the currently
|
||||
* installed timekeeper clocksource
|
||||
* installed timekeeper clocksource and convert to it.
|
||||
*/
|
||||
if (system_counterval.cs_id == CSID_GENERIC ||
|
||||
!convert_base_to_cs(&system_counterval))
|
||||
if (xtstamp->sys_counter.cs_id == CSID_GENERIC ||
|
||||
!convert_base_to_cs(&xtstamp->sys_counter))
|
||||
return -ENODEV;
|
||||
cycles = system_counterval.cycles;
|
||||
|
||||
cycles = syscnt_cycles = xtstamp->sys_counter.cycles;
|
||||
|
||||
/*
|
||||
* Check whether the system counter value provided by the
|
||||
@@ -1573,24 +1574,19 @@ int get_device_system_crosststamp(int (*get_time_fn)
|
||||
* clocksource change
|
||||
*/
|
||||
if (!history_begin ||
|
||||
!timestamp_in_interval(history_begin->cycles,
|
||||
cycles, system_counterval.cycles) ||
|
||||
!timestamp_in_interval(history_begin->cycles, cycles, syscnt_cycles) ||
|
||||
history_begin->cs_was_changed_seq != cs_was_changed_seq)
|
||||
return -EINVAL;
|
||||
partial_history_cycles = cycles - system_counterval.cycles;
|
||||
total_history_cycles = cycles - history_begin->cycles;
|
||||
discontinuity =
|
||||
history_begin->clock_was_set_seq != clock_was_set_seq;
|
||||
|
||||
ret = adjust_historical_crosststamp(history_begin,
|
||||
partial_history_cycles,
|
||||
total_history_cycles,
|
||||
discontinuity, xtstamp);
|
||||
if (ret)
|
||||
return ret;
|
||||
partial_history_cycles = cycles - syscnt_cycles;
|
||||
total_history_cycles = cycles - history_begin->cycles;
|
||||
discontinuity = history_begin->clock_was_set_seq != clock_was_set_seq;
|
||||
|
||||
ret = adjust_historical_crosststamp(history_begin, partial_history_cycles,
|
||||
total_history_cycles, discontinuity, xtstamp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_device_system_crosststamp);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user