Skip to content

Commit 80a76c6

Browse files
committed
Merge tag 'timers-ptp-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull clocksource updates from Thomas Gleixner: "Updates for timekeeping and PTP core. The cross-timestamp mechanism which allows to correlate hardware clocks uses clocksource pointers for describing the correlation. That's suboptimal as drivers need to obtain the pointer, which requires needless exports and exposing internals. This can all be completely avoided by assigning clocksource IDs and using them for describing the correlated clock source. So this adds clocksource IDs to all clocksources in the tree which can be exposed to this mechanism and removes the pointer and now needless exports. A related improvement for the core and the correlation handling has not made it this time, but is expected to get ready for the next round" * tag 'timers-ptp-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: kvmclock: Unexport kvmclock clocksource treewide: Remove system_counterval_t.cs, which is never read timekeeping: Evaluate system_counterval_t.cs_id instead of .cs ptp/kvm, arm_arch_timer: Set system_counterval_t.cs_id to constant x86/kvm, ptp/kvm: Add clocksource ID, set system_counterval_t.cs_id x86/tsc: Add clocksource ID, set system_counterval_t.cs_id timekeeping: Add clocksource ID to struct system_counterval_t x86/tsc: Correct kernel-doc notation
2 parents 397935e + 27f6a9c commit 80a76c6

File tree

10 files changed

+47
-39
lines changed

10 files changed

+47
-39
lines changed

arch/x86/include/asm/kvmclock.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include <linux/percpu.h>
66

7-
extern struct clocksource kvm_clock;
8-
97
DECLARE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
108

119
static __always_inline struct pvclock_vcpu_time_info *this_cpu_pvti(void)

arch/x86/kernel/kvmclock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ static int kvm_cs_enable(struct clocksource *cs)
154154
return 0;
155155
}
156156

157-
struct clocksource kvm_clock = {
157+
static struct clocksource kvm_clock = {
158158
.name = "kvm-clock",
159159
.read = kvm_clock_get_cycles,
160160
.rating = 400,
161161
.mask = CLOCKSOURCE_MASK(64),
162162
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
163+
.id = CSID_X86_KVM_CLK,
163164
.enable = kvm_cs_enable,
164165
};
165-
EXPORT_SYMBOL_GPL(kvm_clock);
166166

167167
static void kvm_register_clock(char *txt)
168168
{

arch/x86/kernel/tsc.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static int __read_mostly tsc_force_recalibrate;
5353
static u32 art_to_tsc_numerator;
5454
static u32 art_to_tsc_denominator;
5555
static u64 art_to_tsc_offset;
56-
static struct clocksource *art_related_clocksource;
56+
static bool have_art;
5757

5858
struct cyc2ns {
5959
struct cyc2ns_data data[2]; /* 0 + 2*16 = 32 */
@@ -652,7 +652,7 @@ static unsigned long quick_pit_calibrate(void)
652652
}
653653

654654
/**
655-
* native_calibrate_tsc
655+
* native_calibrate_tsc - determine TSC frequency
656656
* Determine TSC frequency via CPUID, else return 0.
657657
*/
658658
unsigned long native_calibrate_tsc(void)
@@ -1168,6 +1168,7 @@ static struct clocksource clocksource_tsc_early = {
11681168
.mask = CLOCKSOURCE_MASK(64),
11691169
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
11701170
CLOCK_SOURCE_MUST_VERIFY,
1171+
.id = CSID_X86_TSC_EARLY,
11711172
.vdso_clock_mode = VDSO_CLOCKMODE_TSC,
11721173
.enable = tsc_cs_enable,
11731174
.resume = tsc_resume,
@@ -1190,6 +1191,7 @@ static struct clocksource clocksource_tsc = {
11901191
CLOCK_SOURCE_VALID_FOR_HRES |
11911192
CLOCK_SOURCE_MUST_VERIFY |
11921193
CLOCK_SOURCE_VERIFY_PERCPU,
1194+
.id = CSID_X86_TSC,
11931195
.vdso_clock_mode = VDSO_CLOCKMODE_TSC,
11941196
.enable = tsc_cs_enable,
11951197
.resume = tsc_resume,
@@ -1309,8 +1311,10 @@ struct system_counterval_t convert_art_to_tsc(u64 art)
13091311
do_div(tmp, art_to_tsc_denominator);
13101312
res += tmp + art_to_tsc_offset;
13111313

1312-
return (struct system_counterval_t) {.cs = art_related_clocksource,
1313-
.cycles = res};
1314+
return (struct system_counterval_t) {
1315+
.cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
1316+
.cycles = res,
1317+
};
13141318
}
13151319
EXPORT_SYMBOL(convert_art_to_tsc);
13161320

@@ -1327,12 +1331,10 @@ EXPORT_SYMBOL(convert_art_to_tsc);
13271331
* that this flag is set before conversion to TSC is attempted.
13281332
*
13291333
* Return:
1330-
* struct system_counterval_t - system counter value with the pointer to the
1331-
* corresponding clocksource
1332-
* @cycles: System counter value
1333-
* @cs: Clocksource corresponding to system counter value. Used
1334-
* by timekeeping code to verify comparability of two cycle
1335-
* values.
1334+
* struct system_counterval_t - system counter value with the ID of the
1335+
* corresponding clocksource:
1336+
* cycles: System counter value
1337+
* cs_id: The clocksource ID for validating comparability
13361338
*/
13371339

13381340
struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
@@ -1347,8 +1349,10 @@ struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
13471349
do_div(tmp, USEC_PER_SEC);
13481350
res += tmp;
13491351

1350-
return (struct system_counterval_t) { .cs = art_related_clocksource,
1351-
.cycles = res};
1352+
return (struct system_counterval_t) {
1353+
.cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
1354+
.cycles = res,
1355+
};
13521356
}
13531357
EXPORT_SYMBOL(convert_art_ns_to_tsc);
13541358

@@ -1357,7 +1361,7 @@ static void tsc_refine_calibration_work(struct work_struct *work);
13571361
static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
13581362
/**
13591363
* tsc_refine_calibration_work - Further refine tsc freq calibration
1360-
* @work - ignored.
1364+
* @work: ignored.
13611365
*
13621366
* This functions uses delayed work over a period of a
13631367
* second to further refine the TSC freq value. Since this is
@@ -1455,7 +1459,7 @@ static void tsc_refine_calibration_work(struct work_struct *work)
14551459
goto unreg;
14561460

14571461
if (boot_cpu_has(X86_FEATURE_ART))
1458-
art_related_clocksource = &clocksource_tsc;
1462+
have_art = true;
14591463
clocksource_register_khz(&clocksource_tsc, tsc_khz);
14601464
unreg:
14611465
clocksource_unregister(&clocksource_tsc_early);
@@ -1481,7 +1485,7 @@ static int __init init_tsc_clocksource(void)
14811485
*/
14821486
if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
14831487
if (boot_cpu_has(X86_FEATURE_ART))
1484-
art_related_clocksource = &clocksource_tsc;
1488+
have_art = true;
14851489
clocksource_register_khz(&clocksource_tsc, tsc_khz);
14861490
clocksource_unregister(&clocksource_tsc_early);
14871491

drivers/clocksource/arm_arch_timer.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ TIMER_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
18071807
#endif
18081808

18091809
int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *ts,
1810-
struct clocksource **cs)
1810+
enum clocksource_ids *cs_id)
18111811
{
18121812
struct arm_smccc_res hvc_res;
18131813
u32 ptp_counter;
@@ -1831,8 +1831,8 @@ int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *ts,
18311831
*ts = ktime_to_timespec64(ktime);
18321832
if (cycle)
18331833
*cycle = (u64)hvc_res.a2 << 32 | hvc_res.a3;
1834-
if (cs)
1835-
*cs = &clocksource_counter;
1834+
if (cs_id)
1835+
*cs_id = CSID_ARM_ARCH_COUNTER;
18361836

18371837
return 0;
18381838
}

drivers/ptp/ptp_kvm_common.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ static int ptp_kvm_get_time_fn(ktime_t *device_time,
2828
struct system_counterval_t *system_counter,
2929
void *ctx)
3030
{
31-
long ret;
32-
u64 cycle;
31+
enum clocksource_ids cs_id;
3332
struct timespec64 tspec;
34-
struct clocksource *cs;
33+
u64 cycle;
34+
int ret;
3535

3636
spin_lock(&kvm_ptp_lock);
3737

3838
preempt_disable_notrace();
39-
ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs);
39+
ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs_id);
4040
if (ret) {
4141
spin_unlock(&kvm_ptp_lock);
4242
preempt_enable_notrace();
@@ -46,7 +46,7 @@ static int ptp_kvm_get_time_fn(ktime_t *device_time,
4646
preempt_enable_notrace();
4747

4848
system_counter->cycles = cycle;
49-
system_counter->cs = cs;
49+
system_counter->cs_id = cs_id;
5050

5151
*device_time = timespec64_to_ktime(tspec);
5252

drivers/ptp/ptp_kvm_x86.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int kvm_arch_ptp_get_clock(struct timespec64 *ts)
9393
}
9494

9595
int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *tspec,
96-
struct clocksource **cs)
96+
enum clocksource_ids *cs_id)
9797
{
9898
struct pvclock_vcpu_time_info *src;
9999
unsigned int version;
@@ -123,7 +123,7 @@ int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *tspec,
123123
*cycle = __pvclock_read_cycles(src, clock_pair->tsc);
124124
} while (pvclock_read_retry(src, version));
125125

126-
*cs = &kvm_clock;
126+
*cs_id = CSID_X86_KVM_CLK;
127127

128128
return 0;
129129
}

include/linux/clocksource_ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
enum clocksource_ids {
77
CSID_GENERIC = 0,
88
CSID_ARM_ARCH_COUNTER,
9+
CSID_X86_TSC_EARLY,
10+
CSID_X86_TSC,
11+
CSID_X86_KVM_CLK,
912
CSID_MAX,
1013
};
1114

include/linux/ptp_kvm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
#ifndef _PTP_KVM_H_
99
#define _PTP_KVM_H_
1010

11+
#include <linux/clocksource_ids.h>
1112
#include <linux/types.h>
1213

1314
struct timespec64;
14-
struct clocksource;
1515

1616
int kvm_arch_ptp_init(void);
1717
void kvm_arch_ptp_exit(void);
1818
int kvm_arch_ptp_get_clock(struct timespec64 *ts);
1919
int kvm_arch_ptp_get_crosststamp(u64 *cycle,
20-
struct timespec64 *tspec, struct clocksource **cs);
20+
struct timespec64 *tspec, enum clocksource_ids *cs_id);
2121

2222
#endif /* _PTP_KVM_H_ */

include/linux/timekeeping.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,17 @@ struct system_device_crosststamp {
268268
};
269269

270270
/**
271-
* struct system_counterval_t - system counter value with the pointer to the
271+
* struct system_counterval_t - system counter value with the ID of the
272272
* corresponding clocksource
273273
* @cycles: System counter value
274-
* @cs: Clocksource corresponding to system counter value. Used by
275-
* timekeeping code to verify comparibility of two cycle values
274+
* @cs_id: Clocksource ID corresponding to system counter value. Used by
275+
* timekeeping code to verify comparability of two cycle values.
276+
* The default ID, CSID_GENERIC, does not identify a specific
277+
* clocksource.
276278
*/
277279
struct system_counterval_t {
278280
u64 cycles;
279-
struct clocksource *cs;
281+
enum clocksource_ids cs_id;
280282
};
281283

282284
/*

kernel/time/timekeeping.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,11 +1232,12 @@ int get_device_system_crosststamp(int (*get_time_fn)
12321232
return ret;
12331233

12341234
/*
1235-
* Verify that the clocksource associated with the captured
1236-
* system counter value is the same as the currently installed
1237-
* timekeeper clocksource
1235+
* Verify that the clocksource ID associated with the captured
1236+
* system counter value is the same as for the currently
1237+
* installed timekeeper clocksource
12381238
*/
1239-
if (tk->tkr_mono.clock != system_counterval.cs)
1239+
if (system_counterval.cs_id == CSID_GENERIC ||
1240+
tk->tkr_mono.clock->id != system_counterval.cs_id)
12401241
return -ENODEV;
12411242
cycles = system_counterval.cycles;
12421243

0 commit comments

Comments
 (0)