This patch series change the 32-bit time type (timespec/itimerspec) to the 64-bit one (timespec64/itimerspec64), since 32-bit time types will break in the year 2038.
This patch series introduce new methods with timespec64/itimerspec64 type, and remove the old ones with timespec/itimerspec type for posix clock operation and k_clock structure.
Changes since v3: - Introduce the new structure 'itimerspec64' for 64bit and the conversion function. - Separate original one patch into two patches. - Remove the 32bit unused code - Re-order the patch of the patch series.
Next step will replace the other callback pointers of k_clock structure.
Baolin Wang (12): linux/time64.h:Introduce the 'struct itimerspec64' for 64bit posix_clock:Introduce the new methods with explicit 64 bit seconds timekeeping:Introduce the current_kernel_time64() function with timespec64 type time/hrtimer:Introduce hrtimer_get_res64() with timespec64 type for getting the timer resolution posix timers:Introduce the 64bit methods with timespec64 type for k_clock structure time/posix-timers:Convert to the 64bit methods for k_clock callback functions char/mmtimer:Convert to the 64bit methods for k_clock callback function time/alarmtimer:Convert to the new methods for k_clock structure time/posix-clock:Convert to the 64bit methods for k_clock structure time:Introduce the cputime_to_timespec64/timespec64_to_cputime function time/posix-cpu-timers:Convert to the 64bit methods for k_clock structure k_clock:Remove the 32bit methods with timespec type
arch/powerpc/include/asm/cputime.h | 24 +++++ arch/s390/include/asm/cputime.h | 26 ++++++ drivers/char/mmtimer.c | 38 ++++---- drivers/ptp/ptp_clock.c | 26 ++---- include/asm-generic/cputime_jiffies.h | 8 ++ include/linux/hrtimer.h | 12 ++- include/linux/jiffies.h | 3 + include/linux/posix-clock.h | 10 +-- include/linux/posix-timers.h | 18 ++-- include/linux/time64.h | 37 ++++++++ include/linux/timekeeping.h | 14 ++- kernel/time/alarmtimer.c | 43 ++++----- kernel/time/hrtimer.c | 10 +-- kernel/time/posix-clock.c | 21 ++--- kernel/time/posix-cpu-timers.c | 83 +++++++++-------- kernel/time/posix-timers.c | 159 +++++++++++++++++++-------------- kernel/time/time.c | 21 +++++ kernel/time/timekeeping.c | 6 +- kernel/time/timekeeping.h | 2 +- 19 files changed, 361 insertions(+), 200 deletions(-)
This patch introduces the 'struct itimerspec64' for 64bit to replace itimerspec, and also introduces the conversion methods: itimerspec64_to_itimerspec() and itimerspec_to_itimerspec64().
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/time64.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/linux/time64.h b/include/linux/time64.h index a383147..a6e2aa8 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -18,6 +18,11 @@ struct timespec64 { }; #endif
+struct itimerspec64 { + struct timespec64 it_interval; /* timer period */ + struct timespec64 it_value; /* timer expiration */ +}; + /* Parameters used to convert the timespec values: */ #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L @@ -43,6 +48,16 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ts; }
+static inline struct itimerspec itimerspec64_to_itimerspec(const struct itimerspec64 its64) +{ + return its64; +} + +static inline struct itimerspec64 itimerspec_to_itimerspec64(const struct itimerspec its) +{ + return its; +} + # define timespec64_equal timespec_equal # define timespec64_compare timespec_compare # define set_normalized_timespec64 set_normalized_timespec @@ -75,6 +90,28 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ret; }
+static inline struct itimerspec itimerspec64_to_itimerspec(const struct itimerspec64 its64) +{ + struct itimerspec ret; + + ret.it_interval.tv_sec = (time_t)its64.it_interval.tv_sec; + ret.it_interval.tv_nsec = its64.it_interval.tv_nsec; + ret.it_value.tv_sec = (time_t)its64.it_value.tv_sec; + ret.it_value.tv_nsec = its64.it_value.tv_nsec; + return ret; +} + +static inline struct itimerspec64 itimerspec_to_itimerspec64(const struct itimerspec its) +{ + struct itimerspec64 ret; + + ret.it_interval.tv_sec = its.it_interval.tv_sec; + ret.it_interval.tv_nsec = its.it_interval.tv_nsec; + ret.it_value.tv_sec = its.it_value.tv_sec; + ret.it_value.tv_nsec = its.it_value.tv_nsec; + return ret; +} + static inline int timespec64_equal(const struct timespec64 *a, const struct timespec64 *b) {
On Wednesday 15 April 2015 19:56:38 Baolin Wang wrote:
This patch introduces the 'struct itimerspec64' for 64bit to replace itimerspec, and also introduces the conversion methods: itimerspec64_to_itimerspec() and itimerspec_to_itimerspec64().
Signed-off-by: Baolin Wang baolin.wang@linaro.org
include/linux/time64.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/linux/time64.h b/include/linux/time64.h index a383147..a6e2aa8 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -18,6 +18,11 @@ struct timespec64 { }; #endif +struct itimerspec64 {
- struct timespec64 it_interval; /* timer period */
- struct timespec64 it_value; /* timer expiration */
+};
/* Parameters used to convert the timespec values: */ #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L
I suspect this might be broken on 64-bit machines, because this trick:
@@ -43,6 +48,16 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ts; } +static inline struct itimerspec itimerspec64_to_itimerspec(const struct itimerspec64 its64) +{
- return its64;
+}
+static inline struct itimerspec64 itimerspec_to_itimerspec64(const struct itimerspec its) +{
- return its;
+}
Does not work. Try compiling this for arm64 or x86-64, you probably need a similar trick as for timespec64.
# define timespec64_equal timespec_equal # define timespec64_compare timespec_compare # define set_normalized_timespec64 set_normalized_timespec @@ -75,6 +90,28 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ret; } +static inline struct itimerspec itimerspec64_to_itimerspec(const struct itimerspec64 its64) +{
- struct itimerspec ret;
- ret.it_interval.tv_sec = (time_t)its64.it_interval.tv_sec;
- ret.it_interval.tv_nsec = its64.it_interval.tv_nsec;
- ret.it_value.tv_sec = (time_t)its64.it_value.tv_sec;
- ret.it_value.tv_nsec = its64.it_value.tv_nsec;
- return ret;
+}
+static inline struct itimerspec64 itimerspec_to_itimerspec64(const struct itimerspec its) +{
- struct itimerspec64 ret;
- ret.it_interval.tv_sec = its.it_interval.tv_sec;
- ret.it_interval.tv_nsec = its.it_interval.tv_nsec;
- ret.it_value.tv_sec = its.it_value.tv_sec;
- ret.it_value.tv_nsec = its.it_value.tv_nsec;
- return ret;
+}
This looks good.
Arnd
This patch converts the posix clock operations over to the new methods with timespec64/itimerspec64 type to making them ready for 2038, and it is based on the ptp patch series.
The timex structure will be converted in the next patch series.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- drivers/ptp/ptp_clock.c | 26 ++++++++----------------- include/linux/posix-clock.h | 10 +++++----- kernel/time/posix-clock.c | 45 +++++++++++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index bee8270..8c086e7 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -97,32 +97,24 @@ static s32 scaled_ppm_to_ppb(long ppm)
/* posix clock implementation */
-static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) +static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp) { tp->tv_sec = 0; tp->tv_nsec = 1; return 0; }
-static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) +static int ptp_clock_settime(struct posix_clock *pc, + const struct timespec64 *tp) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - struct timespec64 ts = timespec_to_timespec64(*tp); - - return ptp->info->settime64(ptp->info, &ts); + return ptp->info->settime64(ptp->info, tp); }
-static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp) +static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - struct timespec64 ts; - int err; - - err = ptp->info->gettime64(ptp->info, &ts); - if (!err) - *tp = timespec64_to_timespec(ts); - - return err; + return ptp->info->gettime64(ptp->info, tp); }
static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) @@ -134,8 +126,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) ops = ptp->info;
if (tx->modes & ADJ_SETOFFSET) { - struct timespec ts; - ktime_t kt; + struct timespec64 ts; s64 delta;
ts.tv_sec = tx->time.tv_sec; @@ -147,8 +138,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC) return -EINVAL;
- kt = timespec_to_ktime(ts); - delta = ktime_to_ns(kt); + delta = timespec64_to_ns(&ts); err = ops->adjtime(ops, delta); } else if (tx->modes & ADJ_FREQUENCY) { s32 ppb = scaled_ppm_to_ppb(tx->freq); diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index 34c4498..fd7e22c 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -59,23 +59,23 @@ struct posix_clock_operations {
int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
- int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts); + int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
- int (*clock_getres) (struct posix_clock *pc, struct timespec *ts); + int (*clock_getres)(struct posix_clock *pc, struct timespec64 *ts);
int (*clock_settime)(struct posix_clock *pc, - const struct timespec *ts); + const struct timespec64 *ts);
int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
void (*timer_gettime)(struct posix_clock *pc, - struct k_itimer *kit, struct itimerspec *tsp); + struct k_itimer *kit, struct itimerspec64 *tsp);
int (*timer_settime)(struct posix_clock *pc, struct k_itimer *kit, int flags, - struct itimerspec *tsp, struct itimerspec *old); + struct itimerspec64 *tsp, struct itimerspec64 *old); /* * Optional character device methods: */ diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index ce033c7..fc90e98 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -300,16 +300,19 @@ out: static int pc_clock_gettime(clockid_t id, struct timespec *ts) { struct posix_clock_desc cd; + struct timespec64 *tp; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.clock_gettime) - err = cd.clk->ops.clock_gettime(cd.clk, ts); - else + if (cd.clk->ops.clock_gettime) { + *tp = timespec_to_timespec64(*ts); + err = cd.clk->ops.clock_gettime(cd.clk, tp); + } else { err = -EOPNOTSUPP; + }
put_clock_desc(&cd);
@@ -319,16 +322,19 @@ static int pc_clock_gettime(clockid_t id, struct timespec *ts) static int pc_clock_getres(clockid_t id, struct timespec *ts) { struct posix_clock_desc cd; + struct timespec64 *tp; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.clock_getres) - err = cd.clk->ops.clock_getres(cd.clk, ts); - else + if (cd.clk->ops.clock_getres) { + *tp = timespec_to_timespec64(*ts); + err = cd.clk->ops.clock_getres(cd.clk, tp); + } else { err = -EOPNOTSUPP; + }
put_clock_desc(&cd);
@@ -338,6 +344,7 @@ static int pc_clock_getres(clockid_t id, struct timespec *ts) static int pc_clock_settime(clockid_t id, const struct timespec *ts) { struct posix_clock_desc cd; + struct timespec64 tp; int err;
err = get_clock_desc(id, &cd); @@ -349,10 +356,12 @@ static int pc_clock_settime(clockid_t id, const struct timespec *ts) goto out; }
- if (cd.clk->ops.clock_settime) - err = cd.clk->ops.clock_settime(cd.clk, ts); - else + if (cd.clk->ops.clock_settime) { + tp = timespec_to_timespec64(*ts); + err = cd.clk->ops.clock_settime(cd.clk, &tp); + } else { err = -EOPNOTSUPP; + } out: put_clock_desc(&cd);
@@ -403,12 +412,15 @@ static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec *ts) { clockid_t id = kit->it_clock; struct posix_clock_desc cd; + struct itimerspec64 *ts64;
if (get_clock_desc(id, &cd)) return;
- if (cd.clk->ops.timer_gettime) - cd.clk->ops.timer_gettime(cd.clk, kit, ts); + if (cd.clk->ops.timer_gettime) { + *ts64 = itimerspec_to_itimerspec64(*ts); + cd.clk->ops.timer_gettime(cd.clk, kit, ts64); + }
put_clock_desc(&cd); } @@ -418,16 +430,21 @@ static int pc_timer_settime(struct k_itimer *kit, int flags, { clockid_t id = kit->it_clock; struct posix_clock_desc cd; + struct itimerspec64 ts64; + struct itimerspec64 *old64; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.timer_settime) - err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old); - else + if (cd.clk->ops.timer_settime) { + ts64 = itimerspec_to_itimerspec64(*ts); + *old64 = itimerspec_to_itimerspec64(*old); + err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, old64); + } else { err = -EOPNOTSUPP; + }
put_clock_desc(&cd);
This patch adds current_kernel_time64() function with timespec64 type, and makes current_kernel_time() 'static inline' and moves it to timekeeping.h file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/timekeeping.h | 10 +++++++++- kernel/time/timekeeping.c | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 3eaae47..c6d5ae9 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -18,10 +18,18 @@ extern int do_sys_settimeofday(const struct timespec *tv, * Kernel time accessors */ unsigned long get_seconds(void); -struct timespec current_kernel_time(void); +struct timespec64 current_kernel_time64(void); /* does not take xtime_lock */ struct timespec __current_kernel_time(void);
+static inline struct timespec current_kernel_time(void) +{ + struct timespec64 now; + + now = current_kernel_time64(); + return timespec64_to_timespec(now); +} + /* * timespec based interfaces */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 91db941..8ccc02c 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1721,7 +1721,7 @@ struct timespec __current_kernel_time(void) return timespec64_to_timespec(tk_xtime(tk)); }
-struct timespec current_kernel_time(void) +struct timespec64 current_kernel_time64(void) { struct timekeeper *tk = &tk_core.timekeeper; struct timespec64 now; @@ -1733,9 +1733,9 @@ struct timespec current_kernel_time(void) now = tk_xtime(tk); } while (read_seqcount_retry(&tk_core.seq, seq));
- return timespec64_to_timespec(now); + return now; } -EXPORT_SYMBOL(current_kernel_time); +EXPORT_SYMBOL(current_kernel_time64);
struct timespec64 get_monotonic_coarse64(void) {
On Wednesday 15 April 2015 19:56:40 Baolin Wang wrote:
This patch adds current_kernel_time64() function with timespec64 type, and makes current_kernel_time() 'static inline' and moves it to timekeeping.h file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
This description just repeats the subject line and what can be seen from looking at the patch. Please try to explain better /why/ the change is done.
The patch itself looks good.
Arnd
This patch introduces hrtimer_get_res64() function to get the timer resolution with timespec64 type, and moves the hrtimer_get_res() function into include/linux/hrtimer.h as a 'static inline' helper that just calls hrtimer_get_res64.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/hrtimer.h | 12 +++++++++++- kernel/time/hrtimer.c | 10 +++++----- 2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 05f6df1..ee8ed44 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -383,7 +383,17 @@ static inline int hrtimer_restart(struct hrtimer *timer)
/* Query timers: */ extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); -extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); +extern int hrtimer_get_res64(const clockid_t which_clock, + struct timespec64 *tp); + +static inline int hrtimer_get_res(const clockid_t which_clock, + struct timespec *tp) +{ + struct timespec64 *ts64; + + *ts64 = timespec_to_timespec64(*tp); + return hrtimer_get_res64(which_clock, ts64); +}
extern ktime_t hrtimer_get_next_event(void);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index bee0c1f..508d936 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1175,24 +1175,24 @@ void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, EXPORT_SYMBOL_GPL(hrtimer_init);
/** - * hrtimer_get_res - get the timer resolution for a clock + * hrtimer_get_res64 - get the timer resolution for a clock * @which_clock: which clock to query - * @tp: pointer to timespec variable to store the resolution + * @tp: pointer to timespec64 variable to store the resolution * * Store the resolution of the clock selected by @which_clock in the * variable pointed to by @tp. */ -int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) +int hrtimer_get_res64(const clockid_t which_clock, struct timespec64 *tp) { struct hrtimer_cpu_base *cpu_base; int base = hrtimer_clockid_to_base(which_clock);
cpu_base = raw_cpu_ptr(&hrtimer_bases); - *tp = ktime_to_timespec(cpu_base->clock_base[base].resolution); + *tp = ktime_to_timespec64(cpu_base->clock_base[base].resolution);
return 0; } -EXPORT_SYMBOL_GPL(hrtimer_get_res); +EXPORT_SYMBOL_GPL(hrtimer_get_res64);
static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) {
On Wednesday 15 April 2015 19:56:41 Baolin Wang wrote:
This patch introduces hrtimer_get_res64() function to get the timer resolution with timespec64 type, and moves the hrtimer_get_res() function into include/linux/hrtimer.h as a 'static inline' helper that just calls hrtimer_get_res64.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
Same comments as for patch 3.
Arnd
This patch introduces the new methods with timespec64 type for k_clcok structure, converts the timepsec type to timespec64 type in k_clock structure and converts the itimerspec type to itimerspec64 type to ready for 2038 issue.
Next step will migrate all the k_clock users to use the new methods with timespec64 type and itimerspec64 type, and it contains the files of posix-timers.c, mmtimer.c, alarmtimer.c, posix-clock.c and posix-cpu-timers.c.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/posix-timers.h | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 907f3fd..35786c5 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -98,9 +98,13 @@ struct k_itimer {
struct k_clock { int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); + int (*clock_getres64) (const clockid_t which_clock, struct timespec64 *tp); int (*clock_set) (const clockid_t which_clock, const struct timespec *tp); + int (*clock_set64) (const clockid_t which_clock, + const struct timespec64 *tp); int (*clock_get) (const clockid_t which_clock, struct timespec * tp); + int (*clock_get64) (const clockid_t which_clock, struct timespec64 *tp); int (*clock_adj) (const clockid_t which_clock, struct timex *tx); int (*timer_create) (struct k_itimer *timer); int (*nsleep) (const clockid_t which_clock, int flags, @@ -109,10 +113,15 @@ struct k_clock { int (*timer_set) (struct k_itimer * timr, int flags, struct itimerspec * new_setting, struct itimerspec * old_setting); + int (*timer_set64) (struct k_itimer *timr, int flags, + struct itimerspec64 *new_setting, + struct itimerspec64 *old_setting); int (*timer_del) (struct k_itimer * timr); #define TIMER_RETRY 1 void (*timer_get) (struct k_itimer * timr, struct itimerspec * cur_setting); + void (*timer_get64) (struct k_itimer *timr, + struct itimerspec64 *cur_setting); };
extern struct k_clock clock_posix_cpu;
This patch converts the timepsec type to timespec64 type, and converts the itimerspec type to itimerspec64 type for the k_clock callback functions.
This patch also converts the timespec type to timespec64 type for timekeeping_clocktai function which is used only in the posix-timers.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/timekeeping.h | 4 +- kernel/time/posix-timers.c | 157 +++++++++++++++++++++++++++---------------- kernel/time/timekeeping.h | 2 +- 3 files changed, 102 insertions(+), 61 deletions(-)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index c6d5ae9..bd3df93 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -242,9 +242,9 @@ static inline void get_monotonic_boottime64(struct timespec64 *ts) *ts = ktime_to_timespec64(ktime_get_boottime()); }
-static inline void timekeeping_clocktai(struct timespec *ts) +static inline void timekeeping_clocktai(struct timespec64 *ts) { - *ts = ktime_to_timespec(ktime_get_clocktai()); + *ts = ktime_to_timespec64(ktime_get_clocktai()); }
/* diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 31ea01f..fce456d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -132,9 +132,9 @@ static struct k_clock posix_clocks[MAX_CLOCKS]; static int common_nsleep(const clockid_t, int flags, struct timespec *t, struct timespec __user *rmtp); static int common_timer_create(struct k_itimer *new_timer); -static void common_timer_get(struct k_itimer *, struct itimerspec *); +static void common_timer_get(struct k_itimer *, struct itimerspec64 *); static int common_timer_set(struct k_itimer *, int, - struct itimerspec *, struct itimerspec *); + struct itimerspec64 *, struct itimerspec64 *); static int common_timer_del(struct k_itimer *timer);
static enum hrtimer_restart posix_timer_fn(struct hrtimer *data); @@ -203,17 +203,20 @@ static inline void unlock_timer(struct k_itimer *timr, unsigned long flags) }
/* Get clock_realtime */ -static int posix_clock_realtime_get(clockid_t which_clock, struct timespec *tp) +static int posix_clock_realtime_get(clockid_t which_clock, + struct timespec64 *tp) { - ktime_get_real_ts(tp); + ktime_get_real_ts64(tp); return 0; }
/* Set clock_realtime */ static int posix_clock_realtime_set(const clockid_t which_clock, - const struct timespec *tp) + const struct timespec64 *tp) { - return do_sys_settimeofday(tp, NULL); + struct timespec ts = timespec64_to_timespec(*tp); + + return do_sys_settimeofday(&ts, NULL); }
static int posix_clock_realtime_adj(const clockid_t which_clock, @@ -225,48 +228,51 @@ static int posix_clock_realtime_adj(const clockid_t which_clock, /* * Get monotonic time for posix timers */ -static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp) +static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp) { - ktime_get_ts(tp); + ktime_get_ts64(tp); return 0; }
/* * Get monotonic-raw time for posix timers */ -static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp) +static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec64 *tp) { - getrawmonotonic(tp); + getrawmonotonic64(tp); return 0; }
-static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp) +static int posix_get_realtime_coarse(clockid_t which_clock, + struct timespec64 *tp) { - *tp = current_kernel_time(); + *tp = current_kernel_time64(); return 0; }
static int posix_get_monotonic_coarse(clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { - *tp = get_monotonic_coarse(); + *tp = get_monotonic_coarse64(); return 0; }
-static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp) +static int posix_get_coarse_res(const clockid_t which_clock, + struct timespec64 *tp) { - *tp = ktime_to_timespec(KTIME_LOW_RES); + *tp = ktime_to_timespec64(KTIME_LOW_RES); return 0; }
-static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp) +static int posix_get_boottime(const clockid_t which_clock, + struct timespec64 *tp) { - get_monotonic_boottime(tp); + get_monotonic_boottime64(tp); return 0; }
-static int posix_get_tai(clockid_t which_clock, struct timespec *tp) +static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp) { timekeeping_clocktai(tp); return 0; @@ -278,57 +284,57 @@ static int posix_get_tai(clockid_t which_clock, struct timespec *tp) static __init int init_posix_timers(void) { struct k_clock clock_realtime = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_clock_realtime_get, - .clock_set = posix_clock_realtime_set, + .clock_getres64 = hrtimer_get_res64, + .clock_get64 = posix_clock_realtime_get, + .clock_set64 = posix_clock_realtime_set, .clock_adj = posix_clock_realtime_adj, .nsleep = common_nsleep, .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, - .timer_set = common_timer_set, - .timer_get = common_timer_get, + .timer_set64 = common_timer_set, + .timer_get64 = common_timer_get, .timer_del = common_timer_del, }; struct k_clock clock_monotonic = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_ktime_get_ts, + .clock_getres64 = hrtimer_get_res64, + .clock_get64 = posix_ktime_get_ts, .nsleep = common_nsleep, .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, - .timer_set = common_timer_set, - .timer_get = common_timer_get, + .timer_set64 = common_timer_set, + .timer_get64 = common_timer_get, .timer_del = common_timer_del, }; struct k_clock clock_monotonic_raw = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_get_monotonic_raw, + .clock_getres64 = hrtimer_get_res64, + .clock_get64 = posix_get_monotonic_raw, }; struct k_clock clock_realtime_coarse = { - .clock_getres = posix_get_coarse_res, - .clock_get = posix_get_realtime_coarse, + .clock_getres64 = posix_get_coarse_res, + .clock_get64 = posix_get_realtime_coarse, }; struct k_clock clock_monotonic_coarse = { - .clock_getres = posix_get_coarse_res, - .clock_get = posix_get_monotonic_coarse, + .clock_getres64 = posix_get_coarse_res, + .clock_get64 = posix_get_monotonic_coarse, }; struct k_clock clock_tai = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_get_tai, + .clock_getres64 = hrtimer_get_res64, + .clock_get64 = posix_get_tai, .nsleep = common_nsleep, .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, - .timer_set = common_timer_set, - .timer_get = common_timer_get, + .timer_set64 = common_timer_set, + .timer_get64 = common_timer_get, .timer_del = common_timer_del, }; struct k_clock clock_boottime = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_get_boottime, + .clock_getres64 = hrtimer_get_res64, + .clock_get64 = posix_get_boottime, .nsleep = common_nsleep, .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, - .timer_set = common_timer_set, - .timer_get = common_timer_get, + .timer_set64 = common_timer_set, + .timer_get64 = common_timer_get, .timer_del = common_timer_del, };
@@ -726,18 +732,18 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags) * report. */ static void -common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) +common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) { ktime_t now, remaining, iv; struct hrtimer *timer = &timr->it.real.timer;
- memset(cur_setting, 0, sizeof(struct itimerspec)); + memset(cur_setting, 0, sizeof(struct itimerspec64));
iv = timr->it.real.interval;
/* interval timer ? */ if (iv.tv64) - cur_setting->it_interval = ktime_to_timespec(iv); + cur_setting->it_interval = ktime_to_timespec64(iv); else if (!hrtimer_active(timer) && (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) return; @@ -763,7 +769,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) cur_setting->it_value.tv_nsec = 1; } else - cur_setting->it_value = ktime_to_timespec(remaining); + cur_setting->it_value = ktime_to_timespec64(remaining); }
/* Get the time remaining on a POSIX.1b interval timer. */ @@ -771,6 +777,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, struct itimerspec __user *, setting) { struct itimerspec cur_setting; + struct itimerspec64 cur_setting64; struct k_itimer *timr; struct k_clock *kc; unsigned long flags; @@ -781,10 +788,16 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, return -EINVAL;
kc = clockid_to_kclock(timr->it_clock); - if (WARN_ON_ONCE(!kc || !kc->timer_get)) + if (WARN_ON_ONCE(!kc || !kc->timer_get64 || !kc->timer_get)) { ret = -EINVAL; - else - kc->timer_get(timr, &cur_setting); + } else { + if (kc->timer_get64) { + kc->timer_get64(timr, &cur_setting64); + cur_setting = itimerspec64_to_itimerspec(cur_setting64); + } else { + kc->timer_get(timr, &cur_setting); + } + }
unlock_timer(timr, flags);
@@ -823,7 +836,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) /* timr->it_lock is taken. */ static int common_timer_set(struct k_itimer *timr, int flags, - struct itimerspec *new_setting, struct itimerspec *old_setting) + struct itimerspec64 *new_setting, struct itimerspec64 *old_setting) { struct hrtimer *timer = &timr->it.real.timer; enum hrtimer_mode mode; @@ -852,10 +865,10 @@ common_timer_set(struct k_itimer *timr, int flags, hrtimer_init(&timr->it.real.timer, timr->it_clock, mode); timr->it.real.timer.function = posix_timer_fn;
- hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value)); + hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
/* Convert interval */ - timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); + timr->it.real.interval = timespec64_to_ktime(new_setting->it_interval);
/* SIGEV_NONE timers are not queued ! See common_timer_get */ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { @@ -877,6 +890,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, { struct k_itimer *timr; struct itimerspec new_spec, old_spec; + struct itimerspec64 new_spec64, old_spec64; int error = 0; unsigned long flag; struct itimerspec *rtn = old_setting ? &old_spec : NULL; @@ -897,10 +911,19 @@ retry: return -EINVAL;
kc = clockid_to_kclock(timr->it_clock); - if (WARN_ON_ONCE(!kc || !kc->timer_set)) + if (WARN_ON_ONCE(!kc || !kc->timer_set64 || !kc->timer_set)) { error = -EINVAL; - else - error = kc->timer_set(timr, flags, &new_spec, rtn); + } else { + if (kc->timer_set64) { + new_spec64 = itimerspec_to_itimerspec64(new_spec); + error = kc->timer_set64(timr, flags, &new_spec64, + &old_spec64); + if (old_setting) + old_spec = itimerspec64_to_itimerspec(old_spec64); + } else { + error = kc->timer_set(timr, flags, &new_spec, rtn); + } + }
unlock_timer(timr, flag); if (error == TIMER_RETRY) { @@ -1007,6 +1030,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, { struct k_clock *kc = clockid_to_kclock(which_clock); struct timespec new_tp; + struct timespec64 new_tp64;
if (!kc || !kc->clock_set) return -EINVAL; @@ -1014,7 +1038,12 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, if (copy_from_user(&new_tp, tp, sizeof (*tp))) return -EFAULT;
- return kc->clock_set(which_clock, &new_tp); + if (kc->clock_set64) { + new_tp64 = timespec_to_timespec64(new_tp); + return kc->clock_set64(which_clock, &new_tp64); + } else { + return kc->clock_set(which_clock, &new_tp); + } }
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, @@ -1022,12 +1051,18 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, { struct k_clock *kc = clockid_to_kclock(which_clock); struct timespec kernel_tp; + struct timespec64 kernel_tp64; int error;
if (!kc) return -EINVAL;
- error = kc->clock_get(which_clock, &kernel_tp); + if (kc->clock_get64) { + error = kc->clock_get64(which_clock, &kernel_tp64); + kernel_tp = timespec64_to_timespec(kernel_tp64); + } else { + error = kc->clock_get(which_clock, &kernel_tp); + }
if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) error = -EFAULT; @@ -1063,12 +1098,18 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, { struct k_clock *kc = clockid_to_kclock(which_clock); struct timespec rtn_tp; + struct timespec64 rtn_tp64; int error;
if (!kc) return -EINVAL;
- error = kc->clock_getres(which_clock, &rtn_tp); + if (kc->clock_getres64) { + error = kc->clock_getres64(which_clock, &rtn_tp64); + rtn_tp = timespec64_to_timespec(rtn_tp64); + } else { + error = kc->clock_getres(which_clock, &rtn_tp); + }
if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) error = -EFAULT; diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h index 1d91416..144af14 100644 --- a/kernel/time/timekeeping.h +++ b/kernel/time/timekeeping.h @@ -15,7 +15,7 @@ extern u64 timekeeping_max_deferment(void); extern int timekeeping_inject_offset(struct timespec *ts); extern s32 timekeeping_get_tai_offset(void); extern void timekeeping_set_tai_offset(s32 tai_offset); -extern void timekeeping_clocktai(struct timespec *ts); +extern void timekeeping_clocktai(struct timespec64 *ts); extern int timekeeping_suspend(void); extern void timekeeping_resume(void);
On Wednesday 15 April 2015 19:56:43 Baolin Wang wrote:
This patch converts the timepsec type to timespec64 type, and converts the itimerspec type to itimerspec64 type for the k_clock callback functions.
This patch also converts the timespec type to timespec64 type for timekeeping_clocktai function which is used only in the posix-timers.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
include/linux/timekeeping.h | 4 +- kernel/time/posix-timers.c | 157 +++++++++++++++++++++++++++---------------- kernel/time/timekeeping.h | 2 +- 3 files changed, 102 insertions(+), 61 deletions(-)
You apparently misunderstood my previous explanation about how the patch should be split up.
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 31ea01f..fce456d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -132,9 +132,9 @@ static struct k_clock posix_clocks[MAX_CLOCKS]; static int common_nsleep(const clockid_t, int flags, struct timespec *t, struct timespec __user *rmtp); static int common_timer_create(struct k_itimer *new_timer); -static void common_timer_get(struct k_itimer *, struct itimerspec *); +static void common_timer_get(struct k_itimer *, struct itimerspec64 *); static int common_timer_set(struct k_itimer *, int,
struct itimerspec *, struct itimerspec *);
struct itimerspec64 *, struct itimerspec64 *);
static int common_timer_del(struct k_itimer *timer); static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
This part clearly belongs into patch 5, I assume that was just a mistake on your side.
@@ -897,10 +911,19 @@ retry: return -EINVAL; kc = clockid_to_kclock(timr->it_clock);
- if (WARN_ON_ONCE(!kc || !kc->timer_set))
- if (WARN_ON_ONCE(!kc || !kc->timer_set64 || !kc->timer_set)) { error = -EINVAL;
- else
error = kc->timer_set(timr, flags, &new_spec, rtn);
- } else {
if (kc->timer_set64) {
new_spec64 = itimerspec_to_itimerspec64(new_spec);
error = kc->timer_set64(timr, flags, &new_spec64,
&old_spec64);
if (old_setting)
old_spec = itimerspec64_to_itimerspec(old_spec64);
} else {
error = kc->timer_set(timr, flags, &new_spec, rtn);
}
- }
unlock_timer(timr, flag); if (error == TIMER_RETRY) {
This part however is what I think you misunderstood: all the callers of the kc->*64() function callbacks should be changed in patch 5, which introduces the function pointers. You could even split that part out into a patch between 4 and 5, but I think that would not be helpful. However, the rest of this patch is very clearly a separate step from the introduction of the callback pointers.
Arnd
On 15 April 2015 at 22:47, Arnd Bergmann arnd@linaro.org wrote:
On Wednesday 15 April 2015 19:56:43 Baolin Wang wrote:
This patch converts the timepsec type to timespec64 type, and converts
the
itimerspec type to itimerspec64 type for the k_clock callback functions.
This patch also converts the timespec type to timespec64 type for
timekeeping_clocktai
function which is used only in the posix-timers.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
include/linux/timekeeping.h | 4 +- kernel/time/posix-timers.c | 157
+++++++++++++++++++++++++++----------------
kernel/time/timekeeping.h | 2 +- 3 files changed, 102 insertions(+), 61 deletions(-)
You apparently misunderstood my previous explanation about how the patch should be split up.
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 31ea01f..fce456d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -132,9 +132,9 @@ static struct k_clock posix_clocks[MAX_CLOCKS]; static int common_nsleep(const clockid_t, int flags, struct timespec *t, struct timespec __user *rmtp); static int common_timer_create(struct k_itimer *new_timer); -static void common_timer_get(struct k_itimer *, struct itimerspec *); +static void common_timer_get(struct k_itimer *, struct itimerspec64 *); static int common_timer_set(struct k_itimer *, int,
struct itimerspec *, struct itimerspec *);
struct itimerspec64 *, struct itimerspec64 *);
static int common_timer_del(struct k_itimer *timer);
static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
This part clearly belongs into patch 5, I assume that was just a mistake on your side.
@@ -897,10 +911,19 @@ retry: return -EINVAL;
kc = clockid_to_kclock(timr->it_clock);
if (WARN_ON_ONCE(!kc || !kc->timer_set))
if (WARN_ON_ONCE(!kc || !kc->timer_set64 || !kc->timer_set)) { error = -EINVAL;
else
error = kc->timer_set(timr, flags, &new_spec, rtn);
} else {
if (kc->timer_set64) {
new_spec64 = itimerspec_to_itimerspec64(new_spec);
error = kc->timer_set64(timr, flags, &new_spec64,
&old_spec64);
if (old_setting)
old_spec =
itimerspec64_to_itimerspec(old_spec64);
} else {
error = kc->timer_set(timr, flags, &new_spec, rtn);
}
} unlock_timer(timr, flag); if (error == TIMER_RETRY) {
This part however is what I think you misunderstood: all the callers of the kc->*64() function callbacks should be changed in patch 5, which introduces the function pointers. You could even split that part out into a patch between 4 and 5, but I think that would not be helpful. However, the rest of this patch is very clearly a separate step from the introduction of the callback pointers.
Arnd
Sorry, i have not understand deeply here yet. you mean the blue part also need remove to patch 5? The former ptp patch series also introduce the new callback pointers firstly, then convert each driver separately. So here i introduce the new 64bit callback pointers in patch 5, then convert each driver, include the posix-timers.c driver. So i think the posix-timers.c driver's modification should be split into one patch, is it right?
On Thursday 16 April 2015 20:04:14 Baolin Wang wrote:
return -EINVAL; kc = clockid_to_kclock(timr->it_clock);
if (WARN_ON_ONCE(!kc || !kc->timer_set))
if (WARN_ON_ONCE(!kc || !kc->timer_set64 || !kc->timer_set)) { error = -EINVAL;
else
error = kc->timer_set(timr, flags, &new_spec, rtn);
} else {
if (kc->timer_set64) {
new_spec64 = itimerspec_to_itimerspec64(new_spec);
error = kc->timer_set64(timr, flags, &new_spec64,
&old_spec64);
if (old_setting)
old_spec =
itimerspec64_to_itimerspec(old_spec64);
} else {
error = kc->timer_set(timr, flags, &new_spec, rtn);
}
} unlock_timer(timr, flag); if (error == TIMER_RETRY) {
This part however is what I think you misunderstood: all the callers of the kc->*64() function callbacks should be changed in patch 5, which introduces the function pointers. You could even split that part out into a patch between 4 and 5, but I think that would not be helpful. However, the rest of this patch is very clearly a separate step from the introduction of the callback pointers.
Arnd
Sorry, i have not understand deeply here yet. you mean the blue part also need remove to patch 5?
I don't know what is blue on your screen. The patch cited above should be part of patch 5, yes.
The former ptp patch series also introduce the new callback pointers firstly, then convert each driver separately. So here i introduce the new 64bit callback pointers in patch 5, then convert each driver, include the posix-timers.c driver. So i think the posix-timers.c driver's modification should be split into one patch, is it right?
The point is that posix-timers.c contains both the framework and some of the k_clock implementations. The framework (the structure definition, and any callers of it) should be done in one patch, while the k_clock changes (clock_realtime, clock_monotonic, clock_monotonic_raw, clock_realtime_coarse, clock_monotonic_coarse, clock_tai, and clock_boottime) should be done in a second step.
This is exactly how the ptp changes were done.
Arnd
This patch converts to the 64bit arguments for k_clock callback function, that converts the timespec type to timespec64 type and converts the itimerspec type to itimerspec64 type.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- drivers/char/mmtimer.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 3d6c067..38f0e9d 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -478,18 +478,18 @@ static int sgi_clock_period; static struct timespec sgi_clock_offset; static int sgi_clock_period;
-static int sgi_clock_get(clockid_t clockid, struct timespec *tp) +static int sgi_clock_get(clockid_t clockid, struct timespec64 *tp) { u64 nsec;
nsec = rtc_time() * sgi_clock_period + sgi_clock_offset.tv_nsec; - *tp = ns_to_timespec(nsec); + *tp = ns_to_timespec64(nsec); tp->tv_sec += sgi_clock_offset.tv_sec; return 0; };
-static int sgi_clock_set(const clockid_t clockid, const struct timespec *tp) +static int sgi_clock_set(const clockid_t clockid, const struct timespec64 *tp) {
u64 nsec; @@ -657,7 +657,7 @@ static int sgi_timer_del(struct k_itimer *timr) }
/* Assumption: it_lock is already held with irq's disabled */ -static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) +static void sgi_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) {
if (timr->it.mmtimer.clock == TIMER_OFF) { @@ -668,14 +668,14 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) return; }
- cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period); - cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); + cur_setting->it_interval = ns_to_timespec64(timr->it.mmtimer.incr * sgi_clock_period); + cur_setting->it_value = ns_to_timespec64((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); }
static int sgi_timer_set(struct k_itimer *timr, int flags, - struct itimerspec * new_setting, - struct itimerspec * old_setting) + struct itimerspec64 *new_setting, + struct itimerspec64 *old_setting) { unsigned long when, period, irqflags; int err = 0; @@ -687,8 +687,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, sgi_timer_get(timr, old_setting);
sgi_timer_del(timr); - when = timespec_to_ns(&new_setting->it_value); - period = timespec_to_ns(&new_setting->it_interval); + when = timespec64_to_ns(&new_setting->it_value); + period = timespec64_to_ns(&new_setting->it_interval);
if (when == 0) /* Clear timer */ @@ -699,11 +699,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, return -ENOMEM;
if (flags & TIMER_ABSTIME) { - struct timespec n; + struct timespec64 n; unsigned long now;
- getnstimeofday(&n); - now = timespec_to_ns(&n); + getnstimeofdayi64(&n); + now = timespec64_to_ns(&n); if (when > now) when -= now; else @@ -765,7 +765,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, return err; }
-static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) +static int sgi_clock_getres(const clockid_t which_clock, struct timespec64 *tp) { tp->tv_sec = 0; tp->tv_nsec = sgi_clock_period; @@ -773,13 +773,13 @@ static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) }
static struct k_clock sgi_clock = { - .clock_set = sgi_clock_set, - .clock_get = sgi_clock_get, - .clock_getres = sgi_clock_getres, + .clock_set64 = sgi_clock_set, + .clock_get64 = sgi_clock_get, + .clock_getres64 = sgi_clock_getres, .timer_create = sgi_timer_create, - .timer_set = sgi_timer_set, + .timer_set64 = sgi_timer_set, .timer_del = sgi_timer_del, - .timer_get = sgi_timer_get + .timer_get64 = sgi_timer_get };
/**
On Wednesday 15 April 2015 19:56:44 Baolin Wang wrote:
if (flags & TIMER_ABSTIME) {
struct timespec n;
unsigned long now;struct timespec64 n;
getnstimeofday(&n);
now = timespec_to_ns(&n);
getnstimeofdayi64(&n);
if (when > now) when -= now; elsenow = timespec64_to_ns(&n);
You have a small typo here: getnstimeofday64() instead of getnstimeofdayi64().
Actually, this code could be simplified by using ktime_get_real_ns(), and at the time void the use of the temporary timespec64 value.
Arnd
This patch changes to the new methods with timespec64/itimerspec64 type of k_clock structure, and converts the timespec/itimerspec type to timespec64/itimerspec64 typein alarmtimer.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- kernel/time/alarmtimer.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 1b001ed..68186e1 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -489,35 +489,36 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, /** * alarm_clock_getres - posix getres interface * @which_clock: clockid - * @tp: timespec to fill + * @tp: timespec64 to fill * * Returns the granularity of underlying alarm base clock */ -static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) +static int alarm_clock_getres(const clockid_t which_clock, + struct timespec64 *tp) { clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid;
if (!alarmtimer_get_rtcdev()) return -EINVAL;
- return hrtimer_get_res(baseid, tp); + return hrtimer_get_res64(baseid, tp); }
/** * alarm_clock_get - posix clock_get interface * @which_clock: clockid - * @tp: timespec to fill. + * @tp: timespec64 to fill. * * Provides the underlying alarm base time. */ -static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) +static int alarm_clock_get(clockid_t which_clock, struct timespec64 *tp) { struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];
if (!alarmtimer_get_rtcdev()) return -EINVAL;
- *tp = ktime_to_timespec(base->gettime()); + *tp = ktime_to_timespec64(base->gettime()); return 0; }
@@ -547,24 +548,24 @@ static int alarm_timer_create(struct k_itimer *new_timer) /** * alarm_timer_get - posix timer_get interface * @new_timer: k_itimer pointer - * @cur_setting: itimerspec data to fill + * @cur_setting: itimerspec64 data to fill * * Copies out the current itimerspec data */ static void alarm_timer_get(struct k_itimer *timr, - struct itimerspec *cur_setting) + struct itimerspec64 *cur_setting) { ktime_t relative_expiry_time = alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
if (ktime_to_ns(relative_expiry_time) > 0) { - cur_setting->it_value = ktime_to_timespec(relative_expiry_time); + cur_setting->it_value = ktime_to_timespec64(relative_expiry_time); } else { cur_setting->it_value.tv_sec = 0; cur_setting->it_value.tv_nsec = 0; }
- cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval); + cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval); }
/** @@ -588,14 +589,14 @@ static int alarm_timer_del(struct k_itimer *timr) * alarm_timer_set - posix timer_set interface * @timr: k_itimer pointer to be deleted * @flags: timer flags - * @new_setting: itimerspec to be used - * @old_setting: itimerspec being replaced + * @new_setting: itimerspec64 to be used + * @old_setting: itimerspec64 being replaced * * Sets the timer to new_setting, and starts the timer. */ static int alarm_timer_set(struct k_itimer *timr, int flags, - struct itimerspec *new_setting, - struct itimerspec *old_setting) + struct itimerspec64 *new_setting, + struct itimerspec64 *old_setting) { ktime_t exp;
@@ -613,8 +614,8 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, return TIMER_RETRY;
/* start the timer */ - timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval); - exp = timespec_to_ktime(new_setting->it_value); + timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval); + exp = timespec64_to_ktime(new_setting->it_value); /* Convert (if necessary) to absolute time */ if (flags != TIMER_ABSTIME) { ktime_t now; @@ -670,7 +671,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp)
/** - * update_rmtp - Update remaining timespec value + * update_rmtp - Update remaining timespec64 value * @exp: expiration time * @type: timer type * @rmtp: user pointer to remaining timepsec value @@ -824,12 +825,12 @@ static int __init alarmtimer_init(void) int error = 0; int i; struct k_clock alarm_clock = { - .clock_getres = alarm_clock_getres, - .clock_get = alarm_clock_get, + .clock_getres64 = alarm_clock_getres, + .clock_get64 = alarm_clock_get, .timer_create = alarm_timer_create, - .timer_set = alarm_timer_set, + .timer_set64 = alarm_timer_set, .timer_del = alarm_timer_del, - .timer_get = alarm_timer_get, + .timer_get64 = alarm_timer_get, .nsleep = alarm_timer_nsleep, };
On Wednesday 15 April 2015 19:56:45 Baolin Wang wrote:
This patch changes to the new methods with timespec64/itimerspec64 type of k_clock structure, and converts the timespec/itimerspec type to timespec64/itimerspec64 typein alarmtimer.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
Looks good.
Arnd
This patch introduces the 64bit methods for k_clock structure, that converts the timespec/itimerspec type to timespec64/itimerspec64 type.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- kernel/time/posix-clock.c | 66 +++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 41 deletions(-)
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index fc90e98..bb5c6c8 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -297,54 +297,47 @@ out: return err; }
-static int pc_clock_gettime(clockid_t id, struct timespec *ts) +static int pc_clock_gettime(clockid_t id, struct timespec64 *ts) { struct posix_clock_desc cd; - struct timespec64 *tp; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.clock_gettime) { - *tp = timespec_to_timespec64(*ts); - err = cd.clk->ops.clock_gettime(cd.clk, tp); - } else { + if (cd.clk->ops.clock_gettime) + err = cd.clk->ops.clock_gettime(cd.clk, ts); + else err = -EOPNOTSUPP; - }
put_clock_desc(&cd);
return err; }
-static int pc_clock_getres(clockid_t id, struct timespec *ts) +static int pc_clock_getres(clockid_t id, struct timespec64 *ts) { struct posix_clock_desc cd; - struct timespec64 *tp; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.clock_getres) { - *tp = timespec_to_timespec64(*ts); - err = cd.clk->ops.clock_getres(cd.clk, tp); - } else { + if (cd.clk->ops.clock_getres) + err = cd.clk->ops.clock_getres(cd.clk, ts); + else err = -EOPNOTSUPP; - }
put_clock_desc(&cd);
return err; }
-static int pc_clock_settime(clockid_t id, const struct timespec *ts) +static int pc_clock_settime(clockid_t id, const struct timespec64 *ts) { struct posix_clock_desc cd; - struct timespec64 tp; int err;
err = get_clock_desc(id, &cd); @@ -356,12 +349,11 @@ static int pc_clock_settime(clockid_t id, const struct timespec *ts) goto out; }
- if (cd.clk->ops.clock_settime) { - tp = timespec_to_timespec64(*ts); - err = cd.clk->ops.clock_settime(cd.clk, &tp); - } else { + if (cd.clk->ops.clock_settime) + err = cd.clk->ops.clock_settime(cd.clk, ts); + else err = -EOPNOTSUPP; - } + out: put_clock_desc(&cd);
@@ -408,43 +400,35 @@ static int pc_timer_delete(struct k_itimer *kit) return err; }
-static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec *ts) +static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec64 *ts) { clockid_t id = kit->it_clock; struct posix_clock_desc cd; - struct itimerspec64 *ts64;
if (get_clock_desc(id, &cd)) return;
- if (cd.clk->ops.timer_gettime) { - *ts64 = itimerspec_to_itimerspec64(*ts); - cd.clk->ops.timer_gettime(cd.clk, kit, ts64); - } + if (cd.clk->ops.timer_gettime) + cd.clk->ops.timer_gettime(cd.clk, kit, ts);
put_clock_desc(&cd); }
static int pc_timer_settime(struct k_itimer *kit, int flags, - struct itimerspec *ts, struct itimerspec *old) + struct itimerspec64 *ts, struct itimerspec64 *old) { clockid_t id = kit->it_clock; struct posix_clock_desc cd; - struct itimerspec64 ts64; - struct itimerspec64 *old64; int err;
err = get_clock_desc(id, &cd); if (err) return err;
- if (cd.clk->ops.timer_settime) { - ts64 = itimerspec_to_itimerspec64(*ts); - *old64 = itimerspec_to_itimerspec64(*old); - err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, old64); - } else { + if (cd.clk->ops.timer_settime) + err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old); + else err = -EOPNOTSUPP; - }
put_clock_desc(&cd);
@@ -452,12 +436,12 @@ static int pc_timer_settime(struct k_itimer *kit, int flags, }
struct k_clock clock_posix_dynamic = { - .clock_getres = pc_clock_getres, - .clock_set = pc_clock_settime, - .clock_get = pc_clock_gettime, + .clock_getres64 = pc_clock_getres, + .clock_set64 = pc_clock_settime, + .clock_get64 = pc_clock_gettime, .clock_adj = pc_clock_adjtime, .timer_create = pc_timer_create, - .timer_set = pc_timer_settime, + .timer_set64 = pc_timer_settime, .timer_del = pc_timer_delete, - .timer_get = pc_timer_gettime, + .timer_get64 = pc_timer_gettime, };
On Wednesday 15 April 2015 19:56:46 Baolin Wang wrote:
This patch introduces the 64bit methods for k_clock structure, that converts the timespec/itimerspec type to timespec64/itimerspec64 type.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
The patch looks good, but upon further consideration, I think you could simplify the patch series if you merge patch 2 into this one, because you essentially add code there that gets removed here in turn. Doing it in one step will make it easier to review, as well as more logical.
Arnd
This patch introduces some functions for converting cputime to timespec64 and abck, that repalce the timespec type to timespec64 type, as well as for arch/s390 and arch/powerpc architecture.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- arch/powerpc/include/asm/cputime.h | 24 ++++++++++++++++++++++++ arch/s390/include/asm/cputime.h | 26 ++++++++++++++++++++++++++ include/asm-generic/cputime_jiffies.h | 8 ++++++++ include/linux/jiffies.h | 3 +++ kernel/time/time.c | 21 +++++++++++++++++++++ 5 files changed, 82 insertions(+)
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index e245255..5a2b5ce 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -178,6 +178,30 @@ static inline cputime_t timespec_to_cputime(const struct timespec *p) }
/* + * Convert cputime <-> timespec64 + */ +static inline void cputime_to_timespec64(const cputime_t ct, struct timespec64 *p) +{ + u64 x = (__force u64) ct; + unsigned int frac; + + frac = do_div(x, tb_ticks_per_sec); + p->tv_sec = x; + x = (u64) frac * 1000000000; + do_div(x, tb_ticks_per_sec); + p->tv_nsec = x; +} + +static inline cputime_t timespec64_to_cputime(const struct timespec64 *p) +{ + u64 ct; + + ct = (u64) p->tv_nsec * tb_ticks_per_sec; + do_div(ct, 1000000000); + return (__force cputime_t)(ct + (u64) p->tv_sec * tb_ticks_per_sec); +} + +/* * Convert cputime <-> timeval */ static inline void cputime_to_timeval(const cputime_t ct, struct timeval *p) diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index b91e960..caec0a0 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -115,6 +115,32 @@ static inline void cputime_to_timespec(const cputime_t cputime, }
/* + * Convert cputime to timespec64 and back. + */ +static inline cputime_t timespec64_to_cputime(const struct timespec64 *value) +{ + unsigned long long ret = value->tv_sec * CPUTIME_PER_SEC; + return (__force cputime_t)(ret + __div(value->tv_nsec * CPUTIME_PER_USEC, NSEC_PER_USEC)); +} + +static inline void cputime_to_timespec64(const cputime_t cputime, + struct timespec64 *value) +{ + unsigned long long __cputime = (__force unsigned long long) cputime; +#ifndef CONFIG_64BIT + register_pair rp; + + rp.pair = __cputime >> 1; + asm ("dr %0,%1" : "+d" (rp) : "d" (CPUTIME_PER_SEC / 2)); + value->tv_nsec = rp.subreg.even * NSEC_PER_USEC / CPUTIME_PER_USEC; + value->tv_sec = rp.subreg.odd; +#else + value->tv_nsec = (__cputime % CPUTIME_PER_SEC) * NSEC_PER_USEC / CPUTIME_PER_USEC; + value->tv_sec = __cputime / CPUTIME_PER_SEC; +#endif +} + +/* * Convert cputime to timeval and back. * Since cputime and timeval have the same resolution (microseconds) * this is easy. diff --git a/include/asm-generic/cputime_jiffies.h b/include/asm-generic/cputime_jiffies.h index fe386fc..e9c28e1 100644 --- a/include/asm-generic/cputime_jiffies.h +++ b/include/asm-generic/cputime_jiffies.h @@ -52,6 +52,14 @@ typedef u64 __nocast cputime64_t; jiffies_to_timespec(cputime_to_jiffies(__ct),__val)
/* + * Convert cputime to timespec64 and abck. + */ +#define timespec64_to_cputime(__val) \ + jiffies_to_cputime(timespec64_to_jiffies(__val)) +#define cputime_to_timespec64(__ct,__val) \ + jiffies_to_timespec64(cputime_to_jiffies(__ct),__val) + +/* * Convert cputime to timeval and back. */ #define timeval_to_cputime(__val) \ diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index c367cbd..dbaa4ee 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -293,6 +293,9 @@ extern unsigned long usecs_to_jiffies(const unsigned int u); extern unsigned long timespec_to_jiffies(const struct timespec *value); extern void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value); +extern unsigned long timespec64_to_jiffies(const struct timespec64 *value); +extern void jiffies_to_timespec64(const unsigned long jiffies, + struct timespec64 *value); extern unsigned long timeval_to_jiffies(const struct timeval *value); extern void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value); diff --git a/kernel/time/time.c b/kernel/time/time.c index 2c85b77..d5978c5 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -606,6 +606,27 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) } EXPORT_SYMBOL(jiffies_to_timespec);
+unsigned long +timespec64_to_jiffies(const struct timespec64 *value) +{ + return __timespec_to_jiffies(value->tv_sec, value->tv_nsec); +} +EXPORT_SYMBOL(timespec64_to_jiffies); + +void +jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) +{ + /* + * Convert jiffies to nanoseconds and separate with + * one divide. + */ + u32 rem; + value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC, + NSEC_PER_SEC, &rem); + value->tv_nsec = rem; +} +EXPORT_SYMBOL(jiffies_to_timespec64); + /* * We could use a similar algorithm to timespec_to_jiffies (with a * different multiplier for usec instead of nsec). But this has a
On Wednesday 15 April 2015 19:56:47 Baolin Wang wrote:
This patch introduces some functions for converting cputime to timespec64 and abck, that repalce the timespec type to timespec64 type, as well as for arch/s390 and arch/powerpc architecture.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
arch/powerpc/include/asm/cputime.h | 24 ++++++++++++++++++++++++ arch/s390/include/asm/cputime.h | 26 ++++++++++++++++++++++++++ include/asm-generic/cputime_jiffies.h | 8 ++++++++ include/linux/jiffies.h | 3 +++ kernel/time/time.c | 21 +++++++++++++++++++++ 5 files changed, 82 insertions(+)
It might be better to split this up by architecture, but you could also try it as is.
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index e245255..5a2b5ce 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -178,6 +178,30 @@ static inline cputime_t timespec_to_cputime(const struct timespec *p) } /*
- Convert cputime <-> timespec64
- */
+static inline void cputime_to_timespec64(const cputime_t ct, struct timespec64 *p) +{
- u64 x = (__force u64) ct;
- unsigned int frac;
- frac = do_div(x, tb_ticks_per_sec);
- p->tv_sec = x;
- x = (u64) frac * 1000000000;
- do_div(x, tb_ticks_per_sec);
- p->tv_nsec = x;
+}
+static inline cputime_t timespec64_to_cputime(const struct timespec64 *p) +{
- u64 ct;
- ct = (u64) p->tv_nsec * tb_ticks_per_sec;
- do_div(ct, 1000000000);
- return (__force cputime_t)(ct + (u64) p->tv_sec * tb_ticks_per_sec);
+}
+/*
- Convert cputime <-> timeval
*/
It might be better to replace the existing cputime_to_timespec64 and timespec64_to_cputime with wrappers around these for clarity. If you do it all in one patch, you can just add it in include/linux/cputime.h:
static inline cputime_t timespec_to_cputime(const struct timespec *ts) { struct timespec64 ts64 = timespec_to_timespec64(*ts); return timespec_to_cputime64(&ts64); }
which would then be used for all the implementations.
Arnd
On 15 April 2015 at 23:00, Arnd Bergmann arnd@linaro.org wrote:
On Wednesday 15 April 2015 19:56:47 Baolin Wang wrote:
This patch introduces some functions for converting cputime to
timespec64 and abck,
that repalce the timespec type to timespec64 type, as well as for
arch/s390 and
arch/powerpc architecture.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
arch/powerpc/include/asm/cputime.h | 24 ++++++++++++++++++++++++ arch/s390/include/asm/cputime.h | 26 ++++++++++++++++++++++++++ include/asm-generic/cputime_jiffies.h | 8 ++++++++ include/linux/jiffies.h | 3 +++ kernel/time/time.c | 21 +++++++++++++++++++++ 5 files changed, 82 insertions(+)
It might be better to split this up by architecture, but you could also try it as is.
diff --git a/arch/powerpc/include/asm/cputime.h
b/arch/powerpc/include/asm/cputime.h
index e245255..5a2b5ce 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -178,6 +178,30 @@ static inline cputime_t timespec_to_cputime(const
struct timespec *p)
}
/*
- Convert cputime <-> timespec64
- */
+static inline void cputime_to_timespec64(const cputime_t ct, struct
timespec64 *p)
+{
u64 x = (__force u64) ct;
unsigned int frac;
frac = do_div(x, tb_ticks_per_sec);
p->tv_sec = x;
x = (u64) frac * 1000000000;
do_div(x, tb_ticks_per_sec);
p->tv_nsec = x;
+}
+static inline cputime_t timespec64_to_cputime(const struct timespec64
*p)
+{
u64 ct;
ct = (u64) p->tv_nsec * tb_ticks_per_sec;
do_div(ct, 1000000000);
return (__force cputime_t)(ct + (u64) p->tv_sec *
tb_ticks_per_sec);
+}
+/*
- Convert cputime <-> timeval
*/
It might be better to replace the existing cputime_to_timespec64 and timespec64_to_cputime with wrappers around these for clarity. If you do it all in one patch, you can just add it in include/linux/cputime.h:
static inline cputime_t timespec_to_cputime(const struct timespec *ts) { struct timespec64 ts64 = timespec_to_timespec64(*ts); return timespec_to_cputime64(&ts64); }
which would then be used for all the implementations.
Arnd
*I have another confusion, if we add new *timespec_to_cputime/cputime_to_timespec *in **include/linux/cputime.h, * *the original *timespec_to_cputime/cputime_to_timespec *which located * *in include/asm-generic/cputime_jiffies.h, * *arch/s390/include/asm/cputime.h, and arch/powerpc/include/asm/cputime.h file will be removed?*
On Friday 17 April 2015 14:13:28 Baolin Wang wrote:
*I have another confusion, if we add new *timespec_to_cputime/cputime_to_timespec *in **include/linux/cputime.h, * *the original *timespec_to_cputime/cputime_to_timespec *which located * *in include/asm-generic/cputime_jiffies.h, * *arch/s390/include/asm/cputime.h, and arch/powerpc/include/asm/cputime.h file will be removed?*
Yes, of course. You would modify the existing timespec_to_cputime/cputime_to_timespec to be timespec64_to_cputime/cputime_to_timespec64 and add a wrapper around it at the same time.
Arnd
This patch chenges to the new methods of k_clock structure with timespec64 type, converts the timespec/itimerspec type to timespec64/itimerspec64 type for the callback function in posix-cpu-timers.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- kernel/time/posix-cpu-timers.c | 83 +++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 39 deletions(-)
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 0075da7..51cfead 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -52,7 +52,7 @@ static int check_clock(const clockid_t which_clock) }
static inline unsigned long long -timespec_to_sample(const clockid_t which_clock, const struct timespec *tp) +timespec64_to_sample(const clockid_t which_clock, const struct timespec64 *tp) { unsigned long long ret;
@@ -60,19 +60,19 @@ timespec_to_sample(const clockid_t which_clock, const struct timespec *tp) if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { ret = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec; } else { - ret = cputime_to_expires(timespec_to_cputime(tp)); + ret = cputime_to_expires(timespec64_to_cputime(tp)); } return ret; }
-static void sample_to_timespec(const clockid_t which_clock, +static void sample_to_timespec64(const clockid_t which_clock, unsigned long long expires, - struct timespec *tp) + struct timespec64 *tp) { if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) - *tp = ns_to_timespec(expires); + *tp = ns_to_timespec64(expires); else - cputime_to_timespec((__force cputime_t)expires, tp); + cputime_to_timespec64((__force cputime_t)expires, tp); }
/* @@ -141,7 +141,7 @@ static inline unsigned long long virt_ticks(struct task_struct *p) }
static int -posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) +posix_cpu_clock_getres(const clockid_t which_clock, struct timespec64 *tp) { int error = check_clock(which_clock); if (!error) { @@ -160,7 +160,7 @@ posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) }
static int -posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) +posix_cpu_clock_set(const clockid_t which_clock, const struct timespec64 *tp) { /* * You can never reset a CPU clock, but we check for other errors @@ -263,7 +263,7 @@ static int cpu_clock_sample_group(const clockid_t which_clock,
static int posix_cpu_clock_get_task(struct task_struct *tsk, const clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { int err = -EINVAL; unsigned long long rtn; @@ -277,13 +277,14 @@ static int posix_cpu_clock_get_task(struct task_struct *tsk, }
if (!err) - sample_to_timespec(which_clock, rtn, tp); + sample_to_timespec64(which_clock, rtn, tp);
return err; }
-static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) +static int posix_cpu_clock_get(const clockid_t which_clock, + struct timespec64 *tp) { const pid_t pid = CPUCLOCK_PID(which_clock); int err = -EINVAL; @@ -598,7 +599,7 @@ static inline void posix_cpu_timer_kick_nohz(void) { } * and try again. (This happens when the timer is in the middle of firing.) */ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, - struct itimerspec *new, struct itimerspec *old) + struct itimerspec64 *new, struct itimerspec64 *old) { unsigned long flags; struct sighand_struct *sighand; @@ -608,7 +609,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
WARN_ON_ONCE(p == NULL);
- new_expires = timespec_to_sample(timer->it_clock, &new->it_value); + new_expires = timespec64_to_sample(timer->it_clock, &new->it_value);
/* * Protect against sighand release/switch in exit/exec and p->cpu_timers @@ -669,7 +670,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, bump_cpu_timer(timer, val); if (val < timer->it.cpu.expires) { old_expires = timer->it.cpu.expires - val; - sample_to_timespec(timer->it_clock, + sample_to_timespec64(timer->it_clock, old_expires, &old->it_value); } else { @@ -709,7 +710,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, * Install the new reload setting, and * set up the signal and overrun bookkeeping. */ - timer->it.cpu.incr = timespec_to_sample(timer->it_clock, + timer->it.cpu.incr = timespec64_to_sample(timer->it_clock, &new->it_interval);
/* @@ -734,7 +735,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, ret = 0; out: if (old) { - sample_to_timespec(timer->it_clock, + sample_to_timespec64(timer->it_clock, old_incr, &old->it_interval); } if (!ret) @@ -742,7 +743,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, return ret; }
-static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) +static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp) { unsigned long long now; struct task_struct *p = timer->it.cpu.task; @@ -752,7 +753,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) /* * Easy part: convert the reload time. */ - sample_to_timespec(timer->it_clock, + sample_to_timespec64(timer->it_clock, timer->it.cpu.incr, &itp->it_interval);
if (timer->it.cpu.expires == 0) { /* Timer not armed at all. */ @@ -782,7 +783,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) * Call the timer disarmed, nothing else to do. */ timer->it.cpu.expires = 0; - sample_to_timespec(timer->it_clock, timer->it.cpu.expires, + sample_to_timespec64(timer->it_clock, timer->it.cpu.expires, &itp->it_value); } else { cpu_timer_sample_group(timer->it_clock, p, &now); @@ -791,7 +792,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) }
if (now < timer->it.cpu.expires) { - sample_to_timespec(timer->it_clock, + sample_to_timespec64(timer->it_clock, timer->it.cpu.expires - now, &itp->it_value); } else { @@ -1248,6 +1249,8 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, struct timespec *rqtp, struct itimerspec *it) { struct k_itimer timer; + struct timespec64 ts64; + struct itimerspec64 *it64; int error;
/* @@ -1260,13 +1263,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, error = posix_cpu_timer_create(&timer); timer.it_process = current; if (!error) { - static struct itimerspec zero_it; + static struct itimerspec64 zero_it;
memset(it, 0, sizeof *it); it->it_value = *rqtp;
spin_lock_irq(&timer.it_lock); - error = posix_cpu_timer_set(&timer, flags, it, NULL); + *it64 = itimerspec_to_itimerspec64(*it); + error = posix_cpu_timer_set(&timer, flags, it64, NULL); if (error) { spin_unlock_irq(&timer.it_lock); return error; @@ -1295,8 +1299,9 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, /* * We were interrupted by a signal. */ - sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); - error = posix_cpu_timer_set(&timer, 0, &zero_it, it); + sample_to_timespec64(which_clock, timer.it.cpu.expires, &ts64); + *rqtp = timespec64_to_timespec(ts64); + error = posix_cpu_timer_set(&timer, 0, &zero_it, it64); if (!error) { /* * Timer is now unarmed, deletion can not fail. @@ -1395,12 +1400,12 @@ static long posix_cpu_nsleep_restart(struct restart_block *restart_block) #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED)
static int process_cpu_clock_getres(const clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { return posix_cpu_clock_getres(PROCESS_CLOCK, tp); } static int process_cpu_clock_get(const clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { return posix_cpu_clock_get(PROCESS_CLOCK, tp); } @@ -1420,12 +1425,12 @@ static long process_cpu_nsleep_restart(struct restart_block *restart_block) return -EINVAL; } static int thread_cpu_clock_getres(const clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { return posix_cpu_clock_getres(THREAD_CLOCK, tp); } static int thread_cpu_clock_get(const clockid_t which_clock, - struct timespec *tp) + struct timespec64 *tp) { return posix_cpu_clock_get(THREAD_CLOCK, tp); } @@ -1436,37 +1441,37 @@ static int thread_cpu_timer_create(struct k_itimer *timer) }
struct k_clock clock_posix_cpu = { - .clock_getres = posix_cpu_clock_getres, - .clock_set = posix_cpu_clock_set, - .clock_get = posix_cpu_clock_get, + .clock_getres64 = posix_cpu_clock_getres, + .clock_set64 = posix_cpu_clock_set, + .clock_get64 = posix_cpu_clock_get, .timer_create = posix_cpu_timer_create, .nsleep = posix_cpu_nsleep, .nsleep_restart = posix_cpu_nsleep_restart, - .timer_set = posix_cpu_timer_set, + .timer_set64 = posix_cpu_timer_set, .timer_del = posix_cpu_timer_del, - .timer_get = posix_cpu_timer_get, + .timer_get64 = posix_cpu_timer_get, };
static __init int init_posix_cpu_timers(void) { struct k_clock process = { - .clock_getres = process_cpu_clock_getres, - .clock_get = process_cpu_clock_get, + .clock_getres64 = process_cpu_clock_getres, + .clock_get64 = process_cpu_clock_get, .timer_create = process_cpu_timer_create, .nsleep = process_cpu_nsleep, .nsleep_restart = process_cpu_nsleep_restart, }; struct k_clock thread = { - .clock_getres = thread_cpu_clock_getres, - .clock_get = thread_cpu_clock_get, + .clock_getres64 = thread_cpu_clock_getres, + .clock_get64 = thread_cpu_clock_get, .timer_create = thread_cpu_timer_create, }; - struct timespec ts; + struct timespec64 ts;
posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process); posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread);
- cputime_to_timespec(cputime_one_jiffy, &ts); + cputime_to_timespec64(cputime_one_jiffy, &ts); onecputick = ts.tv_nsec; WARN_ON(ts.tv_sec != 0);
On Wednesday 15 April 2015 19:56:48 Baolin Wang wrote:
This patch chenges to the new methods of k_clock structure with timespec64 type, converts the timespec/itimerspec type to timespec64/itimerspec64 type for the callback function in posix-cpu-timers.c file.
Signed-off-by: Baolin Wang baolin.wang@linaro.org
Looks good.
Arnd
All of the k_clock users have been converted to the new methods. This patch removes the older methods with timepsec/itimerspec type. As a result, the k_clock structure is ready for the year 2038.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/posix-timers.h | 9 ------ kernel/time/posix-timers.c | 72 +++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 52 deletions(-)
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 35786c5..7c3dae2 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -97,29 +97,20 @@ struct k_itimer { };
struct k_clock { - int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); int (*clock_getres64) (const clockid_t which_clock, struct timespec64 *tp); - int (*clock_set) (const clockid_t which_clock, - const struct timespec *tp); int (*clock_set64) (const clockid_t which_clock, const struct timespec64 *tp); - int (*clock_get) (const clockid_t which_clock, struct timespec * tp); int (*clock_get64) (const clockid_t which_clock, struct timespec64 *tp); int (*clock_adj) (const clockid_t which_clock, struct timex *tx); int (*timer_create) (struct k_itimer *timer); int (*nsleep) (const clockid_t which_clock, int flags, struct timespec *, struct timespec __user *); long (*nsleep_restart) (struct restart_block *restart_block); - int (*timer_set) (struct k_itimer * timr, int flags, - struct itimerspec * new_setting, - struct itimerspec * old_setting); int (*timer_set64) (struct k_itimer *timr, int flags, struct itimerspec64 *new_setting, struct itimerspec64 *old_setting); int (*timer_del) (struct k_itimer * timr); #define TIMER_RETRY 1 - void (*timer_get) (struct k_itimer * timr, - struct itimerspec * cur_setting); void (*timer_get64) (struct k_itimer *timr, struct itimerspec64 *cur_setting); }; diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index fce456d..3504928 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -528,13 +528,13 @@ void posix_timers_register_clock(const clockid_t clock_id, return; }
- if (!new_clock->clock_get) { - printk(KERN_WARNING "POSIX clock id %d lacks clock_get()\n", + if (!new_clock->clock_get64) { + printk(KERN_WARNING "POSIX clock id %d lacks clock_get64()\n", clock_id); return; } - if (!new_clock->clock_getres) { - printk(KERN_WARNING "POSIX clock id %d lacks clock_getres()\n", + if (!new_clock->clock_getres64) { + printk(KERN_WARNING "POSIX clock id %d lacks clock_getres64()\n", clock_id); return; } @@ -585,7 +585,7 @@ static struct k_clock *clockid_to_kclock(const clockid_t id) return (id & CLOCKFD_MASK) == CLOCKFD ? &clock_posix_dynamic : &clock_posix_cpu;
- if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres) + if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres64) return NULL; return &posix_clocks[id]; } @@ -788,15 +788,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, return -EINVAL;
kc = clockid_to_kclock(timr->it_clock); - if (WARN_ON_ONCE(!kc || !kc->timer_get64 || !kc->timer_get)) { + if (WARN_ON_ONCE(!kc || !kc->timer_get64)) { ret = -EINVAL; } else { - if (kc->timer_get64) { - kc->timer_get64(timr, &cur_setting64); - cur_setting = itimerspec64_to_itimerspec(cur_setting64); - } else { - kc->timer_get(timr, &cur_setting); - } + kc->timer_get64(timr, &cur_setting64); + cur_setting = itimerspec64_to_itimerspec(cur_setting64); }
unlock_timer(timr, flags); @@ -911,18 +907,14 @@ retry: return -EINVAL;
kc = clockid_to_kclock(timr->it_clock); - if (WARN_ON_ONCE(!kc || !kc->timer_set64 || !kc->timer_set)) { + if (WARN_ON_ONCE(!kc || !kc->timer_set64)) { error = -EINVAL; } else { - if (kc->timer_set64) { - new_spec64 = itimerspec_to_itimerspec64(new_spec); - error = kc->timer_set64(timr, flags, &new_spec64, - &old_spec64); - if (old_setting) - old_spec = itimerspec64_to_itimerspec(old_spec64); - } else { - error = kc->timer_set(timr, flags, &new_spec, rtn); - } + new_spec64 = itimerspec_to_itimerspec64(new_spec); + error = kc->timer_set64(timr, flags, &new_spec64, + &old_spec64); + if (old_setting) + old_spec = itimerspec64_to_itimerspec(old_spec64); }
unlock_timer(timr, flag); @@ -1032,18 +1024,14 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, struct timespec new_tp; struct timespec64 new_tp64;
- if (!kc || !kc->clock_set) + if (!kc || !kc->clock_set64) return -EINVAL;
if (copy_from_user(&new_tp, tp, sizeof (*tp))) return -EFAULT;
- if (kc->clock_set64) { - new_tp64 = timespec_to_timespec64(new_tp); - return kc->clock_set64(which_clock, &new_tp64); - } else { - return kc->clock_set(which_clock, &new_tp); - } + new_tp64 = timespec_to_timespec64(new_tp); + return kc->clock_set64(which_clock, &new_tp64); }
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, @@ -1057,14 +1045,13 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, if (!kc) return -EINVAL;
- if (kc->clock_get64) { - error = kc->clock_get64(which_clock, &kernel_tp64); - kernel_tp = timespec64_to_timespec(kernel_tp64); - } else { - error = kc->clock_get(which_clock, &kernel_tp); - } + error = kc->clock_get64(which_clock, &kernel_tp64); + if (!error) + return error; + + kernel_tp = timespec64_to_timespec(kernel_tp64);
- if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) + if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) error = -EFAULT;
return error; @@ -1104,14 +1091,13 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, if (!kc) return -EINVAL;
- if (kc->clock_getres64) { - error = kc->clock_getres64(which_clock, &rtn_tp64); - rtn_tp = timespec64_to_timespec(rtn_tp64); - } else { - error = kc->clock_getres(which_clock, &rtn_tp); - } + error = kc->clock_getres64(which_clock, &rtn_tp64); + if (!error) + return error; + + rtn_tp = timespec64_to_timespec(rtn_tp64);
- if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) + if (tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) error = -EFAULT;
return error;
On Wednesday 15 April 2015 19:56:49 Baolin Wang wrote:
struct k_clock {
- int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); int (*clock_getres64) (const clockid_t which_clock, struct timespec64 *tp);
- int (*clock_set) (const clockid_t which_clock,
int (*clock_set64) (const clockid_t which_clock, const struct timespec64 *tp);const struct timespec *tp);
- int (*clock_get) (const clockid_t which_clock, struct timespec * tp); int (*clock_get64) (const clockid_t which_clock, struct timespec64 *tp); int (*clock_adj) (const clockid_t which_clock, struct timex *tx); int (*timer_create) (struct k_itimer *timer); int (*nsleep) (const clockid_t which_clock, int flags, struct timespec *, struct timespec __user *); long (*nsleep_restart) (struct restart_block *restart_block);
- int (*timer_set) (struct k_itimer * timr, int flags,
struct itimerspec * new_setting,
int (*timer_set64) (struct k_itimer *timr, int flags, struct itimerspec64 *new_setting, struct itimerspec64 *old_setting); int (*timer_del) (struct k_itimer * timr);struct itimerspec * old_setting);
#define TIMER_RETRY 1
- void (*timer_get) (struct k_itimer * timr,
void (*timer_get64) (struct k_itimer *timr, struct itimerspec64 *cur_setting);struct itimerspec * cur_setting);
};
So far looks good.
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index fce456d..3504928 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -528,13 +528,13 @@ void posix_timers_register_clock(const clockid_t clock_id, return; }
- if (!new_clock->clock_get) {
printk(KERN_WARNING "POSIX clock id %d lacks clock_get()\n",
- if (!new_clock->clock_get64) {
return; }printk(KERN_WARNING "POSIX clock id %d lacks clock_get64()\n", clock_id);
- if (!new_clock->clock_getres) {
printk(KERN_WARNING "POSIX clock id %d lacks clock_getres()\n",
- if (!new_clock->clock_getres64) {
return; }printk(KERN_WARNING "POSIX clock id %d lacks clock_getres64()\n", clock_id);
This part tells me that you forgot to add the caller for clock_getres64 in patch 5, so any k_clock implementation that had only clock_getres64 but not clock_getres was broken until this patch.
@@ -585,7 +585,7 @@ static struct k_clock *clockid_to_kclock(const clockid_t id) return (id & CLOCKFD_MASK) == CLOCKFD ? &clock_posix_dynamic : &clock_posix_cpu;
- if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres)
- if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres64) return NULL; return &posix_clocks[id];
}
Same here.
@@ -788,15 +788,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, return -EINVAL; kc = clockid_to_kclock(timr->it_clock);
- if (WARN_ON_ONCE(!kc || !kc->timer_get64 || !kc->timer_get)) {
- if (WARN_ON_ONCE(!kc || !kc->timer_get64)) { ret = -EINVAL; } else {
if (kc->timer_get64) {
kc->timer_get64(timr, &cur_setting64);
cur_setting = itimerspec64_to_itimerspec(cur_setting64);
} else {
kc->timer_get(timr, &cur_setting);
}
kc->timer_get64(timr, &cur_setting64);
}cur_setting = itimerspec64_to_itimerspec(cur_setting64);
unlock_timer(timr, flags);
This and the rest of the patch looks good again.
Arnd