|
19 | 19 |
|
20 | 20 | #include "timekeeping.h"
|
21 | 21 |
|
22 |
| -/** |
23 |
| - * struct clock_read_data - data required to read from sched_clock() |
24 |
| - * |
25 |
| - * @epoch_ns: sched_clock() value at last update |
26 |
| - * @epoch_cyc: Clock cycle value at last update. |
27 |
| - * @sched_clock_mask: Bitmask for two's complement subtraction of non 64bit |
28 |
| - * clocks. |
29 |
| - * @read_sched_clock: Current clock source (or dummy source when suspended). |
30 |
| - * @mult: Multipler for scaled math conversion. |
31 |
| - * @shift: Shift value for scaled math conversion. |
32 |
| - * |
33 |
| - * Care must be taken when updating this structure; it is read by |
34 |
| - * some very hot code paths. It occupies <=40 bytes and, when combined |
35 |
| - * with the seqcount used to synchronize access, comfortably fits into |
36 |
| - * a 64 byte cache line. |
37 |
| - */ |
38 |
| -struct clock_read_data { |
39 |
| - u64 epoch_ns; |
40 |
| - u64 epoch_cyc; |
41 |
| - u64 sched_clock_mask; |
42 |
| - u64 (*read_sched_clock)(void); |
43 |
| - u32 mult; |
44 |
| - u32 shift; |
45 |
| -}; |
46 |
| - |
47 | 22 | /**
|
48 | 23 | * struct clock_data - all data needed for sched_clock() (including
|
49 | 24 | * registration of a new clock source)
|
@@ -93,20 +68,30 @@ static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
|
93 | 68 | return (cyc * mult) >> shift;
|
94 | 69 | }
|
95 | 70 |
|
| 71 | +struct clock_read_data *sched_clock_read_begin(unsigned int *seq) |
| 72 | +{ |
| 73 | + *seq = raw_read_seqcount(&cd.seq); |
| 74 | + return cd.read_data + (*seq & 1); |
| 75 | +} |
| 76 | + |
| 77 | +int sched_clock_read_retry(unsigned int seq) |
| 78 | +{ |
| 79 | + return read_seqcount_retry(&cd.seq, seq); |
| 80 | +} |
| 81 | + |
96 | 82 | unsigned long long notrace sched_clock(void)
|
97 | 83 | {
|
98 | 84 | u64 cyc, res;
|
99 | 85 | unsigned int seq;
|
100 | 86 | struct clock_read_data *rd;
|
101 | 87 |
|
102 | 88 | do {
|
103 |
| - seq = raw_read_seqcount(&cd.seq); |
104 |
| - rd = cd.read_data + (seq & 1); |
| 89 | + rd = sched_clock_read_begin(&seq); |
105 | 90 |
|
106 | 91 | cyc = (rd->read_sched_clock() - rd->epoch_cyc) &
|
107 | 92 | rd->sched_clock_mask;
|
108 | 93 | res = rd->epoch_ns + cyc_to_ns(cyc, rd->mult, rd->shift);
|
109 |
| - } while (read_seqcount_retry(&cd.seq, seq)); |
| 94 | + } while (sched_clock_read_retry(seq)); |
110 | 95 |
|
111 | 96 | return res;
|
112 | 97 | }
|
|
0 commit comments