From: Hans Verkuil Date: Thu, 5 Jun 2025 06:57:37 +0000 (+0200) Subject: media: dvb-core: dvb_vb2: drop wait_prepare/finish callbacks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbb5cd440d06a87c2c8c5819c5ad5c2a73021687;p=thirdparty%2Fkernel%2Flinux.git media: dvb-core: dvb_vb2: drop wait_prepare/finish callbacks Since commit 88785982a19d ("media: vb2: use lock if wait_prepare/finish are NULL") it is no longer needed to set the wait_prepare/finish vb2_ops callbacks as long as the lock field in vb2_queue is set. Set the queue lock to &ctx->mutex, which makes it possible to drop the wait_prepare/finish callbacks. This simplifies the code and this is a step towards the goal of deleting these callbacks. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 1cc0e9ecc56ad..c946c8ea6e392 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -171,6 +171,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); if (dmxdev->may_do_mmap) dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", + &dmxdev->mutex, file->f_flags & O_NONBLOCK); dvbdev->readers--; } @@ -815,9 +816,21 @@ static int dvb_demux_open(struct inode *inode, struct file *file) dmxdev->may_do_mmap = 0; #endif + /* + * The mutex passed to dvb_vb2_init is unlocked when a buffer + * is in a blocking wait. However, dmxdevfilter has two mutexes: + * dmxdevfilter->mutex and dmxdev->mutex. So this will not work. + * The solution would be to support unlocking two mutexes in vb2, + * but since this problem has been here since the beginning and + * nobody ever complained, we leave it as-is rather than adding + * that second mutex pointer to vb2. + * + * In the unlikely event that someone complains about this, then + * this comment will hopefully help. + */ dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter", - file->f_flags & O_NONBLOCK); + &dmxdevfilter->mutex, file->f_flags & O_NONBLOCK); dmxdevfilter->type = DMXDEV_TYPE_NONE; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0); diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c index 7444bbc2f24d9..672b0efdca21e 100644 --- a/drivers/media/dvb-core/dvb_vb2.c +++ b/drivers/media/dvb-core/dvb_vb2.c @@ -103,31 +103,12 @@ static void _stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&ctx->slock, flags); } -static void _dmxdev_lock(struct vb2_queue *vq) -{ - struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); - - mutex_lock(&ctx->mutex); - dprintk(3, "[%s]\n", ctx->name); -} - -static void _dmxdev_unlock(struct vb2_queue *vq) -{ - struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); - - if (mutex_is_locked(&ctx->mutex)) - mutex_unlock(&ctx->mutex); - dprintk(3, "[%s]\n", ctx->name); -} - static const struct vb2_ops dvb_vb2_qops = { .queue_setup = _queue_setup, .buf_prepare = _buffer_prepare, .buf_queue = _buffer_queue, .start_streaming = _start_streaming, .stop_streaming = _stop_streaming, - .wait_prepare = _dmxdev_unlock, - .wait_finish = _dmxdev_lock, }; static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb) @@ -158,9 +139,10 @@ static const struct vb2_buf_ops dvb_vb2_buf_ops = { }; /* - * Videobuf operations + * vb2 operations */ -int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking) +int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, + struct mutex *mutex, int nonblocking) { struct vb2_queue *q = &ctx->vb_q; int ret; @@ -175,14 +157,7 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking) q->ops = &dvb_vb2_qops; q->mem_ops = &vb2_vmalloc_memops; q->buf_ops = &dvb_vb2_buf_ops; - ret = vb2_core_queue_init(q); - if (ret) { - ctx->state = DVB_VB2_STATE_NONE; - dprintk(1, "[%s] errno=%d\n", ctx->name, ret); - return ret; - } - - mutex_init(&ctx->mutex); + q->lock = mutex; spin_lock_init(&ctx->slock); INIT_LIST_HEAD(&ctx->dvb_q); @@ -190,6 +165,13 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking) ctx->nonblocking = nonblocking; ctx->state = DVB_VB2_STATE_INIT; + ret = vb2_core_queue_init(q); + if (ret) { + ctx->state = DVB_VB2_STATE_NONE; + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + dprintk(3, "[%s]\n", ctx->name); return 0; diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 0fbbfc65157e6..8932396d2c99e 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h @@ -72,8 +72,6 @@ struct dvb_buffer { /** * struct dvb_vb2_ctx - control struct for VB2 handler * @vb_q: pointer to &struct vb2_queue with videobuf2 queue. - * @mutex: mutex to serialize vb2 operations. Used by - * vb2 core %wait_prepare and %wait_finish operations. * @slock: spin lock used to protect buffer filling at dvb_vb2.c. * @dvb_q: List of buffers that are not filled yet. * @buf: Pointer to the buffer that are currently being filled. @@ -96,7 +94,6 @@ struct dvb_buffer { */ struct dvb_vb2_ctx { struct vb2_queue vb_q; - struct mutex mutex; spinlock_t slock; struct list_head dvb_q; struct dvb_buffer *buf; @@ -114,8 +111,8 @@ struct dvb_vb2_ctx { }; #ifndef CONFIG_DVB_MMAP -static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, - const char *name, int non_blocking) +static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, + struct mutex *mutex, int non_blocking) { return 0; }; @@ -138,10 +135,12 @@ static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, * * @ctx: control struct for VB2 handler * @name: name for the VB2 handler + * @mutex: pointer to the mutex that serializes vb2 ioctls * @non_blocking: * if not zero, it means that the device is at non-blocking mode */ -int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking); +int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, + struct mutex *mutex, int non_blocking); /** * dvb_vb2_release - Releases the VB2 handler allocated resources and