Dear Customer,
Your parcel has arrived at June 21. Courier was unable to deliver the parcel to you.
Shipment Label is attached to email.
Yours faithfully,
Fred Crouch,
FedEx Support Manager.
Dear Customer,
Courier was unable to deliver the parcel to you.
Please, open email attachment to print shipment label.
Thank you for choosing FedEx,
Ivan Brewer,
Operation Agent.
Notice to Appear,
You have a unpaid bill for using toll road.
You are kindly asked to service your debt in the shortest time possible.
You can find the invoice is in the attachment.
Kind regards,
Benjamin French,
E-ZPass Manager.
Dear Customer,
Your parcel has arrived at June 16. Courier was unable to deliver the parcel to you.
Shipment Label is attached to email.
Yours faithfully,
Wayne Downing,
Station Agent.
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Delivery Label is attached to this email.
Yours sincerely,
Ivan Forbes,
Station Manager.
Notice to Appear,
You have to appear in the Court on the June 23.
You are kindly asked to prepare and bring the documents relating to the case to Court on the specified date.
Note: If you do not come, the case will be heard in your absence.
You can find the Court Notice is in the attachment.
Sincerely,
Louis Harrington,
Clerk of Court.
This patch series changes the 32-bit time types (timespec/itimerspec) to
the 64-bit types (timespec64/itimerspec64), since 32-bit time types will
break in the year 2038 on 32bit systems.
This patch series introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
---
Changes since v4:
- Rebase the patch series.
- Modify the subject line and the changelog.
Changes since v3:
- Fix some introducing bugs.
Changes since v2:
- Split the syscall conversion patch into small some patches.
Changes since V1:
- Split some patch into small patch.
- Add some default function for new 64bit methods for syscall function.
- Move do_sys_settimeofday() function to head file.
- Modify the EXPORT_SYMPOL issue.
- Add new 64bit methods in cputime_nsecs.h file.
---
Baolin Wang (24):
time: Introduce struct itimerspec64
timekeeping: Introduce current_kernel_time64()
security: Introduce security_settime64()
time: Introduce do_sys_settimeofday64()
posix-timers: Introduce {get,put}_timespec and {get,put}_itimerspec
posix-timers: Factor out the guts of 'timer_gettime'
posix-timers: Implement y2038 safe timer_get64() callback
posix-timers: Factor out the guts of 'timer_settime'
posix-timers: Implement y2038 safe timer_set64() callback
posix-timers: Factor out the guts of 'clock_settime'
posix-timers: Implement y2038 safe clock_set64() callback
posix-timers: Factor out the guts of 'clock_gettime'
posix-timers: Implement y2038 safe clock_get64() callback
posix-timers: Factor out the guts of 'clcok_getres'
posix-timers: Implement y2038 safe clock_getres64() callback
timekeeping: Change the implementation of timekeeping_clocktai()
posix-timers: Convert to y2038 safe callbacks
mmtimer: Convert to y2038 safe callbacks
alarmtimer: Convert to y2038 safe callbacks
posix-clock: Convert to y2038 safe callbacks
time: Introduce timespec64_to_jiffies()/jiffies_to_timespec64()
cputime: Introduce cputime_to_timespec64()/timespec64_to_cputime()
posix-cpu-timers: Convert to y2038 safe callbacks
k_clock: Remove y2038 unsafe callbacks
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 22 +--
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 6 +-
include/linux/cputime.h | 16 ++
include/linux/jiffies.h | 21 ++-
include/linux/lsm_hooks.h | 5 +-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/security.h | 20 ++-
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 25 +++-
kernel/time/alarmtimer.c | 38 ++---
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 84 ++++++-----
kernel/time/posix-timers.c | 257 +++++++++++++++++++++------------
kernel/time/time.c | 19 +--
kernel/time/timekeeping.c | 6 +-
security/commoncap.c | 2 +-
security/security.c | 2 +-
22 files changed, 412 insertions(+), 254 deletions(-)
--
1.7.9.5
Due to the do_sys_settimeofday() with timespec type is not year 2038
safe on 32bit systems, and it should introduce the do_sys_settimeofday64()
function with timespec64 type to make it is ready for 2038 issue.
For removing the old do_sys_settimeofday() function with timespec type
conveniently in future, it should move the do_sys_settimeofday() function
to the timekeeping.h file as a 'static inline' helper that just calls
do_sys_settimeofday64().
Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
---
include/linux/timekeeping.h | 11 +++++++++--
kernel/time/time.c | 8 ++++----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index f886bdb..2dcc86b 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -11,8 +11,15 @@ extern int timekeeping_suspended;
*/
extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday64(const struct timespec64 *ts);
-extern int do_sys_settimeofday(const struct timespec *tv,
- const struct timezone *tz);
+extern int do_sys_settimeofday64(const struct timespec64 *tv,
+ const struct timezone *tz);
+static inline int do_sys_settimeofday(const struct timespec *tv,
+ const struct timezone *tz)
+{
+ struct timespec64 ts64 = timespec_to_timespec64(*tv);
+
+ return do_sys_settimeofday64(&ts64, tz);
+}
/*
* Kernel time accessors
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 972e3bb..5aefe2d 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -160,15 +160,15 @@ static inline void warp_clock(void)
* various programs will get confused when the clock gets warped.
*/
-int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)
+int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz)
{
static int firsttime = 1;
int error = 0;
- if (tv && !timespec_valid(tv))
+ if (tv && !timespec64_valid(tv))
return -EINVAL;
- error = security_settime(tv, tz);
+ error = security_settime64(tv, tz);
if (error)
return error;
@@ -186,7 +186,7 @@ int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz)
}
}
if (tv)
- return do_settimeofday(tv);
+ return do_settimeofday64(tv);
return 0;
}
--
1.7.9.5
For introducing the do_sys_settimeofday64() function with
timespec64 type to make it ready for 2038 issue, it need to
introduce the security_settime64() function with timespec64
type firstly.
Also introduce a default security_settime64() function with
timespec64 type when it hasn't defined the CONFIG_SECURITY macro.
Also this patch changes the "settime" pointer's argument with
timespec64 type in security_operations structure for introducing
the the security_settime64() function.
Meanwhile moves the security_settime() defined in
security/security.c file to include/linux/security.h file as a
static function, that makes it convenient to delete the
security_settime() later.
And change the cap_settime() function's argument with timespec64
type to make it ready for 2038 issue, which is only used by
security_settime64()/security_settime() function.
Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
---
include/linux/security.h | 25 ++++++++++++++++++++-----
security/commoncap.c | 2 +-
security/security.c | 2 +-
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index a1b7dbd..5288794 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -75,7 +75,7 @@ struct timezone;
*/
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
int cap, int audit);
-extern int cap_settime(const struct timespec *ts, const struct timezone *tz);
+extern int cap_settime(const struct timespec64 *ts, const struct timezone *tz);
extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode);
extern int cap_ptrace_traceme(struct task_struct *parent);
extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
@@ -1353,7 +1353,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* Return 0 if permission is granted.
* @settime:
* Check permission to change the system time.
- * struct timespec and timezone are defined in include/linux/time.h
+ * struct timespec64 is defined in include/linux/time64.h and timezone is
+ * defined in include/linux/time.h
* @ts contains new time
* @tz contains new timezone
* Return 0 if permission is granted.
@@ -1483,7 +1484,7 @@ struct security_operations {
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
int (*syslog) (int type);
- int (*settime) (const struct timespec *ts, const struct timezone *tz);
+ int (*settime) (const struct timespec64 *ts, const struct timezone *tz);
int (*vm_enough_memory) (struct mm_struct *mm, long pages);
int (*bprm_set_creds) (struct linux_binprm *bprm);
@@ -1790,7 +1791,13 @@ int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns,
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
int security_syslog(int type);
-int security_settime(const struct timespec *ts, const struct timezone *tz);
+int security_settime64(const struct timespec64 *ts, const struct timezone *tz);
+static int security_settime(const struct timespec *ts, const struct timezone *tz)
+{
+ struct timespec64 ts64 = timespec_to_timespec64(*ts);
+
+ return security_settime64(&ts64, tz);
+}
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
int security_bprm_set_creds(struct linux_binprm *bprm);
int security_bprm_check(struct linux_binprm *bprm);
@@ -2040,10 +2047,18 @@ static inline int security_syslog(int type)
return 0;
}
+static inline int security_settime64(const struct timespec64 *ts,
+ const struct timezone *tz)
+{
+ return cap_settime(ts, tz);
+}
+
static inline int security_settime(const struct timespec *ts,
const struct timezone *tz)
{
- return cap_settime(ts, tz);
+ struct timsepc64 ts64 = timespec_to_timespec64(*ts);
+
+ return cap_settime(&ts64, tz);
}
static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
diff --git a/security/commoncap.c b/security/commoncap.c
index f66713b..bdb8ec0 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -116,7 +116,7 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
* Determine whether the current process may set the system clock and timezone
* information, returning 0 if permission granted, -ve if denied.
*/
-int cap_settime(const struct timespec *ts, const struct timezone *tz)
+int cap_settime(const struct timespec64 *ts, const struct timezone *tz)
{
if (!capable(CAP_SYS_TIME))
return -EPERM;
diff --git a/security/security.c b/security/security.c
index e81d5bb..0be5032 100644
--- a/security/security.c
+++ b/security/security.c
@@ -224,7 +224,7 @@ int security_syslog(int type)
return security_ops->syslog(type);
}
-int security_settime(const struct timespec *ts, const struct timezone *tz)
+int security_settime64(const struct timespec64 *ts, const struct timezone *tz)
{
return security_ops->settime(ts, tz);
}
--
1.7.9.5
struct timeval uses a 32-bit field for representing seconds,
which will overflow in the year 2038 and beyond. This patch replaces
struct timeval with 64-bit ktime_t which is 2038 safe.
The patch is part of a larger effort to remove instances of
32-bit timekeeping variables (timeval, time_t and timespec)
from the kernel.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
--
Changes in v2:
- Use monotonic time (ktime_get_ns()) instead of real time
since we only care about elapsed delta here.
- Use macro ktime_get_ns() instead of getting ktime_t and
converting it to ns.
---
drivers/pci/xen-pcifront.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 7cfd2db..c4796c8 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -20,6 +20,7 @@
#include <linux/workqueue.h>
#include <linux/bitops.h>
#include <linux/time.h>
+#include <linux/ktime.h>
#include <xen/platform_pci.h>
#include <asm/xen/swiotlb-xen.h>
@@ -115,7 +116,6 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
evtchn_port_t port = pdev->evtchn;
unsigned irq = pdev->irq;
s64 ns, ns_timeout;
- struct timeval tv;
spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
@@ -132,8 +132,7 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
* (in the latter case we end up continually re-executing poll() with a
* timeout in the past). 1s difference gives plenty of slack for error.
*/
- do_gettimeofday(&tv);
- ns_timeout = timeval_to_ns(&tv) + 2 * (s64)NSEC_PER_SEC;
+ ns_timeout = ktime_get_ns() + 2 * (s64)NSEC_PER_SEC;
xen_clear_irq_pending(irq);
@@ -141,8 +140,7 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
(unsigned long *)&pdev->sh_info->flags)) {
xen_poll_irq_timeout(irq, jiffies + 3*HZ);
xen_clear_irq_pending(irq);
- do_gettimeofday(&tv);
- ns = timeval_to_ns(&tv);
+ ns = ktime_get_ns();
if (ns > ns_timeout) {
dev_err(&pdev->xdev->dev,
"pciback not responding!!!\n");
--
2.2.0.rc0.207.ga3a616c
>>> + hz = 1000000/delta;
>
> This needs to be on of the do_div family.
>
> Dave.
Hi Dave,
I build-tested the patch for both 32-bit and 64-bit x86. If my
understanding is correct, since the divisor is 64-bit here, the
compiler will do "if (delta > 1000000) hz = 0; else hz =
1000000/(s32)delta" automatically?
In general, is this a good thumb-rule to follow - use do_div if the
dividend is 64-bit, and normal divide operator if only the divisor is
64-bit?
Tina
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.
It is ready for 2038 year when getting the timer resolution by hrtimer_get_res64()
function with timespec64 type, and it is convenient to remove the old
hrtimer_get_res() function in hrtimer.h file.
Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
---
include/linux/hrtimer.h | 16 +++++++++++++++-
kernel/time/hrtimer.c | 10 +++++-----
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 05f6df1..17e9294 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -383,7 +383,21 @@ 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;
+ int ret;
+
+ ret = hrtimer_get_res64(which_clock, &ts64);
+ if (!ret)
+ *tp = timespec64_to_timespec(ts64);
+
+ return ret;
+}
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)
{
--
1.7.9.5
This patch adds current_kernel_time64() function with timespec64 type,
and makes current_kernel_time() 'static inline' and moves it to timekeeping.h
file.
It is convenient for user to get the current kernel time with timespec64 type,
and delete the current_kernel_time() function easily in timekeeping.h file. That
is ready for 2038 when get the current time.
Signed-off-by: Baolin Wang <baolin.wang(a)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)
{
--
1.7.9.5
This patch converts the timespec type to timespec64 type for
timekeeping_clocktai() function which is used only in the
posix-timers.c file, that makes it ready for 2038 issue.
And remove the declaration of timekeeping_clocktai() in
kernel/time/timekeeping.h file, cause nothing uses that
declaration now, and it would conflict with the inline
definition in the include/linux/timekeeping.h file.
Also introduce the clock_get64 callback pointer for the k_clock
structure, and convert the timespec type to timespec64 type for
the posix_get_tai() function.
Next patch will convert all the timespec/itimerspec to the
timespec64/itimerspec64 type for other callbacks of the k_clock
structure in the kernel/time/posix-timers.c file.
Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
---
include/linux/timekeeping.h | 4 ++--
kernel/time/posix-timers.c | 4 ++--
kernel/time/timekeeping.h | 1 -
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 89beb62..c3345d5 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -250,9 +250,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 d2975d9..04d5512 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -296,7 +296,7 @@ static int posix_get_boottime(const clockid_t which_clock, struct timespec *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;
@@ -343,7 +343,7 @@ static __init int init_posix_timers(void)
};
struct k_clock clock_tai = {
.clock_getres = hrtimer_get_res,
- .clock_get = posix_get_tai,
+ .clock_get64 = posix_get_tai,
.nsleep = common_nsleep,
.nsleep_restart = hrtimer_nanosleep_restart,
.timer_create = common_timer_create,
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index 1d91416..04c7943 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -15,7 +15,6 @@ 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 int timekeeping_suspend(void);
extern void timekeeping_resume(void);
--
1.7.9.5
> --
> Changes in v2:
> - Use the more concise ktime_us_delta
Oops, please ignore this patch and please consider the v3 sent out
immediately after instead.
Tina
>
> This doesn't compile:
>
Oops, I sent an older version of the patch with a typo. I've correct
this in a v4. (NS_PER_SEC -> NSEC_PER_SEC). Thanks for taking a look
at this.
Tina
struct timeval uses a 32-bit seconds representation which will
overflow in the year 2038 and beyond. This patch replaces
the usage of struct timeval with ktime_t which is a 64-bit
timestamp and is year 2038 safe.
This patch is part of a larger attempt to remove all instances
of 32-bit timekeeping variables (timeval, timespec, time_t)
which are not year 2038 safe, from the kernel.
The patch is a work-in-progress - correctness of the following
changes is unclear:
(a) Usage of timeval_usec_diff - The function seems to subtract
usec values without caring about the difference of the seconds field.
There may be an implicit assumption in the original code that the
time delta is always of the order of microseconds.
The patch replaces the usage of timeval_usec_diff with
ktime_to_us(ktime_sub()) which computes the real timestamp difference,
not just the difference in the usec field.
(b) printk diffing the tv[i] and tv[i-1] values. The original
printk statement seems to get the order wrong. This patch preserves
that order.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
--
Changes in v2:
- Use the more concise ktime_us_delta
- Preserve the waketime argument in dvb_frontend_sleep_until as
a pointer, fixes bug introduced in v1 of the patch where the caller
doesn't get its timestamp modified.
---
drivers/media/dvb-core/dvb_frontend.c | 40 +++++++++--------------------------
drivers/media/dvb-core/dvb_frontend.h | 3 +--
drivers/media/dvb-frontends/stv0299.c | 11 +++++-----
3 files changed, 17 insertions(+), 37 deletions(-)
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 882ca41..c110e37 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -40,6 +40,7 @@
#include <linux/freezer.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
+#include <linux/ktime.h>
#include <asm/processor.h>
#include "dvb_frontend.h"
@@ -889,42 +890,21 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->thread);
}
-s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
-{
- return ((curtime.tv_usec < lasttime.tv_usec) ?
- 1000000 - lasttime.tv_usec + curtime.tv_usec :
- curtime.tv_usec - lasttime.tv_usec);
-}
-EXPORT_SYMBOL(timeval_usec_diff);
-
-static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
-{
- curtime->tv_usec += add_usec;
- if (curtime->tv_usec >= 1000000) {
- curtime->tv_usec -= 1000000;
- curtime->tv_sec++;
- }
-}
-
/*
* Sleep until gettimeofday() > waketime + add_usec
* This needs to be as precise as possible, but as the delay is
* usually between 2ms and 32ms, it is done using a scheduled msleep
* followed by usleep (normally a busy-wait loop) for the remainder
*/
-void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
+void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec)
{
- struct timeval lasttime;
s32 delta, newdelta;
- timeval_usec_add(waketime, add_usec);
-
- do_gettimeofday(&lasttime);
- delta = timeval_usec_diff(lasttime, *waketime);
+ ktime_add_us(*waketime, add_usec);
+ delta = ktime_us_delta(ktime_get_real(), *waketime);
if (delta > 2500) {
msleep((delta - 1500) / 1000);
- do_gettimeofday(&lasttime);
- newdelta = timeval_usec_diff(lasttime, *waketime);
+ newdelta = ktime_us_delta(ktime_get_real(), *waketime);
delta = (newdelta > delta) ? 0 : newdelta;
}
if (delta > 0)
@@ -2458,13 +2438,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
* include the initialization or start bit
*/
unsigned long swcmd = ((unsigned long) parg) << 1;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
int i;
u8 last = 1;
if (dvb_frontend_debug)
printk("%s switch command: 0x%04lx\n", __func__, swcmd);
- do_gettimeofday(&nexttime);
+ nexttime = ktime_get_real();
if (dvb_frontend_debug)
tv[0] = nexttime;
/* before sending a command, initialize by sending
@@ -2475,7 +2455,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
for (i = 0; i < 9; i++) {
if (dvb_frontend_debug)
- do_gettimeofday(&tv[i + 1]);
+ tv[i+1] = ktime_get_real();
if ((swcmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
@@ -2489,7 +2469,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
err = 0;
fepriv->state = FESTATE_DISEQC;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 816269e..5b64686 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -439,7 +439,6 @@ extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern int dvb_frontend_suspend(struct dvb_frontend *fe);
extern int dvb_frontend_resume(struct dvb_frontend *fe);
-extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
-extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
+extern void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec);
#endif
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b57ecf4..70c8065 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -44,6 +44,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
@@ -404,8 +405,8 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
u8 lv_mask = 0x40;
u8 last = 1;
int i;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
reg0x08 = stv0299_readreg (state, 0x08);
reg0x0c = stv0299_readreg (state, 0x0c);
@@ -418,7 +419,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
if (debug_legacy_dish_switch)
printk ("%s switch command: 0x%04lx\n",__func__, cmd);
- do_gettimeofday (&nexttime);
+ nexttime = ktime_get_real();
if (debug_legacy_dish_switch)
tv[0] = nexttime;
stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
@@ -427,7 +428,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
for (i=0; i<9; i++) {
if (debug_legacy_dish_switch)
- do_gettimeofday (&tv[i+1]);
+ tv[i+1] = ktime_get_real();
if((cmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
@@ -443,7 +444,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
return 0;
--
2.2.0.rc0.207.ga3a616c
This patch series changes the 32-bit time types (timespec/itimerspec) to
the 64-bit types (timespec64/itimerspec64), since 32-bit time types will
break in the year 2038.
This patch series introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
timekeeping: Introduce struct itimerspec64.
timekeeping: Introduce current_kernel_time64().
timekeeping: Change timekeeping_clocktai() with timespec64 type.
hrtimer: Introduce hrtimer_get_res64().
security: Introduce security_settime64().
time: Introduce do_sys_settimeofday64().
time: Introduce jiffies_to_timespec64()/timespec64_to_jiffies().
cputime: Introduce cputime_to_timespec64()/timespec64_to_cputime().
posix-timers: Introduce {get,put}_timespec()/{get,put}_itimerspec().
posix-timers: Split up timer_gettime()/timer_settime()/clock_settime()/
clock_gettime()/clock_getres().
posix-timers: Convert timer_gettime()/timer_settime()/clock_settime()/
clock_gettime()/clock_getres() to timespec64/itimerspec64.
mmtimer: Convert to timespec64/itimerspec64.
alarmtimer: Convert to timespec64/itimerspec64.
posix-clock: Convert to timespec64/itimerspec64.
posix-cpu-timers: Convert to timespec64/itimerspec64.
Baolin Wang (25):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
timekeeping:Introduce the current_kernel_time64() function with
timespec64 type
time/hrtimer:Introduce hrtimer_get_res64() with timespec64 type
security/security: Introduce security_settime64() function with
timespec64 type
time:Introduce the do_sys_settimeofday64() function with timespec64
type
time/posix-timers:Introduce {get,put}_timespec and
{get,put}_itimerspec
posix-timers:Change the implementation for timer_gettime syscall
function
posix-timers:Convert to the 64bit methods for the timer_gettime
syscall function
posix-timers:Change the implementation for timer_settime syscall
posix-timers:Convert to the 64bit methods for the timer_settime
syscall function
posix-timers:Change the implementation for clock_settime syscall
function
posix-timers:Convert to the 64bit methods for the clock_settime
syscall function
posix-timers:Change the implementation for clock_gettime syscall
function
posix-timers:Convert to the 64bit methods for the clock_gettime
syscall function
posix-timers:Change the implementation for clock_getres syscall
function
posix-timers:Convert to the 64bit methods for the clock_getres
syscall function
timekeeping:Introduce the timekeeping_clocktai() function with
timespec64 type
time/posix-timers:Convert to the 64bit methods for k_clock callback
functions
char/mmtimer:Convert to the 64bit methods for k_clock callback
functions
time/alarmtimer:Convert to the new 64bit methods for k_clock
structure
time/posix-clock:Convert to the 64bit methods for k_clock and
posix_clock_operations structure
time/time:Introduce the
timespec64_to_jiffies()/jiffies_to_timespec64() function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 16 ++
include/linux/hrtimer.h | 16 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/security.h | 25 +++-
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 84 ++++++-----
kernel/time/posix-timers.c | 259 +++++++++++++++++++++------------
kernel/time/time.c | 20 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 1 -
security/commoncap.c | 2 +-
security/security.c | 2 +-
24 files changed, 437 insertions(+), 267 deletions(-)
--
1.7.9.5
In the patch series I posted recently [1], I introduce new system calls to deal
with modified data structures, but left the question open on how these should
be best accessed from libc. The patches introduce a new __kernel_time64_t type
and based on that five new data structured: struct __kernel_timespec,
struct __kernel_itimerspec, struct __kernel_stat, struct __kernel_rusage,
and struct __kernel_timex. This works fine for the case when all libc
implementations provide their own definitions to user space, but not for
the simplest case (e.g. klibc) where the user-visible structures come directly
from the kernel uapi headers.
I still don't know what model the various libc developers prefer, so here is
an alternative approach, as a patch on top of the previous series:
Now, we rename the original structures to struct __old_kernel_*, and use a
macro to define either the __old_kernel_* or the __kernel_* structure name
to the name we actually want in user space, based on a __KERNEL_TIME_BITS
macro that can be set to either 32 or 64 for 32-bit architectures by
the libc. Depending on that macro, the compiler will either see one
of these combinations (for each of the five structures):
a) __BITS_PER_LONG == 32 && __KERNEL_TIME_BITS == 32:
struct timespec based on 32-bit __kernel_time_t
struct __kernel_timespec based on 64-bit __kernel_time64_t
b) __BITS_PER_LONG == 64 && __KERNEL_TIME_BITS == 64:
struct timespec based on 64-bit __kernel_time_t
struct __kernel_timespec based on 64-bit __kernel_time64_t
c) __BITS_PER_LONG == 32 && __KERNEL_TIME_BITS == 64:
struct __old_kernel_timespec based on 32-bit __kernel_time_t
struct timespec based on 64-bit __kernel_time64_t
Would this work for everyone? Any alternative suggestions?
Arnd
[1] http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/log/?h=y203…https://lwn.net/Articles/643407/
diff --git a/include/uapi/asm-generic/bitsperlong.h b/include/uapi/asm-generic/bitsperlong.h
index 23e6c416b85f..ecdaf4f77f35 100644
--- a/include/uapi/asm-generic/bitsperlong.h
+++ b/include/uapi/asm-generic/bitsperlong.h
@@ -12,4 +12,13 @@
#define __BITS_PER_LONG 32
#endif
+/*
+ * Traditionally we define defines 'time_t' as 'long', but we need to
+ * migrate to a 64-bit type until 2038. This one is designed to be
+ * overridden by user space if it's prepared to handle 64-bit time_t.
+ */
+#ifndef __KERNEL_TIME_BITS
+#define __KERNEL_TIME_BITS __BITS_PER_LONG
+#endif
+
#endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/uapi/asm-generic/kernel_stat.h b/include/uapi/asm-generic/kernel_stat.h
index d1db22583046..3693496c78aa 100644
--- a/include/uapi/asm-generic/kernel_stat.h
+++ b/include/uapi/asm-generic/kernel_stat.h
@@ -1,6 +1,14 @@
#ifndef __ASM_GENERIC_KERNEL_STAT_H
#define __ASM_GENERIC_KERNEL_STAT_H
+#include <asm/bitsperlong.h>
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_stat2 stat
+#else
+#define __kernel_stat stat
+#endif
+
/*
* The new structure that works on both 32-bit and 64-bit and survives y2038
* The layout matches 'struct stat' from asm-generic/stat.h on 64-bit
diff --git a/include/uapi/asm-generic/stat.h b/include/uapi/asm-generic/stat.h
index 64c32ba7c1a9..f66b28b96c8d 100644
--- a/include/uapi/asm-generic/stat.h
+++ b/include/uapi/asm-generic/stat.h
@@ -22,7 +22,7 @@
#define STAT_HAVE_NSEC 1
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev; /* Device. */
unsigned long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
diff --git a/include/uapi/linux/resource.h b/include/uapi/linux/resource.h
index c4f3ba44db00..9a3876cc4436 100644
--- a/include/uapi/linux/resource.h
+++ b/include/uapi/linux/resource.h
@@ -3,10 +3,16 @@
#include <linux/time.h>
#include <linux/types.h>
+#include <asm/bitsperlong.h>
/*
* Resource control/accounting header file for linux
*/
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_rusage rusage
+#else
+#define __kernel_rusage rusage
+#endif
/*
* Definition of struct rusage taken from BSD 4.3 Reno
@@ -20,7 +26,7 @@
#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
#define RUSAGE_THREAD 1 /* only the calling thread */
-struct rusage {
+struct __old_kernel_rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
__kernel_long_t ru_maxrss; /* maximum resident set size */
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 72d894df3013..b3988606128f 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -6,11 +6,24 @@
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
-struct timespec {
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_timespec timespec
+#else
+#define __kernel_timespec timespec
+#endif
+#endif
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_itimerspec itimerspec
+#else
+#define __kernel_itimerspec itimerspec
+#endif
+
+struct __old_kernel_timespec {
__kernel_time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
-#endif
struct timeval {
__kernel_time_t tv_sec; /* seconds */
@@ -31,7 +44,7 @@ struct timezone {
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
-struct itimerspec {
+struct __old_kernel_itimerspec {
struct timespec it_interval; /* timer period */
struct timespec it_value; /* timer expiration */
};
diff --git a/include/uapi/linux/timex.h b/include/uapi/linux/timex.h
index 9b131f107ada..3cfa50caa77d 100644
--- a/include/uapi/linux/timex.h
+++ b/include/uapi/linux/timex.h
@@ -54,14 +54,22 @@
#define _UAPI_LINUX_TIMEX_H
#include <linux/time.h>
+#include <asm/bitsperlong.h>
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_timex timex
+#else
+#define __kernel_timex timex
+#endif
#define NTP_API 4 /* NTP API version */
+
/*
* syscall interface - used (mainly by NTP daemon)
* to discipline kernel clock oscillator
*/
-struct timex {
+struct __old_kernel_timex {
unsigned int modes; /* mode selector */
__kernel_long_t offset; /* time offset (usec) */
__kernel_long_t freq; /* frequency offset (scaled ppm) */
diff --git a/arch/arm/include/uapi/asm/stat.h b/arch/arm/include/uapi/asm/stat.h
index 537a12553dd8..18ff0e2383ad 100644
--- a/arch/arm/include/uapi/asm/stat.h
+++ b/arch/arm/include/uapi/asm/stat.h
@@ -19,7 +19,7 @@ struct __old_kernel_stat {
#define STAT_HAVE_NSEC
-struct stat {
+struct __old_kernel_stat2 {
#if defined(__ARMEB__)
unsigned short st_dev;
unsigned short __pad1;
diff --git a/arch/avr32/include/uapi/asm/stat.h b/arch/avr32/include/uapi/asm/stat.h
index 2b528ca17985..5df389890f8a 100644
--- a/arch/avr32/include/uapi/asm/stat.h
+++ b/arch/avr32/include/uapi/asm/stat.h
@@ -24,7 +24,7 @@ struct __old_kernel_stat {
unsigned long st_ctime;
};
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
diff --git a/arch/blackfin/include/uapi/asm/stat.h b/arch/blackfin/include/uapi/asm/stat.h
index 99ee343aec23..cd417baf51fc 100644
--- a/arch/blackfin/include/uapi/asm/stat.h
+++ b/arch/blackfin/include/uapi/asm/stat.h
@@ -9,7 +9,7 @@
#include <asm-generic/kernel_stat.h>
-struct stat {
+struct __old_kernel_stat2 {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
diff --git a/arch/cris/include/uapi/asm/stat.h b/arch/cris/include/uapi/asm/stat.h
index 4837884cd2d3..38d1dba3ea6a 100644
--- a/arch/cris/include/uapi/asm/stat.h
+++ b/arch/cris/include/uapi/asm/stat.h
@@ -22,7 +22,7 @@ struct __old_kernel_stat {
#define STAT_HAVE_NSEC 1
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
diff --git a/arch/frv/include/uapi/asm/stat.h b/arch/frv/include/uapi/asm/stat.h
index 5448b198fbb6..5ff15ccef6c3 100644
--- a/arch/frv/include/uapi/asm/stat.h
+++ b/arch/frv/include/uapi/asm/stat.h
@@ -18,7 +18,7 @@ struct __old_kernel_stat {
};
/* This matches struct stat in uClibc/glibc. */
-struct stat {
+struct __old_kernel_stat2 {
unsigned char __pad1[6];
unsigned short st_dev;
diff --git a/arch/m32r/include/uapi/asm/stat.h b/arch/m32r/include/uapi/asm/stat.h
index d0ffa70f73c0..03531561b8cd 100644
--- a/arch/m32r/include/uapi/asm/stat.h
+++ b/arch/m32r/include/uapi/asm/stat.h
@@ -20,7 +20,7 @@ struct __old_kernel_stat {
#define STAT_HAVE_NSEC 1
-struct stat {
+struct __old_kernel_stat2 {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
diff --git a/arch/m68k/include/uapi/asm/stat.h b/arch/m68k/include/uapi/asm/stat.h
index 6f455db47b4e..f7936ed51c09 100644
--- a/arch/m68k/include/uapi/asm/stat.h
+++ b/arch/m68k/include/uapi/asm/stat.h
@@ -17,7 +17,7 @@ struct __old_kernel_stat {
unsigned long st_ctime;
};
-struct stat {
+struct __old_kernel_stat2 {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
diff --git a/arch/mips/include/uapi/asm/stat.h b/arch/mips/include/uapi/asm/stat.h
index 53e58fbd83fa..c0b82a1ccf17 100644
--- a/arch/mips/include/uapi/asm/stat.h
+++ b/arch/mips/include/uapi/asm/stat.h
@@ -16,7 +16,7 @@
#if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
-struct stat {
+struct __old_kernel_stat2 {
unsigned st_dev;
long st_pad1[3]; /* Reserved for network id */
ino_t st_ino;
@@ -90,7 +90,7 @@ struct stat64 {
#if _MIPS_SIM == _MIPS_SIM_ABI64
/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
-struct stat {
+struct __old_kernel_stat2 {
unsigned int st_dev;
unsigned int st_pad0[3]; /* Reserved for st_dev expansion */
diff --git a/arch/mn10300/include/uapi/asm/stat.h b/arch/mn10300/include/uapi/asm/stat.h
index af3b4d6b7b7a..ab507885dd05 100644
--- a/arch/mn10300/include/uapi/asm/stat.h
+++ b/arch/mn10300/include/uapi/asm/stat.h
@@ -17,7 +17,7 @@ struct __old_kernel_stat {
unsigned long st_ctime;
};
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
diff --git a/arch/parisc/include/uapi/asm/stat.h b/arch/parisc/include/uapi/asm/stat.h
index f06ce7ba0115..d632b5453628 100644
--- a/arch/parisc/include/uapi/asm/stat.h
+++ b/arch/parisc/include/uapi/asm/stat.h
@@ -4,7 +4,7 @@
#include <linux/types.h>
#include <asm-generic/kernel_stat.h>
-struct stat {
+struct __old_kernel_stat2 {
unsigned int st_dev; /* dev_t is 32 bits on parisc */
unsigned int st_ino; /* 32 bits */
unsigned short st_mode; /* 16 bits */
diff --git a/arch/powerpc/include/uapi/asm/stat.h b/arch/powerpc/include/uapi/asm/stat.h
index 248d8072267f..4b62b30ed12c 100644
--- a/arch/powerpc/include/uapi/asm/stat.h
+++ b/arch/powerpc/include/uapi/asm/stat.h
@@ -7,6 +7,13 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/types.h>
+#include <asm/bitsperlong.h>
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_stat2 stat
+#else
+#define __kernel_stat stat
+#endif
#define STAT_HAVE_NSEC 1
@@ -26,7 +33,7 @@ struct __old_kernel_stat {
};
#endif /* !__powerpc64__ */
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
ino_t st_ino;
#ifdef __powerpc64__
@@ -78,7 +85,7 @@ struct stat64 {
unsigned int __unused5;
};
-/* this matches the powerpc64 'struct stat' for compat tasks */
+/* this matches the powerpc64 'struct __old_kernel_stat2' for compat tasks */
struct __kernel_stat {
unsigned long long st_dev;
unsigned long long st_ino;
@@ -101,6 +107,5 @@ struct __kernel_stat {
unsigned long long __unused5;
unsigned long long __unused6;
};
#endif /* _ASM_POWERPC_STAT_H */
diff --git a/arch/s390/include/uapi/asm/stat.h b/arch/s390/include/uapi/asm/stat.h
index d4c2711249dd..5f40f51ecdab 100644
--- a/arch/s390/include/uapi/asm/stat.h
+++ b/arch/s390/include/uapi/asm/stat.h
@@ -7,6 +7,14 @@
#ifndef _S390_STAT_H
#define _S390_STAT_H
+#include <asm/bitsperlong.h>
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_stat2 stat
+#else
+#define __kernel_stat stat
+#endif
+
#ifndef __s390x__
struct __old_kernel_stat {
unsigned short st_dev;
@@ -22,7 +30,7 @@ struct __old_kernel_stat {
unsigned long st_ctime;
};
-struct stat {
+struct __old_kernel_stat2 {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
@@ -75,7 +83,7 @@ struct stat64 {
#else /* __s390x__ */
-struct stat {
+struct __old_kernel_stat {
unsigned long st_dev;
unsigned long st_ino;
unsigned long st_nlink;
diff --git a/arch/sh/include/uapi/asm/stat.h b/arch/sh/include/uapi/asm/stat.h
index a13ffbcccd50..0d3358037558 100644
--- a/arch/sh/include/uapi/asm/stat.h
+++ b/arch/sh/include/uapi/asm/stat.h
@@ -18,7 +18,7 @@ struct __old_kernel_stat {
};
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
-struct stat {
+struct __old_kernel_stat2 {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
@@ -77,7 +77,7 @@ struct stat64 {
unsigned long __unused2;
};
#else
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
diff --git a/arch/sparc/include/uapi/asm/stat.h b/arch/sparc/include/uapi/asm/stat.h
index 6d19c7bdc641..8ace4436a31f 100644
--- a/arch/sparc/include/uapi/asm/stat.h
+++ b/arch/sparc/include/uapi/asm/stat.h
@@ -2,6 +2,13 @@
#define __SPARC_STAT_H
#include <linux/types.h>
+#include <asm/bitsperlong.h>
+
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_stat2 stat
+#else
+#define __kernel_stat stat
+#endif
#if defined(__sparc__) && defined(__arch64__)
/* 64 bit sparc */
@@ -48,7 +55,8 @@ struct stat64 {
#else
/* 32 bit sparc */
-struct stat {
+
+struct __old_kernel_stat2 {
unsigned short st_dev;
ino_t st_ino;
mode_t st_mode;
diff --git a/arch/x86/include/uapi/asm/stat.h b/arch/x86/include/uapi/asm/stat.h
index 5d5754fc3d36..5fa5beeafd86 100644
--- a/arch/x86/include/uapi/asm/stat.h
+++ b/arch/x86/include/uapi/asm/stat.h
@@ -2,11 +2,18 @@
#define _ASM_X86_STAT_H
#include <asm/posix_types.h>
+#include <asm/bitsperlong.h>
#define STAT_HAVE_NSEC 1
+#if __KERNEL_TIME_BITS == 32 || __BITS_PER_LONG == 64
+#define __old_kernel_stat2 stat
+#else
+#define __kernel_stat stat
+#endif
+
#ifdef __i386__
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
@@ -73,7 +80,7 @@ struct stat64 {
#else /* __i386__ */
-struct stat {
+struct __old_kernel_stat2 {
__kernel_ulong_t st_dev;
__kernel_ulong_t st_ino;
__kernel_ulong_t st_nlink;
diff --git a/arch/xtensa/include/uapi/asm/stat.h b/arch/xtensa/include/uapi/asm/stat.h
index 8d9c1d9d82d0..94e40d22eb88 100644
--- a/arch/xtensa/include/uapi/asm/stat.h
+++ b/arch/xtensa/include/uapi/asm/stat.h
@@ -15,7 +15,7 @@
#define STAT_HAVE_NSEC 1
-struct stat {
+struct __old_kernel_stat2 {
unsigned long st_dev;
unsigned long st_ino;
unsigned int st_mode;
This patch series changes the 32-bit time types (timespec/itimerspec) to
the 64-bit types (timespec64/itimerspec64), since 32-bit time types will
break in the year 2038.
This patch series introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
timekeeping: Introduce struct itimerspec64.
timekeeping: Introduce current_kernel_time64().
timekeeping: Change timekeeping_clocktai() with timespec64 type.
hrtimer: Introduce hrtimer_get_res64().
security: Introduce security_settime64().
time: Introduce do_sys_settimeofday64().
time: Introduce jiffies_to_timespec64()/timespec64_to_jiffies().
cputime: Introduce cputime_to_timespec64()/timespec64_to_cputime().
posix-timers: Split up timer_gettime()/timer_settime()/clock_settime()/
clock_gettime()/clock_getres().
posix-timers: Convert timer_gettime()/timer_settime()/clock_settime()/
clock_gettime()/clock_getres() to timespec64/itimerspec64.
mmtimer: Convert to timespec64/itimerspec64.
alarmtimer: Convert to timespec64/itimerspec64.
posix-clock: Convert to timespec64/itimerspec64.
posix-cpu-timers: Convert to timespec64/itimerspec64.
Baolin Wang (24):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
timekeeping:Introduce the current_kernel_time64() function with
timespec64 type
time/hrtimer:Introduce hrtimer_get_res64() with timespec64 type for
getting the timer resolution
security/security: Introduce security_settime64() function with
timespec64 type
time:Introduce the do_sys_settimeofday64() function with timespec64
type
posix-timers:Change the implementation for timer_gettime syscall
function
posix-timers:Convert to the 64bit methods for the timer_gettime
syscall function
posix-timers:Change the implementation for timer_settime syscall
posix-timers:Convert to the 64bit methods for the timer_settime
syscall function
posix-timers:Change the implementation for clock_settime syscall
function
posix-timers:Convert to the 64bit methods for the clock_settime
syscall function
posix-timers:Change the implementation for clock_gettime syscall
function
posix-timers:Convert to the 64bit methods for the clock_gettime
syscall function
posix-timers:Change the implementation for clock_getres syscall
function
posix-timers:Convert to the 64bit methods for the clock_getres
syscall function
timekeeping:Introduce the timekeeping_clocktai() function with
timespec64 type
time/posix-timers:Convert to the 64bit methods for k_clock callback
functions
char/mmtimer:Convert to the 64bit methods for k_clock callback
functions
time/alarmtimer:Convert to the new 64bit methods for k_clock
structure
time/posix-clock:Convert to the 64bit methods for k_clock and
posix_clock_operations structure
time/time:Introduce the
timespec64_to_jiffies()/jiffies_to_timespec64() function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 15 ++
include/linux/hrtimer.h | 12 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/security.h | 25 ++-
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 270 ++++++++++++++++++++++-----------
kernel/time/time.c | 20 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 1 -
security/commoncap.c | 2 +-
security/security.c | 2 +-
24 files changed, 447 insertions(+), 262 deletions(-)
--
1.7.9.5
This is a follow-up to the series posted at [1]. To make review
a little easier, I'm focusing on just one class of system calls
here, and this is one that is handled differently from all the
others.
In particular, for sys_msgctl, sys_semctl and sys_shmctl, I do
not introduce a completely new set of replacement system calls,
but instead extend the existing ones to return data in the
reserved fields of the normal data structure.
This should be completely transparent to any existing user space,
and only after the 32-bit time_t wraps, it will make a difference
in the returned data.
libc implementations will consequently have to provide their own
data structures when they move to 64-bit time_t, and convert
the structures in user space from the ones returned by the kernel.
There are three cases here:
- little-endian architectures (except powerpc and mips) can use
the normal layout and just cast the data structure to the
user space type that contains 64-bit numbers.
- parisc and sparc can do the same thing with big-endian user
space
- little-endian powerpc and most big-endian architectures have
to flip the upper and lower 32-bit halves of the time_t value
in memory, but can otherwise keep using the normal layout
- mips and big-endian xtensa need to be more careful because
they are not consistent in their definitions, and they
have to provide custom libc implementations for the system
calls to use 64-bit time_t.
Please review.
Arnd
[1] http://lwn.net/Articles/643407/
Arnd Bergmann (8):
y2038: asm-generic: extend sysvipc data structures
y2038: mips: extend sysvipc data structures
y2038: x86: extend sysvipc data structures
y2038: parisc: extend sysvipc data structures
y2038: sparc: extend sysvipc data structures
y2038: powerpc: extend sysvipc data structures
y2038: xtensa: extend sysvipc data structures
y2038: ipc: report long times to user space
arch/arm64/include/asm/compat.h | 32 +++++++++----------
arch/mips/include/asm/compat.h | 38 +++++++++++-----------
arch/mips/include/uapi/asm/msgbuf.h | 56 +++++++++++++++++++++-----------
arch/mips/include/uapi/asm/sembuf.h | 15 +++++++--
arch/mips/include/uapi/asm/shmbuf.h | 23 ++++++++++++--
arch/parisc/include/asm/compat.h | 32 +++++++++----------
arch/parisc/include/uapi/asm/msgbuf.h | 32 +++++++++----------
arch/parisc/include/uapi/asm/sembuf.h | 13 ++++----
arch/parisc/include/uapi/asm/shmbuf.h | 18 +++++------
arch/powerpc/include/asm/compat.h | 32 +++++++++----------
arch/powerpc/include/uapi/asm/msgbuf.h | 18 +++++------
arch/powerpc/include/uapi/asm/sembuf.h | 14 ++++----
arch/powerpc/include/uapi/asm/shmbuf.h | 18 +++++------
arch/sparc/include/asm/compat.h | 32 +++++++++----------
arch/sparc/include/uapi/asm/msgbuf.h | 21 ++++++------
arch/sparc/include/uapi/asm/sembuf.h | 15 ++++-----
arch/sparc/include/uapi/asm/shmbuf.h | 20 ++++++------
arch/tile/include/asm/compat.h | 32 +++++++++----------
arch/x86/include/asm/compat.h | 32 +++++++++----------
arch/x86/include/uapi/asm/msgbuf.h | 41 +++++++++++++++++++++++-
arch/x86/include/uapi/asm/sembuf.h | 10 ++++++
arch/x86/include/uapi/asm/shmbuf.h | 58 +++++++++++++++++++++++++++++++++-
arch/xtensa/include/uapi/asm/msgbuf.h | 24 +++++++-------
arch/xtensa/include/uapi/asm/sembuf.h | 16 +++++-----
arch/xtensa/include/uapi/asm/shmbuf.h | 36 +++++----------------
include/linux/msg.h | 7 ++--
include/linux/sem.h | 3 +-
include/linux/shm.h | 7 ++--
include/uapi/asm-generic/msgbuf.h | 16 +++++-----
include/uapi/asm-generic/sembuf.h | 26 +++++++++------
include/uapi/asm-generic/shmbuf.h | 16 +++++-----
ipc/compat.c | 8 +++++
ipc/msg.c | 23 ++++++++------
ipc/sem.c | 32 +++++++++++--------
ipc/shm.c | 21 +++++++-----
35 files changed, 499 insertions(+), 338 deletions(-)
--
2.1.0.rc2
struct timeval uses a 32-bit seconds representation which will
overflow in the year 2038 and beyond. This patch replaces
the usage of struct timeval with ktime_t which is a 64-bit
timestamp and is year 2038 safe.
This patch is part of a larger attempt to remove all instances
of 32-bit timekeeping variables (timeval, timespec, time_t)
which are not year 2038 safe, from the kernel.
The patch is a work-in-progress - correctness of the following
changes is unclear:
(a) Usage of timeval_usec_diff - The function seems to subtract
usec values without caring about the difference of the seconds field.
There may be an implicit assumption in the original code that the
time delta is always of the order of microseconds.
The patch replaces the usage of timeval_usec_diff with
ktime_to_us(ktime_sub()) which computes the real timestamp difference,
not just the difference in the usec field.
(b) printk diffing the tv[i] and tv[i-1] values. The original
printk statement seems to get the order wrong. This patch preserves
that order.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
--
Changes in v2:
- Use the more concise ktime_us_delta
- Preserve the waketime argument in dvb_frontend_sleep_until as
a pointer, fixes bug introduced in v1 of the patch where the caller
doesn't get its timestamp modified.
---
drivers/media/dvb-core/dvb_frontend.c | 40 +++++++++--------------------------
drivers/media/dvb-core/dvb_frontend.h | 3 +--
drivers/media/dvb-frontends/stv0299.c | 11 +++++-----
3 files changed, 17 insertions(+), 37 deletions(-)
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 882ca41..c110e37 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -40,6 +40,7 @@
#include <linux/freezer.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
+#include <linux/ktime.h>
#include <asm/processor.h>
#include "dvb_frontend.h"
@@ -889,42 +890,21 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->thread);
}
-s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
-{
- return ((curtime.tv_usec < lasttime.tv_usec) ?
- 1000000 - lasttime.tv_usec + curtime.tv_usec :
- curtime.tv_usec - lasttime.tv_usec);
-}
-EXPORT_SYMBOL(timeval_usec_diff);
-
-static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
-{
- curtime->tv_usec += add_usec;
- if (curtime->tv_usec >= 1000000) {
- curtime->tv_usec -= 1000000;
- curtime->tv_sec++;
- }
-}
-
/*
* Sleep until gettimeofday() > waketime + add_usec
* This needs to be as precise as possible, but as the delay is
* usually between 2ms and 32ms, it is done using a scheduled msleep
* followed by usleep (normally a busy-wait loop) for the remainder
*/
-void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
+void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec)
{
- struct timeval lasttime;
s32 delta, newdelta;
- timeval_usec_add(waketime, add_usec);
-
- do_gettimeofday(&lasttime);
- delta = timeval_usec_diff(lasttime, *waketime);
+ ktime_add_us(*waketime, add_usec);
+ delta = ktime_us_delta(ktime_get_real(), *waketime);
if (delta > 2500) {
msleep((delta - 1500) / 1000);
- do_gettimeofday(&lasttime);
- newdelta = timeval_usec_diff(lasttime, *waketime);
+ newdelta = ktime_us_delta(ktime_get_real(), *waketime);
delta = (newdelta > delta) ? 0 : newdelta;
}
if (delta > 0)
@@ -2458,13 +2438,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
* include the initialization or start bit
*/
unsigned long swcmd = ((unsigned long) parg) << 1;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
int i;
u8 last = 1;
if (dvb_frontend_debug)
printk("%s switch command: 0x%04lx\n", __func__, swcmd);
- do_gettimeofday(&nexttime);
+ nexttime = ktime_get_real();
if (dvb_frontend_debug)
tv[0] = nexttime;
/* before sending a command, initialize by sending
@@ -2475,7 +2455,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
for (i = 0; i < 9; i++) {
if (dvb_frontend_debug)
- do_gettimeofday(&tv[i + 1]);
+ tv[i+1] = ktime_get_real();
if ((swcmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
@@ -2489,7 +2469,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
err = 0;
fepriv->state = FESTATE_DISEQC;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 816269e..5b64686 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -439,7 +439,6 @@ extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern int dvb_frontend_suspend(struct dvb_frontend *fe);
extern int dvb_frontend_resume(struct dvb_frontend *fe);
-extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
-extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
+extern void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec);
#endif
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b57ecf4..70c8065 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -44,6 +44,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
@@ -404,8 +405,8 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
u8 lv_mask = 0x40;
u8 last = 1;
int i;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
reg0x08 = stv0299_readreg (state, 0x08);
reg0x0c = stv0299_readreg (state, 0x0c);
@@ -418,7 +419,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
if (debug_legacy_dish_switch)
printk ("%s switch command: 0x%04lx\n",__func__, cmd);
- do_gettimeofday (&nexttime);
+ nexttime = ktime_get_real();
if (debug_legacy_dish_switch)
tv[0] = nexttime;
stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
@@ -427,7 +428,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
for (i=0; i<9; i++) {
if (debug_legacy_dish_switch)
- do_gettimeofday (&tv[i+1]);
+ tv[i+1] = ktime_get_real();
if((cmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
@@ -443,7 +444,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
return 0;
--
2.2.0.rc0.207.ga3a616c
This is my second draft of how we could modify the system call interface
in Linux to support user space with 64-bit time_t in addition to the
existing 32-bit time_t based interfaces. In order to avoid spamming people
too much, I've picked the first half of the patches only now, and left
some of the more complex ones for later.
If you are interested in the big picture, see
http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/log/?h=y203…
with currently 42 patches. That number may go up a bit over time, but
only because I plan to split some of the patches into smaller chunks
for review purposes, as opposed to adding more system calls.
As part 1 of the series only switches over half the system calls,
I've left out the bits that changes the ARM and x86 architectures.
There are 24 additional architectures that need to moved over to
the new system calls once the basic patches get merged.
The main part I'm not sure about is how the header files should be
structured in order to make it easy for every libc implementation
to pick out the right definitions of the data structures I had to
modify. Hopefully, people on libc-alpha can help me out here.
The overall approach I have taken here is as follows:
* Since 64-bit architectures already support two versions of each system
call that passes a time value in order to run 32-bit user space,
I'm not adding new system calls for the most part, but instead make
32-bit architectures use the same compat handlers that 64-bit
architectures already use.
* The existing syscall numbers are modified to point to the compat_sys_*
functions, and new numbers are assigned to point to the existing handlers
that now deal with 64-bit time_t based structures
* This series does not touch any ioctl implementation, but should be
otherwise complete regarding the system calls. We are still trying
to find out exactly which ioctls are affected and have not come
up with a complete list at this point. It's probably a good idea
though to do at least the essential ioctls before merging the series,
so we can have a better understanding of how it will be done in the
end.
* Each data structure we need to modify gets a new definition with a
__kernel_ prefix, e.g. struct __kernel_timespec to replace struct
timespec. This keeps the new structures out of the user libc
namespace, but still allows the structure to be integrated into
other data structures, e.g. for ioctl.
* There is no #ifdef in the UAPI headers at this point that would
check for the kind of user space that is in use. Unfortunately,
I believe we will need to add that in order to do some of the
particularly tricky ioctls later.
* At first, all system call implementations are modified, but this
is done in a way that is not supposed to have any ABI-visible
effect on existing architectures.
* After all system calls are converted, we can change one architecture
at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
call table accordingly. In this version, I do it for ARM32, x86-32,
and x86-64 for demonstration purposes.
* A follow-up series changes over all other architectures.
* The last patch in the series changes the CONFIG_COMPAT_TIME
Kconfig symbol to be user visible. Disabling this symbol will
get you a kernel that intentionally breaks support for old tasks
in order to provide an interface that will survive 2038.
This is meant mostly as a debugging help for now, to let people
build a y2038 safe distro, but at some point in the 2030s, we
should remove that option and all the compat handling.
Arnd Bergmann (19):
compat: remove compat_printk
initramfs: use vfs_stat/lstat directly
y2038: introduce linux/compat_time.h header
y2038: introduce CONFIG_COMPAT_TIME
y2038: make linux/compat_time.h usable on 32-bit
y2038: compile compat time code even when CONFIG_COMPAT is not set
y2038: add compat_sys_rt_sigtimedwait variants
y2038: introduce struct __kernel_timespec
y2038: introduce struct __kernel_stat
y2038: use __kernel_stat for sys_newstat syscalls
y2038: introduce and use struct __kernel_rusage
y2038: add compat_{get,put}_timespec64
y2038: add compat handling for sys_semtimedop
y2038: use __kernel_timespec for sys_mq_timed{send,receive}
y2038: introduce timespec64_to_jiffies
y2038: use __kernel_timespec in sys_rt_sigtimedwait
y2038: use __kernel_timespec in sys_futex
y2038: introduce jiffies_to_timespec64
y2038: use __kernel_timespec in sys_sched_rr_get_interval
arch/Kconfig | 11 ++
arch/alpha/include/uapi/asm/stat.h | 4 +
arch/alpha/kernel/osf_sys.c | 4 +-
arch/arm/include/uapi/asm/stat.h | 2 +
arch/arm64/include/asm/compat.h | 11 --
arch/avr32/include/uapi/asm/stat.h | 2 +
arch/blackfin/include/uapi/asm/stat.h | 2 +
arch/cris/include/uapi/asm/stat.h | 2 +
arch/frv/include/uapi/asm/stat.h | 2 +
arch/ia64/include/uapi/asm/stat.h | 4 +
arch/m32r/include/uapi/asm/stat.h | 1 +
arch/m68k/include/uapi/asm/stat.h | 2 +
arch/mips/include/asm/compat.h | 11 --
arch/mips/include/uapi/asm/stat.h | 1 +
arch/mn10300/include/uapi/asm/stat.h | 2 +
arch/parisc/include/asm/compat.h | 11 --
arch/parisc/include/uapi/asm/stat.h | 1 +
arch/powerpc/include/asm/compat.h | 11 --
arch/powerpc/include/uapi/asm/stat.h | 25 +++
arch/s390/include/asm/compat.h | 11 --
arch/s390/include/uapi/asm/stat.h | 24 +++
arch/sh/include/uapi/asm/stat.h | 2 +
arch/sparc/include/asm/compat.h | 11 --
arch/sparc/include/uapi/asm/stat.h | 28 ++++
arch/tile/include/asm/compat.h | 11 --
arch/x86/include/asm/compat.h | 12 +-
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/include/uapi/asm/stat.h | 49 ++++--
arch/x86/kernel/cpu/perf_event.c | 2 +-
arch/xtensa/include/uapi/asm/stat.h | 2 +
fs/Makefile | 1 +
fs/compat.c | 26 ++-
fs/stat.c | 12 +-
include/linux/audit.h | 4 +-
include/linux/compat.h | 232 +--------------------------
include/linux/compat_time.h | 285 +++++++++++++++++++++++++++++++++
include/linux/jiffies.h | 23 ++-
include/linux/resource.h | 8 +-
include/linux/signal.h | 3 +-
include/linux/stat.h | 3 +
include/linux/syscalls.h | 32 ++--
include/linux/thread_info.h | 2 +-
include/linux/time64.h | 17 +-
include/uapi/asm-generic/kernel_stat.h | 36 +++++
include/uapi/asm-generic/stat.h | 12 +-
include/uapi/linux/resource.h | 32 ++++
include/uapi/linux/time.h | 17 ++
init/do_mounts.h | 22 +--
init/initramfs.c | 12 +-
ipc/compat.c | 10 --
ipc/mqueue.c | 16 +-
ipc/sem.c | 60 +++++--
ipc/syscall.c | 7 +
kernel/Makefile | 1 +
kernel/audit.h | 2 +-
kernel/auditsc.c | 14 +-
kernel/compat.c | 184 ++++++++++++++++++---
kernel/exit.c | 6 +-
kernel/futex.c | 10 +-
kernel/sched/core.c | 35 +++-
kernel/signal.c | 13 +-
kernel/sys.c | 23 +--
kernel/sysctl.c | 10 --
kernel/time/time.c | 45 ++++--
65 files changed, 950 insertions(+), 530 deletions(-)
create mode 100644 include/linux/compat_time.h
create mode 100644 include/uapi/asm-generic/kernel_stat.h
--
2.1.0.rc2
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Changes since v2:
-Split the syscall conversion patch into small some patches.
Baolin Wang (22):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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:Split out the guts of the syscall and change the
implementation for timer_gettime
posix-timers:Convert to the 64bit methods for the timer_gettime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for timer_settime
posix-timers:Convert to the 64bit methods for the timer_settime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_settime
posix-timers:Convert to the 64bit methods for the clock_settime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_gettime
posix-timers:Convert to the 64bit methods for the clock_gettime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_getres
posix-timers:Convert to the 64bit methods for the clock_getres
syscall function
time:Introduce the do_sys_settimeofday64() function with timespec64
type
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 64bit methods for k_clock
structure
time/posix-clock:Convert to the 64bit methods for k_clock and
posix_clock_operations structure
time/time:Introduce the timespec64_to_jiffies/jiffies_to_timespec64
function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 15 ++
include/linux/hrtimer.h | 12 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 269 ++++++++++++++++++++++-----------
kernel/time/time.c | 22 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
21 files changed, 428 insertions(+), 254 deletions(-)
--
1.7.9.5
struct timeval uses a 32-bit seconds representation which will
overflow in the year 2038 and beyond. This patch replaces
the usage of struct timeval with ktime_t which is a 64-bit
timestamp and is year 2038 safe.
This patch is part of a larger attempt to remove all instances
of 32-bit timekeeping variables (timeval, timespec, time_t)
which are not year 2038 safe, from the kernel.
The patch is a work-in-progress - correctness of the following
changes is unclear:
(a) Usage of timeval_usec_diff - The function seems to subtract
usec values without caring about the difference of the seconds field.
There may be an implicit assumption in the original code that the
time delta is always of the order of microseconds.
The patch replaces the usage of timeval_usec_diff with
ktime_to_us(ktime_sub()) which computes the real timestamp difference,
not just the difference in the usec field.
(b) printk diffing the tv[i] and tv[i-1] values. The original
printk statement seems to get the order wrong. This patch preserves
that order.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
---
drivers/media/dvb-core/dvb_frontend.c | 46 ++++++++++++-----------------------
drivers/media/dvb-core/dvb_frontend.h | 3 +--
drivers/media/dvb-frontends/stv0299.c | 15 ++++++------
3 files changed, 24 insertions(+), 40 deletions(-)
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 882ca41..48c3daf 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -40,6 +40,7 @@
#include <linux/freezer.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
+#include <linux/ktime.h>
#include <asm/processor.h>
#include "dvb_frontend.h"
@@ -889,42 +890,25 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->thread);
}
-s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
-{
- return ((curtime.tv_usec < lasttime.tv_usec) ?
- 1000000 - lasttime.tv_usec + curtime.tv_usec :
- curtime.tv_usec - lasttime.tv_usec);
-}
-EXPORT_SYMBOL(timeval_usec_diff);
-
-static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
-{
- curtime->tv_usec += add_usec;
- if (curtime->tv_usec >= 1000000) {
- curtime->tv_usec -= 1000000;
- curtime->tv_sec++;
- }
-}
-
/*
* Sleep until gettimeofday() > waketime + add_usec
* This needs to be as precise as possible, but as the delay is
* usually between 2ms and 32ms, it is done using a scheduled msleep
* followed by usleep (normally a busy-wait loop) for the remainder
*/
-void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
+void dvb_frontend_sleep_until(ktime_t waketime, u32 add_usec)
{
- struct timeval lasttime;
+ ktime_t lasttime;
s32 delta, newdelta;
- timeval_usec_add(waketime, add_usec);
+ ktime_add_us(waketime, add_usec);
- do_gettimeofday(&lasttime);
- delta = timeval_usec_diff(lasttime, *waketime);
+ lasttime = ktime_get_real();
+ delta = ktime_to_us(ktime_sub(lasttime, waketime));
if (delta > 2500) {
msleep((delta - 1500) / 1000);
- do_gettimeofday(&lasttime);
- newdelta = timeval_usec_diff(lasttime, *waketime);
+ lasttime = ktime_get_real();
+ newdelta = ktime_to_us(ktime_sub(lasttime, waketime));
delta = (newdelta > delta) ? 0 : newdelta;
}
if (delta > 0)
@@ -2458,24 +2442,24 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
* include the initialization or start bit
*/
unsigned long swcmd = ((unsigned long) parg) << 1;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
int i;
u8 last = 1;
if (dvb_frontend_debug)
printk("%s switch command: 0x%04lx\n", __func__, swcmd);
- do_gettimeofday(&nexttime);
+ nexttime = ktime_get_real();
if (dvb_frontend_debug)
tv[0] = nexttime;
/* before sending a command, initialize by sending
* a 32ms 18V to the switch
*/
fe->ops.set_voltage(fe, SEC_VOLTAGE_18);
- dvb_frontend_sleep_until(&nexttime, 32000);
+ dvb_frontend_sleep_until(nexttime, 32000);
for (i = 0; i < 9; i++) {
if (dvb_frontend_debug)
- do_gettimeofday(&tv[i + 1]);
+ tv[i+1] = ktime_get_real();
if ((swcmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
@@ -2483,13 +2467,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
}
swcmd = swcmd >> 1;
if (i != 8)
- dvb_frontend_sleep_until(&nexttime, 8000);
+ dvb_frontend_sleep_until(nexttime, 8000);
}
if (dvb_frontend_debug) {
printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
err = 0;
fepriv->state = FESTATE_DISEQC;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 816269e..5ddd55f 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -439,7 +439,6 @@ extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern int dvb_frontend_suspend(struct dvb_frontend *fe);
extern int dvb_frontend_resume(struct dvb_frontend *fe);
-extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
-extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
+extern void dvb_frontend_sleep_until(ktime_t waketime, u32 add_usec);
#endif
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b57ecf4..8d30865 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -44,6 +44,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
@@ -404,8 +405,8 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
u8 lv_mask = 0x40;
u8 last = 1;
int i;
- struct timeval nexttime;
- struct timeval tv[10];
+ ktime_t nexttime;
+ ktime_t tv[10];
reg0x08 = stv0299_readreg (state, 0x08);
reg0x0c = stv0299_readreg (state, 0x0c);
@@ -418,16 +419,16 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
if (debug_legacy_dish_switch)
printk ("%s switch command: 0x%04lx\n",__func__, cmd);
- do_gettimeofday (&nexttime);
+ nexttime = ktime_get_real();
if (debug_legacy_dish_switch)
tv[0] = nexttime;
stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
- dvb_frontend_sleep_until(&nexttime, 32000);
+ dvb_frontend_sleep_until(nexttime, 32000);
for (i=0; i<9; i++) {
if (debug_legacy_dish_switch)
- do_gettimeofday (&tv[i+1]);
+ tv[i+1] = ktime_get_real();
if((cmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */
stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
@@ -437,13 +438,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
cmd = cmd >> 1;
if (i != 8)
- dvb_frontend_sleep_until(&nexttime, 8000);
+ dvb_frontend_sleep_until(nexttime, 8000);
}
if (debug_legacy_dish_switch) {
printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
__func__, fe->dvb->num);
for (i = 1; i < 10; i++)
- printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ printk("%d: %d\n", i, (int) ktime_to_us(ktime_sub(tv[i-1], tv[i])));
}
return 0;
--
2.2.0.rc0.207.ga3a616c
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.
It is ready for 2038 year when getting the timer resolution by hrtimer_get_res64() function
with timespec64 type, and it is convenient to delete the old hrtimer_get_res() function
in hrtimer.h file.
Signed-off-by: Baolin Wang <baolin.wang(a)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)
{
--
1.7.9.5
This patch adds current_kernel_time64() function with timespec64 type,
and makes current_kernel_time() 'static inline' and moves it to timekeeping.h
file.
It is convenient for user to get the current kernel time with timespec64 type,
and delete the current_kernel_time() function easily in timekeeping.h file. That
is ready for 2038 when get the current time.
Signed-off-by: Baolin Wang <baolin.wang(a)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)
{
--
1.7.9.5
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Changes since v2:
-Split the syscall conversion patch into small some patches.
*** BLURB HERE ***
Baolin Wang (22):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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:Split out the guts of the syscall and change the
implementation for timer_gettime
posix-timers:Convert to the 64bit methods for the timer_gettime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for timer_settime
posix-timers:Convert to the 64bit methods for the timer_settime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_settime
posix-timers:Convert to the 64bit methods for the clock_settime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_gettime
posix-timers:Convert to the 64bit methods for the clock_gettime
syscall function
posix-timers:Split out the guts of the syscall and change the
implementation for clock_getres
posix-timers:Convert to the 64bit methods for the clock_getres
syscall function
time:Introduce the do_sys_settimeofday64() function with timespec64
type
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 64bit methods for k_clock
structure
time/posix-clock:Convert to the 64bit methods for k_clock and
posix_clock_operations structure
time/time:Introduce the timespec64_to_jiffies/jiffies_to_timespec64
function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 15 ++
include/linux/hrtimer.h | 12 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 269 ++++++++++++++++++++++-----------
kernel/time/time.c | 22 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
21 files changed, 428 insertions(+), 254 deletions(-)
--
1.7.9.5
Apologies for the overly long patch series, I was hoping this
would have been simpler.
This is my first draft of how we could modify the system call interface
in Linux to support user space with 64-bit time_t in addition to the
existing 32-bit time_t based interfaces. For the time being, I'm mainly
interested in feedback about the general approach, to see if this is
a reasonable concept, or whether we should do this in a completely
different way.
The current submission is for a relatively small group of people and
only for the y2038 mailing list, and if we can agree on the approach,
I will post it to a wider group of people and mailing lists next.
The overall approach I have taken here is as follows:
* Since 64-bit architectures already support two versions of each system
call that passes a time value in order to run 32-bit user space,
I'm not adding new system calls for the most part, but instead make
32-bit architectures use the same compat handlers that 64-bit
architectures already use.
* The existing syscall numbers are modified to point to the compat_sys_*
functions, and new numbers are assigned to point to the existing handlers
that now deal with 64-bit time_t based structures
* This series does not touch any ioctl implementation, but should be
otherwise complete regarding the system calls. We are still trying
to find out exactly which ioctls are affected and have not come
up with a complete list at this point. It's probably a good idea
though to do at least the essential ioctls before merging the series,
so we can have a better understanding of how it will be done in the
end.
* Each data structure we need to modify gets a new definition with a
__kernel_ prefix, e.g. struct __kernel_timespec to replace struct
timespec. This keeps the new structures out of the user libc
namespace, but still allows the structure to be integrated into
other data structures, e.g. for ioctl.
* There is no #ifdef in the UAPI headers at this point that would
check for the kind of user space that is in use. Unfortunately,
I believe we will need to add that in order to do some of the
particularly tricky ioctls later.
* At first, all system call implementations are modified, but this
is done in a way that is not supposed to have any ABI-visible
effect on existing architectures.
* After all system calls are converted, we can change one architecture
at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
call table accordingly. In this version, I do it for ARM32, x86-32,
and x86-64 for demonstration purposes.
* A follow-up series changes over all other architectures.
* The last patch in the series changes the CONFIG_COMPAT_TIME
Kconfig symbol to be user visible. Disabling this symbol will
get you a kernel that intentionally breaks support for old tasks
in order to provide an interface that will survive 2038.
This is meant mostly as a debugging help for now, to let people
build a y2038 safe distro, but at some point in the 2030s, we
should remove that option and all the compat handling.
Arnd Bergmann (37):
initramfs: use vfs_stat/lstat directly
y2038: introduce linux/compat_time.h header
y2038: introduce CONFIG_COMPAT_TIME
y2038: make linux/compat_time.h usable on 32-bit
y2038: compile compat time code even when CONFIG_COMPAT is not set
y2038: add compat_sys_rt_sigtimedwait variants
y2038: introduce struct __kernel_rusage
y2038: introduce struct __kernel_timespec
y2038: introduce struct __kernel_stat
y2038: use timespec64 for poll/select/recvmmsg
y2038: add compat_{get,put}_timespec64
y2038: use __kernel_timespec in sys_aio_getevents
y2038: factor out compat fd_set and sigset handling
y2038: add compat handling for sys_recvmmsg
y2038: add compat handling for sys_semtimedop
y2038: extend sysvipc data structures for 64-bit time_t
y2038: ipc: report long times to user space
y2038: introduce {get,put}_itimerspec
y2038: use __kernel_itimerspec in timerfd
y2038: introduce compat_sys_pselect6_time64
y2038: introduce compat_sys_ppoll_time64
y2038: use __kernel_timespec for sys_mq_timed{send,receive}
y2038: make compat_sys_mq_timed{send,receive} usable on 32-bit
y2038: use __kernel_timespec in sys_utimensat
y2038: introduce timespec64_to_jiffies
y2038: use __kernel_timespec in sys_rt_sigtimedwait
y2038: use __kernel_timespec in sys_futex
y2038: introduce jiffies_to_timespec64
y2038: use __kernel_timespec in sys_sched_rr_get_interval
y2038: move compat posix time handling to posix-timers.c
y2038: introduce struct __kernel_timex
y2038: convert all timex users to use __kernel_timex
y2038: convert posix clock syscalls
y2038: ignore new syscalls for now
ARM: use CONFIG_COMPAT_TIME
x86: use COMPAT_SYS_TIME
[NOT YET] y2038: make CONFIG_COMPAT_TIME optional
arch/Kconfig | 12 ++
arch/alpha/include/asm/Kbuild | 4 +
arch/alpha/include/uapi/asm/ipcbuf.h | 1 -
arch/alpha/include/uapi/asm/msgbuf.h | 27 ---
arch/alpha/include/uapi/asm/sembuf.h | 22 --
arch/alpha/include/uapi/asm/shmbuf.h | 38 ----
arch/alpha/include/uapi/asm/stat.h | 4 +
arch/alpha/kernel/osf_sys.c | 8 +-
arch/arm/Kconfig | 1 +
arch/arm/include/asm/unistd.h | 11 +-
arch/arm/include/uapi/asm/stat.h | 2 +
arch/arm/include/uapi/asm/unistd.h | 22 ++
arch/arm/kernel/calls.S | 101 ++++++----
arch/arm/kernel/sys_oabi-compat.c | 9 +-
arch/arm64/include/asm/compat.h | 43 ++--
arch/avr32/include/asm/Kbuild | 4 +
arch/avr32/include/uapi/asm/Kbuild | 1 -
arch/avr32/include/uapi/asm/msgbuf.h | 31 ---
arch/avr32/include/uapi/asm/sembuf.h | 25 ---
arch/avr32/include/uapi/asm/shmbuf.h | 42 ----
arch/avr32/include/uapi/asm/stat.h | 2 +
arch/blackfin/include/uapi/asm/stat.h | 2 +
arch/cris/include/asm/Kbuild | 6 +-
arch/cris/include/uapi/asm/ipcbuf.h | 1 -
arch/cris/include/uapi/asm/msgbuf.h | 33 ---
arch/cris/include/uapi/asm/sembuf.h | 25 ---
arch/cris/include/uapi/asm/shmbuf.h | 42 ----
arch/cris/include/uapi/asm/stat.h | 2 +
arch/frv/include/asm/Kbuild | 4 +
arch/frv/include/uapi/asm/ipcbuf.h | 1 -
arch/frv/include/uapi/asm/msgbuf.h | 32 ---
arch/frv/include/uapi/asm/sembuf.h | 26 ---
arch/frv/include/uapi/asm/shmbuf.h | 43 ----
arch/frv/include/uapi/asm/stat.h | 2 +
arch/ia64/include/asm/Kbuild | 4 +
arch/ia64/include/uapi/asm/ipcbuf.h | 1 -
arch/ia64/include/uapi/asm/msgbuf.h | 27 ---
arch/ia64/include/uapi/asm/sembuf.h | 22 --
arch/ia64/include/uapi/asm/shmbuf.h | 38 ----
arch/ia64/include/uapi/asm/stat.h | 4 +
arch/m32r/include/asm/Kbuild | 4 +
arch/m32r/include/uapi/asm/ipcbuf.h | 1 -
arch/m32r/include/uapi/asm/msgbuf.h | 31 ---
arch/m32r/include/uapi/asm/sembuf.h | 25 ---
arch/m32r/include/uapi/asm/shmbuf.h | 42 ----
arch/m32r/include/uapi/asm/stat.h | 1 +
arch/m68k/include/uapi/asm/stat.h | 2 +
arch/mips/include/asm/compat.h | 49 ++---
arch/mips/include/uapi/asm/msgbuf.h | 56 ++++--
arch/mips/include/uapi/asm/sembuf.h | 15 +-
arch/mips/include/uapi/asm/shmbuf.h | 23 ++-
arch/mips/include/uapi/asm/stat.h | 1 +
arch/mn10300/include/asm/Kbuild | 4 +
arch/mn10300/include/uapi/asm/ipcbuf.h | 1 -
arch/mn10300/include/uapi/asm/msgbuf.h | 31 ---
arch/mn10300/include/uapi/asm/sembuf.h | 25 ---
arch/mn10300/include/uapi/asm/shmbuf.h | 42 ----
arch/mn10300/include/uapi/asm/stat.h | 2 +
arch/parisc/include/asm/compat.h | 43 ++--
arch/parisc/include/uapi/asm/msgbuf.h | 32 +--
arch/parisc/include/uapi/asm/sembuf.h | 13 +-
arch/parisc/include/uapi/asm/shmbuf.h | 18 +-
arch/parisc/include/uapi/asm/stat.h | 1 +
arch/powerpc/include/asm/compat.h | 43 ++--
arch/powerpc/include/uapi/asm/msgbuf.h | 18 +-
arch/powerpc/include/uapi/asm/sembuf.h | 14 +-
arch/powerpc/include/uapi/asm/shmbuf.h | 18 +-
arch/powerpc/include/uapi/asm/stat.h | 25 +++
arch/s390/include/asm/Kbuild | 4 +-
arch/s390/include/asm/compat.h | 43 ++--
arch/s390/include/uapi/asm/msgbuf.h | 37 ----
arch/s390/include/uapi/asm/sembuf.h | 29 ---
arch/s390/include/uapi/asm/shmbuf.h | 48 -----
arch/s390/include/uapi/asm/stat.h | 24 +++
arch/s390/kernel/time.c | 2 +-
arch/sh/include/uapi/asm/stat.h | 2 +
arch/sparc/include/asm/compat.h | 43 ++--
arch/sparc/include/uapi/asm/msgbuf.h | 21 +-
arch/sparc/include/uapi/asm/sembuf.h | 15 +-
arch/sparc/include/uapi/asm/shmbuf.h | 20 +-
arch/sparc/include/uapi/asm/stat.h | 28 +++
arch/tile/include/asm/compat.h | 43 ++--
arch/x86/Kconfig | 1 +
arch/x86/include/asm/compat.h | 44 ++--
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/include/asm/unistd.h | 21 +-
arch/x86/include/uapi/asm/msgbuf.h | 41 +++-
arch/x86/include/uapi/asm/sembuf.h | 10 +
arch/x86/include/uapi/asm/shmbuf.h | 58 +++++-
arch/x86/include/uapi/asm/stat.h | 49 +++--
arch/x86/kernel/cpu/perf_event.c | 2 +-
arch/x86/syscalls/syscall_32.tbl | 98 +++++----
arch/xtensa/include/uapi/asm/msgbuf.h | 24 +--
arch/xtensa/include/uapi/asm/sembuf.h | 16 +-
arch/xtensa/include/uapi/asm/shmbuf.h | 36 +---
arch/xtensa/include/uapi/asm/stat.h | 2 +
drivers/ptp/ptp_clock.c | 2 +-
fs/Makefile | 1 +
fs/aio.c | 54 +++--
fs/compat.c | 198 +++++++++++-------
fs/eventpoll.c | 12 +-
fs/select.c | 64 +++---
fs/stat.c | 12 +-
fs/timerfd.c | 13 +-
fs/utimes.c | 19 +-
include/linux/audit.h | 4 +-
include/linux/compat.h | 261 +++---------------------
include/linux/compat_time.h | 298 +++++++++++++++++++++++++++
include/linux/hrtimer.h | 2 +-
include/linux/jiffies.h | 23 ++-
include/linux/msg.h | 7 +-
include/linux/poll.h | 10 +-
include/linux/posix-clock.h | 2 +-
include/linux/posix-timers.h | 11 +-
include/linux/resource.h | 8 +-
include/linux/sem.h | 3 +-
include/linux/shm.h | 7 +-
include/linux/signal.h | 3 +-
include/linux/socket.h | 4 +-
include/linux/stat.h | 3 +
include/linux/syscalls.h | 73 ++++---
include/linux/thread_info.h | 8 +-
include/linux/time.h | 11 +-
include/linux/time64.h | 25 ++-
include/linux/timex.h | 6 +-
include/net/compat.h | 3 +
include/uapi/asm-generic/kernel_stat.h | 36 ++++
include/uapi/asm-generic/msgbuf.h | 16 +-
include/uapi/asm-generic/sembuf.h | 26 ++-
include/uapi/asm-generic/shmbuf.h | 16 +-
include/uapi/asm-generic/stat.h | 12 +-
include/uapi/linux/net.h | 1 +
include/uapi/linux/resource.h | 32 +++
include/uapi/linux/time.h | 17 ++
include/uapi/linux/timex.h | 45 +++++
init/do_mounts.h | 22 +-
init/initramfs.c | 14 +-
ipc/compat.c | 18 +-
ipc/compat_mq.c | 28 ---
ipc/mqueue.c | 140 +++++++++----
ipc/msg.c | 23 ++-
ipc/sem.c | 92 ++++++---
ipc/shm.c | 21 +-
ipc/syscall.c | 9 +-
kernel/Makefile | 1 +
kernel/audit.h | 2 +-
kernel/auditsc.c | 14 +-
kernel/compat.c | 340 +++++++++++++------------------
kernel/exit.c | 6 +-
kernel/futex.c | 10 +-
kernel/sched/core.c | 35 +++-
kernel/signal.c | 13 +-
kernel/sys.c | 23 ++-
kernel/sys_ni.c | 38 ++++
kernel/time/alarmtimer.c | 13 +-
kernel/time/hrtimer.c | 20 +-
kernel/time/ntp.c | 16 +-
kernel/time/ntp_internal.h | 4 +-
kernel/time/posix-clock.c | 2 +-
kernel/time/posix-cpu-timers.c | 14 +-
kernel/time/posix-timers.c | 357 ++++++++++++++++++++++++++++-----
kernel/time/time.c | 63 ++++--
kernel/time/timekeeping.c | 2 +-
net/compat.c | 18 +-
net/socket.c | 52 ++++-
scripts/checksyscalls.sh | 25 +++
167 files changed, 2564 insertions(+), 2289 deletions(-)
delete mode 100644 arch/alpha/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/alpha/include/uapi/asm/msgbuf.h
delete mode 100644 arch/alpha/include/uapi/asm/sembuf.h
delete mode 100644 arch/alpha/include/uapi/asm/shmbuf.h
delete mode 100644 arch/avr32/include/uapi/asm/msgbuf.h
delete mode 100644 arch/avr32/include/uapi/asm/sembuf.h
delete mode 100644 arch/avr32/include/uapi/asm/shmbuf.h
delete mode 100644 arch/cris/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/cris/include/uapi/asm/msgbuf.h
delete mode 100644 arch/cris/include/uapi/asm/sembuf.h
delete mode 100644 arch/cris/include/uapi/asm/shmbuf.h
delete mode 100644 arch/frv/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/frv/include/uapi/asm/msgbuf.h
delete mode 100644 arch/frv/include/uapi/asm/sembuf.h
delete mode 100644 arch/frv/include/uapi/asm/shmbuf.h
delete mode 100644 arch/ia64/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/ia64/include/uapi/asm/msgbuf.h
delete mode 100644 arch/ia64/include/uapi/asm/sembuf.h
delete mode 100644 arch/ia64/include/uapi/asm/shmbuf.h
delete mode 100644 arch/m32r/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/m32r/include/uapi/asm/msgbuf.h
delete mode 100644 arch/m32r/include/uapi/asm/sembuf.h
delete mode 100644 arch/m32r/include/uapi/asm/shmbuf.h
delete mode 100644 arch/mn10300/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/mn10300/include/uapi/asm/msgbuf.h
delete mode 100644 arch/mn10300/include/uapi/asm/sembuf.h
delete mode 100644 arch/mn10300/include/uapi/asm/shmbuf.h
delete mode 100644 arch/s390/include/uapi/asm/msgbuf.h
delete mode 100644 arch/s390/include/uapi/asm/sembuf.h
delete mode 100644 arch/s390/include/uapi/asm/shmbuf.h
create mode 100644 include/linux/compat_time.h
create mode 100644 include/uapi/asm-generic/kernel_stat.h
--
2.1.0.rc2
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.
It is ready for 2038 year when getting the timer resolution by hrtimer_get_res64() function
with timespec64 type, and it is convenient to delete the old hrtimer_get_res() function
in hrtimer.h file.
Signed-off-by: Baolin Wang <baolin.wang(a)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)
{
--
1.7.9.5
This patch adds current_kernel_time64() function with timespec64 type,
and makes current_kernel_time() 'static inline' and moves it to timekeeping.h
file.
It is convenient for user to get the current kernel time with timespec64 type,
and delete the current_kernel_time() function easily in timekeeping.h file. That
is ready for 2038 when get the current time.
Signed-off-by: Baolin Wang <baolin.wang(a)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)
{
--
1.7.9.5
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Changes since V1:
-Split some patch into small patch.
-Change the methods for converting the syscall and add some default function for new 64bit methods for syscall function.
-Introduce the new function do_sys_settimeofday64() and move do_sys_settimeofday() function to head file.
-Modify the EXPORT_SYMPOL issue.
-Add new 64bit methods in cputime_nsecs.h file.
-Modify some patch logs.
Baolin Wang (15):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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
posix-timers:Split out the guts of the syscall and change the
implementation
posix-timers:Convert to the 64bit methods for the syscall function
time:Introduce the do_sys_settimeofday64() function with timespec64
type
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 and
posix_clock_operations structure
time/time:Introduce the timespec64_to_jiffies/jiffies_to_timespec64
function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 15 ++
include/linux/hrtimer.h | 12 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 269 ++++++++++++++++++++++-----------
kernel/time/time.c | 22 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
21 files changed, 428 insertions(+), 254 deletions(-)
--
1.7.9.5
On 30 April 2015 at 00:31, Mark Brown <broonie(a)kernel.org> wrote:
> On Wed, Apr 29, 2015 at 06:04:58PM +0200, Arnd Bergmann wrote:
> > On Wednesday 29 April 2015 22:55:23 Baolin Wang wrote:
>
> > Last time, you actually had more people than necessary on Cc, and that
> can
> > end up in spam filters. If someone is a maintainer for just one or two
> patches
> > out of the series, it can be better to add an explicit 'Cc:
> person(a)example.org'
> > statement in those patches, and not Cc them for the whole series.
>
> But do include people on the cover letter or otherwise make sure they've
> got some idea what the series overall is all about (especially if
> there's interdependencies) to avoid confusions.
>
Ok, Thanks for your suggestions, and i'll send out the patch series asap.
--
Baolin.wang
Best Regards
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Changes since V1:
-Split some patch into small patch.
-Add some default function for new 64bit methods for syscall function.
-Move do_sys_settimeofday() function to head file.
-Modify the EXPORT_SYMPOL issue.
-Add new 64bit methods in cputime_nsecs.h file.
Baolin Wang (15):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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
posix-timers:Split out the guts of the syscall and change the
implementation
posix-timers:Convert to the 64bit methods for the syscall function
time:Introduce the do_sys_settimeofday64() function with timespec64
type
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 and
posix_clock_operations structure
time/time:Introduce the timespec64_to_jiffies/jiffies_to_timespec64
function
cputime: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/itimerspec type
arch/powerpc/include/asm/cputime.h | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/asm-generic/cputime_nsecs.h | 4 +-
include/linux/cputime.h | 15 ++
include/linux/hrtimer.h | 12 +-
include/linux/jiffies.h | 21 ++-
include/linux/posix-clock.h | 10 +-
include/linux/posix-timers.h | 18 +--
include/linux/time64.h | 35 +++++
include/linux/timekeeping.h | 26 +++-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 269 ++++++++++++++++++++++-----------
kernel/time/time.c | 22 +--
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
21 files changed, 428 insertions(+), 254 deletions(-)
--
1.7.9.5
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Changes since V0:
-Split some patch into small patch.
-Modify some patch logs.
-Change the methods for converting the syscall function.
-Introduce the new function do_sys_settimeofday64().
Baolin Wang (14):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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
posix-timers:Introduce the 64bit methods for posix-timer.c file
time:Introduce the do_sys_settimeofday64() function with timespec64
type
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 and
posix_clock_operations structure
time/time:Introduce the timespec64_to_jiffies/jiffies_to_timespec64
function
cputime: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 | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 +++--
drivers/ptp/ptp_clock.c | 26 +---
include/asm-generic/cputime_jiffies.h | 10 +-
include/linux/cputime.h | 15 ++
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 | 25 +++
include/linux/timekeeping.h | 16 +-
kernel/time/alarmtimer.c | 43 +++---
kernel/time/hrtimer.c | 10 +-
kernel/time/posix-clock.c | 20 +--
kernel/time/posix-cpu-timers.c | 83 +++++-----
kernel/time/posix-timers.c | 269 ++++++++++++++++++++++-----------
kernel/time/time.c | 41 ++++-
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
20 files changed, 414 insertions(+), 245 deletions(-)
--
1.7.9.5
This patch series changes 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 introduces new methods with timespec64/itimerspec64 type,
and removes the old ones with timespec/itimerspec type for posix_clock_operations
and k_clock structure.
Also introduces some new functions with timespec64/itimerspec64 type, like current_kernel_time64(),
hrtimer_get_res64(), cputime_to_timespec64() and timespec64_to_cputime().
Baolin Wang (11):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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 and
posix_clock_operations structure
cputime: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 | 6 +-
arch/s390/include/asm/cputime.h | 8 +-
drivers/char/mmtimer.c | 36 ++++----
drivers/ptp/ptp_clock.c | 26 ++----
include/asm-generic/cputime_jiffies.h | 10 +--
include/linux/cputime.h | 15 ++++
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 | 13 +++
include/linux/timekeeping.h | 14 ++-
kernel/time/alarmtimer.c | 43 ++++-----
kernel/time/hrtimer.c | 10 +--
kernel/time/posix-clock.c | 20 ++---
kernel/time/posix-cpu-timers.c | 83 +++++++++--------
kernel/time/posix-timers.c | 157 +++++++++++++++++++--------------
kernel/time/time.c | 21 +++++
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
20 files changed, 302 insertions(+), 211 deletions(-)
--
1.7.9.5
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_operations
and k_clock structure.
Changes since v4:
- Modify the conversion between the itimerspec64 and itimerspec for 64bit.
- Continue to split up and merge the patch.
- Explain more for the patch log.
- Re-order the patch of the patch series.
Next step will replace the other callback pointers of k_clock structure.
Baolin Wang (11):
linux/time64.h:Introduce the 'struct itimerspec64' for 64bit
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 and
posix_clock_operations structure
cputime: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 | 36 ++++----
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 | 45 ++++++++++
include/linux/timekeeping.h | 14 ++-
kernel/time/alarmtimer.c | 43 ++++-----
kernel/time/hrtimer.c | 10 +--
kernel/time/posix-clock.c | 20 ++---
kernel/time/posix-cpu-timers.c | 83 +++++++++--------
kernel/time/posix-timers.c | 157 +++++++++++++++++++--------------
kernel/time/time.c | 21 +++++
kernel/time/timekeeping.c | 6 +-
kernel/time/timekeeping.h | 2 +-
19 files changed, 365 insertions(+), 199 deletions(-)
--
1.7.9.5
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(-)
--
1.7.9.5
On Wednesday 15 April 2015 17:41:28 Miroslav Lichvar wrote:
> On systems with 32-bit time_t, it seems there are quite a few problems
> that applications may have with time overflowing in year 2038. Beside
> getting in an unexpected state by not checking integer operations with
> time_t variables, some system calls have unexpected behavior, e.g. the
> system time can't be set back to the current time (negative value),
> timers with the ABSTIME flag can't be set (negative value) or they
> expire immediately (current time is always larger).
>
> It would be unrealistic to expect all applications to be able to handle
> all these problems. Year 2038 is still many years away, but this can be
> a problem even now. The clock can be set close to the overflow
> accidentally or maliciously, e.g. when the clock is synchronized over
> network by NTP or PTP.
>
> This patch sets a maximum value of the system time to prevent the system
> time from getting too close to the overflow. The time can't be set to a
> larger value. When the maximum is reached in normal time accumulation,
> the clock will be stepped back by one week.
>
> A new kernel sysctl time_max is added to select the maximum time. It can
> be set to 0 for no limit, 1 for one week before 32-bit time_t overflow,
> and 2 for one week before ktime_t overflow. The default value is 1 with
> 32-bit time_t and 2 with 64-bit time_t. This can be changed later to be
> always 2 when 64-bit versions of system calls using 32-bit time_t are
> available.
>
> Signed-off-by: Miroslav Lichvar <mlichvar(a)redhat.com>
I have just created a y2038(a)lists.linaro.org mailing list, added to Cc in
this reply.
The patch looks basically ok to me, though I have no opinion on whether
a sysctl is the best API for configuring this.
Arnd
> ---
> Documentation/sysctl/kernel.txt | 19 +++++++++++++
> include/linux/timekeeping.h | 5 ++++
> include/uapi/linux/sysctl.h | 1 +
> kernel/sysctl.c | 9 ++++++
> kernel/sysctl_binary.c | 1 +
> kernel/time/timekeeping.c | 62 +++++++++++++++++++++++++++++++++++++----
> 6 files changed, 91 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
> index 83ab256..08e4f28 100644
> --- a/Documentation/sysctl/kernel.txt
> +++ b/Documentation/sysctl/kernel.txt
> @@ -82,6 +82,7 @@ show up in /proc/sys/kernel:
> - sysctl_writes_strict
> - tainted
> - threads-max
> +- time_max
> - unknown_nmi_panic
> - watchdog_thresh
> - version
> @@ -847,6 +848,24 @@ can be ORed together:
>
> ==============================================================
>
> +time_max:
> +
> +Select the maximum allowed value of the system time. The system clock cannot be
> +set to a larger value and when it reaches the maximum on its own, it will be
> +stepped back by one week.
> +
> +0: No limit.
> +
> +1: One week before 32-bit time_t overflows, i.e. Jan 12 03:14:07 UTC 2038.
> + This is currently the default value with 32-bit time_t, but it will likely
> + change when 64-bit versions of system calls using time_t are available.
> +
> +2: One week before time in the internal kernel representation (ktime_t)
> + overflows, i.e. Apr 4 23:47:16 UTC 2262. This is the default value with
> + 64-bit time_t.
> +
> +==============================================================
> +
> unknown_nmi_panic:
>
> The value in this file affects behavior of handling NMI. When the
> diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
> index 99176af..51fc970 100644
> --- a/include/linux/timekeeping.h
> +++ b/include/linux/timekeeping.h
> @@ -5,6 +5,11 @@
>
> void timekeeping_init(void);
> extern int timekeeping_suspended;
> +extern int sysctl_time_max;
> +
> +struct ctl_table;
> +extern int sysctl_time_max_handler(struct ctl_table *table, int write,
> + void __user *buffer, size_t *length, loff_t *ppos);
>
> /*
> * Get and set timeofday
> diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h
> index 0956373..8fd2aab 100644
> --- a/include/uapi/linux/sysctl.h
> +++ b/include/uapi/linux/sysctl.h
> @@ -154,6 +154,7 @@ enum
> KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
> KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
> KERN_PANIC_ON_WARN=77, /* int: call panic() in WARN() functions */
> + KERN_TIMEMAX=78, /* int: select maximum allowed system time */
> };
>
>
> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> index ce410bb..6713a5b 100644
> --- a/kernel/sysctl.c
> +++ b/kernel/sysctl.c
> @@ -1120,6 +1120,15 @@ static struct ctl_table kern_table[] = {
> .extra1 = &zero,
> .extra2 = &one,
> },
> + {
> + .procname = "time_max",
> + .data = &sysctl_time_max,
> + .maxlen = sizeof(int),
> + .mode = 0644,
> + .proc_handler = sysctl_time_max_handler,
> + .extra1 = &zero,
> + .extra2 = &two,
> + },
> { }
> };
>
> diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
> index 7e7746a..66c0946 100644
> --- a/kernel/sysctl_binary.c
> +++ b/kernel/sysctl_binary.c
> @@ -138,6 +138,7 @@ static const struct bin_table bin_kern_table[] = {
> { CTL_INT, KERN_MAX_LOCK_DEPTH, "max_lock_depth" },
> { CTL_INT, KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" },
> { CTL_INT, KERN_PANIC_ON_WARN, "panic_on_warn" },
> + { CTL_INT, KERN_TIMEMAX, "time_max" },
> {}
> };
>
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index 946acb7..112932f 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -32,6 +32,9 @@
> #define TK_MIRROR (1 << 1)
> #define TK_CLOCK_WAS_SET (1 << 2)
>
> +#define SEC_PER_DAY (24 * 3600)
> +#define SEC_PER_WEEK (7 * SEC_PER_DAY)
> +
> /*
> * The most important data for readout fits into a single 64 byte
> * cache line.
> @@ -884,6 +887,37 @@ EXPORT_SYMBOL(getnstime_raw_and_real);
>
> #endif /* CONFIG_NTP_PPS */
>
> +/* Maximum allowed system time as a sysctl setting and in seconds */
> +int sysctl_time_max __read_mostly;
> +static u64 time_max_sec __read_mostly;
> +
> +static void update_time_max_sec(int tm)
> +{
> + if (tm > 1) {
> + /* One week before ktime_t overflow */
> + time_max_sec = KTIME_SEC_MAX - SEC_PER_WEEK;
> + } else if (tm == 1) {
> + /* One week before 32-bit time_t overflow */
> + time_max_sec = 0x7fffffff - SEC_PER_WEEK;
> + } else {
> + /* No limit */
> + time_max_sec = -1;
> + }
> +}
> +
> +int sysctl_time_max_handler(struct ctl_table *table, int write,
> + void __user *buffer, size_t *length, loff_t *ppos)
> +{
> + int rc;
> +
> + rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
> + if (rc)
> + return rc;
> +
> + update_time_max_sec(sysctl_time_max);
> + return 0;
> +}
> +
> /**
> * do_gettimeofday - Returns the time of day in a timeval
> * @tv: pointer to the timeval to be set
> @@ -912,7 +946,7 @@ int do_settimeofday64(const struct timespec64 *ts)
> struct timespec64 ts_delta, xt;
> unsigned long flags;
>
> - if (!timespec64_valid_strict(ts))
> + if (!timespec64_valid_strict(ts) || ts->tv_sec >= time_max_sec)
> return -EINVAL;
>
> raw_spin_lock_irqsave(&timekeeper_lock, flags);
> @@ -965,7 +999,7 @@ int timekeeping_inject_offset(struct timespec *ts)
>
> /* Make sure the proposed value is valid */
> tmp = timespec64_add(tk_xtime(tk), ts64);
> - if (!timespec64_valid_strict(&tmp)) {
> + if (!timespec64_valid_strict(&tmp) || tmp.tv_sec >= time_max_sec) {
> ret = -EINVAL;
> goto error;
> }
> @@ -1238,6 +1272,10 @@ void __init timekeeping_init(void)
> write_seqcount_begin(&tk_core.seq);
> ntp_init();
>
> + /* For now, prevent 32-bit time_t overflow by default */
> + sysctl_time_max = sizeof(time_t) > 4 ? 2 : 1;
> + update_time_max_sec(sysctl_time_max);
> +
> clock = clocksource_default_clock();
> if (clock->enable)
> clock->enable(clock);
> @@ -1687,23 +1725,35 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
>
> while (tk->tkr_mono.xtime_nsec >= nsecps) {
> int leap;
> + s64 step;
>
> tk->tkr_mono.xtime_nsec -= nsecps;
> tk->xtime_sec++;
>
> /* Figure out if its a leap sec and apply if needed */
> leap = second_overflow(tk->xtime_sec);
> - if (unlikely(leap)) {
> + step = leap;
> +
> + /* If the system time reached the maximum, step it back */
> + if (unlikely(tk->xtime_sec >= time_max_sec)) {
> + step = time_max_sec - tk->xtime_sec - SEC_PER_WEEK;
> + printk(KERN_NOTICE
> + "Clock: maximum time reached, stepping back\n");
> + }
> +
> + if (unlikely(step)) {
> struct timespec64 ts;
>
> - tk->xtime_sec += leap;
> + tk->xtime_sec += step;
>
> - ts.tv_sec = leap;
> + ts.tv_sec = step;
> ts.tv_nsec = 0;
> tk_set_wall_to_mono(tk,
> timespec64_sub(tk->wall_to_monotonic, ts));
>
> - __timekeeping_set_tai_offset(tk, tk->tai_offset - leap);
> + if (leap)
> + __timekeeping_set_tai_offset(tk,
> + tk->tai_offset - leap);
>
> clock_set = TK_CLOCK_WAS_SET;
> }
>
Hi,
I've created a new mailing list on the Linaro mailing list server for
discussing the kernel patches for y2038:
https://lists.linaro.org/mailman/listinfo/y2038
Please join if you are interested in discussing these or want to send
patches. The intention at the moment much to keep this list explicitly
open to newbies, so we will get a lot of incorrect patches there along
with other patches. Patches can get sent here for an initial review
before they get sent to the real maintainers, or you can put the list
on Cc when sending a patch that should be applied and you already know
what you are doing.
We already got a lot of patches last year through the Outreachy
(then known as OPW) application process, and John and I also use
this work as part of our Linaro job to train new kernel developers.
There also a wiki page at http://kernelnewbies.org/y2038 to describe
what we are doing, and anybody who wants to help out here is
welcome to contribute patches on this list.
Arnd
On Saturday 11 April 2015 18:46:54 Baolin Wang wrote:
> This patch introduces the cputime_to_timespec64() function and
> jiffies_to_timespec64() function for converting the jiffies
> value to timespec64 value.
>
> Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
> ---
> include/asm-generic/cputime_jiffies.h | 6 ++++++
> include/linux/jiffies.h | 2 ++
> kernel/time/time.c | 14 ++++++++++++++
> 3 files changed, 22 insertions(+)
>
> diff --git a/include/asm-generic/cputime_jiffies.h b/include/asm-generic/cputime_jiffies.h
> index fe386fc..c0c4fcb 100644
> --- a/include/asm-generic/cputime_jiffies.h
> +++ b/include/asm-generic/cputime_jiffies.h
> @@ -52,6 +52,12 @@ typedef u64 __nocast cputime64_t;
> jiffies_to_timespec(cputime_to_jiffies(__ct),__val)
>
> /*
> + * Convert cputime to timespec64.
> + */
> +#define cputime_to_timespec64(__ct,__val) \
> + jiffies_to_timespec64(cputime_to_jiffies(__ct),__val)
> +
> +/*
> * Convert cputime to timeval and back.
You missed an important piece here: cputime_to_timespec64 is architecture
specific, and arch/s390 as well as arch/powerpc have their own implementations,
so you have to introduce all three cputime_to_timespec64 implementations
before using it.
Arnd
On Saturday 11 April 2015 18:46:50 Baolin Wang wrote:
> 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 implements
> some callback function.
>
> This patch also converts the timespec type to timespec64 type for timekeeping_clocktai
> function which is used only in the posix-timers.c file.
>
> Next step will migrate all the k_clock users to use the new methods with timespec64 type,
> and it contains the files of mmtimer.c, alarmtimer.c, posix-clock.c and
> posix-cpu-timers.c.
>
> Signed-off-by: Baolin Wang <baolin.wang(a)linaro.org>
The changes in this patch all look good, but as I mentioned, I would
separate the two things you do here:
> 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,
a) introducing and using the function pointers
> @@ -278,9 +284,9 @@ 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,
and b) converting some of the k_clock definitions.
Arnd
On Saturday 11 April 2015 18:46:49 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(a)linaro.org>
>
Looks good.
Arnd