Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e95be158 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Mauro Carvalho Chehab
Browse files

[media] dvb: use ktime_t for internal timeout



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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 84345a23
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -143,7 +143,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);
};
+1 −1
Original line number Diff line number Diff line
@@ -556,7 +556,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;
+6 −11
Original line number Diff line number Diff line
@@ -398,28 +398,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) {
				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));
@@ -666,7 +661,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)

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;
+2 −2
Original line number Diff line number Diff line
@@ -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 */
};

+1 −1
Original line number Diff line number Diff line
@@ -997,7 +997,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");