From patchwork Tue Aug 13 06:58:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaik Ameer Basha X-Patchwork-Id: 2843468 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 50A319F271 for ; Tue, 13 Aug 2013 06:54:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 40B71204D9 for ; Tue, 13 Aug 2013 06:54:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8EB6B204CF for ; Tue, 13 Aug 2013 06:54:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756496Ab3HMGyV (ORCPT ); Tue, 13 Aug 2013 02:54:21 -0400 Received: from mail-pd0-f170.google.com ([209.85.192.170]:59987 "EHLO mail-pd0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756466Ab3HMGyT (ORCPT ); Tue, 13 Aug 2013 02:54:19 -0400 Received: by mail-pd0-f170.google.com with SMTP id x10so4500500pdj.15 for ; Mon, 12 Aug 2013 23:54:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=9OskRsvRXE5EsIaXipcIiuiyCYsm0L4Bnwu3zWEUFcU=; b=Zv8t6FK+kvbGU5Ue0X/z9OR8x4fqUc+mYnxxYoXrjLK7ik0oGIrIJue3+nfSK7hIjl pBWL+T/HWA2ILHcMbR2+MRJ5QzkRzpRqVi59mPxUz6YjuPetqwEfhQzntQF7J1FhD7qp yW5SFzOx2TApD/dx3Ovwcgpmpu/XO56GdrZ8pcvf+hHwTQo96f2i2g3JYNNJ0wfhS+7N i+64ueC2d0urMIS+5PTczM+yenP9mTuN7S4l8JKkiymPMaSJPtH9Krardra2PXbsAL+b 94a05K2uI5z5EMdHPZWRR63Q9hdJlsC0LXfw60K3JazVsnw8842pCADjffpwYU+i8jEB KtFQ== X-Received: by 10.68.13.132 with SMTP id h4mr2933130pbc.99.1376376858191; Mon, 12 Aug 2013 23:54:18 -0700 (PDT) Received: from localhost.localdomain ([115.113.119.130]) by mx.google.com with ESMTPSA id oj6sm44688882pab.9.2013.08.12.23.54.15 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 12 Aug 2013 23:54:17 -0700 (PDT) From: Shaik Ameer Basha To: linux-media@vger.kernel.org Cc: s.nawrocki@samsung.com, posciak@google.com Subject: [PATCH] [media] v4l2-mem2mem: clear m2m context from job_queue before ctx streamoff Date: Tue, 13 Aug 2013 12:28:07 +0530 Message-Id: <1376377087-19473-1-git-send-email-shaik.ameer@samsung.com> X-Mailer: git-send-email 1.7.9.5 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When streamoff is called on the context and the context is added to the job_queue, 1] sometimes device_run receives the empty vb2 buffers (as v4l2_m2m_streamoff is dropping the ready queue). 2] sometimes v4l2_m2m_job_finish may not succeed as the m2m_dev->curr_ctx is made NULL in the v4l2_m2m_streamoff() The above points may stop the execution of the other queued contexts. This patch makes sure that before streamoff is executed on any context, that context should "not be running" or "not queued" in the job_queue. 1] If the current context is running, then abort job will be called. 2] If the current context is queued, then the context will be removed from the job_queue. Signed-off-by: Shaik Ameer Basha --- drivers/media/v4l2-core/v4l2-mem2mem.c | 59 ++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 89b9067..7c43712 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -266,6 +266,39 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) } /** + * v4l2_m2m_cancel_job() - cancel pending jobs for the context + * + * In case of streamoff or release called on any context, + * 1] If the context is currently running, then abort job will be called + * 2] If the context is queued, then the context will be removed from + * the job_queue + */ +static void v4l2_m2m_cancel_job(struct v4l2_m2m_ctx *m2m_ctx) +{ + struct v4l2_m2m_dev *m2m_dev; + unsigned long flags; + + m2m_dev = m2m_ctx->m2m_dev; + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + if (m2m_ctx->job_flags & TRANS_RUNNING) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); + dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx); + wait_event(m2m_ctx->finished, + !(m2m_ctx->job_flags & TRANS_RUNNING)); + } else if (m2m_ctx->job_flags & TRANS_QUEUED) { + list_del(&m2m_ctx->queue); + m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("m2m_ctx: %p had been on queue and was removed\n", + m2m_ctx); + } else { + /* Do nothing, was not on queue/running */ + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + } +} + +/** * v4l2_m2m_job_finish() - inform the framework that a job has been finished * and have it clean up * @@ -436,6 +469,9 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, unsigned long flags_job, flags; int ret; + /* wait until the current context is dequeued from job_queue */ + v4l2_m2m_cancel_job(m2m_ctx); + q_ctx = get_queue_ctx(m2m_ctx, type); ret = vb2_streamoff(&q_ctx->q, type); if (ret) @@ -658,27 +694,8 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init); */ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx) { - struct v4l2_m2m_dev *m2m_dev; - unsigned long flags; - - m2m_dev = m2m_ctx->m2m_dev; - - spin_lock_irqsave(&m2m_dev->job_spinlock, flags); - if (m2m_ctx->job_flags & TRANS_RUNNING) { - spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); - dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx); - wait_event(m2m_ctx->finished, !(m2m_ctx->job_flags & TRANS_RUNNING)); - } else if (m2m_ctx->job_flags & TRANS_QUEUED) { - list_del(&m2m_ctx->queue); - m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); - spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - dprintk("m2m_ctx: %p had been on queue and was removed\n", - m2m_ctx); - } else { - /* Do nothing, was not on queue/running */ - spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); - } + /* wait until the current context is dequeued from job_queue */ + v4l2_m2m_cancel_job(m2m_ctx); vb2_queue_release(&m2m_ctx->cap_q_ctx.q); vb2_queue_release(&m2m_ctx->out_q_ctx.q);