Message ID | 20240210180414.49184-1-randy.li@synaptics.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-60511-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp1588891dyd; Sat, 10 Feb 2024 10:05:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUMm2Lb1iBlNj2maVp9CbLriZW4tJAdhG0kAwntXFZnN3S6n6kO3DJIHuznJNLS33U/L9Y6PfYOlHPZ8aAcpFLkOgtwcA== X-Google-Smtp-Source: AGHT+IHnwsoQnVvXkjVH7hciDBFErWDNsOGQSmW0gAS3Nx1317ujMEuj/MU76s5I+t+XyPI6CEpI X-Received: by 2002:a05:6402:1acb:b0:55f:e2be:ec0e with SMTP id ba11-20020a0564021acb00b0055fe2beec0emr1515132edb.1.1707588317946; Sat, 10 Feb 2024 10:05:17 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXnjml4/+1Iqu7ZEvPq+Fk/+NugjpMWKMpjAWnTyFgjVTZNCeFH0+DwxhaD1DlbxNJB3alUq1rWk0N99D2DiD9qra7WqA== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id k19-20020a508ad3000000b00560a1525fc1si1042652edk.303.2024.02.10.10.05.17 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 Feb 2024 10:05:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-60511-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@synaptics.com header.s=selector1 header.b=ujrJN76n; arc=fail (signature failed); spf=pass (google.com: domain of linux-kernel+bounces-60511-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-60511-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synaptics.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 60A431F24950 for <ouuuleilei@gmail.com>; Sat, 10 Feb 2024 18:05:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BF2D95D735; Sat, 10 Feb 2024 18:04:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=synaptics.com header.i=@synaptics.com header.b="ujrJN76n" Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2098.outbound.protection.outlook.com [40.107.243.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8349A259B; Sat, 10 Feb 2024 18:04:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.98 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707588294; cv=fail; b=KRiOu73nZF4SS6fBrjQcA3tihzUVeeKD2mhizQEgp3lhVYu9TAppt7LcND29fJSdDkI1QewrTJ5fVDFkikOfE0Q5p0CNTIzd8sa94USGuI/utlK+8AE9TjAz0ni95rvOOAAYr+1ZOEt/kh8+CRHe1ooaOkQE1tJb/JBVvwQrJwI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707588294; c=relaxed/simple; bh=txWABCYrxdCJ+204b+0wT5TZ+gKWxn3HolVMlaGWhnU=; h=From:To:Cc:Subject:Date:Message-ID:Content-Type:MIME-Version; b=gmuhRycg52gTpRv8USWIBXh1py4hmOOoskQ9C+p2txQADA0crHjlFb77E1plc2IKwqIqApyCnKsJ93EVrTv1R2QB0dBU3Uz+IsKEzWWpef7XfYwYxf9/rM76iiCLuwztaXCr2Wdj8duRmfNBiNgsLJH/4HfW7RxtVF1QSudK1G8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=synaptics.com; spf=pass smtp.mailfrom=synaptics.com; dkim=pass (1024-bit key) header.d=synaptics.com header.i=@synaptics.com header.b=ujrJN76n; arc=fail smtp.client-ip=40.107.243.98 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=synaptics.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=synaptics.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=O3qusijYTDKzbCzTBGRynVm1omT8tnVPltnUFf9/FWDuvJkQdB+lw2zbk7FLuGLZ88AGHLT+OB33Mw5IU/UOM675h12NYhNhhobcIleO2sHVbSVb/hSYayZqCox9z8ZsJeGFU7RFjI/85tlyNvd5G8GZDbgV13QpXeoHjC5je0FGX2Dudtn8SO6WvW8s3NyjlB6Dl7RmpzJpxYw/9QIVU42WkFCQq4cCiwQBwjPMW6QFU9dVAq4bBNpoHkqUOlvL24YAMd7/AXDgJAgdnb+ulUgCLjwO0DLblwTAsGDKJWsGl+0rDeyn8sXLT9YGlnieKl3R7tMRPB4kixcV+9ZClw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Yd0tOkOiF3YhEnUFUGnck53/Rp2hL/+Up8uGYDlbZaA=; b=TY0CalLYGdS5qXpYjIoG7RPVJo5WOkmkRCKHpw2QNgqTpdPMd7scnwSS5IJ6Lr1TCG7OEJ7mb7LW9uLChvQIa4RqmzuDVKV9SB/JlZn6KnRbHsVVpYvKrBfLAikqi/RUVuPY8sygYKU2kRsIFUGSn6uNYLks5e3BUPVkLarTWx8JCFaDedao9+aXBLxMUIMJk1ilElKw+iILx+ZLgsoxkK+7blffRZ95DDgjoE4S8xeHLs1ibW7Ghxb9Teha1NMx6zeK6YdS0SLMOwinJqmuHRWliP3wDzamEC4qKuYTF3beJJJOXLkv9ahK+ry3pw7wNiskhanFLIujpkFBM0m+7A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=synaptics.com; dmarc=pass action=none header.from=synaptics.com; dkim=pass header.d=synaptics.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=synaptics.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Yd0tOkOiF3YhEnUFUGnck53/Rp2hL/+Up8uGYDlbZaA=; b=ujrJN76nyFEaD31N6LqDHQU5Zv90n8gzmwnTsH/9E1lSUcMLylO3BgrV93d7hCKVm2K8HgKI2ss7G+spwpzQwc8cycTaPqabAu0jOdiKagF1qbxvl6qWKz4BjFMYi346ZH7RlXtaW6kIbn/zes/vymFirPSbCRvbQZwLPebhtcQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=synaptics.com; Received: from DM6PR03MB5196.namprd03.prod.outlook.com (2603:10b6:5:24a::19) by BL1PR03MB6102.namprd03.prod.outlook.com (2603:10b6:208:31c::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7270.35; Sat, 10 Feb 2024 18:04:48 +0000 Received: from DM6PR03MB5196.namprd03.prod.outlook.com ([fe80::1676:f700:fa63:91b5]) by DM6PR03MB5196.namprd03.prod.outlook.com ([fe80::1676:f700:fa63:91b5%6]) with mapi id 15.20.7270.033; Sat, 10 Feb 2024 18:04:47 +0000 From: Hsia-Jun Li <randy.li@synaptics.com> To: linux-media@vger.kernel.org Cc: mchehab@kernel.org, hverkuil-cisco@xs4all.nl, sebastian.fricke@collabora.com, nicolas.dufresne@collabora.com, alexious@zju.edu.cn, ayaka@soulik.info, linux-kernel@vger.kernel.org, "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> Subject: [PATCH] media: v4l2-mem2mem: fix mem order in last buf Date: Sun, 11 Feb 2024 02:04:06 +0800 Message-ID: <20240210180414.49184-1-randy.li@synaptics.com> X-Mailer: git-send-email 2.43.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SJ0PR03CA0213.namprd03.prod.outlook.com (2603:10b6:a03:39f::8) To DM6PR03MB5196.namprd03.prod.outlook.com (2603:10b6:5:24a::19) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM6PR03MB5196:EE_|BL1PR03MB6102:EE_ X-MS-Office365-Filtering-Correlation-Id: 62b0772e-3f70-42eb-53bf-08dc2a62c4ab X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: EtXkrksErg8loALkG1vCOuzEH9kmYKOe5vGxK6FwjxS7XYnItRyRVgQKbdKPsKT34nc98tRCi9yunYJG6w5r9yGbisfkwq8NQtbaNiZiEkG9V1/hmTADrvSARez5hJvE0hZ/5n9RdHbgmwkRj6Lzl0I1OsfBLZWQdhClv5zcKDUART7csyJThSt1y6kIU4XBoOoovi7kt8Xwkm2jdxvEbljqiHmfTARu8FdQe4HD1h1vTVx+ju40qNGV4b6rALZnrwfcaSPgo7rs9fAR/Z2rKoG/5igyUHG4P7a1lCw1iKCL05Th0GEpkw+4R6dLnHAfQLQYY9mN0yeVJqfnlvmxA1HlMAMqS3O6LJySn1F4IKU2K+dfKfd36mBhtbS05UaN/XhoXAyabJYl7oa38eDPGZlpYOe9KQfeYPgn6BQG7VIiLFpPcZQactEoxNcWTmKmhMej1zbxLLYkobi66fGxtcs1DvYeZWhq393hwKQhzEaMoHCoB9Aw2Hgmm5llORsZVSx1QZyWWrSYmyvn39L0Ks4+IaDmKwfKvZnZw+AVoTm5YqgLpO5jgxb9eBCGD4BKuhANkYPeMRWoUdgoTp9NqW6fxbPtRqRtIzWwCHW6IjZr/6ebUfIEtUqSlSE98P6A X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM6PR03MB5196.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(346002)(136003)(376002)(39850400004)(366004)(230922051799003)(186009)(451199024)(64100799003)(1800799012)(2906002)(4744005)(8936002)(4326008)(8676002)(5660300002)(83380400001)(2616005)(1076003)(107886003)(26005)(38100700002)(36756003)(86362001)(38350700005)(6916009)(316002)(66946007)(66556008)(66476007)(6506007)(52116002)(6666004)(6512007)(6486002)(478600001)(41300700001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: DzL/PCbwhmDYBGyrTSkwLX0R8Il1/9rnSRBDLK/9csjUup6P9dUA1hWBISRGmcqWDWX2U25eeME3FD0uRJW+HgNa/2hEJEXSv6GIygN3cdK1YpwGMIqgeZAc6+IJCb1/kQ+ETe8Fp94QfTlRkBWJZD8eNJ2tE2arh5HCLGU49ZlFV69QI7eYGG6LJap4QLUIV50yXYNefAJkz7/r6xdReCKoQ7xV0G1twD6nMmvFl0OupFvS0Zb87VwIkKcGlv+BRJAJCpVmf9NOmK1XcZDVc9rZqlD7hxEJ83YqRVTyQvcn5WGLAffLzvaQ3QzFX9GbUoPVVPjIbhN+t4G2vf+6rcKMNQ7hSpN5OApNP8sy9VT6rM6GQBpSqyP+dMOAFV8epXl63C+mAYCLunrLZOui6o/Z85ANKo1/z6v7EFw1ft+YlaCzYODWQyFhVBJFwSWrxD/N5qDBL8Me/B1AgwxWqxgL10JPDwMMGcHRcKUphj3UH8MEJHtwl441SRopg08132aC/KKyP5xd0IvrNFFmmQV3eNpoFfk+o2CvoKTf2exJswLuqRU1dDFY/eLfGFNbrTqOFQQc/RveMurMroD8C41NHNlRlBq36jdDbVqVIXVKgQrDxfhg/XJjZqS1gS/IMUkdwmMsVvE9fPcB6If2UNoRoNyi9idIDznQGoHKHTHodnCy8o5R7CTNHA3jxZj4tDWIE/rMYtW3xWvSkIiELIDIYc9SNjVJyaEI/ZD1GC3Jk78xR01NwvizwXTZpR6oGBeR8nEMNlOq3/dlXpTYmOocyxCMJsxZ/6wYusk8NNAhvloKa+Iure6wA0lJucjVKHOkGQDPrlh140lADph5eRBdHk/HoiG22B4fEsT58H37nd8d92BhTGwq7nlE+CmTk9m079aNCDbnCIAX9W+/uhirb0Y5cL6FheoRMNSeJq4ykURvSdXUmr/tWqnQpxpEI0u54Hns1ApUID+i3sPIuS4IqxhsCNNFr63fvflnTFk1WLLgNTqqr6MzPMXheFvuj2wy/wF4qeucMf+fcHSaSfN3L8NXOrQ9MtQAkHa5U2TYhMz/ImXmQCq46n1t2xiWlp87Ka+RT3HuO5V4TIAvaVz2psBbRbWzmFFjajncrHZtg3UhSbKq2fK20QcFwShh2HjkNx4safsGIFnVHw9ibOmZGYIx3dwDcrcwMZxHiq7tlWUnFyRaB5UUVK1Ny2XcAgsUbpmyEoPSElo7URn5E6FluHCwQxpIDn510IKiqEfMjGclwMqoPW9j+HJ3FvhymOZ7k/N6hkQIUliv7TsYJYOVyQBZY3puhC0XWD2V36YsoLHDL0DFqZWZ6ccwW3nC4Fm9UxqkIZke61t50GSlOg77K/unLJbQNZKELbLwaG0ppPZksRPpQh/s3+R2h3E0ATSuixBtPMSQP/yHbhzW9wNqVuV7MeuuVu/Bys5AREQlZdx0fwegsESMU9n/3kZ2wkJ0DD17hyaYWYnTeEKYk8O9Nk72MWLdA6q5F4g41qshiYtBEErZ2fT3/Y6kmM5ROIowiJHqiO8raohjlnm4fPPZ7JbMkkaNTF2WK4Ywqs0l6BkUPqyJYEJjM6YBGR9T X-OriginatorOrg: synaptics.com X-MS-Exchange-CrossTenant-Network-Message-Id: 62b0772e-3f70-42eb-53bf-08dc2a62c4ab X-MS-Exchange-CrossTenant-AuthSource: DM6PR03MB5196.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Feb 2024 18:04:47.8447 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 335d1fbc-2124-4173-9863-17e7051a2a0e X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 8Q59CzCR7p3ibx35/SYKVViqxgV5hwJ0AdgwS4jTTEVzgCNcKUPnOfPGU/2d6Kp6vv6RePVKONhsosPIXTW70g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR03MB6102 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790536127907555948 X-GMAIL-MSGID: 1790536127907555948 |
Series |
media: v4l2-mem2mem: fix mem order in last buf
|
|
Commit Message
Hsia-Jun Li
Feb. 10, 2024, 6:04 p.m. UTC
From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> The has_stopped property in struct v4l2_m2m_ctx is operated without a lock protecction. Then the userspace calls to v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to a critical section issue. Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> --- drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Comments
Hi, > media: v4l2-mem2mem: fix mem order in last buf mem order ? Did you mean call order ? Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> > > The has_stopped property in struct v4l2_m2m_ctx is operated > without a lock protecction. Then the userspace calls to protection When ? ~~ > v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to > a critical section issue. As there is no locking, there is no critical section, perhaps a better phrasing could help. > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> > --- > drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c > index 75517134a5e9..f1de71031e02 100644 > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c > @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, > struct vb2_v4l2_buffer *vbuf) > { > vbuf->flags |= V4L2_BUF_FLAG_LAST; > - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > - > v4l2_m2m_mark_stopped(m2m_ctx); > + > + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); While it most likely fix the issue while testing, since userspace most likely polls on that queue and don't touch the driver until the poll was signalled, I strongly believe this is insufficient. When I look at vicodec and wave5, they both add a layer of locking on top of the mem2mem framework to fix this issue. I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans accessed in many places that aren't in any known atomic context. I think it would be nice to remove the spurious locking in drivers and try and fix this issue in the framework itself. Nicolas > } > EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >
On 2024/2/15 04:38, Nicolas Dufresne wrote: > Hi, > >> media: v4l2-mem2mem: fix mem order in last buf > mem order ? Did you mean call order ? std::memory_order > > Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : >> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> >> >> The has_stopped property in struct v4l2_m2m_ctx is operated >> without a lock protecction. Then the userspace calls to > protection When ? ~~ Access to those 3 booleans you mentioned later. >> v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to >> a critical section issue. > As there is no locking, there is no critical section, perhaps a better phrasing > could help. "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the concurrent access." It didn't say we need a lock here. >> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> >> --- >> drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >> index 75517134a5e9..f1de71031e02 100644 >> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >> @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, >> struct vb2_v4l2_buffer *vbuf) >> { >> vbuf->flags |= V4L2_BUF_FLAG_LAST; >> - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >> - >> v4l2_m2m_mark_stopped(m2m_ctx); >> + >> + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > While it most likely fix the issue while testing, since userspace most likely > polls on that queue and don't touch the driver until the poll was signalled, I > strongly believe this is insufficient. When I look at vicodec and wave5, they > both add a layer of locking on top of the mem2mem framework to fix this issue. Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. > I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans > accessed in many places that aren't in any known atomic context. I think it > would be nice to remove the spurious locking in drivers and try and fix this > issue in the framework itself. I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. > > Nicolas > >> } >> EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >>
On 15/02/2024 04:16, Randy Li wrote: > > On 2024/2/15 04:38, Nicolas Dufresne wrote: >> Hi, >> >>> media: v4l2-mem2mem: fix mem order in last buf >> mem order ? Did you mean call order ? > std::memory_order >> >> Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : >>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> >>> >>> The has_stopped property in struct v4l2_m2m_ctx is operated >>> without a lock protecction. Then the userspace calls to >> protection When ? ~~ > Access to those 3 booleans you mentioned later. >>> v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to >>> a critical section issue. >> As there is no locking, there is no critical section, perhaps a better phrasing >> could help. > > "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the > concurrent access." > > It didn't say we need a lock here. > >>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> >>> --- >>> drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- >>> 1 file changed, 2 insertions(+), 2 deletions(-) >>> >>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >>> index 75517134a5e9..f1de71031e02 100644 >>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >>> @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, >>> struct vb2_v4l2_buffer *vbuf) >>> { >>> vbuf->flags |= V4L2_BUF_FLAG_LAST; >>> - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>> - >>> v4l2_m2m_mark_stopped(m2m_ctx); >>> + >>> + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >> While it most likely fix the issue while testing, since userspace most likely >> polls on that queue and don't touch the driver until the poll was signalled, I >> strongly believe this is insufficient. When I look at vicodec and wave5, they >> both add a layer of locking on top of the mem2mem framework to fix this issue. > > Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. > > When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. > >> I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans >> accessed in many places that aren't in any known atomic context. I think it >> would be nice to remove the spurious locking in drivers and try and fix this >> issue in the framework itself. > I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. I think the root cause is something else. Let me say first of all that swapping the order of the two calls does make sense: before returning the buffer you want to mark the queue as stopped. But the real problem is that for drivers using the mem2mem framework the streaming ioctls can be serialized with a different lock than the VIDIOC_DE/ENCODER_CMD ioctls. The reason for that is that those two ioctls are not marked with INFO_FL_QUEUE, but I think they should. These ioctls are really part of the streaming ioctls and should all use the same lock. Note that for many drivers the same mutex is used for the streaming ioctls as for all other ioctls, but it looks like at least the venus driver uses separate mutexes. With that change in v4l2-core/v4l2-ioctl.c I don't believe any locking is needed, since it should always be serialized by the same top-level mutex. The v4l2_ioctl_get_lock() function in v4l2-ioctl.c is the one that selects which mutex to use for a given ioctl. Regards, Hans >> >> Nicolas >> >>> } >>> EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >>> >
Le jeudi 15 février 2024 à 11:16 +0800, Randy Li a écrit : > On 2024/2/15 04:38, Nicolas Dufresne wrote: > > Hi, > > > > > media: v4l2-mem2mem: fix mem order in last buf > > mem order ? Did you mean call order ? > std::memory_order > > > > Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> > > > > > > The has_stopped property in struct v4l2_m2m_ctx is operated > > > without a lock protecction. Then the userspace calls to > > protection When ? ~~ > Access to those 3 booleans you mentioned later. There were commenting you commit message typos, not a question. > > > v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to > > > a critical section issue. > > As there is no locking, there is no critical section, perhaps a better phrasing > > could help. > > "concurrent accesses to shared resources can lead to unexpected or > erroneous behavior, so parts of the program where the shared resource is > accessed need to be protected in ways that avoid the concurrent access." > > It didn't say we need a lock here. I said it. > > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> > > > --- > > > drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > index 75517134a5e9..f1de71031e02 100644 > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, > > > struct vb2_v4l2_buffer *vbuf) > > > { > > > vbuf->flags |= V4L2_BUF_FLAG_LAST; > > > - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > > - > > > v4l2_m2m_mark_stopped(m2m_ctx); > > > + > > > + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > While it most likely fix the issue while testing, since userspace most likely > > polls on that queue and don't touch the driver until the poll was signalled, I > > strongly believe this is insufficient. When I look at vicodec and wave5, they > > both add a layer of locking on top of the mem2mem framework to fix this issue. > > Maybe a memory barrier is enough. Since vb2_buffer_done() itself would > invoke the (spin)lock operation. > > When the poll() returns in userspace, the future operation for those > three boolean variables won't happen before the lock. > > > I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans > > accessed in many places that aren't in any known atomic context. I think it > > would be nice to remove the spurious locking in drivers and try and fix this > > issue in the framework itself. > I tend to not introduce more locks here. There is a spinlock in m2m_ctx > which is a pain in the ass, something we could reuse it to save our CPU > but it just can't be access. If you can find a way with memory barrier, but that is difficult to maintain and often breaks without noticing. I'm happy to review something that introduce thread safety rather then depending on userspace call order. Can't disagree with the spinlock, its been difficult in Wave5 and there is still a bug report of one more case were we get that spinlock mixed with mutex. Nicolas > > > > Nicolas > > > > > } > > > EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); > > > >
Le jeudi 15 février 2024 à 09:41 +0100, Hans Verkuil a écrit : > On 15/02/2024 04:16, Randy Li wrote: > > > > On 2024/2/15 04:38, Nicolas Dufresne wrote: > > > Hi, > > > > > > > media: v4l2-mem2mem: fix mem order in last buf > > > mem order ? Did you mean call order ? > > std::memory_order > > > > > > Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : > > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> > > > > > > > > The has_stopped property in struct v4l2_m2m_ctx is operated > > > > without a lock protecction. Then the userspace calls to > > > protection When ? ~~ > > Access to those 3 booleans you mentioned later. > > > > v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to > > > > a critical section issue. > > > As there is no locking, there is no critical section, perhaps a better phrasing > > > could help. > > > > "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the > > concurrent access." > > > > It didn't say we need a lock here. > > > > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> > > > > --- > > > > drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- > > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > index 75517134a5e9..f1de71031e02 100644 > > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, > > > > struct vb2_v4l2_buffer *vbuf) > > > > { > > > > vbuf->flags |= V4L2_BUF_FLAG_LAST; > > > > - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > > > - > > > > v4l2_m2m_mark_stopped(m2m_ctx); > > > > + > > > > + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > > While it most likely fix the issue while testing, since userspace most likely > > > polls on that queue and don't touch the driver until the poll was signalled, I > > > strongly believe this is insufficient. When I look at vicodec and wave5, they > > > both add a layer of locking on top of the mem2mem framework to fix this issue. > > > > Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. > > > > When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. > > > > > I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans > > > accessed in many places that aren't in any known atomic context. I think it > > > would be nice to remove the spurious locking in drivers and try and fix this > > > issue in the framework itself. > > I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. > > I think the root cause is something else. > > Let me say first of all that swapping the order of the two calls does make sense: > before returning the buffer you want to mark the queue as stopped. > > But the real problem is that for drivers using the mem2mem framework the streaming > ioctls can be serialized with a different lock than the VIDIOC_DE/ENCODER_CMD ioctls. > > The reason for that is that those two ioctls are not marked with INFO_FL_QUEUE, > but I think they should. These ioctls are really part of the streaming ioctls > and should all use the same lock. > > Note that for many drivers the same mutex is used for the streaming ioctls as for > all other ioctls, but it looks like at least the venus driver uses separate mutexes. > > With that change in v4l2-core/v4l2-ioctl.c I don't believe any locking is needed, > since it should always be serialized by the same top-level mutex. > > The v4l2_ioctl_get_lock() function in v4l2-ioctl.c is the one that selects which > mutex to use for a given ioctl. There was no way to comply with the spec without accessing that state in the irq thread in Wave5. In that case, we need to decide if we continue or cancel a dynamic resolution change. if (!v4l2_m2m_has_stopped(m2m_ctx)) { switch_state(inst, VPU_INST_STATE_STOP); if (dec_info.sequence_changed) handle_dynamic_resolution_change(inst); else send_eos_event(inst); flag_last_buffer_done(inst); } That forced us to introduce a spinlock to protect that state in that driver. As for locking cmd_start, that might help, its certainly a behaviour change and will have to be taken with care. How does the ioctl lock interact with blocking QBUF notably ? Nicolas > > Regards, > > Hans > > > > > > > Nicolas > > > > > > > } > > > > EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); > > > > > > > >
On 2/17/24 02:56, Nicolas Dufresne wrote: > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe. > > > Le jeudi 15 février 2024 à 11:16 +0800, Randy Li a écrit : >> On 2024/2/15 04:38, Nicolas Dufresne wrote: >>> Hi, >>> >>>> media: v4l2-mem2mem: fix mem order in last buf >>> mem order ? Did you mean call order ? >> std::memory_order >>> >>> Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : >>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> >>>> >>>> The has_stopped property in struct v4l2_m2m_ctx is operated >>>> without a lock protecction. Then the userspace calls to >>> protection When ? ~~ >> Access to those 3 booleans you mentioned later. > > There were commenting you commit message typos, not a question. > >>>> v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to >>>> a critical section issue. >>> As there is no locking, there is no critical section, perhaps a better phrasing >>> could help. >> >> "concurrent accesses to shared resources can lead to unexpected or >> erroneous behavior, so parts of the program where the shared resource is >> accessed need to be protected in ways that avoid the concurrent access." >> >> It didn't say we need a lock here. > > I said it. > I mean, I think my description was correct. Because the critical section don't need a lock invoked. >> >>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> >>>> --- >>>> drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- >>>> 1 file changed, 2 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>> index 75517134a5e9..f1de71031e02 100644 >>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>> @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, >>>> struct vb2_v4l2_buffer *vbuf) >>>> { >>>> vbuf->flags |= V4L2_BUF_FLAG_LAST; >>>> - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>>> - >>>> v4l2_m2m_mark_stopped(m2m_ctx); >>>> + >>>> + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>> While it most likely fix the issue while testing, since userspace most likely >>> polls on that queue and don't touch the driver until the poll was signalled, I >>> strongly believe this is insufficient. When I look at vicodec and wave5, they >>> both add a layer of locking on top of the mem2mem framework to fix this issue. >> >> Maybe a memory barrier is enough. Since vb2_buffer_done() itself would >> invoke the (spin)lock operation. >> >> When the poll() returns in userspace, the future operation for those >> three boolean variables won't happen before the lock. >> >>> I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans >>> accessed in many places that aren't in any known atomic context. I think it >>> would be nice to remove the spurious locking in drivers and try and fix this >>> issue in the framework itself. >> I tend to not introduce more locks here. There is a spinlock in m2m_ctx >> which is a pain in the ass, something we could reuse it to save our CPU >> but it just can't be access. > > If you can find a way with memory barrier, but that is difficult to maintain and I was thinking the spin lock which already existed in vb2_buffer_done() is an implicit memory barrier. Anyway, the problem is a clear, the other thread who would access those three 3 variables should happen after the write operation here(v4l2_m2m_last_buffer_done()). I would try to offer a possible memory barrier solution appended to this version. > often breaks without noticing. I'm happy to review something that introduce > thread safety rather then depending on userspace call order. Can't disagree with > the spinlock, its been difficult in Wave5 and there is still a bug report of one > more case were we get that spinlock mixed with mutex. > I don't want to introduce a new spinlock either. But since the code here has already used one, if we needed one, it would be a variant of spinlock. > Nicolas > >>> >>> Nicolas >>> >>>> } >>>> EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >>>> >> >
On 2/17/24 03:09, Nicolas Dufresne wrote: > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe. > > > Le jeudi 15 février 2024 à 09:41 +0100, Hans Verkuil a écrit : >> On 15/02/2024 04:16, Randy Li wrote: >>> >>> On 2024/2/15 04:38, Nicolas Dufresne wrote: >>>> Hi, >>>> >>>>> media: v4l2-mem2mem: fix mem order in last buf >>>> mem order ? Did you mean call order ? >>> std::memory_order >>>> >>>> Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : >>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> >>>>> >>>>> The has_stopped property in struct v4l2_m2m_ctx is operated >>>>> without a lock protecction. Then the userspace calls to >>>> protection When ? ~~ >>> Access to those 3 booleans you mentioned later. >>>>> v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to >>>>> a critical section issue. >>>> As there is no locking, there is no critical section, perhaps a better phrasing >>>> could help. >>> >>> "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the >>> concurrent access." >>> >>> It didn't say we need a lock here. >>> >>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> >>>>> --- >>>>> drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- >>>>> 1 file changed, 2 insertions(+), 2 deletions(-) >>>>> >>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>> index 75517134a5e9..f1de71031e02 100644 >>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>> @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, >>>>> struct vb2_v4l2_buffer *vbuf) >>>>> { >>>>> vbuf->flags |= V4L2_BUF_FLAG_LAST; >>>>> - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>>>> - >>>>> v4l2_m2m_mark_stopped(m2m_ctx); >>>>> + >>>>> + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>>> While it most likely fix the issue while testing, since userspace most likely >>>> polls on that queue and don't touch the driver until the poll was signalled, I >>>> strongly believe this is insufficient. When I look at vicodec and wave5, they >>>> both add a layer of locking on top of the mem2mem framework to fix this issue. >>> >>> Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. >>> >>> When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. >>> >>>> I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans >>>> accessed in many places that aren't in any known atomic context. I think it >>>> would be nice to remove the spurious locking in drivers and try and fix this >>>> issue in the framework itself. >>> I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. >> >> I think the root cause is something else. >> >> Let me say first of all that swapping the order of the two calls does make sense: >> before returning the buffer you want to mark the queue as stopped. >> >> But the real problem is that for drivers using the mem2mem framework the streaming >> ioctls can be serialized with a different lock than the VIDIOC_DE/ENCODER_CMD ioctls. >> >> The reason for that is that those two ioctls are not marked with INFO_FL_QUEUE, >> but I think they should. These ioctls are really part of the streaming ioctls >> and should all use the same lock. >> >> Note that for many drivers the same mutex is used for the streaming ioctls as for >> all other ioctls, but it looks like at least the venus driver uses separate mutexes. >> But I saw many drivers didn't assign that q_lock here. I am an one. Since it is an optional mutex lock. >> With that change in v4l2-core/v4l2-ioctl.c I don't believe any locking is needed, >> since it should always be serialized by the same top-level mutex. >> >> The v4l2_ioctl_get_lock() function in v4l2-ioctl.c is the one that selects which >> mutex to use for a given ioctl. > > There was no way to comply with the spec without accessing that state in the irq > thread in Wave5. In that case, we need to decide if we continue or cancel a > dynamic resolution change. > > > if (!v4l2_m2m_has_stopped(m2m_ctx)) { > switch_state(inst, VPU_INST_STATE_STOP); > > if (dec_info.sequence_changed) > handle_dynamic_resolution_change(inst); > else > send_eos_event(inst); > > flag_last_buffer_done(inst); > } > > That forced us to introduce a spinlock to protect that state in that driver. > Usually we won't do buffer operation in the irq handler context. It causes too many times, But that makes a point. Sometimes, I can't just introduce that a mutex, while most of the m2m context has acquired a spinlock. > As for locking cmd_start, that might help, its certainly a behaviour change and > will have to be taken with care. How does the ioctl lock interact with blocking > QBUF notably ? > > Nicolas > >> >> Regards, >> >> Hans >> >>>> >>>> Nicolas >>>> >>>>> } >>>>> EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >>>>> >>> >> >> >
Le mercredi 21 février 2024 à 18:37 +0800, Hsia-Jun Li a écrit : > > On 2/17/24 03:09, Nicolas Dufresne wrote: > > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe. > > > > > > Le jeudi 15 février 2024 à 09:41 +0100, Hans Verkuil a écrit : > > > On 15/02/2024 04:16, Randy Li wrote: > > > > > > > > On 2024/2/15 04:38, Nicolas Dufresne wrote: > > > > > Hi, > > > > > > > > > > > media: v4l2-mem2mem: fix mem order in last buf > > > > > mem order ? Did you mean call order ? > > > > std::memory_order > > > > > > > > > > Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : > > > > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> > > > > > > > > > > > > The has_stopped property in struct v4l2_m2m_ctx is operated > > > > > > without a lock protecction. Then the userspace calls to > > > > > protection When ? ~~ > > > > Access to those 3 booleans you mentioned later. > > > > > > v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to > > > > > > a critical section issue. > > > > > As there is no locking, there is no critical section, perhaps a better phrasing > > > > > could help. > > > > > > > > "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the > > > > concurrent access." > > > > > > > > It didn't say we need a lock here. > > > > > > > > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> > > > > > > --- > > > > > > drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- > > > > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > > > > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > > > index 75517134a5e9..f1de71031e02 100644 > > > > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c > > > > > > @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, > > > > > > struct vb2_v4l2_buffer *vbuf) > > > > > > { > > > > > > vbuf->flags |= V4L2_BUF_FLAG_LAST; > > > > > > - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > > > > > - > > > > > > v4l2_m2m_mark_stopped(m2m_ctx); > > > > > > + > > > > > > + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); > > > > > While it most likely fix the issue while testing, since userspace most likely > > > > > polls on that queue and don't touch the driver until the poll was signalled, I > > > > > strongly believe this is insufficient. When I look at vicodec and wave5, they > > > > > both add a layer of locking on top of the mem2mem framework to fix this issue. > > > > > > > > Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. > > > > > > > > When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. > > > > > > > > > I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans > > > > > accessed in many places that aren't in any known atomic context. I think it > > > > > would be nice to remove the spurious locking in drivers and try and fix this > > > > > issue in the framework itself. > > > > I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. > > > > > > I think the root cause is something else. > > > > > > Let me say first of all that swapping the order of the two calls does make sense: > > > before returning the buffer you want to mark the queue as stopped. > > > > > > But the real problem is that for drivers using the mem2mem framework the streaming > > > ioctls can be serialized with a different lock than the VIDIOC_DE/ENCODER_CMD ioctls. > > > > > > The reason for that is that those two ioctls are not marked with INFO_FL_QUEUE, > > > but I think they should. These ioctls are really part of the streaming ioctls > > > and should all use the same lock. > > > > > > Note that for many drivers the same mutex is used for the streaming ioctls as for > > > all other ioctls, but it looks like at least the venus driver uses separate mutexes. > > > > > But I saw many drivers didn't assign that q_lock here. I am an one. > Since it is an optional mutex lock. > > > > With that change in v4l2-core/v4l2-ioctl.c I don't believe any locking is needed, > > > since it should always be serialized by the same top-level mutex. > > > > > > The v4l2_ioctl_get_lock() function in v4l2-ioctl.c is the one that selects which > > > mutex to use for a given ioctl. > > > > There was no way to comply with the spec without accessing that state in the irq > > thread in Wave5. In that case, we need to decide if we continue or cancel a > > dynamic resolution change. > > > > > > if (!v4l2_m2m_has_stopped(m2m_ctx)) { > > switch_state(inst, VPU_INST_STATE_STOP); > > > > if (dec_info.sequence_changed) > > handle_dynamic_resolution_change(inst); > > else > > send_eos_event(inst); > > > > flag_last_buffer_done(inst); > > } > > > > That forced us to introduce a spinlock to protect that state in that driver. > > > Usually we won't do buffer operation in the irq handler context. It > causes too many times, I took this one out of context, but this is inside a threaded IRQ handle, we indeed have too much work and state to match with how Wave5 firmware behave As discuss on IRC, not being able to see the Synaptics driver you are referring to has its limitation. > > But that makes a point. Sometimes, I can't just introduce that a mutex, > while most of the m2m context has acquired a spinlock. In wave5, we had to use a spinlock as the framework holds its own spinlock while calling job_ready() (can't mix lock mutex while a spinlock is held), and we need thread safety in that call in order to use that state to make the right decisions. On agressive stress test, we were getting stalls due to decisions being made with partially written state. > > As for locking cmd_start, that might help, its certainly a behaviour change and > > will have to be taken with care. How does the ioctl lock interact with blocking > > QBUF notably ? > > > > Nicolas > > > > > > > > Regards, > > > > > > Hans > > > > > > > > > > > > > Nicolas > > > > > > > > > > > } > > > > > > EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); > > > > > > > > > > > > > > > > > > >
On 2/21/24 23:32, Nicolas Dufresne wrote: > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe. > > > Le mercredi 21 février 2024 à 18:37 +0800, Hsia-Jun Li a écrit : >> >> On 2/17/24 03:09, Nicolas Dufresne wrote: >>> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe. >>> >>> >>> Le jeudi 15 février 2024 à 09:41 +0100, Hans Verkuil a écrit : >>>> On 15/02/2024 04:16, Randy Li wrote: >>>>> >>>>> On 2024/2/15 04:38, Nicolas Dufresne wrote: >>>>>> Hi, >>>>>> >>>>>>> media: v4l2-mem2mem: fix mem order in last buf >>>>>> mem order ? Did you mean call order ? >>>>> std::memory_order >>>>>> >>>>>> Le dimanche 11 février 2024 à 02:04 +0800, Hsia-Jun Li a écrit : >>>>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com> >>>>>>> >>>>>>> The has_stopped property in struct v4l2_m2m_ctx is operated >>>>>>> without a lock protecction. Then the userspace calls to >>>>>> protection When ? ~~ >>>>> Access to those 3 booleans you mentioned later. >>>>>>> v4l2_m2m_encoder_cmd()/v4l2_m2m_decoder_cmd() may lead to >>>>>>> a critical section issue. >>>>>> As there is no locking, there is no critical section, perhaps a better phrasing >>>>>> could help. >>>>> >>>>> "concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed need to be protected in ways that avoid the >>>>> concurrent access." >>>>> >>>>> It didn't say we need a lock here. >>>>> >>>>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com> >>>>>>> --- >>>>>>> drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- >>>>>>> 1 file changed, 2 insertions(+), 2 deletions(-) >>>>>>> >>>>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>>>> index 75517134a5e9..f1de71031e02 100644 >>>>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >>>>>>> @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, >>>>>>> struct vb2_v4l2_buffer *vbuf) >>>>>>> { >>>>>>> vbuf->flags |= V4L2_BUF_FLAG_LAST; >>>>>>> - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>>>>>> - >>>>>>> v4l2_m2m_mark_stopped(m2m_ctx); >>>>>>> + >>>>>>> + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); >>>>>> While it most likely fix the issue while testing, since userspace most likely >>>>>> polls on that queue and don't touch the driver until the poll was signalled, I >>>>>> strongly believe this is insufficient. When I look at vicodec and wave5, they >>>>>> both add a layer of locking on top of the mem2mem framework to fix this issue. >>>>> >>>>> Maybe a memory barrier is enough. Since vb2_buffer_done() itself would invoke the (spin)lock operation. >>>>> >>>>> When the poll() returns in userspace, the future operation for those three boolean variables won't happen before the lock. >>>>> >>>>>> I think this is unfortunate, but v4l2_m2m_mark_stopped() is backed by 3 booleans >>>>>> accessed in many places that aren't in any known atomic context. I think it >>>>>> would be nice to remove the spurious locking in drivers and try and fix this >>>>>> issue in the framework itself. >>>>> I tend to not introduce more locks here. There is a spinlock in m2m_ctx which is a pain in the ass, something we could reuse it to save our CPU but it just can't be access. >>>> >>>> I think the root cause is something else. >>>> >>>> Let me say first of all that swapping the order of the two calls does make sense: >>>> before returning the buffer you want to mark the queue as stopped. >>>> >>>> But the real problem is that for drivers using the mem2mem framework the streaming >>>> ioctls can be serialized with a different lock than the VIDIOC_DE/ENCODER_CMD ioctls. >>>> >>>> The reason for that is that those two ioctls are not marked with INFO_FL_QUEUE, >>>> but I think they should. These ioctls are really part of the streaming ioctls >>>> and should all use the same lock. >>>> >>>> Note that for many drivers the same mutex is used for the streaming ioctls as for >>>> all other ioctls, but it looks like at least the venus driver uses separate mutexes. >>>> >> >> But I saw many drivers didn't assign that q_lock here. I am an one. >> Since it is an optional mutex lock. >> >>>> With that change in v4l2-core/v4l2-ioctl.c I don't believe any locking is needed, >>>> since it should always be serialized by the same top-level mutex. >>>> >>>> The v4l2_ioctl_get_lock() function in v4l2-ioctl.c is the one that selects which >>>> mutex to use for a given ioctl. >>> >>> There was no way to comply with the spec without accessing that state in the irq >>> thread in Wave5. In that case, we need to decide if we continue or cancel a >>> dynamic resolution change. >>> >>> >>> if (!v4l2_m2m_has_stopped(m2m_ctx)) { >>> switch_state(inst, VPU_INST_STATE_STOP); >>> >>> if (dec_info.sequence_changed) >>> handle_dynamic_resolution_change(inst); >>> else >>> send_eos_event(inst); >>> >>> flag_last_buffer_done(inst); >>> } >>> >>> That forced us to introduce a spinlock to protect that state in that driver. >>> >> Usually we won't do buffer operation in the irq handler context. It >> causes too many times, > > I took this one out of context, but this is inside a threaded IRQ handle, we > indeed have too much work and state to match with how Wave5 firmware behave. As > discuss on IRC, not being able to see the Synaptics driver you are referring to > has its limitation. > I think it is common sense not sleep lock(mutex) inside irq handler. Besides, it is not wrong to keep the runtime of the irq handler short. You are occupied a CPU core non-preempt. I could show you a few slices of our driver while it is not formal released. The released version could be mediocre one. static irqreturn_t syna_vpu_isr(int irq, void *dev_id) { struct syna_vpu_dev *vpu = dev_id; vpu_srv_isr_done(vpu->srv); return IRQ_HANDLED; } The real work in a separated thread(work queue): static void syna_vdec_v4g_worker(struct work_struct *work) { .. if (ctrl->status.flags & BERLIN_VPU_STATUS_WAIT_INTERRUPTER) { ctrl->status.flags &= (~BERLIN_VPU_STATUS_WAIT_INTERRUPTER); ret = vpu_srv_wait_isr(vpu->srv, DEC_V4G_TIMEOUT_DELAY); if (ret) { ret = syna_vdec_hw_abort(ctx); /** * NOTE: if it failed, keep the device power here * then we could dump registers from the device. */ if (ret) goto bail; } goto decoding; } pm_runtime_put(vpu->dev); .. } >> >> But that makes a point. Sometimes, I can't just introduce that a mutex, >> while most of the m2m context has acquired a spinlock. > > In wave5, we had to use a spinlock as the framework holds its own spinlock while > calling job_ready() (can't mix lock mutex while a spinlock is held), and we need Yes, in __v4l2_m2m_try_queue() > thread safety in that call in order to use that state to make the right > decisions. On agressive stress test, we were getting stalls due to decisions > being made with partially written state. > For those three variables, only the has_stopped matters here. I am not sure which case would need more lock acquired here? CMD_STOP a context after it has been started? They would always go through rdy_spinlock. >>> As for locking cmd_start, that might help, its certainly a behaviour change and >>> will have to be taken with care. How does the ioctl lock interact with blocking >>> QBUF notably ? QBUF? m2m would use rdy_spinlock here. I didn't really get your case? >>> >>> Nicolas >>> >>>> >>>> Regards, >>>> >>>> Hans >>>> >>>>>> >>>>>> Nicolas >>>>>> >>>>>>> } >>>>>>> EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done); >>>>>>> >>>>> >>>> >>>> >>> >> >
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 75517134a5e9..f1de71031e02 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -635,9 +635,9 @@ void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf) { vbuf->flags |= V4L2_BUF_FLAG_LAST; - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); - v4l2_m2m_mark_stopped(m2m_ctx); + + vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); } EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done);