[PATCH v2 1/1] Staging: android: Replace timeval with ktime_t in timed_gpio.c

33 views
Skip to first unread message

Somya Anand

unread,
Oct 20, 2014, 6:09:25 AM10/20/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
'struct timeval t' is used to return remaining time in milliseconds.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the android driver to use ktime_t.

---

Changes since v1:
* Reword commit message

Signed-off-by: Somya Anand <somyaa...@gmail.com>
---
drivers/staging/android/timed_gpio.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index 8fa4758..12d5514 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -20,6 +20,7 @@
#include <linux/hrtimer.h>
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/ktime.h>

#include "timed_output.h"
#include "timed_gpio.h"
@@ -46,16 +47,16 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
static int gpio_get_time(struct timed_output_dev *dev)
{
struct timed_gpio_data *data;
- struct timeval t;
+ ktime_t t;

data = container_of(dev, struct timed_gpio_data, dev);

if (!hrtimer_active(&data->timer))
return 0;

- t = ktime_to_timeval(hrtimer_get_remaining(&data->timer));
+ t = hrtimer_get_remaining(&data->timer);

- return t.tv_sec * 1000 + t.tv_usec / 1000;
+ return ktime_to_ms(t);
}

static void gpio_enable(struct timed_output_dev *dev, int value)
--
1.9.1

Daniel Baluta

unread,
Oct 20, 2014, 6:11:47 AM10/20/14
to Somya Anand, Arnd Bergmann, opw-kernel
On Mon, Oct 20, 2014 at 1:08 PM, Somya Anand <somyaa...@gmail.com> wrote:
> 'struct timeval t' is used to return remaining time in milliseconds.
>
> 32-bit systems using 'struct timeval' will break in the year 2038,
> so we have to replace that code with more appropriate types.
> This patch changes the android driver to use ktime_t.
>
> ---
>
> Changes since v1:
> * Reword commit message
>
Do not manually add "---" line.

> Signed-off-by: Somya Anand <somyaa...@gmail.com>
> ---

Change history should be here.
> --
> You received this message because you are subscribed to the Google Groups "opw-kernel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to opw-kernel+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Somya Anand

unread,
Oct 20, 2014, 6:24:12 AM10/20/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
'struct timeval t' is used to return remaining time in milliseconds.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the android driver to use ktime_t.

Signed-off-by: Somya Anand <somyaa...@gmail.com>
---
Changes since v2:
* Moved chnage history below 'Signed-off-by'

Arnd Bergmann

unread,
Oct 20, 2014, 7:57:47 AM10/20/14
to Somya Anand, opw-k...@googlegroups.com
On Monday 20 October 2014 15:53:50 Somya Anand wrote:
> 'struct timeval t' is used to return remaining time in milliseconds.
>
> 32-bit systems using 'struct timeval' will break in the year 2038,
> so we have to replace that code with more appropriate types.
> This patch changes the android driver to use ktime_t.
>
> Signed-off-by: Somya Anand <somyaa...@gmail.com>

Patch looks correct, two trivial things I noticed:

- the description above has an extra space at the beginning of each line
- it would be nicer to remove the temporary variable and just return
ktime_to_ms(hrtimer_get_remaining(...));

With those changed, please add

Reviewed-by: Arnd Bergmann <ar...@arndb.de>

Somya Anand

unread,
Oct 20, 2014, 10:09:19 AM10/20/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
'struct timeval t' is used to return remaining time in milliseconds.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the android driver to use ktime_t.

Signed-off-by: Somya Anand <somyaa...@gmail.com>

Reviewed-by: Arnd Bergmann ar...@arndb.de
---
Changes since v3:
* Reword commit message
* Remove temporary variable

Changes since v2:
* Moved change history below 'Signed-off-by'

Changes since v1:
* Reword commit message
---
drivers/staging/android/timed_gpio.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index 8fa4758..3373c98 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -20,6 +20,7 @@
#include <linux/hrtimer.h>
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/ktime.h>

#include "timed_output.h"
#include "timed_gpio.h"
@@ -46,16 +47,13 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
static int gpio_get_time(struct timed_output_dev *dev)
{
struct timed_gpio_data *data;
- struct timeval t;

data = container_of(dev, struct timed_gpio_data, dev);

if (!hrtimer_active(&data->timer))
return 0;

- t = ktime_to_timeval(hrtimer_get_remaining(&data->timer));
-
- return t.tv_sec * 1000 + t.tv_usec / 1000;
+ return ktime_to_ms(hrtimer_get_remaining(&data->timer));

Somya Anand

unread,
Oct 21, 2014, 7:40:55 AM10/21/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
'struct timeval t' is used to return remaining time in milliseconds.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the android driver to use ktime_t.

Signed-off-by: Somya Anand <somyaa...@gmail.com>
Reviewed-by: Arnd Bergmann <ar...@arndb.de>
---
Changes since v4:
* Moved change log below '---'

Changes since v3:
* Reword commit message
* Remove temporary variable

Changes since v2:
* Moved change history below 'Signed-off-by'

Changes since v1:
* Reword commit message

Somya Anand

unread,
Oct 21, 2014, 7:41:05 AM10/21/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
'struct timeval last' is used for recording last time interrupt.
'struct timeval now' is used for calculating elapsed time.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the comedi driver to use ktime_t.

Since this code doesn't communicate the time values
to the outside (user space, file system, network).Thus ktime_get()
is a better than using do_gettimeofday() as it uses monotonic
clock.

ktime_to_us() returns an 's64', and using the '%' operator on that requires
doing a 64-bit division which needs an expensive library function call
the specific value of usec_current does not actually matter although it might
matter that it's not always the same
which will start with the offset from the lower 32 bit of the microsecond.
Therefore:
devpriv->usec_current = (ktime_to_us(devpriv->last) % USEC_PER_SEC)
% devpriv->usec_period;
is replaced by

devpriv->usec_current = ((u32)ktime_to_us(devpriv->last))
% devpriv->usec_period;

Signed-off-by: Somya Anand <somyaa...@gmail.com>
Reviewed-by: Arnd Bergmann <ar...@arndb.de>
---
Changes since v6:
* Reword commit message

drivers/staging/comedi/drivers/comedi_test.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 00c03df..d73a151 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -52,13 +52,14 @@ zero volts).

#include "comedi_fc.h"
#include <linux/timer.h>
+#include <linux/ktime.h>

#define N_CHANS 8

/* Data unique to this driver */
struct waveform_private {
struct timer_list timer;
- struct timeval last; /* time last timer interrupt occurred */
+ ktime_t last; /* time last timer interrupt occurred */
unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */
unsigned long usec_period; /* waveform period in microseconds */
unsigned long usec_current; /* current time (mod waveform period) */
@@ -170,14 +171,12 @@ static void waveform_ai_interrupt(unsigned long arg)
/* all times in microsec */
unsigned long elapsed_time;
unsigned int num_scans;
- struct timeval now;
+ ktime_t now;
bool stopping = false;

- do_gettimeofday(&now);
+ now = ktime_get();

- elapsed_time =
- 1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec -
- devpriv->last.tv_usec;
+ elapsed_time = ktime_to_us(ktime_sub(now, devpriv->last));
devpriv->last = now;
num_scans =
(devpriv->usec_remainder + elapsed_time) / devpriv->scan_period;
@@ -316,8 +315,9 @@ static int waveform_ai_cmd(struct comedi_device *dev,
else /* TRIG_TIMER */
devpriv->convert_period = cmd->convert_arg / nano_per_micro;

- do_gettimeofday(&devpriv->last);
- devpriv->usec_current = devpriv->last.tv_usec % devpriv->usec_period;
+ devpriv->last = ktime_get();
+ devpriv->usec_current =
+ ((u32)ktime_to_us(devpriv->last)) % devpriv->usec_period;
devpriv->usec_remainder = 0;

devpriv->timer.expires = jiffies + 1;
--
1.9.1

Somya Anand

unread,
Oct 21, 2014, 7:41:15 AM10/21/14
to ar...@arndb.de, opw-k...@googlegroups.com, somyaa...@gmail.com
The output written by dgnc_sniff_nowait_nolock() is never used
anywhere since commit 35cf90459312f ("staging: dgnc: removes proc code")
deleted the code that used to copy it to user space.
dgnc_sniff_nowait_nolock() uses 'timeval' to create header timestamps for
the data dump.

32-bit systems using 'struct timeval' will break in the year 2038,
This patch removes dgnc_sniff_nowait_nolock() and all ch_sniff_* members
of struct channel_t defined in "dgnc_driver.h". It also removes their usage
from the driver files and hence y2038 issue is also resolved.

Signed-off-by: Somya Anand <somyaa...@gmail.com>
Reviewed-by: Arnd Bergmann <ar...@arndb.de>
---
Changes since v2:
* Merged patch set in one patch
* Reword commit message

drivers/staging/dgnc/dgnc_cls.c | 4 --
drivers/staging/dgnc/dgnc_driver.h | 14 ----
drivers/staging/dgnc/dgnc_neo.c | 3 -
drivers/staging/dgnc/dgnc_tty.c | 127 -------------------------------------
drivers/staging/dgnc/dgnc_tty.h | 2 -
5 files changed, 150 deletions(-)

diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c
index a17f4f6..1f013ed 100644
--- a/drivers/staging/dgnc/dgnc_cls.c
+++ b/drivers/staging/dgnc/dgnc_cls.c
@@ -928,8 +928,6 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
| UART_LSR_FE);
ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
- dgnc_sniff_nowait_nolock(ch, "UART READ",
- ch->ch_rqueue + head, 1);

qleft--;

@@ -1098,8 +1096,6 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
ch->ch_tun.un_flags |= (UN_EMPTY);
}
writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
- dgnc_sniff_nowait_nolock(ch, "UART WRITE",
- ch->ch_wqueue + ch->ch_w_tail, 1);
ch->ch_w_tail++;
ch->ch_w_tail &= WQUEUEMASK;
ch->ch_txcount++;
diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h
index f901957c..b52a182 100644
--- a/drivers/staging/dgnc/dgnc_driver.h
+++ b/drivers/staging/dgnc/dgnc_driver.h
@@ -134,8 +134,6 @@
#define _POSIX_VDISABLE '\0'
#endif

-#define SNIFF_MAX 65536 /* Sniff buffer size (2^n) */
-#define SNIFF_MASK (SNIFF_MAX - 1) /* Sniff wrap mask */

/*
* All the possible states the driver can be while being loaded.
@@ -342,13 +340,6 @@ struct un_t {
#define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */
#define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */

-/*
- * Definitions for ch_sniff_flags
- */
-#define SNIFF_OPEN 0x1
-#define SNIFF_WAIT_DATA 0x2
-#define SNIFF_WAIT_SPACE 0x4
-

/* Our Read/Error/Write queue sizes */
#define RQUEUEMASK 0x1FFF /* 8 K - 1 */
@@ -442,11 +433,6 @@ struct channel_t {
struct proc_dir_entry *proc_entry_pointer;
struct dgnc_proc_entry *dgnc_channel_table;

- uint ch_sniff_in;
- uint ch_sniff_out;
- char *ch_sniff_buf; /* Sniff buffer for proc */
- ulong ch_sniff_flags; /* Channel flags */
- wait_queue_head_t ch_sniff_wait;
};

/*
diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c
index a5bd08f..e8b9103 100644
--- a/drivers/staging/dgnc/dgnc_neo.c
+++ b/drivers/staging/dgnc/dgnc_neo.c
@@ -1224,7 +1224,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)

/* Copy data from uart to the queue */
memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n);
- dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, n);

/*
* Since RX_FIFO_DATA_ERROR was 0, we are guarenteed
@@ -1310,7 +1309,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)

memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1);
ch->ch_equeue[head] = (unsigned char) linestatus;
- dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, 1);

/* Ditch any remaining linestatus value. */
linestatus = 0;
@@ -1563,7 +1561,6 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
}

memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s);
- dgnc_sniff_nowait_nolock(ch, "UART WRITE", ch->ch_wqueue + tail, s);

/* Add and flip queue if needed */
tail = (tail + s) & WQUEUEMASK;
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 03c1506..26e93bc 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -49,7 +49,6 @@
#include <linux/delay.h> /* For udelay */
#include <linux/uaccess.h> /* For copy_from_user/copy_to_user */
#include <linux/pci.h>
-
#include "dgnc_driver.h"
#include "dgnc_tty.h"
#include "dgnc_types.h"
@@ -371,7 +370,6 @@ int dgnc_tty_init(struct dgnc_board *brd)
init_waitqueue_head(&ch->ch_flags_wait);
init_waitqueue_head(&ch->ch_tun.un_flags_wait);
init_waitqueue_head(&ch->ch_pun.un_flags_wait);
- init_waitqueue_head(&ch->ch_sniff_wait);

{
struct device *classp;
@@ -446,127 +444,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd)

#define TMPBUFLEN (1024)

-/*
- * dgnc_sniff - Dump data out to the "sniff" buffer if the
- * proc sniff file is opened...
- */
-void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int len)
-{
- struct timeval tv;
- int n;
- int r;
- int nbuf;
- int i;
- int tmpbuflen;
- char *tmpbuf;
- char *p;
- int too_much_data;
-
- tmpbuf = kzalloc(TMPBUFLEN, GFP_ATOMIC);
- if (!tmpbuf)
- return;
- p = tmpbuf;
-
- /* Leave if sniff not open */
- if (!(ch->ch_sniff_flags & SNIFF_OPEN))
- goto exit;
-
- do_gettimeofday(&tv);
-
- /* Create our header for data dump */
- p += sprintf(p, "<%ld %ld><%s><", tv.tv_sec, tv.tv_usec, text);
- tmpbuflen = p - tmpbuf;
-
- do {
- too_much_data = 0;
-
- for (i = 0; i < len && tmpbuflen < (TMPBUFLEN - 4); i++) {
- p += sprintf(p, "%02x ", *buf);
- buf++;
- tmpbuflen = p - tmpbuf;
- }
-
- if (tmpbuflen < (TMPBUFLEN - 4)) {
- if (i > 0)
- p += sprintf(p - 1, "%s\n", ">");
- else
- p += sprintf(p, "%s\n", ">");
- } else {
- too_much_data = 1;
- len -= i;
- }
-
- nbuf = strlen(tmpbuf);
- p = tmpbuf;
-
- /*
- * Loop while data remains.
- */
- while (nbuf > 0 && ch->ch_sniff_buf) {
- /*
- * Determine the amount of available space left in the
- * buffer. If there's none, wait until some appears.
- */
- n = (ch->ch_sniff_out - ch->ch_sniff_in - 1) & SNIFF_MASK;
-
- /*
- * If there is no space left to write to in our sniff buffer,
- * we have no choice but to drop the data.
- * We *cannot* sleep here waiting for space, because this
- * function was probably called by the interrupt/timer routines!
- */
- if (n == 0)
- goto exit;
-
- /*
- * Copy as much data as will fit.
- */
-
- if (n > nbuf)
- n = nbuf;
-
- r = SNIFF_MAX - ch->ch_sniff_in;
-
- if (r <= n) {
- memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, r);
-
- n -= r;
- ch->ch_sniff_in = 0;
- p += r;
- nbuf -= r;
- }
-
- memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, n);
-
- ch->ch_sniff_in += n;
- p += n;
- nbuf -= n;
-
- /*
- * Wakeup any thread waiting for data
- */
- if (ch->ch_sniff_flags & SNIFF_WAIT_DATA) {
- ch->ch_sniff_flags &= ~SNIFF_WAIT_DATA;
- wake_up_interruptible(&ch->ch_sniff_wait);
- }
- }
-
- /*
- * If the user sent us too much data to push into our tmpbuf,
- * we need to keep looping around on all the data.
- */
- if (too_much_data) {
- p = tmpbuf;
- tmpbuflen = 0;
- }
-
- } while (too_much_data);
-
-exit:
- kfree(tmpbuf);
-}
-
-
/*=======================================================================
*
* dgnc_wmove - Write data to transmit queue.
@@ -781,8 +658,6 @@ void dgnc_input(struct channel_t *ch)
tty_insert_flip_string(tp->port, ch->ch_rqueue + tail, s);
}

- dgnc_sniff_nowait_nolock(ch, "USER READ", ch->ch_rqueue + tail, s);
-
tail += s;
n -= s;
/* Flip queue if needed */
@@ -1974,7 +1849,6 @@ static int dgnc_tty_write(struct tty_struct *tty,
if (n >= remain) {
n -= remain;
memcpy(ch->ch_wqueue + head, buf, remain);
- dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain);
head = 0;
buf += remain;
}
@@ -1985,7 +1859,6 @@ static int dgnc_tty_write(struct tty_struct *tty,
*/
remain = n;
memcpy(ch->ch_wqueue + head, buf, remain);
- dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain);
head += remain;
}

diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h
index 58eef25..3975f04 100644
--- a/drivers/staging/dgnc/dgnc_tty.h
+++ b/drivers/staging/dgnc/dgnc_tty.h
@@ -37,6 +37,4 @@ void dgnc_carrier(struct channel_t *ch);
void dgnc_wakeup_writes(struct channel_t *ch);
void dgnc_check_queue_flow_control(struct channel_t *ch);

-void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int nbuf);
-
#endif
--
1.9.1

Somya Anand

unread,
Oct 22, 2014, 7:53:11 AM10/22/14
to opw-k...@googlegroups.com, Somya Anand
'struct timeval t' is used to return remaining time in milliseconds.

32-bit systems using 'struct timeval' will break in the year 2038,
so we have to replace that code with more appropriate types.
This patch changes the android driver to use ktime_t.

Signed-off-by: Somya Anand <somyaa...@gmail.com>
Reviewed-by: Arnd Bergmann <ar...@arndb.de>
---

Somya Anand

unread,
Oct 22, 2014, 7:54:28 AM10/22/14
to opw-k...@googlegroups.com, Somya Anand
The output written by dgnc_sniff_nowait_nolock() is never used
anywhere since commit 35cf90459312f ("staging: dgnc: removes proc code")
deleted the code that used to copy it to user space.
dgnc_sniff_nowait_nolock() uses 'timeval' to create header timestamps for
the data dump.

32-bit systems using 'struct timeval' will break in the year 2038,
This patch removes dgnc_sniff_nowait_nolock() and all ch_sniff_* members
of struct channel_t defined in "dgnc_driver.h". It also removes their usage
from the driver files and hence y2038 issue is also resolved.

Signed-off-by: Somya Anand <somyaa...@gmail.com>
Reviewed-by: Arnd Bergmann <ar...@arndb.de>
---
Reply all
Reply to author
Forward
0 new messages