[PATCH v4 1/2] sched: Add sched_clock_register_new()

From: Paul Cercueil
Date: Mon Feb 10 2020 - 08:42:48 EST


The sched_clock_register_new() behaves like sched_clock_register() but
takes an extra parameter which is passed to the read callback.

Signed-off-by: Paul Cercueil <paul@xxxxxxxxxxxxxxx>
---

Notes:
v4: New patch

include/linux/sched_clock.h | 2 ++
kernel/time/sched_clock.c | 36 +++++++++++++++++++++++++-----------
2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 0bb04a96a6d4..15509487fd16 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -10,6 +10,8 @@ extern void generic_sched_clock_init(void);

extern void sched_clock_register(u64 (*read)(void), int bits,
unsigned long rate);
+extern void sched_clock_register_new(u64 (*read)(void *), int bits,
+ unsigned long rate, void *data);
#else
static inline void generic_sched_clock_init(void) { }

diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index e4332e3e2d56..9ba61814ea48 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -27,6 +27,7 @@
* @sched_clock_mask: Bitmask for two's complement subtraction of non 64bit
* clocks.
* @read_sched_clock: Current clock source (or dummy source when suspended).
+ * @data: Callback data for the current clock source.
* @mult: Multipler for scaled math conversion.
* @shift: Shift value for scaled math conversion.
*
@@ -39,7 +40,8 @@ struct clock_read_data {
u64 epoch_ns;
u64 epoch_cyc;
u64 sched_clock_mask;
- u64 (*read_sched_clock)(void);
+ u64 (*read_sched_clock)(void *);
+ void *data;
u32 mult;
u32 shift;
};
@@ -53,6 +55,7 @@ struct clock_read_data {
* @read_data: Data required to read from sched_clock.
* @wrap_kt: Duration for which clock can run before wrapping.
* @rate: Tick rate of the registered clock.
+ * @data: Callback data for the registered clock read function.
* @actual_read_sched_clock: Registered hardware level clock read function.
*
* The ordering of this structure has been chosen to optimize cache
@@ -65,7 +68,8 @@ struct clock_data {
ktime_t wrap_kt;
unsigned long rate;

- u64 (*actual_read_sched_clock)(void);
+ void *data;
+ u64 (*actual_read_sched_clock)(void *);
};

static struct hrtimer sched_clock_timer;
@@ -73,7 +77,7 @@ static int irqtime = -1;

core_param(irqtime, irqtime, int, 0400);

-static u64 notrace jiffy_sched_clock_read(void)
+static u64 notrace jiffy_sched_clock_read(void *d)
{
/*
* We don't need to use get_jiffies_64 on 32-bit arches here
@@ -103,7 +107,7 @@ unsigned long long notrace sched_clock(void)
seq = raw_read_seqcount(&cd.seq);
rd = cd.read_data + (seq & 1);

- cyc = (rd->read_sched_clock() - rd->epoch_cyc) &
+ cyc = (rd->read_sched_clock(rd->data) - rd->epoch_cyc) &
rd->sched_clock_mask;
res = rd->epoch_ns + cyc_to_ns(cyc, rd->mult, rd->shift);
} while (read_seqcount_retry(&cd.seq, seq));
@@ -147,7 +151,7 @@ static void update_sched_clock(void)

rd = cd.read_data[0];

- cyc = cd.actual_read_sched_clock();
+ cyc = cd.actual_read_sched_clock(cd.data);
ns = rd.epoch_ns + cyc_to_ns((cyc - rd.epoch_cyc) & rd.sched_clock_mask, rd.mult, rd.shift);

rd.epoch_ns = ns;
@@ -165,7 +169,8 @@ static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt)
}

void __init
-sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
+sched_clock_register_new(u64 (*read)(void *), int bits,
+ unsigned long rate, void *data)
{
u64 res, wrap, new_mask, new_epoch, cyc, ns;
u32 new_mult, new_shift;
@@ -192,12 +197,14 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
rd = cd.read_data[0];

/* Update epoch for new counter and update 'epoch_ns' from old counter*/
- new_epoch = read();
- cyc = cd.actual_read_sched_clock();
+ new_epoch = read(data);
+ cyc = cd.actual_read_sched_clock(cd.data);
ns = rd.epoch_ns + cyc_to_ns((cyc - rd.epoch_cyc) & rd.sched_clock_mask, rd.mult, rd.shift);
cd.actual_read_sched_clock = read;
+ cd.data = data;

rd.read_sched_clock = read;
+ rd.data = data;
rd.sched_clock_mask = new_mask;
rd.mult = new_mult;
rd.shift = new_shift;
@@ -239,6 +246,12 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
pr_debug("Registered %pS as sched_clock source\n", read);
}

+void __init
+sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
+{
+ sched_clock_register_new((u64 (*)(void *))read, bits, rate, NULL);
+}
+
void __init generic_sched_clock_init(void)
{
/*
@@ -246,7 +259,8 @@ void __init generic_sched_clock_init(void)
* make it the final one one.
*/
if (cd.actual_read_sched_clock == jiffy_sched_clock_read)
- sched_clock_register(jiffy_sched_clock_read, BITS_PER_LONG, HZ);
+ sched_clock_register_new(jiffy_sched_clock_read,
+ BITS_PER_LONG, HZ, NULL);

update_sched_clock();

@@ -270,7 +284,7 @@ void __init generic_sched_clock_init(void)
* at the end of the critical section to be sure we observe the
* correct copy of 'epoch_cyc'.
*/
-static u64 notrace suspended_sched_clock_read(void)
+static u64 notrace suspended_sched_clock_read(void *d)
{
unsigned int seq = raw_read_seqcount(&cd.seq);

@@ -292,7 +306,7 @@ void sched_clock_resume(void)
{
struct clock_read_data *rd = &cd.read_data[0];

- rd->epoch_cyc = cd.actual_read_sched_clock();
+ rd->epoch_cyc = cd.actual_read_sched_clock(cd.data);
hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
rd->read_sched_clock = cd.actual_read_sched_clock;
}
--
2.24.1