This patch introduces the timer_get64 method with itimerspec64 type for k_clock structure, that makes it ready for the 2038 year.
Convert to the 64bit method with itimerspec64 type for the timer_gettime syscall function, and change the timer_gettime syscall implementation according to the CONFIG_64BIT macro.
Also add a default 64bit method for the timer_get64 pointer of k_clock structure, and it will be removed after all the drivers are converted to 64bit methods.
Signed-off-by: Baolin Wang baolin.wang@linaro.org --- include/linux/posix-timers.h | 2 ++ kernel/time/posix-timers.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 907f3fd..e84436b 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -113,6 +113,8 @@ struct k_clock { #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; diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 9df664a..91036b1 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -140,6 +140,7 @@ static int common_timer_del(struct k_itimer *timer); static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags); +static struct k_clock *clockid_to_kclock(const clockid_t id);
#define lock_timer(tid, flags) \ ({ struct k_itimer *__timr; \ @@ -513,6 +514,16 @@ static struct pid *good_sigevent(sigevent_t * event) return task_pid(rtn); }
+static void default_timer_get64(struct k_itimer *timr, + struct itimerspec64 *cur_setting64) +{ + struct itimerspec cur_setting; + struct k_clock *kc = clockid_to_kclock(timr->it_clock); + + kc->timer_get(timr, &cur_setting); + *cur_setting64 = itimerspec_to_itimerspec64(&cur_setting); +} + void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock) { @@ -533,6 +544,9 @@ void posix_timers_register_clock(const clockid_t clock_id, return; }
+ if (new_clock->timer_get && !new_clock->timer_get64) + new_clock->timer_get64 = default_timer_get64; + posix_clocks[clock_id] = *new_clock; } EXPORT_SYMBOL_GPL(posix_timers_register_clock); @@ -766,7 +780,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) cur_setting->it_value = ktime_to_timespec(remaining); }
-static int __timer_gettime(timer_t timer_id, struct itimerspec *cur_setting) +static int __timer_gettime(timer_t timer_id, struct itimerspec64 *cur_setting) { struct k_itimer *timr; struct k_clock *kc; @@ -778,10 +792,10 @@ static int __timer_gettime(timer_t timer_id, struct itimerspec *cur_setting) 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)) ret = -EINVAL; else - kc->timer_get(timr, cur_setting); + kc->timer_get64(timr, cur_setting);
unlock_timer(timr, flags); return ret; @@ -791,8 +805,17 @@ static int __timer_gettime(timer_t timer_id, struct itimerspec *cur_setting) SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, struct itimerspec __user *, setting) { - struct itimerspec cur_setting; +#ifdef CONFIG_64BIT + struct itimerspec64 cur_setting; int ret = __timer_gettime(timer_id, &cur_setting); +#else + struct itimerspec64 cur_setting64; + struct itimerspec cur_setting; + + int ret = __timer_gettime(timer_id, &cur_setting64); + if (!ret) + cur_setting = itimerspec64_to_itimerspec(&cur_setting64); +#endif
if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting))) return -EFAULT;
On Tuesday 12 May 2015 22:07:53 Baolin Wang wrote:
} +static void default_timer_get64(struct k_itimer *timr,
struct itimerspec64 *cur_setting64)
+{
struct itimerspec cur_setting;
struct k_clock *kc = clockid_to_kclock(timr->it_clock);
kc->timer_get(timr, &cur_setting);
*cur_setting64 = itimerspec_to_itimerspec64(&cur_setting);
+}
The new version is correct, but when I asked you in private to send the update, what I meant was a reply to my email, and only the updated function for the sake of discussion. You have now sent the patch as a new thread, which means we have two email conversations with the same subject line and different contents, which is rather confusing and should be avoided.
Arnd
On 12 May 2015 at 23:33, Arnd Bergmann arnd@arndb.de wrote:
On Tuesday 12 May 2015 22:07:53 Baolin Wang wrote:
}
+static void default_timer_get64(struct k_itimer *timr,
struct itimerspec64 *cur_setting64)
+{
struct itimerspec cur_setting;
struct k_clock *kc = clockid_to_kclock(timr->it_clock);
kc->timer_get(timr, &cur_setting);
*cur_setting64 = itimerspec_to_itimerspec64(&cur_setting);
+}
The new version is correct, but when I asked you in private to send the update, what I meant was a reply to my email, and only the updated function for the sake of discussion. You have now sent the patch as a new thread, which means we have two email conversations with the same subject line and different contents, which is rather confusing and should be avoided.
Arnd
Sorry to cause the confusion. Cause i reorder the patch, and i'll avoid this situation in the future. Thanks.