On Wednesday 04 November 2015 00:29:42 Arnd Bergmann wrote:
> On Wednesday 28 October 2015 00:30:41 Amitoj Kaur Chawla wrote:
> > 32 bit systems using 'struct timeval' will break in the year 2038, so
> > we modify the code appropriately.
> >
> > This patch replaces the use of struct timeval and do_gettimeofday()
> > with 64 bit ktime_get_real_seconds().
> >
> > Signed-off-by: Amitoj Kaur Chawla <amitoj1606(a)gmail.com>
>
> This code looks like a copy of the bfa_svc.c file from your earlier patch,
> and the same comments apply: Make sure that stats_reset_time has an
> appropriate type, and convert to monotonic time.
>
To further clarify: when you change to using monotonic time, using a 32-bit
variable to store the time is sufficient and you don't need to change
the type, but you should still explain that in the patch description
if you do it.
Arnd
This patch changes the use of struct timespec in
dccp_probe to use struct timespec64 instead. timespec uses a 32-bit
seconds field which will overflow in the year 2038 and beyond. timespec64
uses a 64-bit seconds field. Note that the correctness of the code isn't
changed, since the original code only uses the timestamps to compute a
small elapsed interval. This patch is part of a larger attempt to remove
instances of 32-bit timekeeping structures (timespec, timeval, time_t)
from the kernel so it is easier to identify where the real 2038 issues
are.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
---
net/dccp/probe.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index d8346d0..3d3fda0 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/kfifo.h>
#include <linux/vmalloc.h>
+#include <linux/time64.h>
#include <linux/gfp.h>
#include <net/net_namespace.h>
@@ -47,20 +48,20 @@ static struct {
struct kfifo fifo;
spinlock_t lock;
wait_queue_head_t wait;
- struct timespec tstart;
+ struct timespec64 tstart;
} dccpw;
static void printl(const char *fmt, ...)
{
va_list args;
int len;
- struct timespec now;
+ struct timespec64 now;
char tbuf[256];
va_start(args, fmt);
- getnstimeofday(&now);
+ getnstimeofday64(&now);
- now = timespec_sub(now, dccpw.tstart);
+ now = timespec64_sub(now, dccpw.tstart);
len = sprintf(tbuf, "%lu.%06lu ",
(unsigned long) now.tv_sec,
@@ -110,7 +111,7 @@ static struct jprobe dccp_send_probe = {
static int dccpprobe_open(struct inode *inode, struct file *file)
{
kfifo_reset(&dccpw.fifo);
- getnstimeofday(&dccpw.tstart);
+ getnstimeofday64(&dccpw.tstart);
return 0;
}
--
1.9.1
The new USBTEST_REQUEST ioctl is intended to eventually replace
the old timeval exposing interface. struct timeval can have different
sizes based on whether the kernel/ userspace are compiled in 32 bit/
64 bit mode. The new ioctl exposes the duration the tests run as a
scalar nanosecond value.
Rename old ioctl and data types to COMPAT_USBTEST_REQUEST and
usbtest_param_compat, respectively.
The change also uses monotonic time instead of real time for both ioctls.
This ensures that the time duration is always positive. Also use ktime
api's for time routines accomodating moving all of kernel to use 64 bit
time eventually.
Refactor usbtest_ioctl for readability to clarify that the only
difference is in how delta time is returned.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
Resending due to incorrect recipient list
This patch is intended for the next branch of the usb tree:
git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
drivers/usb/misc/usbtest.c | 208 +++++++++++++++++++++++++++++----------------
1 file changed, 134 insertions(+), 74 deletions(-)
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 637f3f7..00daff3 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -22,7 +22,11 @@ static void complicated_callback(struct urb *urb);
/*-------------------------------------------------------------------------*/
/* FIXME make these public somewhere; usbdevfs.h? */
-struct usbtest_param {
+
+/* Compat parameter for the compat interface.
+ * This is deprecated due to the timeval output parameter.
+ */
+struct usbtest_param_compat {
/* inputs */
unsigned test_num; /* 0..(TEST_CASES-1) */
unsigned iterations;
@@ -33,7 +37,27 @@ struct usbtest_param {
/* outputs */
struct timeval duration;
};
-#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
+
+/* Parameters to the usbtest driver */
+struct usbtest_param {
+ /* inputs */
+ unsigned test_num; /* 0..(TEST_CASES-1) */
+ unsigned iterations;
+ unsigned length;
+ unsigned vary;
+ unsigned sglen;
+
+ /* outputs */
+ s64 duration_ns;
+};
+
+/*
+ * COMPAT IOCTL interface to the driver.
+ * The interface is deprecated and should not be used by new code.
+ */
+#define USBTEST_REQUEST_COMPAT _IOWR('U', 100, struct usbtest_param_compat)
+/* IOCTL interface to the driver. */
+#define USBTEST_REQUEST _IOWR('U', 101, struct usbtest_param)
/*-------------------------------------------------------------------------*/
@@ -2049,81 +2073,20 @@ static int test_unaligned_bulk(
return retval;
}
-/*-------------------------------------------------------------------------*/
-
-/* We only have this one interface to user space, through usbfs.
- * User mode code can scan usbfs to find N different devices (maybe on
- * different busses) to use when testing, and allocate one thread per
- * test. So discovery is simplified, and we have no device naming issues.
- *
- * Don't use these only as stress/load tests. Use them along with with
- * other USB bus activity: plugging, unplugging, mousing, mp3 playback,
- * video capture, and so on. Run different tests at different times, in
- * different sequences. Nothing here should interact with other devices,
- * except indirectly by consuming USB bandwidth and CPU resources for test
- * threads and request completion. But the only way to know that for sure
- * is to test when HC queues are in use by many devices.
- *
- * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(),
- * it locks out usbcore in certain code paths. Notably, if you disconnect
- * the device-under-test, hub_wq will wait block forever waiting for the
- * ioctl to complete ... so that usb_disconnect() can abort the pending
- * urbs and then call usbtest_disconnect(). To abort a test, you're best
- * off just killing the userspace task and waiting for it to exit.
- */
-
+/* Run tests. */
static int
-usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
+usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param *param)
{
struct usbtest_dev *dev = usb_get_intfdata(intf);
struct usb_device *udev = testdev_to_usbdev(dev);
- struct usbtest_param *param = buf;
- int retval = -EOPNOTSUPP;
struct urb *urb;
struct scatterlist *sg;
struct usb_sg_request req;
- struct timeval start;
unsigned i;
-
- /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */
-
- pattern = mod_pattern;
-
- if (code != USBTEST_REQUEST)
- return -EOPNOTSUPP;
+ int retval = -EOPNOTSUPP;
if (param->iterations <= 0)
return -EINVAL;
-
- if (param->sglen > MAX_SGLEN)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&dev->lock))
- return -ERESTARTSYS;
-
- /* FIXME: What if a system sleep starts while a test is running? */
-
- /* some devices, like ez-usb default devices, need a non-default
- * altsetting to have any active endpoints. some tests change
- * altsettings; force a default so most tests don't need to check.
- */
- if (dev->info->alt >= 0) {
- int res;
-
- if (intf->altsetting->desc.bInterfaceNumber) {
- mutex_unlock(&dev->lock);
- return -ENODEV;
- }
- res = set_altsetting(dev, dev->info->alt);
- if (res) {
- dev_err(&intf->dev,
- "set altsetting to %d failed, %d\n",
- dev->info->alt, res);
- mutex_unlock(&dev->lock);
- return res;
- }
- }
-
/*
* Just a bunch of test cases that every HCD is expected to handle.
*
@@ -2133,7 +2096,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
* FIXME add more tests! cancel requests, verify the data, control
* queueing, concurrent read+write threads, and so on.
*/
- do_gettimeofday(&start);
switch (param->test_num) {
case 0:
@@ -2548,17 +2510,116 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
dev->in_pipe, NULL, 0);
break;
}
- do_gettimeofday(¶m->duration);
- param->duration.tv_sec -= start.tv_sec;
- param->duration.tv_usec -= start.tv_usec;
- if (param->duration.tv_usec < 0) {
- param->duration.tv_usec += 1000 * 1000;
- param->duration.tv_sec -= 1;
+ return retval;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* We only have this one interface to user space, through usbfs.
+ * User mode code can scan usbfs to find N different devices (maybe on
+ * different busses) to use when testing, and allocate one thread per
+ * test. So discovery is simplified, and we have no device naming issues.
+ *
+ * Don't use these only as stress/load tests. Use them along with with
+ * other USB bus activity: plugging, unplugging, mousing, mp3 playback,
+ * video capture, and so on. Run different tests at different times, in
+ * different sequences. Nothing here should interact with other devices,
+ * except indirectly by consuming USB bandwidth and CPU resources for test
+ * threads and request completion. But the only way to know that for sure
+ * is to test when HC queues are in use by many devices.
+ *
+ * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(),
+ * it locks out usbcore in certain code paths. Notably, if you disconnect
+ * the device-under-test, hub_wq will wait block forever waiting for the
+ * ioctl to complete ... so that usb_disconnect() can abort the pending
+ * urbs and then call usbtest_disconnect(). To abort a test, you're best
+ * off just killing the userspace task and waiting for it to exit.
+ */
+
+static int
+usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
+{
+
+ struct usbtest_dev *dev = usb_get_intfdata(intf);
+ struct usbtest_param_compat *param_compat = buf;
+ struct usbtest_param temp;
+ struct usbtest_param *param = buf;
+ ktime_t start;
+ ktime_t end;
+ ktime_t duration;
+ int retval = -EOPNOTSUPP;
+
+ /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */
+
+ pattern = mod_pattern;
+
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
+
+ /* FIXME: What if a system sleep starts while a test is running? */
+
+ /* some devices, like ez-usb default devices, need a non-default
+ * altsetting to have any active endpoints. some tests change
+ * altsettings; force a default so most tests don't need to check.
+ */
+ if (dev->info->alt >= 0) {
+ if (intf->altsetting->desc.bInterfaceNumber) {
+ retval = -ENODEV;
+ goto free_mutex;
+ }
+ retval = set_altsetting(dev, dev->info->alt);
+ if (retval) {
+ dev_err(&intf->dev,
+ "set altsetting to %d failed, %d\n",
+ dev->info->alt, retval);
+ goto free_mutex;
+ }
+ }
+
+ switch (code) {
+ case USBTEST_REQUEST_COMPAT:
+ temp.test_num = param_compat->test_num;
+ temp.iterations = param_compat->iterations;
+ temp.length = param_compat->length;
+ temp.sglen = param_compat->sglen;
+ temp.vary = param_compat->vary;
+ param = &temp;
+ break;
+
+ case USBTEST_REQUEST:
+ break;
+
+ default:
+ retval = -EOPNOTSUPP;
+ goto free_mutex;
+ }
+
+ start = ktime_get();
+
+ retval = usbtest_do_ioctl(intf, param);
+ if (retval)
+ goto free_mutex;
+
+ end = ktime_get();
+
+ duration = ktime_sub(end, start);
+
+ switch (code) {
+ case USBTEST_REQUEST_COMPAT:
+ param_compat->duration = ktime_to_timeval(duration);
+ break;
+
+ case USBTEST_REQUEST:
+ param->duration_ns = ktime_to_ns(duration);
+ break;
}
+
+free_mutex:
mutex_unlock(&dev->lock);
return retval;
}
+
/*-------------------------------------------------------------------------*/
static unsigned force_interrupt;
@@ -2891,4 +2952,3 @@ module_exit(usbtest_exit);
MODULE_DESCRIPTION("USB Core/HCD Testing Driver");
MODULE_LICENSE("GPL");
-
--
1.9.1