From patchwork Tue Mar 12 10:34:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 779893 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 8106379DB3 for ; Tue, 12 Mar 2024 10:34:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710239683; cv=none; b=pqCAJFAiAMmAPoENVqoH/nO1C+3N6S3njdVSmliEvDn7ecU+8mPVKe1GpG4+P4NLqzHVD+tiNyFdD0ZD74PorpkUi8sdq9giuVPn5rVIecVUj03gU7pbXs4ig2cfVtJX38ORgpDCk2AuSOrWKS+AHLhyWm7CMy3Z78ojO5F7quE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710239683; c=relaxed/simple; bh=FS0nhNcBPCInVIG4RYXDiiNQbo0LCaPWxZJEEPTZ4oQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YO2GfrsUsi6kHGfqRUgWp8OaQn7O0xMvmlgxgHaqQ3sU15JFti9UsmccXzY21WQXhv7PTJ6W5+Pbwi580yYqE2igceABFotoh8m4iD+UNvZpDd3V4QoJ8MojpF1NzkdA+uFnNXJHa5ZC73acOOktX2Pjoo/9QmXdLHW/XwjaHow= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=fhDz16+m; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="fhDz16+m" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1710239682; x=1741775682; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FS0nhNcBPCInVIG4RYXDiiNQbo0LCaPWxZJEEPTZ4oQ=; b=fhDz16+m7zht/uuM37xXjrF0oqqsOjWVUds1FZHttMIElL8UxTR2OPAT U4ia8SBAoKT1N2bwjtc6hIQjkY0NLFqvvTRjpJ1apfOeDtCnrl06g+/lM KTk6s8EY5k9TykhJKXd4UVqWeOPGdNK+KsUcRIIUr+7d6SG6vIWQKk2Q9 ZhMws0nbC01de7qUCEecCTA5IrnhyH59STUH/zQ783Tx8/bUn3u6U83F9 9NknON3wH6QX9/97ajGjZdFOAR1ogLEzxtiNqK00TPW1zoccvmvFfTm6S 5naN/GXzJOmVNgnHDckQpFa35e5soKKhTbrYV8cvcbj+0rQaLPeh5evh3 g==; X-IronPort-AV: E=McAfee;i="6600,9927,11010"; a="4794334" X-IronPort-AV: E=Sophos;i="6.07,119,1708416000"; d="scan'208";a="4794334" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Mar 2024 03:34:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,119,1708416000"; d="scan'208";a="16194108" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Mar 2024 03:34:40 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id F2D6A11FB11; Tue, 12 Mar 2024 12:34:36 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v3 21/26] media: mc: Add per-file-handle data support Date: Tue, 12 Mar 2024 12:34:17 +0200 Message-Id: <20240312103422.216484-22-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312103422.216484-1-sakari.ailus@linux.intel.com> References: <20240312103422.216484-1-sakari.ailus@linux.intel.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Laurent Pinchart The media devnode core associates devnodes with files by storing the devnode pointer in the file structure private_data field. In order to allow tracking of per-file-handle data introduce a new media devnode file handle structure that stores the devnode pointer, and store a pointer to that structure in the file private_data field. Users of the media devnode code (the only existing user being media_device) are responsible for managing their own subclass of the media_devnode_fh structure. Signed-off-by: Laurent Pinchart Prepare struct media_device_fh to be used for maintaining file handle list to avoid shuffling things here and there right after. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 14 +++++++++++++- drivers/media/mc/mc-devnode.c | 20 +++++++++----------- include/media/media-device.h | 7 +++++++ include/media/media-devnode.h | 18 +++++++++++++++++- include/media/media-fh.h | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 include/media/media-fh.h diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 10426c2796b6..67a39cb63f89 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #ifdef CONFIG_MEDIA_CONTROLLER @@ -35,7 +36,6 @@ #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff #define MEDIA_ENT_T_DEVNODE_UNKNOWN (MEDIA_ENT_F_OLD_BASE | \ MEDIA_ENT_SUBTYPE_MASK) - /* ----------------------------------------------------------------------------- * Userspace API */ @@ -47,11 +47,23 @@ static inline void __user *media_get_uptr(__u64 arg) static int media_device_open(struct file *filp) { + struct media_device_fh *fh; + + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (!fh) + return -ENOMEM; + + filp->private_data = &fh->fh; + return 0; } static int media_device_close(struct file *filp) { + struct media_device_fh *fh = media_device_fh(filp); + + kfree(fh); + return 0; } diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 6fb3a202eb26..4fdb1572ff9b 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -133,6 +133,7 @@ static long media_compat_ioctl(struct file *filp, unsigned int cmd, static int media_open(struct inode *inode, struct file *filp) { struct media_devnode *devnode; + struct media_devnode_fh *fh; int ret; /* Check if the media device is available. This needs to be done with @@ -153,17 +154,15 @@ static int media_open(struct inode *inode, struct file *filp) get_device(&devnode->dev); mutex_unlock(&media_devnode_lock); - filp->private_data = devnode; - - if (devnode->fops->open) { - ret = devnode->fops->open(filp); - if (ret) { - put_device(&devnode->dev); - filp->private_data = NULL; - return ret; - } + ret = devnode->fops->open(filp); + if (ret) { + put_device(&devnode->dev); + return ret; } + fh = filp->private_data; + fh->devnode = devnode; + return 0; } @@ -172,8 +171,7 @@ static int media_release(struct inode *inode, struct file *filp) { struct media_devnode *devnode = media_devnode_data(filp); - if (devnode->fops->release) - devnode->fops->release(filp); + devnode->fops->release(filp); filp->private_data = NULL; diff --git a/include/media/media-device.h b/include/media/media-device.h index fe4625f3f62b..f9f7c37e7d57 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -110,6 +110,10 @@ struct media_device_ops { * other operations that stop or start streaming. * @request_id: Used to generate unique request IDs * + * @fh_list: List of file handles in the media device + * (struct media_device_fh.mdev_list). + * @fh_list_lock: Serialise access to fh_list list. + * * This structure represents an abstract high-level media device. It allows easy * access to entities and provides basic media device-level support. The * structure can be allocated directly or embedded in a larger structure. @@ -182,6 +186,9 @@ struct media_device { struct mutex req_queue_mutex; atomic_t request_id; + + struct list_head fh_list; + spinlock_t fh_list_lock; }; /* We don't need to include usb.h here */ diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 113c317e6a0e..e4e8552598eb 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -53,6 +53,20 @@ struct media_file_operations { int (*release) (struct file *); }; +/** + * struct media_devnode_fh - Media device node file handle + * @devnode: pointer to the media device node + * + * This structure serves as a base for per-file-handle data storage. Media + * device node users embed media_devnode_fh in their custom file handle data + * structures and store the media_devnode_fh in the file private_data in order + * to let the media device node core locate the media_devnode corresponding to a + * file handle. + */ +struct media_devnode_fh { + struct media_devnode *devnode; +}; + /** * struct media_devnode - Media device node * @fops: pointer to struct &media_file_operations with media device ops @@ -136,7 +150,9 @@ void media_devnode_unregister(struct media_devnode *devnode); */ static inline struct media_devnode *media_devnode_data(struct file *filp) { - return filp->private_data; + struct media_devnode_fh *fh = filp->private_data; + + return fh->devnode; } /** diff --git a/include/media/media-fh.h b/include/media/media-fh.h new file mode 100644 index 000000000000..6f00744b81d6 --- /dev/null +++ b/include/media/media-fh.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Media device file handle + * + * Copyright (C) 2019--2023 Intel Corporation + */ + +#ifndef MEDIA_FH_H +#define MEDIA_FH_H + +#include +#include + +#include + +/** + * struct media_device_fh - File handle specific information on MC + * + * @fh: The media device file handle + * @mdev_list: This file handle in media device's list of file handles + */ +struct media_device_fh { + struct media_devnode_fh fh; + struct list_head mdev_list; +}; + +static inline struct media_device_fh *media_device_fh(struct file *filp) +{ + return container_of(filp->private_data, struct media_device_fh, fh); +} + +#endif /* MEDIA_FH_H */