On Thursday 22 October 2015 12:08:14 Amitoj Kaur Chawla wrote:
> Hi Arnd,
>
>
> A couple of doubts I had while working on some patches.
Hi Amitoj,
I've put the y2038 and outreachy mailing lists on Cc, I hope that's
ok with you.
You ask good and important questions, and it will help others to
read my reply as well.
> I was working on drivers/net/wireless/atmel.c which has time_t in it.
> According to the y2038 page it should be replaced with ktime_t. But
> while reading online on y2038, I found time64_t as well.
> My question, what is the difference between time64_t and ktime_t and
> how do you decide which to use where?
time64_t uses seconds, while ktime_t uses nanoseconds. They are both
appropriate solutions for the problem, but it depends on the driver's
requirements which one work better. Most drivers want sub-second
resolution, so ktime_t has to be used. When a driver is only interested
in seconds, using time64_t is more efficient, because it avoids the
64-bit integer division required to convert nanoseconds into seconds.
> I found another patch in an archive where you've mentioned
> ktime_get(), ktime_get_real(), ktime_get_ts64(),
> ktime_get_real_ts64(), ktime_get_seconds() and
> ktime_get_real_seconds().
> What is the difference between ktime_get() and ktime_get_ts64()?
ktime_get_ts64() returns a 'struct timespec64' rather than 'ktime_t'.
The two are essentially equivalent, but using ktime_t is generally
more preferred, except that converting ktime_t into timespec64 later
is again an expensive operation. If a driver wants separate
seconds/nanoseconds fields, using timespec64 is better.
> You've also mentioned there that 'real is used when driver wants to
> know wallclock but is okay with time going backwards.'
> I didn't understand this, how do you know that the driver is 'okay
> with time going backwards' ?
Most of them are not: if a driver wants to know how much time has
passed between two events, and it gets a negative answer, things
can go wrong.
An example for a driver that does not care about time going backwards
is one that just prints the current time in a printk() statement
and does not compare it to another time value.
There are also examples where you have to use 'real' time, in particular
when the time value is passed through an external interface with a
known format (e.g. to user processes, on the network, or stored on disk).
Here, changing the code to monotonic time causes problems for the code
on the other end of that interface.
Arnd
Hi,
I am following up on my previous email (mentioned below) to see if you had a
chance to review it.
Is there any more information you'd like to know from my end regarding the
email list?
Let me know your current target audience so that I can get back to you with
relevant information.
Let me know if we can schedule a quick call.
I appreciate a response from you.
Warm regards,
Emily
From: Emily Collins [mailto:emily.collins@edatalead.com]
Sent: Thursday, October 15, 2015 7:18 AM
To: 'y2038(a)lists.linaro.org'
Subject: Canonical end users
Hi,
Would you like to acquire list of Canonical end users?
Some of the technology contact database which you might be interested:
. Redhat
. Linux.
. Centos.
. Ubuntu and more.
Information fields: Contact First Name, Last Name, Job Title, Email Address,
Phone Number, Fax Number, Company Name, Company Physical Address, and
Company Web Address, SIC Code, NAICS code, Primary Industry, Employee Size,
Revenue, Technology Type
If you have any other requirement, let me know your criteria and I'll get
back to you with more relevant information.
Thank you and I look forward to hearing from you.
Regards
Emily Collins
Sr. Marketing Executive
________________________________________
We respect your privacy. If you do not wish to receive future e-mail please
reply with "REMOVE".
On Sunday 18 October 2015 21:21:22 Deepa Dinamani wrote:
> Hi Arnd,
>
> I'm working on the usbtest ioctl task.
> I was trying to figure out how to copy a timespec64 value to userspace.
(I'm adding the y2038 and outreachy lists to Cc, hope that's ok for you)
> I found this patch online:
> https://lists.linaro.org/pipermail/y2038/2015-May/000201.html
> But, this doesn't seem to be merged anywhere.
> Is the plan to expose timespec64 through __kernel_timespec still on?
Yes, that is the current plan, but there are a number of dependencies.
However, the driver here uses 'struct timeval', not 'struct timespec',
and I do *not* plan to have the same infrastructure for timeval that
I submitted for timespec. Almost all user space facing users of timeval
have been replaced with timespec based interfaces (this one has not)
over time.
We should still keep this for backwards compatibility, but I think it's
better to solve the timeval users case-by-case rather than adding
infrastructure for it.
> I'm using the staging tree as the usb/misc folder does not have a specific
> maintainer.
I checked using "git log torvalds/master..next/master --merges drivers/usb/misc/"
and found that Felipe Balbi has queued up one patch for this driver in his
tree at git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git#next
(see the list in linux-next/Next/Trees for a mapping from tree names to
URLS). It probably makes sense to use that tree as a base, even if Felipe
is not the official maintainer.
Arnd
Hi,
Would you like to acquire list of Canonical end users?
Some of the technology contact database which you might be interested:
. Redhat
. Linux.
. Centos.
. Ubuntu and more.
Information fields: Contact First Name, Last Name, Job Title, Email Address,
Phone Number, Fax Number, Company Name, Company Physical Address, and
Company Web Address, SIC Code, NAICS code, Primary Industry, Employee Size,
Revenue, Technology Type
If you have any other requirement, let me know your criteria and I'll get
back to you with more relevant information.
Thank you and I look forward to hearing from you.
Regards
Emily Collins
Sr. Marketing Executive
________________________________________
We respect your privacy. If you do not wish to receive future e-mail please
reply with "REMOVE".
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Delivery Label is attached to this email.
Thanks and best regards,
Eddie Leblanc,
Support Agent.
Hi everyone,
This is a set of changes for network drivers and core code to
get rid of the use of time_t and derived data structures.
I have a longer set of patches that enables me to build kernels
with the time_t definition removed completely as a help to find
y2038 overflow issues. This is the subset for networking that
contains all code that has a reasonable way of fixing at the
moment and that is either commonly used (in one of the defconfigs)
or that blocks building a whole subsystem.
Most of the patches in this series should be noncontroversial,
but the last two that I marked [RFC] are a bit tricky and
need input from people that are more familiar with the code than
I am. All 12 patches are independent of one another and can
be applied in any order, so feel free to pick all that look
good.
Patches that are not included here are:
- disabling less common device drivers that I don't have a fix
for yet, this includes
drivers/net/ethernet/brocade/bna/bfa_ioc.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
drivers/net/ethernet/tile/tilegx.c
drivers/net/hamradio/baycom_ser_fdx.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath9k/
drivers/net/wireless/ath/ath9k/
drivers/net/wireless/atmel.c
drivers/net/wireless/prism54/isl_38xx.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/net/wireless/rtlwifi/
drivers/net/wireless/ti/wlcore/
drivers/staging/ozwpan/
net/atm/mpoa_caches.c
net/atm/mpoa_proc.c
net/dccp/probe.c
net/ipv4/tcp_probe.c
net/netfilter/nfnetlink_queue_core.c
net/netfilter/nfnetlink_queue_core.c
net/netfilter/xt_time.c
net/openvswitch/flow.c
net/sctp/probe.c
net/sunrpc/auth_gss/
net/sunrpc/svcauth_unix.c
net/vmw_vsock/af_vsock.c
We'll get there eventually, or we an add a dependency to ensure
they are not built on 32-bit kernels that need to survive
beyond 2038. Most of these should be really easy to fix.
- recvmmsg/sendmmsg system calls: patches have been sent out
as part of the syscall series, need a little more work and
review
- SIOCGSTAMP/SIOCGSTAMPNS/ ioctl calls: tricky, need to discuss
with some folks at kernel summit
- SO_RCVTIMEO/SO_SNDTIMEO/SO_TIMESTAMP/SO_TIMESTAMPNS socket
opt: similar and related to the ioctl
- mmapped packet socket: need to create v4 of the API, nontrivial
- pktgen: sends 32-bit timestamps over network, need to find out
if using unsigned stamps is good enough
- af_rxpc: similar to pktgen, uses 32-bit times for deadlines
- ppp ioctl: patch is being worked on, nontrivial but doable
Arnd
Arnd Bergmann (12):
net: fec: avoid timespec use
net: stmmac: avoid using timespec
net: igb: avoid using timespec
mwifiex: use ktime_get_real for timestamping
mwifiex: avoid gettimeofday in ba_threshold setting
mac80211: use ktime_get_seconds
atm: hide 'struct zatm_t_hist'
nfnetlink: use y2038 safe timestamp
ipv6: use ktime_t for internal timestamps
net: sctp: avoid incorrect time_t use
[RFC] ipv4: avoid timespec in timestamp computation
[RFC] can: avoid using timeval for uapi
drivers/net/ethernet/freescale/fec_ptp.c | 6 ++--
drivers/net/ethernet/intel/igb/igb.h | 4 +--
drivers/net/ethernet/intel/igb/igb_main.c | 15 +++++-----
drivers/net/ethernet/intel/igb/igb_ptp.c | 8 +++---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++--
drivers/net/wireless/mwifiex/11n_aggr.c | 4 +--
drivers/net/wireless/mwifiex/wmm.c | 15 +++-------
include/linux/timekeeping.h | 2 ++
include/uapi/linux/atm_zatm.h | 3 +-
include/uapi/linux/can/bcm.h | 7 ++++-
kernel/time/timekeeping.c | 34 +++++++++++++++++++++++
net/can/bcm.c | 15 ++++++----
net/ipv4/icmp.c | 8 ++----
net/ipv4/ip_options.c | 9 ++----
net/ipv6/mip6.c | 16 +++++------
net/mac80211/sta_info.c | 8 ++----
net/netfilter/nfnetlink_log.c | 6 ++--
net/sctp/sm_make_chunk.c | 2 +-
net/sctp/sm_statefuns.c | 2 +-
19 files changed, 99 insertions(+), 73 deletions(-)
Cc: coreteam(a)netfilter.org
Cc: intel-wired-lan(a)lists.osuosl.org
Cc: linux-api(a)vger.kernel.org
Cc: linux-atm-general(a)lists.sourceforge.net
Cc: linux-can(a)vger.kernel.org
Cc: linux-sctp(a)vger.kernel.org
Cc: linux-wireless(a)vger.kernel.org
Cc: netfilter-devel(a)vger.kernel.org
--
2.1.0.rc2
On systems with 32-bit time_t there are quite a few problems that
applications may have with time overflowing in year 2038. Beside getting
to 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 get close to the overflow accidentally
or maliciously, e.g. when it 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 working with time_t are
available.
Cc: John Stultz <john.stultz(a)linaro.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Prarit Bhargava <prarit(a)redhat.com>
Cc: Richard Cochran <richardcochran(a)gmail.com>
Cc: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Miroslav Lichvar <mlichvar(a)redhat.com>
---
v2: - optimized code in accumulate_nsecs_to_secs() a bit
- improved log message and increased its level to warning
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 | 64 +++++++++++++++++++++++++++++++++++++----
6 files changed, 93 insertions(+), 6 deletions(-)
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 6fccb69..9b2bbdd 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -83,6 +83,7 @@ show up in /proc/sys/kernel:
- sysctl_writes_strict
- tainted
- threads-max
+- time_max
- unknown_nmi_panic
- watchdog
- watchdog_thresh
@@ -893,6 +894,24 @@ available RAM pages threads-max is reduced accordingly.
==============================================================
+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 may change
+ when 64-bit versions of system calls working with 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 ba0ae09..f25df65 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 e69201d..c2cfb33 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1130,6 +1130,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,
+ },
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
{
.procname = "timer_migration",
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 3739ac6..4f4653b 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
@@ -913,7 +947,7 @@ int do_settimeofday64(const struct timespec64 *ts)
unsigned long flags;
int ret = 0;
- 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);
@@ -972,7 +1006,7 @@ int timekeeping_inject_offset(struct timespec *ts)
/* Make sure the proposed value is valid */
tmp = timespec64_add(tk_xtime(tk), ts64);
if (timespec64_compare(&tk->wall_to_monotonic, &ts64) > 0 ||
- !timespec64_valid_strict(&tmp)) {
+ !timespec64_valid_strict(&tmp) || tmp.tv_sec >= time_max_sec) {
ret = -EINVAL;
goto error;
}
@@ -1237,6 +1271,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);
@@ -1692,17 +1730,31 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
/* Figure out if its a leap sec and apply if needed */
leap = second_overflow(tk->xtime_sec);
- if (unlikely(leap)) {
+
+ if (unlikely(leap || tk->xtime_sec >= time_max_sec)) {
struct timespec64 ts;
+ s64 step = leap;
+
+ /* If the system time has reached the allowed maximum,
+ step it back by one week */
+ if (tk->xtime_sec >= time_max_sec) {
+ step = time_max_sec - tk->xtime_sec;
+ step -= SEC_PER_WEEK;
+ printk(KERN_WARNING
+ "Clock: maximum time reached, stepping"
+ " back to one week before maximum\n");
+ }
- 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;
}
--
2.1.0