linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations
@ 2017-11-10 15:58 Arnd Bergmann
  2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Arnd Bergmann @ 2017-11-10 15:58 UTC (permalink / raw)
  To: Adam Radford, James E.J. Bottomley, Martin K. Petersen
  Cc: Arnd Bergmann, Sumit Saxena, linux-scsi, linux-kernel

twl_aen_queue_event/twa_aen_queue_event, we use do_gettimeofday()
to read the lower 32 bits of the current time in seconds, to pass
them to the TW_IOCTL_GET_NEXT_EVENT ioctl or the 3ware_aen_read
sysfs file.

This will overflow on all architectures in year 2106, there is
not much we can do about that without breaking the ABI. User
space has 90 years to learn to deal with it, so it's probably ok.

I'm changing it to use ktime_get_real_seconds() with a comment
to document what happens when.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/scsi/3w-9xxx.c | 5 ++---
 drivers/scsi/3w-sas.c  | 5 ++---
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 00e7968a1d70..cb9af3f7b653 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -369,7 +369,6 @@ static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 {
 	u32 local_time;
-	struct timeval time;
 	TW_Event *event;
 	unsigned short aen;
 	char host[16];
@@ -392,8 +391,8 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
 	memset(event, 0, sizeof(TW_Event));
 
 	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
-	do_gettimeofday(&time);
-	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	/* event->time_stamp_sec overflows in y2106 */
+	local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 	event->time_stamp_sec = local_time;
 	event->aen_code = aen;
 	event->retrieved = TW_AEN_NOT_RETRIEVED;
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index b150e131b2e7..c283fdb3cb24 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -221,7 +221,6 @@ static char *twl_aen_severity_lookup(unsigned char severity_code)
 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 {
 	u32 local_time;
-	struct timeval time;
 	TW_Event *event;
 	unsigned short aen;
 	char host[16];
@@ -240,8 +239,8 @@ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
 	memset(event, 0, sizeof(TW_Event));
 
 	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
-	do_gettimeofday(&time);
-	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	/* event->time_stamp_sec overflows in y2106 */
+	local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 	event->time_stamp_sec = local_time;
 	event->aen_code = aen;
 	event->retrieved = TW_AEN_NOT_RETRIEVED;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync
  2017-11-10 15:58 [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations Arnd Bergmann
@ 2017-11-10 15:58 ` Arnd Bergmann
  2017-11-10 19:43   ` adam radford
  2017-11-21  3:06   ` Martin K. Petersen
  2017-11-10 15:58 ` [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts Arnd Bergmann
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 9+ messages in thread
From: Arnd Bergmann @ 2017-11-10 15:58 UTC (permalink / raw)
  To: Adam Radford, James E.J. Bottomley, Martin K. Petersen
  Cc: Arnd Bergmann, Sumit Saxena, linux-scsi, linux-kernel

The calculation of the number of seconds since Sunday 00:00:00 overflows
in 2106, meaning that we instead will return the seconds since Wednesday
06:28:16 afterwards.

Using 64-bit time stamps avoids this slight inconsistency, and the
deprecated do_gettimeofday(), replacing it with the simpler
ktime_get_real_seconds().

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/scsi/3w-9xxx.c |  8 +++-----
 drivers/scsi/3w-sas.c  | 10 ++++------
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index cb9af3f7b653..b1c9bd9c1bfd 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -472,11 +472,10 @@ static char *twa_aen_severity_lookup(unsigned char severity_code)
 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 {
 	u32 schedulertime;
-	struct timeval utc;
 	TW_Command_Full *full_command_packet;
 	TW_Command *command_packet;
 	TW_Param_Apache *param;
-	u32 local_time;
+	time64_t local_time;
 
 	/* Fill out the command packet */
 	full_command_packet = tw_dev->command_packet_virt[request_id];
@@ -498,9 +497,8 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 
 	/* Convert system time in UTC to local time seconds since last 
            Sunday 12:00AM */
-	do_gettimeofday(&utc);
-	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
-	schedulertime = local_time - (3 * 86400);
+	local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
+	div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
 	schedulertime = cpu_to_le32(schedulertime % 604800);
 
 	memcpy(param->data, &schedulertime, sizeof(u32));
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index c283fdb3cb24..cf9f2a09b47d 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -407,11 +407,10 @@ static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 {
 	u32 schedulertime;
-	struct timeval utc;
 	TW_Command_Full *full_command_packet;
 	TW_Command *command_packet;
 	TW_Param_Apache *param;
-	u32 local_time;
+	time64_t local_time;
 
 	/* Fill out the command packet */
 	full_command_packet = tw_dev->command_packet_virt[request_id];
@@ -433,10 +432,9 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 
 	/* Convert system time in UTC to local time seconds since last 
            Sunday 12:00AM */
-	do_gettimeofday(&utc);
-	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
-	schedulertime = local_time - (3 * 86400);
-	schedulertime = cpu_to_le32(schedulertime % 604800);
+	local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
+	div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
+	schedulertime = cpu_to_le32(schedulertime);
 
 	memcpy(param->data, &schedulertime, sizeof(u32));
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts
  2017-11-10 15:58 [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations Arnd Bergmann
  2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
@ 2017-11-10 15:58 ` Arnd Bergmann
  2017-11-10 19:36   ` adam radford
  2017-11-21  3:07   ` Martin K. Petersen
  2017-11-10 19:42 ` [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations adam radford
  2017-11-21  3:06 ` Martin K. Petersen
  3 siblings, 2 replies; 9+ messages in thread
From: Arnd Bergmann @ 2017-11-10 15:58 UTC (permalink / raw)
  To: Adam Radford, James E.J. Bottomley, Martin K. Petersen
  Cc: Arnd Bergmann, Sumit Saxena, linux-scsi, linux-kernel

The TW_IOCTL_GET_LOCK ioctl uses do_gettimeofday() to check whether
a lock has expired. This can misbehave due to a concurrent
settimeofday() call, as it is based on 'real' time, and it
will overflow in y2038 on 32-bit architectures, producing
unexpected results when used across the overflow time.

This changes it to using monotonic time, using ktime_get()
to simplify the code.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/scsi/3w-9xxx.c | 13 ++++++-------
 drivers/scsi/3w-9xxx.h |  2 +-
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index b1c9bd9c1bfd..b42c9c479d4b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -645,8 +645,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
 	TW_Command_Full *full_command_packet;
 	TW_Compatibility_Info *tw_compat_info;
 	TW_Event *event;
-	struct timeval current_time;
-	u32 current_time_ms;
+	ktime_t current_time;
 	TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
 	int retval = TW_IOCTL_ERROR_OS_EFAULT;
 	void __user *argp = (void __user *)arg;
@@ -837,17 +836,17 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
 		break;
 	case TW_IOCTL_GET_LOCK:
 		tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
-		do_gettimeofday(&current_time);
-		current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
+		current_time = ktime_get();
 
-		if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
+		if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) ||
+		    ktime_after(current_time, tw_dev->ioctl_time)) {
 			tw_dev->ioctl_sem_lock = 1;
-			tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
+			tw_dev->ioctl_time = ktime_add_ms(current_time, tw_lock->timeout_msec);
 			tw_ioctl->driver_command.status = 0;
 			tw_lock->time_remaining_msec = tw_lock->timeout_msec;
 		} else {
 			tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
-			tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
+			tw_lock->time_remaining_msec = ktime_ms_delta(tw_dev->ioctl_time, current_time);
 		}
 		break;
 	case TW_IOCTL_RELEASE_LOCK:
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
index b6c208cc474f..d88cd3499bd5 100644
--- a/drivers/scsi/3w-9xxx.h
+++ b/drivers/scsi/3w-9xxx.h
@@ -666,7 +666,7 @@ typedef struct TAG_TW_Device_Extension {
 	unsigned char		event_queue_wrapped;
 	unsigned int            error_sequence_id;
 	int                     ioctl_sem_lock;
-	u32                     ioctl_msec;
+	ktime_t                 ioctl_time;
 	int			chrdev_request_id;
 	wait_queue_head_t	ioctl_wqueue;
 	struct mutex		ioctl_lock;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts
  2017-11-10 15:58 ` [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts Arnd Bergmann
@ 2017-11-10 19:36   ` adam radford
  2017-11-21  3:07   ` Martin K. Petersen
  1 sibling, 0 replies; 9+ messages in thread
From: adam radford @ 2017-11-10 19:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: James E.J. Bottomley, Martin K. Petersen, Sumit Saxena,
	linux-scsi, linux-kernel

On Fri, Nov 10, 2017 at 7:58 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> The TW_IOCTL_GET_LOCK ioctl uses do_gettimeofday() to check whether
> a lock has expired. This can misbehave due to a concurrent
> settimeofday() call, as it is based on 'real' time, and it
> will overflow in y2038 on 32-bit architectures, producing
> unexpected results when used across the overflow time.
>
> This changes it to using monotonic time, using ktime_get()
> to simplify the code.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/scsi/3w-9xxx.c | 13 ++++++-------
>  drivers/scsi/3w-9xxx.h |  2 +-
>  2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
> index b1c9bd9c1bfd..b42c9c479d4b 100644
> --- a/drivers/scsi/3w-9xxx.c
> +++ b/drivers/scsi/3w-9xxx.c
> @@ -645,8 +645,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
>         TW_Command_Full *full_command_packet;
>         TW_Compatibility_Info *tw_compat_info;
>         TW_Event *event;
> -       struct timeval current_time;
> -       u32 current_time_ms;
> +       ktime_t current_time;
>         TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
>         int retval = TW_IOCTL_ERROR_OS_EFAULT;
>         void __user *argp = (void __user *)arg;
> @@ -837,17 +836,17 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
>                 break;
>         case TW_IOCTL_GET_LOCK:
>                 tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
> -               do_gettimeofday(&current_time);
> -               current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
> +               current_time = ktime_get();
>
> -               if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
> +               if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) ||
> +                   ktime_after(current_time, tw_dev->ioctl_time)) {
>                         tw_dev->ioctl_sem_lock = 1;
> -                       tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
> +                       tw_dev->ioctl_time = ktime_add_ms(current_time, tw_lock->timeout_msec);
>                         tw_ioctl->driver_command.status = 0;
>                         tw_lock->time_remaining_msec = tw_lock->timeout_msec;
>                 } else {
>                         tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
> -                       tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
> +                       tw_lock->time_remaining_msec = ktime_ms_delta(tw_dev->ioctl_time, current_time);
>                 }
>                 break;
>         case TW_IOCTL_RELEASE_LOCK:
> diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
> index b6c208cc474f..d88cd3499bd5 100644
> --- a/drivers/scsi/3w-9xxx.h
> +++ b/drivers/scsi/3w-9xxx.h
> @@ -666,7 +666,7 @@ typedef struct TAG_TW_Device_Extension {
>         unsigned char           event_queue_wrapped;
>         unsigned int            error_sequence_id;
>         int                     ioctl_sem_lock;
> -       u32                     ioctl_msec;
> +       ktime_t                 ioctl_time;
>         int                     chrdev_request_id;
>         wait_queue_head_t       ioctl_wqueue;
>         struct mutex            ioctl_lock;
> --
> 2.9.0
>

Looks good...  Thanks for this fix!

Acked-by: Adam Radford <aradford@gmail.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations
  2017-11-10 15:58 [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations Arnd Bergmann
  2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
  2017-11-10 15:58 ` [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts Arnd Bergmann
@ 2017-11-10 19:42 ` adam radford
  2017-11-21  3:06 ` Martin K. Petersen
  3 siblings, 0 replies; 9+ messages in thread
From: adam radford @ 2017-11-10 19:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: James E.J. Bottomley, Martin K. Petersen, Sumit Saxena,
	linux-scsi, linux-kernel

On Fri, Nov 10, 2017 at 7:58 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> twl_aen_queue_event/twa_aen_queue_event, we use do_gettimeofday()
> to read the lower 32 bits of the current time in seconds, to pass
> them to the TW_IOCTL_GET_NEXT_EVENT ioctl or the 3ware_aen_read
> sysfs file.
>
> This will overflow on all architectures in year 2106, there is
> not much we can do about that without breaking the ABI. User
> space has 90 years to learn to deal with it, so it's probably ok.
>
> I'm changing it to use ktime_get_real_seconds() with a comment
> to document what happens when.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/scsi/3w-9xxx.c | 5 ++---
>  drivers/scsi/3w-sas.c  | 5 ++---
>  2 files changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
> index 00e7968a1d70..cb9af3f7b653 100644
> --- a/drivers/scsi/3w-9xxx.c
> +++ b/drivers/scsi/3w-9xxx.c
> @@ -369,7 +369,6 @@ static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
>  static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
>  {
>         u32 local_time;
> -       struct timeval time;
>         TW_Event *event;
>         unsigned short aen;
>         char host[16];
> @@ -392,8 +391,8 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
>         memset(event, 0, sizeof(TW_Event));
>
>         event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
> -       do_gettimeofday(&time);
> -       local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> +       /* event->time_stamp_sec overflows in y2106 */
> +       local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
>         event->time_stamp_sec = local_time;
>         event->aen_code = aen;
>         event->retrieved = TW_AEN_NOT_RETRIEVED;
> diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
> index b150e131b2e7..c283fdb3cb24 100644
> --- a/drivers/scsi/3w-sas.c
> +++ b/drivers/scsi/3w-sas.c
> @@ -221,7 +221,6 @@ static char *twl_aen_severity_lookup(unsigned char severity_code)
>  static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
>  {
>         u32 local_time;
> -       struct timeval time;
>         TW_Event *event;
>         unsigned short aen;
>         char host[16];
> @@ -240,8 +239,8 @@ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
>         memset(event, 0, sizeof(TW_Event));
>
>         event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
> -       do_gettimeofday(&time);
> -       local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> +       /* event->time_stamp_sec overflows in y2106 */
> +       local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
>         event->time_stamp_sec = local_time;
>         event->aen_code = aen;
>         event->retrieved = TW_AEN_NOT_RETRIEVED;
> --
> 2.9.0
>

Acked-by: Adam Radford <aradford@gmail.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync
  2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
@ 2017-11-10 19:43   ` adam radford
  2017-11-21  3:06   ` Martin K. Petersen
  1 sibling, 0 replies; 9+ messages in thread
From: adam radford @ 2017-11-10 19:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: James E.J. Bottomley, Martin K. Petersen, Sumit Saxena,
	linux-scsi, linux-kernel

On Fri, Nov 10, 2017 at 7:58 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> The calculation of the number of seconds since Sunday 00:00:00 overflows
> in 2106, meaning that we instead will return the seconds since Wednesday
> 06:28:16 afterwards.
>
> Using 64-bit time stamps avoids this slight inconsistency, and the
> deprecated do_gettimeofday(), replacing it with the simpler
> ktime_get_real_seconds().
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/scsi/3w-9xxx.c |  8 +++-----
>  drivers/scsi/3w-sas.c  | 10 ++++------
>  2 files changed, 7 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
> index cb9af3f7b653..b1c9bd9c1bfd 100644
> --- a/drivers/scsi/3w-9xxx.c
> +++ b/drivers/scsi/3w-9xxx.c
> @@ -472,11 +472,10 @@ static char *twa_aen_severity_lookup(unsigned char severity_code)
>  static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
>  {
>         u32 schedulertime;
> -       struct timeval utc;
>         TW_Command_Full *full_command_packet;
>         TW_Command *command_packet;
>         TW_Param_Apache *param;
> -       u32 local_time;
> +       time64_t local_time;
>
>         /* Fill out the command packet */
>         full_command_packet = tw_dev->command_packet_virt[request_id];
> @@ -498,9 +497,8 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
>
>         /* Convert system time in UTC to local time seconds since last
>             Sunday 12:00AM */
> -       do_gettimeofday(&utc);
> -       local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
> -       schedulertime = local_time - (3 * 86400);
> +       local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
> +       div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
>         schedulertime = cpu_to_le32(schedulertime % 604800);
>
>         memcpy(param->data, &schedulertime, sizeof(u32));
> diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
> index c283fdb3cb24..cf9f2a09b47d 100644
> --- a/drivers/scsi/3w-sas.c
> +++ b/drivers/scsi/3w-sas.c
> @@ -407,11 +407,10 @@ static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
>  static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
>  {
>         u32 schedulertime;
> -       struct timeval utc;
>         TW_Command_Full *full_command_packet;
>         TW_Command *command_packet;
>         TW_Param_Apache *param;
> -       u32 local_time;
> +       time64_t local_time;
>
>         /* Fill out the command packet */
>         full_command_packet = tw_dev->command_packet_virt[request_id];
> @@ -433,10 +432,9 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
>
>         /* Convert system time in UTC to local time seconds since last
>             Sunday 12:00AM */
> -       do_gettimeofday(&utc);
> -       local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
> -       schedulertime = local_time - (3 * 86400);
> -       schedulertime = cpu_to_le32(schedulertime % 604800);
> +       local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
> +       div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
> +       schedulertime = cpu_to_le32(schedulertime);
>
>         memcpy(param->data, &schedulertime, sizeof(u32));
>
> --
> 2.9.0
>

Acked-by: Adam Radford <aradford@gmail.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations
  2017-11-10 15:58 [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations Arnd Bergmann
                   ` (2 preceding siblings ...)
  2017-11-10 19:42 ` [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations adam radford
@ 2017-11-21  3:06 ` Martin K. Petersen
  3 siblings, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2017-11-21  3:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Adam Radford, James E.J. Bottomley, Martin K. Petersen,
	Sumit Saxena, linux-scsi, linux-kernel


Arnd,

> twl_aen_queue_event/twa_aen_queue_event, we use do_gettimeofday()
> to read the lower 32 bits of the current time in seconds, to pass
> them to the TW_IOCTL_GET_NEXT_EVENT ioctl or the 3ware_aen_read
> sysfs file.
>
> This will overflow on all architectures in year 2106, there is
> not much we can do about that without breaking the ABI. User
> space has 90 years to learn to deal with it, so it's probably ok.
>
> I'm changing it to use ktime_get_real_seconds() with a comment
> to document what happens when.

Applied to 4.16/scsi-queue.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync
  2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
  2017-11-10 19:43   ` adam radford
@ 2017-11-21  3:06   ` Martin K. Petersen
  1 sibling, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2017-11-21  3:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Adam Radford, James E.J. Bottomley, Martin K. Petersen,
	Sumit Saxena, linux-scsi, linux-kernel


Arnd,

> The calculation of the number of seconds since Sunday 00:00:00
> overflows in 2106, meaning that we instead will return the seconds
> since Wednesday 06:28:16 afterwards.
>
> Using 64-bit time stamps avoids this slight inconsistency, and the
> deprecated do_gettimeofday(), replacing it with the simpler
> ktime_get_real_seconds().

Applied to 4.16/scsi-queue.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts
  2017-11-10 15:58 ` [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts Arnd Bergmann
  2017-11-10 19:36   ` adam radford
@ 2017-11-21  3:07   ` Martin K. Petersen
  1 sibling, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2017-11-21  3:07 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Adam Radford, James E.J. Bottomley, Martin K. Petersen,
	Sumit Saxena, linux-scsi, linux-kernel


Arnd,

> The TW_IOCTL_GET_LOCK ioctl uses do_gettimeofday() to check whether a
> lock has expired. This can misbehave due to a concurrent
> settimeofday() call, as it is based on 'real' time, and it will
> overflow in y2038 on 32-bit architectures, producing unexpected
> results when used across the overflow time.
>
> This changes it to using monotonic time, using ktime_get() to simplify
> the code.

Applied to 4.16/scsi-queue, thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-11-21  3:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-10 15:58 [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations Arnd Bergmann
2017-11-10 15:58 ` [PATCH 2/3] scsi: 3ware: use 64-bit times for FW time sync Arnd Bergmann
2017-11-10 19:43   ` adam radford
2017-11-21  3:06   ` Martin K. Petersen
2017-11-10 15:58 ` [PATCH 3/3] scsi: 3w-9xxx: rework lock timeouts Arnd Bergmann
2017-11-10 19:36   ` adam radford
2017-11-21  3:07   ` Martin K. Petersen
2017-11-10 19:42 ` [PATCH 1/3] scsi: 3ware: fix 32-bit time calculations adam radford
2017-11-21  3:06 ` Martin K. Petersen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).