[media] coda: fix timestamp list handling
authorPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 5 Aug 2014 17:00:17 +0000 (14:00 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Thu, 21 Aug 2014 20:25:25 +0000 (15:25 -0500)
Lock modification of the timestamp list with bitstream_mutex and do not
try to remove a timestamp element if the list is empty. This can happen
if the userspace feeds us garbage or multiple encoded frames in a single
buffer.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c

index 529cc3e8acb0b088b3f37a9199093de0a88aad11..18fa369d204d354dbe86822fdfbf09e45a2b6800 100644 (file)
@@ -1699,18 +1699,28 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                v4l2_err(&dev->v4l2_dev,
                         "decoded frame index out of range: %d\n", decoded_idx);
        } else {
-               ts = list_first_entry(&ctx->timestamp_list,
-                                     struct coda_timestamp, list);
-               list_del(&ts->list);
                val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
                val -= ctx->sequence_offset;
-               if (val != (ts->sequence & 0xffff)) {
-                       v4l2_err(&dev->v4l2_dev,
-                                "sequence number mismatch (%d(%d) != %d)\n",
-                                val, ctx->sequence_offset, ts->sequence);
+               mutex_lock(&ctx->bitstream_mutex);
+               if (!list_empty(&ctx->timestamp_list)) {
+                       ts = list_first_entry(&ctx->timestamp_list,
+                                             struct coda_timestamp, list);
+                       list_del(&ts->list);
+                       if (val != (ts->sequence & 0xffff)) {
+                               v4l2_err(&dev->v4l2_dev,
+                                        "sequence number mismatch (%d(%d) != %d)\n",
+                                        val, ctx->sequence_offset,
+                                        ts->sequence);
+                       }
+                       ctx->frame_timestamps[decoded_idx] = *ts;
+                       kfree(ts);
+               } else {
+                       v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
+                       memset(&ctx->frame_timestamps[decoded_idx], 0,
+                              sizeof(struct coda_timestamp));
+                       ctx->frame_timestamps[decoded_idx].sequence = val;
                }
-               ctx->frame_timestamps[decoded_idx] = *ts;
-               kfree(ts);
+               mutex_unlock(&ctx->bitstream_mutex);
 
                val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7;
                if (val == 0)
index 0f8a2c9704052d3bf9e93a5764af336083646b71..e84b32088fc089fe22f62b72f752543b09e83247 100644 (file)
@@ -1116,12 +1116,14 @@ static void coda_stop_streaming(struct vb2_queue *q)
        if (!ctx->streamon_out && !ctx->streamon_cap) {
                struct coda_timestamp *ts;
 
+               mutex_lock(&ctx->bitstream_mutex);
                while (!list_empty(&ctx->timestamp_list)) {
                        ts = list_first_entry(&ctx->timestamp_list,
                                              struct coda_timestamp, list);
                        list_del(&ts->list);
                        kfree(ts);
                }
+               mutex_unlock(&ctx->bitstream_mutex);
                kfifo_init(&ctx->bitstream_fifo,
                        ctx->bitstream.vaddr, ctx->bitstream.size);
                ctx->runcounter = 0;