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

Commit 3f98387e authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (7854): cx18/ivtv: improve and fix out-of-memory handling



- don't show kernel backtrace when the allocation of the buffers fails: the
  normal ivtv/cx18 messages are clear enough and the backtrace scares users.
- fix cleanup after the buffer allocation fails (caused kernel panic).

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 6a4a7935
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -805,7 +805,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
	return 0;

free_streams:
	cx18_streams_cleanup(cx);
	cx18_streams_cleanup(cx, 1);
free_irq:
	free_irq(cx->dev->irq, (void *)cx);
free_i2c:
@@ -908,7 +908,7 @@ static void cx18_remove(struct pci_dev *pci_dev)

	cx18_halt_firmware(cx);

	cx18_streams_cleanup(cx);
	cx18_streams_cleanup(cx, 1);

	exit_cx18_i2c(cx);

+3 −3
Original line number Diff line number Diff line
@@ -239,12 +239,12 @@ int cx18_stream_alloc(struct cx18_stream *s)

	/* allocate stream buffers. Initially all buffers are in q_free. */
	for (i = 0; i < s->buffers; i++) {
		struct cx18_buffer *buf =
			kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
						GFP_KERNEL|__GFP_NOWARN);

		if (buf == NULL)
			break;
		buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
		if (buf->buf == NULL) {
			kfree(buf);
			break;
+8 −5
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ int cx18_streams_setup(struct cx18 *cx)
		return 0;

	/* One or more streams could not be initialized. Clean 'em all up. */
	cx18_streams_cleanup(cx);
	cx18_streams_cleanup(cx, 0);
	return -ENOMEM;
}

@@ -296,12 +296,12 @@ int cx18_streams_register(struct cx18 *cx)
		return 0;

	/* One or more streams could not be initialized. Clean 'em all up. */
	cx18_streams_cleanup(cx);
	cx18_streams_cleanup(cx, 1);
	return -ENOMEM;
}

/* Unregister v4l2 devices */
void cx18_streams_cleanup(struct cx18 *cx)
void cx18_streams_cleanup(struct cx18 *cx, int unregister)
{
	struct video_device *vdev;
	int type;
@@ -319,8 +319,11 @@ void cx18_streams_cleanup(struct cx18 *cx)

		cx18_stream_free(&cx->streams[type]);

		/* Unregister device */
		/* Unregister or release device */
		if (unregister)
			video_unregister_device(vdev);
		else
			video_device_release(vdev);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
u32 cx18_find_handle(struct cx18 *cx);
int cx18_streams_setup(struct cx18 *cx);
int cx18_streams_register(struct cx18 *cx);
void cx18_streams_cleanup(struct cx18 *cx);
void cx18_streams_cleanup(struct cx18 *cx, int unregister);

/* Capture related */
int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
+2 −2
Original line number Diff line number Diff line
@@ -1232,7 +1232,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
	return 0;

free_streams:
	ivtv_streams_cleanup(itv);
	ivtv_streams_cleanup(itv, 1);
free_irq:
	free_irq(itv->dev->irq, (void *)itv);
free_i2c:
@@ -1377,7 +1377,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
	flush_workqueue(itv->irq_work_queues);
	destroy_workqueue(itv->irq_work_queues);

	ivtv_streams_cleanup(itv);
	ivtv_streams_cleanup(itv, 1);
	ivtv_udma_free(itv);

	exit_ivtv_i2c(itv);
Loading