Re: [PATCH 1/7] [media] dvb: use ktime_t for internal timeout

From: Andreas Oberritter
Date: Tue Sep 15 2015 - 14:03:05 EST


Hello Arnd,

On 15.09.2015 17:49, Arnd Bergmann wrote:
> The dvb demuxer code uses a 'struct timespec' to pass a timeout
> as absolute time. This will cause problems on 32-bit architectures
> in 2038 when time_t overflows, and it is racy with a concurrent
> settimeofday() call.
>
> This patch changes the code to use ktime_get() instead, using
> the monotonic time base to avoid both the race and the overflow.
>
> Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
> ---
> drivers/media/dvb-core/demux.h | 2 +-
> drivers/media/dvb-core/dmxdev.c | 2 +-
> drivers/media/dvb-core/dvb_demux.c | 17 ++++++-----------
> drivers/media/dvb-core/dvb_demux.h | 4 ++--
> drivers/media/dvb-core/dvb_net.c | 2 +-
> 5 files changed, 11 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/media/dvb-core/demux.h b/drivers/media/dvb-core/demux.h
> index 833191bcd810..d8e2b1213bef 100644
> --- a/drivers/media/dvb-core/demux.h
> +++ b/drivers/media/dvb-core/demux.h
> @@ -92,7 +92,7 @@ struct dmx_ts_feed {
> int type,
> enum dmx_ts_pes pes_type,
> size_t circular_buffer_size,
> - struct timespec timeout);
> + ktime_t timeout);
> int (*start_filtering) (struct dmx_ts_feed* feed);
> int (*stop_filtering) (struct dmx_ts_feed* feed);
> };
> diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
> index d0e3f9d85f34..0d20b379eeec 100644
> --- a/drivers/media/dvb-core/dmxdev.c
> +++ b/drivers/media/dvb-core/dmxdev.c
> @@ -558,7 +558,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
> struct dmxdev_filter *filter,
> struct dmxdev_feed *feed)
> {
> - struct timespec timeout = { 0 };
> + ktime_t timeout = ktime_set(0, 0);
> struct dmx_pes_filter_params *para = &filter->params.pes;
> dmx_output_t otype;
> int ret;
> diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
> index 6c7ff0cdcd32..d83dd0eb5757 100644
> --- a/drivers/media/dvb-core/dvb_demux.c
> +++ b/drivers/media/dvb-core/dvb_demux.c
> @@ -399,28 +399,23 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
> int dvr_done = 0;
>
> if (dvb_demux_speedcheck) {
> - struct timespec cur_time, delta_time;
> + ktime_t cur_time;
> u64 speed_bytes, speed_timedelta;
>
> demux->speed_pkts_cnt++;
>
> /* show speed every SPEED_PKTS_INTERVAL packets */
> if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) {
> - cur_time = current_kernel_time();
> + cur_time = ktime_get();
>
> - if (demux->speed_last_time.tv_sec != 0 &&
> - demux->speed_last_time.tv_nsec != 0) {
> - delta_time = timespec_sub(cur_time,
> - demux->speed_last_time);
> + if (ktime_to_ns(demux->speed_last_time) == 0) {

if ktime_to_ns does what I think it does, then you should invert the logic.

Regards,
Andreas

> speed_bytes = (u64)demux->speed_pkts_cnt
> * 188 * 8;
> /* convert to 1024 basis */
> speed_bytes = 1000 * div64_u64(speed_bytes,
> 1024);
> - speed_timedelta =
> - (u64)timespec_to_ns(&delta_time);
> - speed_timedelta = div64_u64(speed_timedelta,
> - 1000000); /* nsec -> usec */
> + speed_timedelta = ktime_ms_delta(cur_time,
> + demux->speed_last_time);
> printk(KERN_INFO "TS speed %llu Kbits/sec \n",
> div64_u64(speed_bytes,
> speed_timedelta));
> @@ -667,7 +662,7 @@ out:
>
> static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
> enum dmx_ts_pes pes_type,
> - size_t circular_buffer_size, struct timespec timeout)
> + size_t circular_buffer_size, ktime_t timeout)
> {
> struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
> struct dvb_demux *demux = feed->demux;
> diff --git a/drivers/media/dvb-core/dvb_demux.h b/drivers/media/dvb-core/dvb_demux.h
> index ae7fc33c3231..5ed3cab4ad28 100644
> --- a/drivers/media/dvb-core/dvb_demux.h
> +++ b/drivers/media/dvb-core/dvb_demux.h
> @@ -83,7 +83,7 @@ struct dvb_demux_feed {
> u8 *buffer;
> int buffer_size;
>
> - struct timespec timeout;
> + ktime_t timeout;
> struct dvb_demux_filter *filter;
>
> int ts_type;
> @@ -134,7 +134,7 @@ struct dvb_demux {
>
> uint8_t *cnt_storage; /* for TS continuity check */
>
> - struct timespec speed_last_time; /* for TS speed check */
> + ktime_t speed_last_time; /* for TS speed check */
> uint32_t speed_pkts_cnt; /* for TS speed check */
> };
>
> diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
> index b81e026edab3..df3ba15c007e 100644
> --- a/drivers/media/dvb-core/dvb_net.c
> +++ b/drivers/media/dvb-core/dvb_net.c
> @@ -998,7 +998,7 @@ static int dvb_net_feed_start(struct net_device *dev)
> netdev_dbg(dev, "start filtering\n");
> priv->secfeed->start_filtering(priv->secfeed);
> } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
> - struct timespec timeout = { 0, 10000000 }; // 10 msec
> + ktime_t timeout = ns_to_ktime(10 * NSEC_PER_MSEC);
>
> /* we have payloads encapsulated in TS */
> netdev_dbg(dev, "alloc tsfeed\n");
>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/