From patchwork Fri Aug 14 07:11:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xia Jiang X-Patchwork-Id: 256176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.4 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MIME_BASE64_TEXT, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B2F0C433E1 for ; Fri, 14 Aug 2020 07:15:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 31A7D2074D for ; Fri, 14 Aug 2020 07:15:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="BJXj/rKR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726719AbgHNHNU (ORCPT ); Fri, 14 Aug 2020 03:13:20 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:13311 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726674AbgHNHNT (ORCPT ); Fri, 14 Aug 2020 03:13:19 -0400 X-UUID: 77f47ef2a04e4f228624d3dc5eaf6a01-20200814 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=IbiFDDHum+jOdniC/v+DA+ppKQzebMyLkYXcc0l8USM=; b=BJXj/rKR2C/1cRoMW/6kkNdaCgwOfZY4/QASnoXWJ0IHjjvWQkPAZ6mqBIQfoanvExPFep+voC5ohEDnbXPcfGa9X78BQ1WCd/JVYla4DFWhF1Cz1wRLsUylmj4LNT8N233wwVqOoheZp8jYQMDxAzweKs0eAQcZtod1+GtqW/M=; X-UUID: 77f47ef2a04e4f228624d3dc5eaf6a01-20200814 Received: from mtkcas06.mediatek.inc [(172.21.101.30)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1253427356; Fri, 14 Aug 2020 15:13:13 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 15:13:11 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 14 Aug 2020 15:13:10 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , Matthias Brugger , Rick Chang CC: , , , , , Marek Szyprowski , Tomasz Figa , , , , , , Pi-Hsun Shih , Jerry-ch Chen Subject: [PATCH v12 07/29] media: v4l2-mem2mem: add v4l2_m2m_suspend, v4l2_m2m_resume Date: Fri, 14 Aug 2020 15:11:40 +0800 Message-ID: <20200814071202.25067-9-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200814071202.25067-1-xia.jiang@mediatek.com> References: <20200814071202.25067-1-xia.jiang@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Pi-Hsun Shih Add two functions that can be used to stop new jobs from being queued / continue running queued job. This can be used while a driver using m2m helper is going to suspend / wake up from resume, and can ensure that there's no job running in suspend process. BUG=b:143046833 TEST=build Signed-off-by: Pi-Hsun Shih Signed-off-by: Jerry-ch Chen Reviewed-by: Tomasz Figa --- v12: add this relied patch to the series --- drivers/media/v4l2-core/v4l2-mem2mem.c | 41 ++++++++++++++++++++++++++ include/media/v4l2-mem2mem.h | 22 ++++++++++++++ 2 files changed, 63 insertions(+) -- 2.18.0 Reviewed-by: Hans Verkuil Tested-by: Adrian Ratiu diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 62ac9424c92a..ddfdb6375064 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -43,6 +43,10 @@ module_param(debug, bool, 0644); #define TRANS_ABORT (1 << 2) +/* The job queue is not running new jobs */ +#define QUEUE_PAUSED (1 << 0) + + /* Offset base for buffers on the destination queue - used to distinguish * between source and destination buffers when mmapping - they receive the same * offsets but for different queues */ @@ -84,6 +88,7 @@ static const char * const m2m_entity_name[] = { * @job_queue: instances queued to run * @job_spinlock: protects job_queue * @job_work: worker to run queued jobs. + * @job_queue_flags: flags of the queue status, %QUEUE_PAUSED. * @m2m_ops: driver callbacks */ struct v4l2_m2m_dev { @@ -101,6 +106,7 @@ struct v4l2_m2m_dev { struct list_head job_queue; spinlock_t job_spinlock; struct work_struct job_work; + unsigned long job_queue_flags; const struct v4l2_m2m_ops *m2m_ops; }; @@ -263,6 +269,12 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) return; } + if (m2m_dev->job_queue_flags & QUEUE_PAUSED) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("Running new jobs is paused\n"); + return; + } + m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx, queue); m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING; @@ -504,6 +516,7 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, if (WARN_ON(!src_buf || !dst_buf)) goto unlock; + v4l2_m2m_buf_done(src_buf, state); dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; if (!dst_buf->is_held) { v4l2_m2m_dst_buf_remove(m2m_ctx); @@ -528,6 +541,34 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, } EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish); +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev) +{ + unsigned long flags; + struct v4l2_m2m_ctx *curr_ctx; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + m2m_dev->job_queue_flags |= QUEUE_PAUSED; + curr_ctx = m2m_dev->curr_ctx; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + + if (curr_ctx) + wait_event(curr_ctx->finished, + !(curr_ctx->job_flags & TRANS_RUNNING)); +} +EXPORT_SYMBOL(v4l2_m2m_suspend); + +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + m2m_dev->job_queue_flags &= ~QUEUE_PAUSED; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + + v4l2_m2m_try_run(m2m_dev); +} +EXPORT_SYMBOL(v4l2_m2m_resume); + int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs) { diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 98753f00df7e..5a91b548ecc0 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -304,6 +304,28 @@ v4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx, void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf); +/** + * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job + * to finish + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Called by a driver in the suspend hook. Stop new jobs from being run, and + * wait for current running job to finish. + */ +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev); + +/** + * v4l2_m2m_resume() - resume job running and try to run a queued job + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Called by a driver in the resume hook. This reverts the operation of + * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if + * there is any. + */ +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev); + /** * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer *