From patchwork Wed Dec 20 10:36:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499892 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 E1B2B208DF for ; Wed, 20 Dec 2023 10:37:20 +0000 (UTC) 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="n08vFq4d" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068641; x=1734604641; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fn5vdqTgrAwxvRPY8aEkpwtLLDHNckvF5vsntZp7xeE=; b=n08vFq4dquIqyXkwV4tARzvC2JBNbMinLia5xRRa9+xjkyq1SxPbhtIA sJklQJCrQokicqv//C2b4Pn1RZAEt6YPNLtGbCUagi9/Q+QkIZo8X1w3O kyAKiQJ01Zno/WQxNi4AymHNvMs8ZUlpj0BUufh8lY2dzG+0a0pho+s06 OYaVQTQM3Mt9nOJrlZZS1SFMLJ2JdtIGKFVBFFn1osWBluSE/NLFhru23 00kYaBe4f8Y77cZJLlBqKyPP0FwXg0weYrRW5clgb1E/wTdSBFDRg78UH IR43X/YYY2JPX2H18/g1b+G4uINCl7ENyQmR8tKzFGxkOzasUVCijWSfN Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174301" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174301" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544226" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544226" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:17 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 947F811FC49; Wed, 20 Dec 2023 12:37:14 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 01/29] Revert "[media] media: fix media devnode ioctl/syscall and unregister race" Date: Wed, 20 Dec 2023 12:36:45 +0200 Message-Id: <20231220103713.113386-2-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 This reverts commit 6f0dd24a084a ("[media] media: fix media devnode ioctl/syscall and unregister race"). The commit was part of an original patchset to avoid crashes when an unregistering device is in use. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 15 +++++++-------- drivers/media/mc/mc-devnode.c | 8 +------- include/media/media-devnode.h | 16 ++-------------- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index c0dd4ae57227..6c569ecd4b3d 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -741,7 +741,6 @@ int __must_check __media_device_register(struct media_device *mdev, if (ret < 0) { /* devnode free is handled in media_devnode_*() */ mdev->devnode = NULL; - media_devnode_unregister_prepare(devnode); media_devnode_unregister(devnode); return ret; } @@ -797,9 +796,6 @@ void media_device_unregister(struct media_device *mdev) return; } - /* Clear the devnode register bit to avoid races with media dev open */ - media_devnode_unregister_prepare(mdev->devnode); - /* Remove all entities from the media device */ list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) __media_device_unregister_entity(entity); @@ -824,10 +820,13 @@ void media_device_unregister(struct media_device *mdev) dev_dbg(mdev->dev, "Media device unregistered\n"); - device_remove_file(&mdev->devnode->dev, &dev_attr_model); - media_devnode_unregister(mdev->devnode); - /* devnode free is handled in media_devnode_*() */ - mdev->devnode = NULL; + /* Check if mdev devnode was registered */ + if (media_devnode_is_registered(mdev->devnode)) { + device_remove_file(&mdev->devnode->dev, &dev_attr_model); + media_devnode_unregister(mdev->devnode); + /* devnode free is handled in media_devnode_*() */ + mdev->devnode = NULL; + } } EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 680fbb3a9340..0ab33214d243 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -267,7 +267,7 @@ int __must_check media_devnode_register(struct media_device *mdev, return ret; } -void media_devnode_unregister_prepare(struct media_devnode *devnode) +void media_devnode_unregister(struct media_devnode *devnode) { /* Check if devnode was ever registered at all */ if (!media_devnode_is_registered(devnode)) @@ -275,12 +275,6 @@ void media_devnode_unregister_prepare(struct media_devnode *devnode) mutex_lock(&media_devnode_lock); clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - mutex_unlock(&media_devnode_lock); -} - -void media_devnode_unregister(struct media_devnode *devnode) -{ - mutex_lock(&media_devnode_lock); /* Delete the cdev on this minor as well */ cdev_device_del(&devnode->cdev, &devnode->dev); devnode->media_dev = NULL; diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index d27c1c646c28..46f0d3ae44d1 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -115,19 +115,6 @@ int __must_check media_devnode_register(struct media_device *mdev, struct media_devnode *devnode, struct module *owner); -/** - * media_devnode_unregister_prepare - clear the media device node register bit - * @devnode: the device node to prepare for unregister - * - * This clears the passed device register bit. Future open calls will be met - * with errors. Should be called before media_devnode_unregister() to avoid - * races with unregister and device file open calls. - * - * This function can safely be called if the device node has never been - * registered or has already been unregistered. - */ -void media_devnode_unregister_prepare(struct media_devnode *devnode); - /** * media_devnode_unregister - unregister a media device node * @devnode: the device node to unregister @@ -135,7 +122,8 @@ void media_devnode_unregister_prepare(struct media_devnode *devnode); * This unregisters the passed device. Future open calls will be met with * errors. * - * Should be called after media_devnode_unregister_prepare() + * This function can safely be called if the device node has never been + * registered or has already been unregistered. */ void media_devnode_unregister(struct media_devnode *devnode); From patchwork Wed Dec 20 10:36:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499891 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 D6500208CB for ; Wed, 20 Dec 2023 10:37:20 +0000 (UTC) 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="CeYpKJnB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068641; x=1734604641; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0yFGytW7x2A6ZfvHtRLSwiouOMVOj1u806YhOcEW060=; b=CeYpKJnBtvCC/4lwr01527aIqQreY/LlkOpeYEuOym8y1Phae1GOLRX2 6nVtBKp5lSpTWIvua0W1NDxY160J8WxMotq31bXKPI8q6+tYDem3jUsyG aiDFPzBX0ayMA5XIKrJG+VfkcyL8GkBYktNHREu3NFC6gTU8PGD2K1NOW ISNZVZmp68n0qayZKDDSuprA8CtRy63eojw4y1xPSZ4Xdzjqql/wQYYkU p2C8htjd1Sl3H6aVZJmFPSV8dMhQSacBY8cCh3QLzRSv6U7sRxMmNUyEp kFUvvTcwgS55kVSkia+TlVXoUS9ZdlP2mOt1DeF9Y0IaXndej6gIwrcUx Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174304" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174304" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544229" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544229" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:17 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 299721201D0; Wed, 20 Dec 2023 12:37:15 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 02/29] Revert "media: utilize new cdev_device_add helper function" Date: Wed, 20 Dec 2023 12:36:46 +0200 Message-Id: <20231220103713.113386-3-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 This reverts commit 857313e51006ff51524579bcd8808b70f9a80812. This patch is temporarily reverted for internal rework. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/cec/core/cec-core.c | 16 ++++++++++++---- drivers/media/mc/mc-devnode.c | 21 ++++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 7e153c5cad04..0645e68411fb 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -137,19 +137,26 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, /* Part 2: Initialize and register the character device */ cdev_init(&devnode->cdev, &cec_devnode_fops); + devnode->cdev.kobj.parent = &devnode->dev.kobj; devnode->cdev.owner = owner; kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor); devnode->registered = true; - ret = cdev_device_add(&devnode->cdev, &devnode->dev); - if (ret) { + ret = cdev_add(&devnode->cdev, devnode->dev.devt, 1); + if (ret < 0) { + pr_err("%s: cdev_add failed\n", __func__); devnode->registered = false; - pr_err("%s: cdev_device_add failed\n", __func__); goto clr_bit; } + ret = device_add(&devnode->dev); + if (ret) + goto cdev_del; + return 0; +cdev_del: + cdev_del(&devnode->cdev); clr_bit: mutex_lock(&cec_devnode_lock); clear_bit(devnode->minor, cec_devnode_nums); @@ -195,7 +202,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap) cec_adap_enable(adap); mutex_unlock(&adap->lock); - cdev_device_del(&devnode->cdev, &devnode->dev); + device_del(&devnode->dev); + cdev_del(&devnode->cdev); put_device(&devnode->dev); } diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 0ab33214d243..740573552e5d 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -240,23 +240,33 @@ int __must_check media_devnode_register(struct media_device *mdev, dev_set_name(&devnode->dev, "media%d", devnode->minor); device_initialize(&devnode->dev); - /* Part 2: Initialize the character device */ + /* Part 2: Initialize and register the character device */ cdev_init(&devnode->cdev, &media_devnode_fops); devnode->cdev.owner = owner; + devnode->cdev.kobj.parent = &devnode->dev.kobj; kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); - /* Part 3: Add the media and char device */ - ret = cdev_device_add(&devnode->cdev, &devnode->dev); + ret = cdev_add(&devnode->cdev, MKDEV(MAJOR(media_dev_t), + devnode->minor), 1); if (ret < 0) { - pr_err("%s: cdev_device_add failed\n", __func__); + pr_err("%s: cdev_add failed\n", __func__); goto cdev_add_error; } + /* Part 3: Add the media device */ + ret = device_add(&devnode->dev); + if (ret < 0) { + pr_err("%s: device_add failed\n", __func__); + goto device_add_error; + } + /* Part 4: Activate this minor. The char device can now be used. */ set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); return 0; +device_add_error: + cdev_del(&devnode->cdev); cdev_add_error: mutex_lock(&media_devnode_lock); clear_bit(devnode->minor, media_devnode_nums); @@ -276,9 +286,10 @@ void media_devnode_unregister(struct media_devnode *devnode) mutex_lock(&media_devnode_lock); clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); /* Delete the cdev on this minor as well */ - cdev_device_del(&devnode->cdev, &devnode->dev); + cdev_del(&devnode->cdev); devnode->media_dev = NULL; mutex_unlock(&media_devnode_lock); + device_del(&devnode->dev); put_device(&devnode->dev); } From patchwork Wed Dec 20 10:36:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499893 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 7707820B0A for ; Wed, 20 Dec 2023 10:37:22 +0000 (UTC) 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="dNNVQb1a" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068642; x=1734604642; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2FRHYbaD0qGk5u2qPqy3j4HFfKrb/qZwigaUVNXV8EU=; b=dNNVQb1atKQf0vzeL3Qx5UosnBh9RWgrwklLlszqRMK9eqZpIWYoD6kj Aqi1zBd4/nOFmxsTCOMe8XHd/FUyDpzu4UqGTObVKgKUr8o0gcJxzGhNr zMdEgr4JMfr/B+w5HorwUgCN+qqpBF/izoo9NPEGKJicnbvCH5mQpQCsb MKIv6afY3V31fp7wHeD4ZXONnc36KObU907mwldvdAXEvN4s+J2d24x+n ZV5NPrpUR8Jt9Mhh71MwRpPQbCZaRjCGbhM1S9imyntuPipZetkce/CnH 3zzt9OXtH3odEHN2SOFers2JGLAjHoc/WxSIcu3hQ6/C9TYKhAXLVwvio Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174308" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174308" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544230" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544230" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:18 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id B406312068E; Wed, 20 Dec 2023 12:37:15 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 03/29] Revert "[media] media: fix use-after-free in cdev_put() when app exits after driver unbind" Date: Wed, 20 Dec 2023 12:36:47 +0200 Message-Id: <20231220103713.113386-4-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 This reverts commit 5b28dde51d0c ("[media] media: fix use-after-free in cdev_put() when app exits after driver unbind"). The commit was part of an original patchset to avoid crashes when an unregistering device is in use. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 6 ++--- drivers/media/mc/mc-devnode.c | 48 ++++++++++++++--------------------- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 6c569ecd4b3d..4772a7f55112 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -732,16 +732,16 @@ int __must_check __media_device_register(struct media_device *mdev, ret = media_devnode_register(mdev, devnode, owner); if (ret < 0) { - /* devnode free is handled in media_devnode_*() */ mdev->devnode = NULL; + kfree(devnode); return ret; } ret = device_create_file(&devnode->dev, &dev_attr_model); if (ret < 0) { - /* devnode free is handled in media_devnode_*() */ mdev->devnode = NULL; media_devnode_unregister(devnode); + kfree(devnode); return ret; } @@ -824,8 +824,6 @@ void media_device_unregister(struct media_device *mdev) if (media_devnode_is_registered(mdev->devnode)) { device_remove_file(&mdev->devnode->dev, &dev_attr_model); media_devnode_unregister(mdev->devnode); - /* devnode free is handled in media_devnode_*() */ - mdev->devnode = NULL; } } EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 740573552e5d..1e1792c3ae3f 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -51,8 +51,13 @@ static void media_devnode_release(struct device *cd) struct media_devnode *devnode = to_media_devnode(cd); mutex_lock(&media_devnode_lock); + + /* Delete the cdev on this minor as well */ + cdev_del(&devnode->cdev); + /* Mark device node number as free */ clear_bit(devnode->minor, media_devnode_nums); + mutex_unlock(&media_devnode_lock); /* Release media_devnode and perform other cleanups as needed. */ @@ -60,7 +65,6 @@ static void media_devnode_release(struct device *cd) devnode->release(devnode); kfree(devnode); - pr_debug("%s: Media Devnode Deallocated\n", __func__); } static struct bus_type media_bus_type = { @@ -189,8 +193,6 @@ static int media_release(struct inode *inode, struct file *filp) /* decrease the refcount unconditionally since the release() return value is ignored. */ put_device(&devnode->dev); - - pr_debug("%s: Media Release\n", __func__); return 0; } @@ -221,7 +223,6 @@ int __must_check media_devnode_register(struct media_device *mdev, if (minor == MEDIA_NUM_DEVICES) { mutex_unlock(&media_devnode_lock); pr_err("could not get a free minor\n"); - kfree(devnode); return -ENFILE; } @@ -231,33 +232,29 @@ int __must_check media_devnode_register(struct media_device *mdev, devnode->minor = minor; devnode->media_dev = mdev; - /* Part 1: Initialize dev now to use dev.kobj for cdev.kobj.parent */ - devnode->dev.bus = &media_bus_type; - devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor); - devnode->dev.release = media_devnode_release; - if (devnode->parent) - devnode->dev.parent = devnode->parent; - dev_set_name(&devnode->dev, "media%d", devnode->minor); - device_initialize(&devnode->dev); - /* Part 2: Initialize and register the character device */ cdev_init(&devnode->cdev, &media_devnode_fops); devnode->cdev.owner = owner; - devnode->cdev.kobj.parent = &devnode->dev.kobj; kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); ret = cdev_add(&devnode->cdev, MKDEV(MAJOR(media_dev_t), devnode->minor), 1); if (ret < 0) { pr_err("%s: cdev_add failed\n", __func__); - goto cdev_add_error; + goto error; } - /* Part 3: Add the media device */ - ret = device_add(&devnode->dev); + /* Part 3: Register the media device */ + devnode->dev.bus = &media_bus_type; + devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor); + devnode->dev.release = media_devnode_release; + if (devnode->parent) + devnode->dev.parent = devnode->parent; + dev_set_name(&devnode->dev, "media%d", devnode->minor); + ret = device_register(&devnode->dev); if (ret < 0) { - pr_err("%s: device_add failed\n", __func__); - goto device_add_error; + pr_err("%s: device_register failed\n", __func__); + goto error; } /* Part 4: Activate this minor. The char device can now be used. */ @@ -265,15 +262,12 @@ int __must_check media_devnode_register(struct media_device *mdev, return 0; -device_add_error: - cdev_del(&devnode->cdev); -cdev_add_error: +error: mutex_lock(&media_devnode_lock); + cdev_del(&devnode->cdev); clear_bit(devnode->minor, media_devnode_nums); - devnode->media_dev = NULL; mutex_unlock(&media_devnode_lock); - put_device(&devnode->dev); return ret; } @@ -285,13 +279,9 @@ void media_devnode_unregister(struct media_devnode *devnode) mutex_lock(&media_devnode_lock); clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - /* Delete the cdev on this minor as well */ - cdev_del(&devnode->cdev); - devnode->media_dev = NULL; mutex_unlock(&media_devnode_lock); - device_del(&devnode->dev); - put_device(&devnode->dev); + device_unregister(&devnode->dev); } /* From patchwork Wed Dec 20 10:36:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499896 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 67229208CE for ; Wed, 20 Dec 2023 10:37:22 +0000 (UTC) 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="nvw8XPe9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068642; x=1734604642; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zfyjOPPGPExsCBpco+FV+gtpUcFP8ASz6xiOXmFUrI0=; b=nvw8XPe9B4o9rjD1PI3Fd/pdpnxTD/zsSTJNuojgGO+6PwvXWdv9rQQC tDTUYsko5YAErWDkYVzkZy5mJkRM0Cxjxnv4nsrtNpaMG13Jaku/54Q+4 pYWZukbJvEJQ++XcMevbIh1DfTBkturl+ycPHQDCY4DzQpYKIJV2N8VXJ e0crfZS6rskrj7GvWkYtAlQAyu6Bx2MiI3eJXhPCs6mDP5XcK34K6NXfS UPaDUe2gTsiEj23+7S2JKhRtnFrqPX33Q3yCHhE5pKobs5NxBz5vOWR/b JapQRwaTyOwAMneznjbFK1jDbUaLfZLibAh6jNeOcFIRgkJpsGOQMvQrD w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174314" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174314" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544233" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544233" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:19 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 55130120706; Wed, 20 Dec 2023 12:37:16 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 04/29] media: mc: utilize new cdev_device_add helper function Date: Wed, 20 Dec 2023 12:36:48 +0200 Message-Id: <20231220103713.113386-5-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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: Logan Gunthorpe Replace the open coded registration of the cdev and dev with the new device_add_cdev() helper. The helper replaces a common pattern by taking the proper reference against the parent device and adding both the cdev and the device. Signed-off-by: Logan Gunthorpe Acked-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/cec/core/cec-core.c | 16 ++++------------ drivers/media/mc/mc-devnode.c | 23 +++++++++-------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 0645e68411fb..15494b46458a 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -137,26 +137,19 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, /* Part 2: Initialize and register the character device */ cdev_init(&devnode->cdev, &cec_devnode_fops); - devnode->cdev.kobj.parent = &devnode->dev.kobj; devnode->cdev.owner = owner; kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor); devnode->registered = true; - ret = cdev_add(&devnode->cdev, devnode->dev.devt, 1); - if (ret < 0) { - pr_err("%s: cdev_add failed\n", __func__); + ret = cdev_device_add(&devnode->cdev, &devnode->dev); + if (ret) { + pr_err("%s: cdev_device_add failed\n", __func__); devnode->registered = false; goto clr_bit; } - ret = device_add(&devnode->dev); - if (ret) - goto cdev_del; - return 0; -cdev_del: - cdev_del(&devnode->cdev); clr_bit: mutex_lock(&cec_devnode_lock); clear_bit(devnode->minor, cec_devnode_nums); @@ -202,8 +195,7 @@ static void cec_devnode_unregister(struct cec_adapter *adap) cec_adap_enable(adap); mutex_unlock(&adap->lock); - device_del(&devnode->dev); - cdev_del(&devnode->cdev); + cdev_device_del(&devnode->cdev, &devnode->dev); put_device(&devnode->dev); } diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 1e1792c3ae3f..fabcd646679b 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -232,29 +232,24 @@ int __must_check media_devnode_register(struct media_device *mdev, devnode->minor = minor; devnode->media_dev = mdev; - /* Part 2: Initialize and register the character device */ + /* Part 2: Initialize the media and character devices */ cdev_init(&devnode->cdev, &media_devnode_fops); devnode->cdev.owner = owner; kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); - ret = cdev_add(&devnode->cdev, MKDEV(MAJOR(media_dev_t), - devnode->minor), 1); - if (ret < 0) { - pr_err("%s: cdev_add failed\n", __func__); - goto error; - } - - /* Part 3: Register the media device */ devnode->dev.bus = &media_bus_type; devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor); devnode->dev.release = media_devnode_release; if (devnode->parent) devnode->dev.parent = devnode->parent; dev_set_name(&devnode->dev, "media%d", devnode->minor); - ret = device_register(&devnode->dev); + device_initialize(&devnode->dev); + + /* Part 3: Add the media and character devices */ + ret = cdev_device_add(&devnode->cdev, &devnode->dev); if (ret < 0) { - pr_err("%s: device_register failed\n", __func__); - goto error; + pr_err("%s: cdev_device_add failed\n", __func__); + goto cdev_add_error; } /* Part 4: Activate this minor. The char device can now be used. */ @@ -262,9 +257,9 @@ int __must_check media_devnode_register(struct media_device *mdev, return 0; -error: +cdev_add_error: mutex_lock(&media_devnode_lock); - cdev_del(&devnode->cdev); + cdev_device_del(&devnode->cdev, &devnode->dev); clear_bit(devnode->minor, media_devnode_nums); mutex_unlock(&media_devnode_lock); From patchwork Wed Dec 20 10:36:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499895 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 E1DE120B24 for ; Wed, 20 Dec 2023 10:37:23 +0000 (UTC) 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="YUi4pFkG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068644; x=1734604644; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L17h0r0iEjhtzkeRVkRm3svQatuR622eHCre3ky53EY=; b=YUi4pFkGWpTtrXGN1nEeLMp1Q/wE5uq8IXQ4e3flKcWQZG/lKlGA/c0z 13shPYfI4wHAiCnKKbOo7vIoRsQr8hpM6sN7UP9iMEVWNA94dZ8BCFMzp oyD9pK69tAUUX9a1nPD/7xxbZSgU5Z7C7lR7pfdrOkxHCQjA8l97YjHvH 4H79LSBjNnjOnAke60J7N8qsTTBr2jt+fDbG2uHXhlJ7riE38inla3L14 cdX+3NnxylxepZO6ysY6NhX//XrG/mRbU53Akm9VjpAigOBVZLpjKydH1 kIqQDBBwHT06lf1Qimq7ZjIGAQk2rzrO9c8nsfIu9kunlftXJs+Ra9v1t Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174323" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174323" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:22 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544240" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544240" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:20 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id CD26B120788; Wed, 20 Dec 2023 12:37:16 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 05/29] Revert "media: uvcvideo: Refactor teardown of uvc on USB disconnect" Date: Wed, 20 Dec 2023 12:36:49 +0200 Message-Id: <20231220103713.113386-6-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 This reverts commit 10e1fdb95809ed21406f53b5b4f064673a1b9ceb. Temporarily revert this patch to revert a dependent patch. The patch is re-applied later, rebased on the revert. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/usb/uvc/uvc_driver.c | 13 ++++--------- drivers/media/usb/uvc/uvc_status.c | 12 ++++-------- drivers/media/usb/uvc/uvcvideo.h | 1 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index bbd90123a4e7..fe8b251f47e7 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1859,7 +1859,11 @@ static void uvc_delete(struct kref *kref) usb_put_intf(dev->intf); usb_put_dev(dev->udev); + if (dev->vdev.dev) + v4l2_device_unregister(&dev->vdev); #ifdef CONFIG_MEDIA_CONTROLLER + if (media_devnode_is_registered(dev->mdev.devnode)) + media_device_unregister(&dev->mdev); media_device_cleanup(&dev->mdev); #endif @@ -1916,15 +1920,6 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } - - uvc_status_unregister(dev); - - if (dev->vdev.dev) - v4l2_device_unregister(&dev->vdev); -#ifdef CONFIG_MEDIA_CONTROLLER - if (media_devnode_is_registered(dev->mdev.devnode)) - media_device_unregister(&dev->mdev); -#endif } int uvc_register_video_device(struct uvc_device *dev, diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index a78a88c710e2..015be0886801 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -73,7 +73,7 @@ static int uvc_input_init(struct uvc_device *dev) return ret; } -static void uvc_input_unregister(struct uvc_device *dev) +static void uvc_input_cleanup(struct uvc_device *dev) { if (dev->input) input_unregister_device(dev->input); @@ -90,7 +90,7 @@ static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, #else #define uvc_input_init(dev) -#define uvc_input_unregister(dev) +#define uvc_input_cleanup(dev) #define uvc_input_report_key(dev, code, value) #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ @@ -290,16 +290,12 @@ int uvc_status_init(struct uvc_device *dev) return 0; } -void uvc_status_unregister(struct uvc_device *dev) -{ - usb_kill_urb(dev->int_urb); - uvc_input_unregister(dev); -} - void uvc_status_cleanup(struct uvc_device *dev) { + usb_kill_urb(dev->int_urb); usb_free_urb(dev->int_urb); kfree(dev->status); + uvc_input_cleanup(dev); } int uvc_status_start(struct uvc_device *dev, gfp_t flags) diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 6fb0a78b1b00..ab8de60f5de2 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -742,7 +742,6 @@ int uvc_register_video_device(struct uvc_device *dev, /* Status */ int uvc_status_init(struct uvc_device *dev); -void uvc_status_unregister(struct uvc_device *dev); void uvc_status_cleanup(struct uvc_device *dev); int uvc_status_start(struct uvc_device *dev, gfp_t flags); void uvc_status_stop(struct uvc_device *dev); From patchwork Wed Dec 20 10:36:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499894 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 78B0620B1A for ; Wed, 20 Dec 2023 10:37:23 +0000 (UTC) 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="bdWa3xPq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068643; x=1734604643; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PhOuyz9RnP0CM07VW5m7jpNcMxocyOzQCNfex26x3Ig=; b=bdWa3xPqQahrtOv08oQRukc0CnqwSfUJVeCB7XLkt2nxKy/laftu7HcE 6xo90iz8XlnQ5fnBqj/mXQT1aAXmrg85aplWugt/5M/AKYa7Mog3QWHSu wmgZzDPl9b00vwc6GwqyxsQBmp6kLX1nfN7YUm2w+1vkiRpFkx5dsr1R5 oNF/jmOPY0+XDb71X1cRFebenfazWj/g8YaZdVZ0UMISfQDLRU58uX9vY 2le6uUH6bLh8JsaABqSpprMnbHlhe4lzZvkfVv7OhhCN6V6g9Qfpi0Q2i DgrIiLHM7NjpeYU08sMq/ZRgHE389YSmeSJ/tIsGGoS80wH8hbMW1NMLf g==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174319" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174319" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:22 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544239" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544239" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:20 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 9685F12098A; Wed, 20 Dec 2023 12:37:17 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 06/29] Revert "[media] media-device: dynamically allocate struct media_devnode" Date: Wed, 20 Dec 2023 12:36:50 +0200 Message-Id: <20231220103713.113386-7-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 This reverts commit a087ce704b80 ("[media] media-device: dynamically allocate struct media_devnode"). The commit was part of an original patchset to avoid crashes when an unregistering device is in use. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 44 +++++++-------------- drivers/media/mc/mc-devnode.c | 7 +--- drivers/media/usb/au0828/au0828-core.c | 4 +- drivers/media/usb/uvc/uvc_driver.c | 2 +- drivers/staging/media/sunxi/cedrus/cedrus.c | 2 +- include/media/media-device.h | 5 ++- include/media/media-devnode.h | 15 +------ 7 files changed, 25 insertions(+), 54 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 4772a7f55112..d4553a3705f5 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -435,7 +435,7 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long __arg) { struct media_devnode *devnode = media_devnode_data(filp); - struct media_device *dev = devnode->media_dev; + struct media_device *dev = to_media_device(devnode); const struct media_ioctl_info *info; void __user *arg = (void __user *)__arg; char __karg[256], *karg = __karg; @@ -519,7 +519,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct media_devnode *devnode = media_devnode_data(filp); - struct media_device *dev = devnode->media_dev; + struct media_device *dev = to_media_device(devnode); long ret; switch (cmd) { @@ -555,8 +555,7 @@ static const struct media_file_operations media_device_fops = { static ssize_t model_show(struct device *cd, struct device_attribute *attr, char *buf) { - struct media_devnode *devnode = to_media_devnode(cd); - struct media_device *mdev = devnode->media_dev; + struct media_device *mdev = to_media_device(to_media_devnode(cd)); return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model); } @@ -714,34 +713,23 @@ EXPORT_SYMBOL_GPL(media_device_cleanup); int __must_check __media_device_register(struct media_device *mdev, struct module *owner) { - struct media_devnode *devnode; int ret; - devnode = kzalloc(sizeof(*devnode), GFP_KERNEL); - if (!devnode) - return -ENOMEM; - /* Register the device node. */ - mdev->devnode = devnode; - devnode->fops = &media_device_fops; - devnode->parent = mdev->dev; - devnode->release = media_device_release; + mdev->devnode.fops = &media_device_fops; + mdev->devnode.parent = mdev->dev; + mdev->devnode.release = media_device_release; /* Set version 0 to indicate user-space that the graph is static */ mdev->topology_version = 0; - ret = media_devnode_register(mdev, devnode, owner); - if (ret < 0) { - mdev->devnode = NULL; - kfree(devnode); + ret = media_devnode_register(&mdev->devnode, owner); + if (ret < 0) return ret; - } - ret = device_create_file(&devnode->dev, &dev_attr_model); + ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); if (ret < 0) { - mdev->devnode = NULL; - media_devnode_unregister(devnode); - kfree(devnode); + media_devnode_unregister(&mdev->devnode); return ret; } @@ -791,7 +779,7 @@ void media_device_unregister(struct media_device *mdev) mutex_lock(&mdev->graph_mutex); /* Check if mdev was ever registered at all */ - if (!media_devnode_is_registered(mdev->devnode)) { + if (!media_devnode_is_registered(&mdev->devnode)) { mutex_unlock(&mdev->graph_mutex); return; } @@ -818,13 +806,9 @@ void media_device_unregister(struct media_device *mdev) mutex_unlock(&mdev->graph_mutex); - dev_dbg(mdev->dev, "Media device unregistered\n"); - - /* Check if mdev devnode was registered */ - if (media_devnode_is_registered(mdev->devnode)) { - device_remove_file(&mdev->devnode->dev, &dev_attr_model); - media_devnode_unregister(mdev->devnode); - } + device_remove_file(&mdev->devnode.dev, &dev_attr_model); + dev_dbg(mdev->dev, "Media device unregistering\n"); + media_devnode_unregister(&mdev->devnode); } EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index fabcd646679b..ce93ab9be676 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -32,7 +32,6 @@ #include #include -#include #define MEDIA_NUM_DEVICES 256 #define MEDIA_NAME "media" @@ -63,8 +62,6 @@ static void media_devnode_release(struct device *cd) /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) devnode->release(devnode); - - kfree(devnode); } static struct bus_type media_bus_type = { @@ -210,8 +207,7 @@ static const struct file_operations media_devnode_fops = { .llseek = no_llseek, }; -int __must_check media_devnode_register(struct media_device *mdev, - struct media_devnode *devnode, +int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner) { int minor; @@ -230,7 +226,6 @@ int __must_check media_devnode_register(struct media_device *mdev, mutex_unlock(&media_devnode_lock); devnode->minor = minor; - devnode->media_dev = mdev; /* Part 2: Initialize the media and character devices */ cdev_init(&devnode->cdev, &media_devnode_fops); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 1e246b47766d..4101e12cda5a 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -128,7 +128,7 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) struct media_device *mdev = dev->media_dev; struct media_entity_notify *notify, *nextp; - if (!mdev || !media_devnode_is_registered(mdev->devnode)) + if (!mdev || !media_devnode_is_registered(&mdev->devnode)) return; /* Remove au0828 entity_notify callbacks */ @@ -566,7 +566,7 @@ static int au0828_media_device_register(struct au0828_dev *dev, if (!dev->media_dev) return 0; - if (!media_devnode_is_registered(dev->media_dev->devnode)) { + if (!media_devnode_is_registered(&dev->media_dev->devnode)) { /* register media device */ ret = media_device_register(dev->media_dev); diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index fe8b251f47e7..1044e13976b5 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1862,7 +1862,7 @@ static void uvc_delete(struct kref *kref) if (dev->vdev.dev) v4l2_device_unregister(&dev->vdev); #ifdef CONFIG_MEDIA_CONTROLLER - if (media_devnode_is_registered(dev->mdev.devnode)) + if (media_devnode_is_registered(&dev->mdev.devnode)) media_device_unregister(&dev->mdev); media_device_cleanup(&dev->mdev); #endif diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index f52df6836045..f8f678835a4c 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -548,7 +548,7 @@ static void cedrus_remove(struct platform_device *pdev) struct cedrus_dev *dev = platform_get_drvdata(pdev); cancel_delayed_work_sync(&dev->watchdog_work); - if (media_devnode_is_registered(dev->mdev.devnode)) { + if (media_devnode_is_registered(&dev->mdev.devnode)) { media_device_unregister(&dev->mdev); v4l2_m2m_unregister_media_controller(dev->m2m_dev); media_device_cleanup(&dev->mdev); diff --git a/include/media/media-device.h b/include/media/media-device.h index 2c146d0b2b1c..fb0855b217ce 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -145,7 +145,7 @@ struct media_device_ops { struct media_device { /* dev->driver_data points to this struct. */ struct device *dev; - struct media_devnode *devnode; + struct media_devnode devnode; char model[32]; char driver_name[32]; @@ -191,6 +191,9 @@ struct usb_device; #define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0 #define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 +/* media_devnode to media_device */ +#define to_media_device(node) container_of(node, struct media_device, devnode) + /** * media_device_init() - Initializes a media device element * diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 46f0d3ae44d1..1117d1dfd6bf 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -21,8 +21,6 @@ #include #include -struct media_device; - /* * Flag to mark the media_devnode struct as registered. Drivers must not touch * this flag directly, it will be set and cleared by media_devnode_register and @@ -73,8 +71,6 @@ struct media_file_operations { * before registering the node. */ struct media_devnode { - struct media_device *media_dev; - /* device ops */ const struct media_file_operations *fops; @@ -97,8 +93,7 @@ struct media_devnode { /** * media_devnode_register - register a media device node * - * @mdev: struct media_device we want to register a device node - * @devnode: media device node structure we want to register + * @devnode: struct media_devnode we want to register a device node * @owner: should be filled with %THIS_MODULE * * The registration code assigns minor numbers and registers the new device node @@ -111,8 +106,7 @@ struct media_devnode { * the media_devnode structure is *not* called, so the caller is responsible for * freeing any data. */ -int __must_check media_devnode_register(struct media_device *mdev, - struct media_devnode *devnode, +int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner); /** @@ -142,14 +136,9 @@ static inline struct media_devnode *media_devnode_data(struct file *filp) * false otherwise. * * @devnode: pointer to struct &media_devnode. - * - * Note: If mdev is NULL, it also returns false. */ static inline int media_devnode_is_registered(struct media_devnode *devnode) { - if (!devnode) - return false; - return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); } From patchwork Wed Dec 20 10:36:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499898 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 4009E20DCC for ; Wed, 20 Dec 2023 10:37:25 +0000 (UTC) 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="jq8mg5r0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068645; x=1734604645; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=T/C9ZAO8qLneaLiBytVbO1mPwOAigpXoR7B3eXx1GyA=; b=jq8mg5r0ppTdTFAbzsAUR0YdYOal4uL3jAJOwPFJ3zioGMDLmidEtFjP QoGyFVPTUm61acaXjH/KNe4bXFc7VR8JyHEH2iRqsm5XhkWkX/9licHSW XG2SjYkw9jouNOODPOMZ2yjkqji4WYSWLCDgR8g2Lh+wACWO5EK981UlW C/6qQK15n3x0NICRKqjts2FVDbH5KMZjtnaf9h7wcTUw+H+AVsOD3pDod xPu7Txx2wwNVbN3M4DaSg+/66qfitq8iBLCa4eTpWzHVd5Afq8DSoGm+1 pWX9uRZ+qexi4ouvT8lZ78klA9F/O84FP3EKofq+QFs4m939nj7jokPex A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174330" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174330" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544244" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544244" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:21 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 68119120A70; Wed, 20 Dec 2023 12:37:18 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 07/29] media: uvcvideo: Refactor teardown of uvc on USB disconnect Date: Wed, 20 Dec 2023 12:36:51 +0200 Message-Id: <20231220103713.113386-8-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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: Daniel Axtens Currently, disconnecting a USB webcam while it is in use prints out a number of warnings, such as: WARNING: CPU: 2 PID: 3118 at /build/linux-ezBi1T/linux-4.8.0/fs/sysfs/group.c:237 sysfs_remove_group+0x8b/0x90 sysfs group ffffffffa7cd0780 not found for kobject 'event13' This has been noticed before. [0] This is because of the order in which things are torn down. If there are no streams active during a USB disconnect: - uvc_disconnect() is invoked via device_del() through the bus notifier mechanism. - this calls uvc_unregister_video(). - uvc_unregister_video() unregisters the video device for each stream, - because there are no streams open, it calls uvc_delete() - uvc_delete() calls uvc_status_cleanup(), which cleans up the status input device. - uvc_delete() calls media_device_unregister(), which cleans up the media device - uvc_delete(), uvc_unregister_video() and uvc_disconnect() all return, and we end up back in device_del(). - device_del() then cleans up the sysfs folder for the camera with dpm_sysfs_remove(). Because uvc_status_cleanup() and media_device_unregister() have already been called, this all works nicely. If, on the other hand, there *are* streams active during a USB disconnect: - uvc_disconnect() is invoked - this calls uvc_unregister_video() - uvc_unregister_video() unregisters the video device for each stream, - uvc_unregister_video() and uvc_disconnect() return, and we end up back in device_del(). - device_del() then cleans up the sysfs folder for the camera with dpm_sysfs_remove(). Because the status input device and the media device are children of the USB device, this also deletes their sysfs folders. - Sometime later, the final stream is closed, invoking uvc_release(). - uvc_release() calls uvc_delete() - uvc_delete() calls uvc_status_cleanup(), which cleans up the status input device. Because the sysfs directory has already been removed, this causes a WARNing. - uvc_delete() calls media_device_unregister(), which cleans up the media device. Because the sysfs directory has already been removed, this causes another WARNing. To fix this, we need to make sure the devices are always unregistered before the end of uvc_disconnect(). To this, move the unregistration into the disconnect path: - split uvc_status_cleanup() into two parts, one on disconnect that unregisters and one on delete that frees. - move v4l2_device_unregister() and media_device_unregister() into the disconnect path. [0]: https://lkml.org/lkml/2016/12/8/657 [Renamed uvc_input_cleanup() to uvc_input_unregister()] Signed-off-by: Daniel Axtens Acked-by: Greg Kroah-Hartman Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab [Sakari Ailus: Rebase on patch Revert "[media] media-device: dynamically allocate struct media_devnode"] Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/usb/uvc/uvc_driver.c | 13 +++++++++---- drivers/media/usb/uvc/uvc_status.c | 12 ++++++++---- drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 1044e13976b5..7add92f45329 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1859,11 +1859,7 @@ static void uvc_delete(struct kref *kref) usb_put_intf(dev->intf); usb_put_dev(dev->udev); - if (dev->vdev.dev) - v4l2_device_unregister(&dev->vdev); #ifdef CONFIG_MEDIA_CONTROLLER - if (media_devnode_is_registered(&dev->mdev.devnode)) - media_device_unregister(&dev->mdev); media_device_cleanup(&dev->mdev); #endif @@ -1920,6 +1916,15 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } + + uvc_status_unregister(dev); + + if (dev->vdev.dev) + v4l2_device_unregister(&dev->vdev); +#ifdef CONFIG_MEDIA_CONTROLLER + if (media_devnode_is_registered(&dev->mdev.devnode)) + media_device_unregister(&dev->mdev); +#endif } int uvc_register_video_device(struct uvc_device *dev, diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 015be0886801..a78a88c710e2 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -73,7 +73,7 @@ static int uvc_input_init(struct uvc_device *dev) return ret; } -static void uvc_input_cleanup(struct uvc_device *dev) +static void uvc_input_unregister(struct uvc_device *dev) { if (dev->input) input_unregister_device(dev->input); @@ -90,7 +90,7 @@ static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, #else #define uvc_input_init(dev) -#define uvc_input_cleanup(dev) +#define uvc_input_unregister(dev) #define uvc_input_report_key(dev, code, value) #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ @@ -290,12 +290,16 @@ int uvc_status_init(struct uvc_device *dev) return 0; } -void uvc_status_cleanup(struct uvc_device *dev) +void uvc_status_unregister(struct uvc_device *dev) { usb_kill_urb(dev->int_urb); + uvc_input_unregister(dev); +} + +void uvc_status_cleanup(struct uvc_device *dev) +{ usb_free_urb(dev->int_urb); kfree(dev->status); - uvc_input_cleanup(dev); } int uvc_status_start(struct uvc_device *dev, gfp_t flags) diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index ab8de60f5de2..6fb0a78b1b00 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -742,6 +742,7 @@ int uvc_register_video_device(struct uvc_device *dev, /* Status */ int uvc_status_init(struct uvc_device *dev); +void uvc_status_unregister(struct uvc_device *dev); void uvc_status_cleanup(struct uvc_device *dev); int uvc_status_start(struct uvc_device *dev, gfp_t flags); void uvc_status_stop(struct uvc_device *dev); From patchwork Wed Dec 20 10:36:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499897 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 1EF6D20DC3 for ; Wed, 20 Dec 2023 10:37:25 +0000 (UTC) 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="C0Z127t4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068645; x=1734604645; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ypPxmiCEoMuIT5PCFLOgXYxZd0j5UG09Sj3dfTR8FqA=; b=C0Z127t4FQpbwCwppUHwgJ+nWIAWAFf3JnMUhqLYThZWXf8rJdgLCuAo zrdUoKThHaxho3okmSgb1FPLqaD8ePdDaez9SYRKM+YYP7zZUUlT215Ui 3L8x1drSU8FWaCdkFQRssy01u4tYykx51IUoE+f2Dot3WD8M38Y9cJUrS F4ioYdmYgQenyJ9VYOvW2t7Gx0V18b78Oxq6BPS+uU2jScd8e8E9aFfN9 VokTqu9D9wqnbuZzTHQ59xMkaUI6LiuNYsqZPP5evdgML44b0BTl6rb+Z 7R1PqTPnnxJMhdKYFw9fhmNMNSG/Km1qmhd1IvJDfbPZfg8wUWfLQeNpy A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174327" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174327" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544246" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544246" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:21 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 2567F11FB5E; Wed, 20 Dec 2023 12:37:19 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 08/29] media: mc: Drop nop release callback Date: Wed, 20 Dec 2023 12:36:52 +0200 Message-Id: <20231220103713.113386-9-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The release callback is only used to print a debug message. Drop it. (It will be re-introduced later in a different form.) Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-device.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index d4553a3705f5..c0ea08a8fc31 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -566,11 +566,6 @@ static DEVICE_ATTR_RO(model); * Registration/unregistration */ -static void media_device_release(struct media_devnode *devnode) -{ - dev_dbg(devnode->parent, "Media device released\n"); -} - static void __media_device_unregister_entity(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; @@ -718,7 +713,6 @@ int __must_check __media_device_register(struct media_device *mdev, /* Register the device node. */ mdev->devnode.fops = &media_device_fops; mdev->devnode.parent = mdev->dev; - mdev->devnode.release = media_device_release; /* Set version 0 to indicate user-space that the graph is static */ mdev->topology_version = 0; From patchwork Wed Dec 20 10:36:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499899 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 4E83C20DEF for ; Wed, 20 Dec 2023 10:37:26 +0000 (UTC) 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="B4D4tGsK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068646; x=1734604646; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cnQVp1AUtNnhG5EZc1r0XssIluaqMK1nwvl07Q2tM9Q=; b=B4D4tGsKQABBfbTWpAE+y7bGHRmbuONEpt0VNmwg38o5iWbML0+gEw8A 3On6BzMaYkv+gTbCXHtFm89teI1ygtJ7D79nMO4iOKNFCfqRRaT0niBLH jjG9RrmjGSyfBkKHiESxExi5rgM4dxyb6xnDC+KA84x5FI3O6TuDscnGO tc9+RepE6rUainIkoFdLTuRHquASNtUzZlKKpgHPk36/oXtC0SNqWSHZ6 lAyvJ3nthj8QCvaxnryWPErVf755dMXhp4bt+mjYGidj+8x0Nn5JXLr1L a3rlCsUKQ+k3NSS44eIINglNe7dClwl8NkaKBVw2AO2uDzfoAqtj2A2xb w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174333" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174333" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544247" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544247" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:22 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id EACA311FC49; Wed, 20 Dec 2023 12:37:19 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 09/29] media: mc: Do not call cdev_device_del() if cdev_device_add() fails Date: Wed, 20 Dec 2023 12:36:53 +0200 Message-Id: <20231220103713.113386-10-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 cdev_device_del() is the right function to remove a device when cdev_device_add() succeeds. If it does not, however, put_device() needs to be used instead. Fix this. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-devnode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index ce93ab9be676..7e22938dfd81 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -254,7 +254,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode, cdev_add_error: mutex_lock(&media_devnode_lock); - cdev_device_del(&devnode->cdev, &devnode->dev); clear_bit(devnode->minor, media_devnode_nums); mutex_unlock(&media_devnode_lock); From patchwork Wed Dec 20 10:36:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499900 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 6783220DF3 for ; Wed, 20 Dec 2023 10:37:26 +0000 (UTC) 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="RkTbjYp+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068646; x=1734604646; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=05/GurQC+tFTFg0EilvY/mjumAa9KUU6C9I+HxauEVg=; b=RkTbjYp+x0HZOB9kwu/p8s3P33KvqvDhOs4PZtjO2kXwctQbpuUPTtB7 vnioeZnuRU5KlehkPR9ttlacqE2Wmv3r32bvCeWKy+KUGz0YE1F/Ssq1f UDWThwHHxzqd+kVLTXq7qFV3ap4KLYgGZulJDCFGP/ahUOjLRniURpYSB CwqYZgeG5M5gCVuOa5Ukhzp0Gz/D919zpf0npSzjorj+Mw9LAxtqA1xAC 17r8AQC9r+NHy0DLwXznTakty+Aj/QPGdQv+icHJd43nXn2IrTGRp/dBP X2oY2FCpQjrT4Sfh3oj4oUDvkimHYOVAsTwhfj7V2Ht5L8PH70w1lmh/J A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174336" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174336" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544250" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544250" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:23 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 6F8C61201D0; Wed, 20 Dec 2023 12:37:20 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 10/29] media: mc: Delete character device early Date: Wed, 20 Dec 2023 12:36:54 +0200 Message-Id: <20231220103713.113386-11-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The parent of the character device related to the media devnode is the media devnode. Thus the character device needs to be released before the media devnode's release function. Move it to unregistering of the media devnode, which mirrors adding the character device in conjunction with registering the media devnode. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-devnode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 7e22938dfd81..8bc7450ac144 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -51,9 +51,6 @@ static void media_devnode_release(struct device *cd) mutex_lock(&media_devnode_lock); - /* Delete the cdev on this minor as well */ - cdev_del(&devnode->cdev); - /* Mark device node number as free */ clear_bit(devnode->minor, media_devnode_nums); @@ -270,6 +267,7 @@ void media_devnode_unregister(struct media_devnode *devnode) clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); mutex_unlock(&media_devnode_lock); + cdev_del(&devnode->cdev); device_unregister(&devnode->dev); } From patchwork Wed Dec 20 10:36:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499901 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 C76A5210E8 for ; Wed, 20 Dec 2023 10:37:26 +0000 (UTC) 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="bndpTBfE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068647; x=1734604647; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ij13MlaFCYNiYzoFfrF4YVx9TkIbZLlFYdwK6gFGWqM=; b=bndpTBfEapqubYsGHtkmjzSfIHNXK3gfdd2Iiv1QdVTXq7W1oXndlddX cCzQKUyY1eF8WErueoozb6y0RdJQMyEuSDtj5Q6JHa49NOwmuJt0XdwGn FsQjAuiplhBXazFM3F4JKC+3XYiVrjFWwN65pwiv1ePdgljQx1hswFtc5 lJI4nXJ4RLScW4MxdIBKOPTFJSXUnf5LcC9TJnnVQijUIFNwbacWjiJro KE+JzXtuzyNdd3nwCAQH/esAE2QFiSiRNile0XHcG7KDgBnFT+5cct3Ws MfXFMnAVulPGbzUUq151EZUMnOqjaVoRDw/ZVx6lzWGEydqAjaVJ+8u8I A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174339" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174339" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544251" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544251" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:23 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 1B5B312068E; Wed, 20 Dec 2023 12:37:21 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 11/29] media: mc: Split initialising and adding media devnode Date: Wed, 20 Dec 2023 12:36:55 +0200 Message-Id: <20231220103713.113386-12-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 As registering a device node of an entity belonging to a media device will require a reference to the struct device. Taking that reference is only possible once the device has been initialised, which took place only when it was registered. Split this in two, and initialise the device when the media device is allocated. Don't distribute the effects of these changes yet. Add media_device_get() and media_device_put() first. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-device.c | 18 +++++++++++++----- drivers/media/mc/mc-devnode.c | 17 ++++++++++------- include/media/media-devnode.h | 19 ++++++++++++++----- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index c0ea08a8fc31..ebf037cd5f4a 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -717,19 +717,26 @@ int __must_check __media_device_register(struct media_device *mdev, /* Set version 0 to indicate user-space that the graph is static */ mdev->topology_version = 0; + media_devnode_init(&mdev->devnode); + ret = media_devnode_register(&mdev->devnode, owner); if (ret < 0) - return ret; + goto out_put; ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); - if (ret < 0) { - media_devnode_unregister(&mdev->devnode); - return ret; - } + if (ret < 0) + goto out_unregister; dev_dbg(mdev->dev, "Media device registered\n"); return 0; + +out_unregister: + media_devnode_unregister(&mdev->devnode); +out_put: + put_device(&mdev->devnode.dev); + + return ret; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -803,6 +810,7 @@ void media_device_unregister(struct media_device *mdev) device_remove_file(&mdev->devnode.dev, &dev_attr_model); dev_dbg(mdev->dev, "Media device unregistering\n"); media_devnode_unregister(&mdev->devnode); + put_device(&mdev->devnode.dev); } EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 8bc7450ac144..7b17419050fb 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -204,6 +204,11 @@ static const struct file_operations media_devnode_fops = { .llseek = no_llseek, }; +void media_devnode_init(struct media_devnode *devnode) +{ + device_initialize(&devnode->dev); +} + int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner) { @@ -235,7 +240,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode, if (devnode->parent) devnode->dev.parent = devnode->parent; dev_set_name(&devnode->dev, "media%d", devnode->minor); - device_initialize(&devnode->dev); /* Part 3: Add the media and character devices */ ret = cdev_device_add(&devnode->cdev, &devnode->dev); @@ -267,14 +271,13 @@ void media_devnode_unregister(struct media_devnode *devnode) clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); mutex_unlock(&media_devnode_lock); - cdev_del(&devnode->cdev); - device_unregister(&devnode->dev); + cdev_device_del(&devnode->cdev, &devnode->dev); } /* * Initialise media for linux */ -static int __init media_devnode_init(void) +static int __init media_devnode_module_init(void) { int ret; @@ -296,14 +299,14 @@ static int __init media_devnode_init(void) return 0; } -static void __exit media_devnode_exit(void) +static void __exit media_devnode_module_exit(void) { bus_unregister(&media_bus_type); unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES); } -subsys_initcall(media_devnode_init); -module_exit(media_devnode_exit) +subsys_initcall(media_devnode_module_init); +module_exit(media_devnode_module_exit) MODULE_AUTHOR("Laurent Pinchart "); MODULE_DESCRIPTION("Device node registration for media drivers"); diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 1117d1dfd6bf..6d46c658be21 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -90,6 +90,17 @@ struct media_devnode { /* dev to media_devnode */ #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) +/** + * media_devnode_init - initialise a media devnode + * + * @devnode: struct media_devnode we want to initialise + * + * Initialise a media devnode. Note that after initialising the media + * devnode is refcounted. Releasing references to it may be done using + * put_device(). + */ +void media_devnode_init(struct media_devnode *devnode); + /** * media_devnode_register - register a media device node * @@ -100,11 +111,9 @@ struct media_devnode { * with the kernel. An error is returned if no free minor number can be found, * or if the registration of the device node fails. * - * Zero is returned on success. - * - * Note that if the media_devnode_register call fails, the release() callback of - * the media_devnode structure is *not* called, so the caller is responsible for - * freeing any data. + * Zero is returned on success. Note that in case + * media_devnode_register() fails, the caller is responsible for + * releasing the reference to the device using put_device(). */ int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner); From patchwork Wed Dec 20 10:36:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499902 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 82D70210FC for ; Wed, 20 Dec 2023 10:37:27 +0000 (UTC) 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="PRE6j4vF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068647; x=1734604647; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HOzRLelRw5VDilK37nbbPR6Q6DkmhJ5MpT0c9fWu5wo=; b=PRE6j4vFfZjgWAGxbKAcDBwNB9xsC7W5D5ClwjV6g3ELDyTe6dR+F3O9 sOmsNL9ZftYagN+/nnhvU57CaBG+DblOyqfrtRKwk/1ZM5UblErOXta7I XsGeD6MepkwUJJW2zio/qAP+74KTM3nfZcHFyv9whAGcorYTUIcRYUP0w 1feaw0nQk6NvO0JKk+x4Q8mBjP++QfM9anoaKJbNa6D+pSm/6nlhqZId+ EAY39s95fRtDYrKdvPeytMWKHaSTjmncR8E4ZH9wAyyrIyRLOCw9NdNZC hK9CnszZ/5S9qj1PFVBeg0nzEdnoDhnH3AZUtN9CLcDU9mmfgdwYMj75u g==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174342" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174342" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544252" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544252" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:24 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id B9AB3120706; Wed, 20 Dec 2023 12:37:21 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 12/29] media: mc: Shuffle functions around Date: Wed, 20 Dec 2023 12:36:56 +0200 Message-Id: <20231220103713.113386-13-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 As the call paths of the functions in question will change, move them around in anticipation of that. No other changes. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-device.c | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index ebf037cd5f4a..44685ab6a450 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -673,6 +673,33 @@ void media_device_unregister_entity(struct media_entity *entity) } EXPORT_SYMBOL_GPL(media_device_unregister_entity); +void media_device_register_entity_notify(struct media_device *mdev, + struct media_entity_notify *nptr) +{ + mutex_lock(&mdev->graph_mutex); + list_add_tail(&nptr->list, &mdev->entity_notify); + mutex_unlock(&mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_device_register_entity_notify); + +/* + * Note: Should be called with mdev->lock held. + */ +static void __media_device_unregister_entity_notify(struct media_device *mdev, + struct media_entity_notify *nptr) +{ + list_del(&nptr->list); +} + +void media_device_unregister_entity_notify(struct media_device *mdev, + struct media_entity_notify *nptr) +{ + mutex_lock(&mdev->graph_mutex); + __media_device_unregister_entity_notify(mdev, nptr); + mutex_unlock(&mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify); + void media_device_init(struct media_device *mdev) { INIT_LIST_HEAD(&mdev->entities); @@ -740,33 +767,6 @@ int __must_check __media_device_register(struct media_device *mdev, } EXPORT_SYMBOL_GPL(__media_device_register); -void media_device_register_entity_notify(struct media_device *mdev, - struct media_entity_notify *nptr) -{ - mutex_lock(&mdev->graph_mutex); - list_add_tail(&nptr->list, &mdev->entity_notify); - mutex_unlock(&mdev->graph_mutex); -} -EXPORT_SYMBOL_GPL(media_device_register_entity_notify); - -/* - * Note: Should be called with mdev->lock held. - */ -static void __media_device_unregister_entity_notify(struct media_device *mdev, - struct media_entity_notify *nptr) -{ - list_del(&nptr->list); -} - -void media_device_unregister_entity_notify(struct media_device *mdev, - struct media_entity_notify *nptr) -{ - mutex_lock(&mdev->graph_mutex); - __media_device_unregister_entity_notify(mdev, nptr); - mutex_unlock(&mdev->graph_mutex); -} -EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify); - void media_device_unregister(struct media_device *mdev) { struct media_entity *entity; From patchwork Wed Dec 20 10:36:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499903 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 B71FE21105 for ; Wed, 20 Dec 2023 10:37:27 +0000 (UTC) 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="HUc6LTY5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068648; x=1734604648; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3eYoyL85RZ0NXQdOXP/zvPjuOHNqncO7h8P3i0dE8HU=; b=HUc6LTY50IdfLBdpzAurs1iiFC05wG9u0FHN987XyG6OhbhSoiEzQyq3 a4Ev3taZBxMb+ogmc0X5tcKwdqwqYy+fbhq1x3vvgaeL2WJit+MpkZhsK FPElFrxgeBWDmVyvY6QAzp/qc3GltzxofKva1h/0hvE/WC76kW9EtkFGq cgM+FsH5E9vjjxLflbFqRmfEx3yjkbN1lXM8jt7mhNpD1LrTxakj4/gst vHDvF21IynWn+nSIp5N/y3lg1BJ+64+4b4C6tMtUqoVIvQaz00hOUL4PI l2CcNy2kN7Ckk/BFF8GAGWth6BKUcCmpL5aN3A4EjPUFAlRLOUJ2RiB/b w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174345" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174345" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544256" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544256" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:25 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 63128120788; Wed, 20 Dec 2023 12:37:22 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 13/29] media: mc: Initialise media devnode in media_device_init() Date: Wed, 20 Dec 2023 12:36:57 +0200 Message-Id: <20231220103713.113386-14-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Call media_devnode_init() from media_device_init(). This has the effect of creating a struct device for the media_devnode before it is registered, making it possible to obtain a reference to it for e.g. video devices. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-device.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 44685ab6a450..e6ac9b066524 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -711,8 +711,8 @@ void media_device_init(struct media_device *mdev) mutex_init(&mdev->req_queue_mutex); mutex_init(&mdev->graph_mutex); ida_init(&mdev->entity_internal_idx); - atomic_set(&mdev->request_id, 0); + media_devnode_init(&mdev->devnode); if (!*mdev->bus_info) media_set_bus_info(mdev->bus_info, sizeof(mdev->bus_info), @@ -729,6 +729,7 @@ void media_device_cleanup(struct media_device *mdev) media_graph_walk_cleanup(&mdev->pm_count_walk); mutex_destroy(&mdev->graph_mutex); mutex_destroy(&mdev->req_queue_mutex); + put_device(&mdev->devnode.dev); } EXPORT_SYMBOL_GPL(media_device_cleanup); @@ -744,26 +745,19 @@ int __must_check __media_device_register(struct media_device *mdev, /* Set version 0 to indicate user-space that the graph is static */ mdev->topology_version = 0; - media_devnode_init(&mdev->devnode); - ret = media_devnode_register(&mdev->devnode, owner); if (ret < 0) - goto out_put; + return ret; ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); - if (ret < 0) - goto out_unregister; + if (ret < 0) { + media_devnode_unregister(&mdev->devnode); + return ret; + } dev_dbg(mdev->dev, "Media device registered\n"); return 0; - -out_unregister: - media_devnode_unregister(&mdev->devnode); -out_put: - put_device(&mdev->devnode.dev); - - return ret; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -810,7 +804,6 @@ void media_device_unregister(struct media_device *mdev) device_remove_file(&mdev->devnode.dev, &dev_attr_model); dev_dbg(mdev->dev, "Media device unregistering\n"); media_devnode_unregister(&mdev->devnode); - put_device(&mdev->devnode.dev); } EXPORT_SYMBOL_GPL(media_device_unregister); From patchwork Wed Dec 20 10:36:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499904 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 4580821116 for ; Wed, 20 Dec 2023 10:37:28 +0000 (UTC) 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="IW2QOBPH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068648; x=1734604648; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f4QZYuk5GOjZevZxAHm7nfSqVvf3WIo8y/0km/Uo4k4=; b=IW2QOBPHRqEHrMVCxHvxvj8SWiwG+GQekwKlwAeKSjOIl8IPPB3GyOfF VQH0MMU7SDurNOO3QJhoagcbjVCkKhGX/OSZ18qYMnbFpOX1QY/8OdI4+ 5kk9hKpJVyoPm+FdXO6QwLQgOohKkM1ddPQbKKBLrSNmVDpBv+Vuirysx AgFi/X/HWu6hsHVmwtfDlGzarek+qFtguhoMxGXAkECAspebIi//u4oAm GPvZL+N/Cq0W/bsDh1SXYVz804/DnsHiOm3n3LUdUwAE30vCjJRdL+NES 47MFmHQTUj6dDyyvIY0rI3imId+54CcO3w/2ccV2AKj9jQ7D8MyaTPvwz A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174351" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174351" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544257" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544257" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:25 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 2E6AD11FB5E; Wed, 20 Dec 2023 12:37:23 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 14/29] media: mc: Refactor media devnode minor clearing Date: Wed, 20 Dec 2023 12:36:58 +0200 Message-Id: <20231220103713.113386-15-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Refactor clearing media devnode minor bit in media devnode bitmap. Note that number is used instead of struct media_devnode as argument since the minor number will also be stored in a different structure soon. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-devnode.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 7b17419050fb..717408791a7c 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -44,17 +44,22 @@ static dev_t media_dev_t; static DEFINE_MUTEX(media_devnode_lock); static DECLARE_BITMAP(media_devnode_nums, MEDIA_NUM_DEVICES); -/* Called when the last user of the media device exits. */ -static void media_devnode_release(struct device *cd) +static void media_devnode_free_minor(unsigned int minor) { - struct media_devnode *devnode = to_media_devnode(cd); - mutex_lock(&media_devnode_lock); /* Mark device node number as free */ - clear_bit(devnode->minor, media_devnode_nums); + clear_bit(minor, media_devnode_nums); mutex_unlock(&media_devnode_lock); +} + +/* Called when the last user of the media device exits. */ +static void media_devnode_release(struct device *cd) +{ + struct media_devnode *devnode = to_media_devnode(cd); + + media_devnode_free_minor(devnode->minor); /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) @@ -254,9 +259,7 @@ int __must_check media_devnode_register(struct media_devnode *devnode, return 0; cdev_add_error: - mutex_lock(&media_devnode_lock); - clear_bit(devnode->minor, media_devnode_nums); - mutex_unlock(&media_devnode_lock); + media_devnode_free_minor(devnode->minor); return ret; } From patchwork Wed Dec 20 10:36:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499905 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 DF34221340 for ; Wed, 20 Dec 2023 10:37:28 +0000 (UTC) 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="H4OP9f27" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068649; x=1734604649; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+d7iJXIRHrUkm3+oWHno0huhYBxKZlBeeISLKQ+MAYQ=; b=H4OP9f27dRyH7l3JlVOJd+2APAzTXWFvFbE/Uuzq/L/5LgRiLDU+2ZzI k3PfSZTv+BK/PwpthTakWHBfIvj5sO4o+hCs/OSsCNeqR2vPl0MJLTzWq WWNLPMy+RyC7jZ1GoIcw/TAq1u+rf1Vb3QuluQHMK0K9hDGmQoHdM7dX+ OIuoJu40rwsfOaqK1MLz76FWOfMBv1SoD+DxYfE4qSrqMfv4p2tlDeY7t 4JvyODjcw4c8CuS05H7zkrYDRizZIHndcPLRK02aFgbIVkTl3bNlqvSlz MjfizmQd50OtSX121Hm9v2wiYiWakMx0u8y1gDTWBoRwgtkbLgQ/ujbth w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174356" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174356" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544258" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544258" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:26 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id D509512098A; Wed, 20 Dec 2023 12:37:23 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 15/29] media: mc: Unassign minor only if it has been assigned Date: Wed, 20 Dec 2023 12:36:59 +0200 Message-Id: <20231220103713.113386-16-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Assign the media device minor to -1 if it has not been previously assigned. There's no dependence to this yes but it will be required by patch "media: mc: Implement best effort media device removal safety sans refcount" soon. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-devnode.c | 9 ++++++++- include/media/media-devnode.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 717408791a7c..5057c48f8870 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -59,7 +59,8 @@ static void media_devnode_release(struct device *cd) { struct media_devnode *devnode = to_media_devnode(cd); - media_devnode_free_minor(devnode->minor); + if (devnode->minor != -1) + media_devnode_free_minor(devnode->minor); /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) @@ -212,6 +213,7 @@ static const struct file_operations media_devnode_fops = { void media_devnode_init(struct media_devnode *devnode) { device_initialize(&devnode->dev); + devnode->minor = -1; } int __must_check media_devnode_register(struct media_devnode *devnode, @@ -220,6 +222,9 @@ int __must_check media_devnode_register(struct media_devnode *devnode, int minor; int ret; + if (devnode->minor != -1) + return -EINVAL; + /* Part 1: Find a free minor number */ mutex_lock(&media_devnode_lock); minor = find_first_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES); @@ -261,6 +266,8 @@ int __must_check media_devnode_register(struct media_devnode *devnode, cdev_add_error: media_devnode_free_minor(devnode->minor); + devnode->minor = -1; + return ret; } diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 6d46c658be21..d050f54f252a 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -60,7 +60,7 @@ struct media_file_operations { * @dev: pointer to struct &device containing the media controller device * @cdev: struct cdev pointer character device * @parent: parent device - * @minor: device node minor number + * @minor: device node minor number, -1 if unassigned * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants * @release: release callback called at the end of ``media_devnode_release()`` * routine at media-device.c. From patchwork Wed Dec 20 10:37:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499906 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 1565C2134A for ; Wed, 20 Dec 2023 10:37:29 +0000 (UTC) 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="V6JzCyEM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068649; x=1734604649; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AuhiUd0lvh2AZG/DF52hVKm1+VmJk7dFMC744uMD+rw=; b=V6JzCyEMyb7KIjdAekAi2Sl4Gdj21qllg0KDgHbgot0hahDE7HaqpFEC 1XlKzOsXGhY71Wp2RHfs664tNrIjfcw0ja4bLpqEHld7v2N8TClNfwTAi gVOXW8/iB2ZIHNrx6RRenLOVLVXNAcvdowL0O1+s8DXRldadm62RwdOar RzMZtcODlt76BbGy+apf2LDDmhjbEJyyZnJ5uOLy16MtGwa1fPBkC5Qxi I0gTy++Ho/qFgIoi7GdE6EN8XwHITDjKAiaMBJTkYKw7vfifdtR/UKhwy xDM6xG3wkC9TTIBaNY7OmnGd4+2+FZLp/q4rDi2UVSi88eqfAxnvEbFR/ Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174359" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174359" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544259" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544259" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:26 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 6EA6E11FC49; Wed, 20 Dec 2023 12:37:24 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 16/29] media: mc: Refcount the media device Date: Wed, 20 Dec 2023 12:37:00 +0200 Message-Id: <20231220103713.113386-17-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 As the struct media_device embeds struct media_devnode, the lifetime of that object must be that same than that of the media_device. References are obtained by media_device_get() and released by media_device_put(). In order to use refcounting, the driver must set the release callback before calling media_device_init() on the media device. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 36 +++++++++++++++++++++++++++++------ drivers/media/mc/mc-devnode.c | 6 +++++- include/media/media-device.h | 28 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index e6ac9b066524..bbc233e726d2 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -700,6 +700,31 @@ void media_device_unregister_entity_notify(struct media_device *mdev, } EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify); +static void __media_device_release(struct media_device *mdev) +{ + dev_dbg(mdev->dev, "Media device released\n"); + + ida_destroy(&mdev->entity_internal_idx); + mdev->entity_internal_idx_max = 0; + media_graph_walk_cleanup(&mdev->pm_count_walk); + mutex_destroy(&mdev->graph_mutex); + mutex_destroy(&mdev->req_queue_mutex); +} + +static void media_device_release(struct media_devnode *devnode) +{ + struct media_device *mdev = to_media_device(devnode); + + if (mdev->ops && mdev->ops->release) { + /* + * If release op isn't set, __media_device_release() is called + * via media_device_cleanup(). + */ + __media_device_release(mdev); + mdev->ops->release(mdev); + } +} + void media_device_init(struct media_device *mdev) { INIT_LIST_HEAD(&mdev->entities); @@ -712,6 +737,8 @@ void media_device_init(struct media_device *mdev) mutex_init(&mdev->graph_mutex); ida_init(&mdev->entity_internal_idx); atomic_set(&mdev->request_id, 0); + + mdev->devnode.release = media_device_release; media_devnode_init(&mdev->devnode); if (!*mdev->bus_info) @@ -724,12 +751,9 @@ EXPORT_SYMBOL_GPL(media_device_init); void media_device_cleanup(struct media_device *mdev) { - ida_destroy(&mdev->entity_internal_idx); - mdev->entity_internal_idx_max = 0; - media_graph_walk_cleanup(&mdev->pm_count_walk); - mutex_destroy(&mdev->graph_mutex); - mutex_destroy(&mdev->req_queue_mutex); - put_device(&mdev->devnode.dev); + WARN_ON(mdev->ops && mdev->ops->release); + __media_device_release(mdev); + media_device_put(mdev); } EXPORT_SYMBOL_GPL(media_device_cleanup); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 5057c48f8870..4ea05e42dafb 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -59,6 +59,10 @@ static void media_devnode_release(struct device *cd) { struct media_devnode *devnode = to_media_devnode(cd); + /* If the devnode has a ref, it is simply released by the user. */ + if (devnode->ref) + return; + if (devnode->minor != -1) media_devnode_free_minor(devnode->minor); @@ -213,6 +217,7 @@ static const struct file_operations media_devnode_fops = { void media_devnode_init(struct media_devnode *devnode) { device_initialize(&devnode->dev); + devnode->dev.release = media_devnode_release; devnode->minor = -1; } @@ -246,7 +251,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode, devnode->dev.bus = &media_bus_type; devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor); - devnode->dev.release = media_devnode_release; if (devnode->parent) devnode->dev.parent = devnode->parent; dev_set_name(&devnode->dev, "media%d", devnode->minor); diff --git a/include/media/media-device.h b/include/media/media-device.h index fb0855b217ce..c6816be0eee8 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -62,6 +62,7 @@ struct media_entity_notify { * request (and thus the buffer) must be available to the driver. * And once a buffer is queued, then the driver can complete * or delete objects from the request before req_queue exits. + * @release: Release the resources of the media device. */ struct media_device_ops { int (*link_notify)(struct media_link *link, u32 flags, @@ -70,6 +71,7 @@ struct media_device_ops { void (*req_free)(struct media_request *req); int (*req_validate)(struct media_request *req); void (*req_queue)(struct media_request *req); + void (*release)(struct media_device *mdev); }; /** @@ -219,6 +221,30 @@ struct usb_device; */ void media_device_init(struct media_device *mdev); +/** + * media_device_get() - Get a reference to a media device + * + * @mdev: media device + */ +#define media_device_get(mdev) \ + do { \ + dev_dbg((mdev)->dev, "%s: get media device %s\n", \ + __func__, (mdev)->bus_info); \ + get_device(&(mdev)->devnode.dev); \ + } while (0) + +/** + * media_device_put() - Put a reference to a media device + * + * @mdev: media device + */ +#define media_device_put(mdev) \ + do { \ + dev_dbg((mdev)->dev, "%s: put media device %s\n", \ + __func__, (mdev)->bus_info); \ + put_device(&(mdev)->devnode.dev); \ + } while (0) + /** * media_device_cleanup() - Cleanups a media device element * @@ -432,6 +458,8 @@ void __media_device_usb_init(struct media_device *mdev, const char *driver_name); #else +#define media_device_get(mdev) do { } while (0) +#define media_device_put(mdev) do { } while (0) static inline int media_device_register(struct media_device *mdev) { return 0; From patchwork Wed Dec 20 10:37:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499907 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 8D96C21358 for ; Wed, 20 Dec 2023 10:37:29 +0000 (UTC) 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="GP4LYJcI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068649; x=1734604649; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DljlbCt0FSsT8kkZ5/vM2Z0AgTD0mlbqYy7HsNaKVdY=; b=GP4LYJcIKRyp5Fyuh20xlywB9m0CKXXbmu/nmXmkZdcQBSTwVF7bFqsT JPow+QEMfZJI1A20nl+KRnghlK1YYFVD/I3Q2sftfLdnLF7RbMrul9zQ+ jvPy8a6hH78XGrrNUJwGyqsaKHpkSZ866cgeyUzY6KzAutNZPlFVUS6QV QYcUvSp9jWUp7SwZoRG+zM4uqkgem1Q2NxnUpQpC0AAo9ba5FOn9YtsdY KVCLToPD8tJLiyQOqXeRB309JjxgvzmWvk35OpC5bku1dJEv2gdMpjMD7 tsD2w89Zs7KChZkozzC80eR47MJ/8oMQNCzfMO60xrHg+wDB59bMoZlBF w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174364" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174364" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544265" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544265" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:27 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 05FA01201D0; Wed, 20 Dec 2023 12:37:24 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 17/29] media: v4l: Acquire a reference to the media device for every video device Date: Wed, 20 Dec 2023 12:37:01 +0200 Message-Id: <20231220103713.113386-18-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The video device depends on the existence of its media device --- if there is one. Acquire a reference to it. Note that when the media device release callback is used, then the V4L2 device release callback is ignored and a warning is issued if both are set. Signed-off-by: Sakari Ailus --- drivers/media/v4l2-core/v4l2-dev.c | 51 ++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index d13954bd31fd..c1e4995eaf5c 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -176,6 +176,11 @@ static void v4l2_device_release(struct device *cd) { struct video_device *vdev = to_video_device(cd); struct v4l2_device *v4l2_dev = vdev->v4l2_dev; + bool v4l2_dev_has_release = v4l2_dev->release; +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = v4l2_dev->mdev; + bool mdev_has_release = mdev && mdev->ops && mdev->ops->release; +#endif mutex_lock(&videodev_lock); if (WARN_ON(video_devices[vdev->minor] != vdev)) { @@ -198,8 +203,8 @@ static void v4l2_device_release(struct device *cd) mutex_unlock(&videodev_lock); -#if defined(CONFIG_MEDIA_CONTROLLER) - if (v4l2_dev->mdev && vdev->vfl_dir != VFL_DIR_M2M) { +#ifdef CONFIG_MEDIA_CONTROLLER + if (mdev && vdev->vfl_dir != VFL_DIR_M2M) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode); if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) @@ -207,23 +212,31 @@ static void v4l2_device_release(struct device *cd) } #endif - /* Do not call v4l2_device_put if there is no release callback set. - * Drivers that have no v4l2_device release callback might free the - * v4l2_dev instance in the video_device release callback below, so we - * must perform this check here. - * - * TODO: In the long run all drivers that use v4l2_device should use the - * v4l2_device release callback. This check will then be unnecessary. - */ - if (v4l2_dev->release == NULL) - v4l2_dev = NULL; - /* Release video_device and perform other cleanups as needed. */ vdev->release(vdev); - /* Decrease v4l2_device refcount */ - if (v4l2_dev) +#ifdef CONFIG_MEDIA_CONTROLLER + if (mdev) + media_device_put(mdev); + + /* + * Generally both struct media_device and struct v4l2_device are + * embedded in the same driver's context struct so having a release + * callback in both is a bug. + */ + WARN_ON(v4l2_dev_has_release && mdev_has_release); +#endif + + /* + * Decrease v4l2_device refcount, but only if the media device doesn't + * have a release callback. + */ + if (v4l2_dev_has_release +#ifdef CONFIG_MEDIA_CONTROLLER + && !mdev_has_release +#endif + ) v4l2_device_put(v4l2_dev); } @@ -792,11 +805,14 @@ static int video_register_media_controller(struct video_device *vdev) u32 intf_type; int ret; - /* Memory-to-memory devices are more complex and use + /* + * Memory-to-memory devices are more complex and use * their own function to register its mc entities. */ - if (!vdev->v4l2_dev->mdev || vdev->vfl_dir == VFL_DIR_M2M) + if (!vdev->v4l2_dev->mdev || vdev->vfl_dir == VFL_DIR_M2M) { + media_device_get(vdev->v4l2_dev->mdev); return 0; + } vdev->entity.obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE; vdev->entity.function = MEDIA_ENT_F_UNKNOWN; @@ -875,6 +891,7 @@ static int video_register_media_controller(struct video_device *vdev) /* FIXME: how to create the other interface links? */ + media_device_get(vdev->v4l2_dev->mdev); #endif return 0; } From patchwork Wed Dec 20 10:37:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499908 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 42A8F21362 for ; Wed, 20 Dec 2023 10:37:30 +0000 (UTC) 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="L0JzkDlx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068650; x=1734604650; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=b8A0zAtDgHgdySNbkiiN2Py2hl+u3/NaWACsnHEcZGk=; b=L0JzkDlxYDTWG51V5sNuCpt0PWFRWLk0/U1ryw4GNdNFRs8xHImS/37f pzCt7fj4Dyxo9Mo1uQHaWS/wUQxMXjBqvMlGzc7cBiCawMzQhDGyNf5Oo hcLjBQKU2Oi3kFQXHnRr3RxlqLYK8P/VCj0Vn8gaOqurrRe5yJshC7QRD XJ2Wxhh9t2CFSfqJXbyLqR0xxWAQhoYbRSf4wIC0meMyXQL6Zv7PnIM/7 oP12RuZnWQmn0CxNzLVG731EM3o5Hdw6ICXNYWdDMfTgAz2pYEm/hXKng SxhozcM/0zx2EbLmrs17E3++Wk5caoHRwdo7wHsrgD38UHGYMEZq6O3Y0 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174367" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174367" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544269" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544269" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:28 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 8F90F12068E; Wed, 20 Dec 2023 12:37:25 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 18/29] media: mc: Postpone graph object removal until free Date: Wed, 20 Dec 2023 12:37:02 +0200 Message-Id: <20231220103713.113386-19-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The media device itself will be unregistered based on it being unbound and driver's remove callback being called. The graph objects themselves may still be in use; rely on the media device release callback to release them. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 53 +++++++++++++++++------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index bbc233e726d2..10426c2796b6 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -702,8 +702,33 @@ EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify); static void __media_device_release(struct media_device *mdev) { + struct media_entity *entity; + struct media_entity *next; + struct media_interface *intf, *tmp_intf; + struct media_entity_notify *notify, *nextp; + dev_dbg(mdev->dev, "Media device released\n"); + /* Remove all entities from the media device */ + list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) + __media_device_unregister_entity(entity); + + /* Remove all entity_notify callbacks from the media device */ + list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list) + __media_device_unregister_entity_notify(mdev, notify); + + /* Remove all interfaces from the media device */ + list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { + /* + * Unlink the interface, but don't free it here; the + * module which created it is responsible for freeing + * it + */ + __media_remove_intf_links(intf); + media_gobj_destroy(&intf->graph_obj); + } + ida_destroy(&mdev->entity_internal_idx); mdev->entity_internal_idx_max = 0; media_graph_walk_cleanup(&mdev->pm_count_walk); @@ -787,42 +812,14 @@ EXPORT_SYMBOL_GPL(__media_device_register); void media_device_unregister(struct media_device *mdev) { - struct media_entity *entity; - struct media_entity *next; - struct media_interface *intf, *tmp_intf; - struct media_entity_notify *notify, *nextp; - if (mdev == NULL) return; mutex_lock(&mdev->graph_mutex); - - /* Check if mdev was ever registered at all */ if (!media_devnode_is_registered(&mdev->devnode)) { mutex_unlock(&mdev->graph_mutex); return; } - - /* Remove all entities from the media device */ - list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) - __media_device_unregister_entity(entity); - - /* Remove all entity_notify callbacks from the media device */ - list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list) - __media_device_unregister_entity_notify(mdev, notify); - - /* Remove all interfaces from the media device */ - list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, - graph_obj.list) { - /* - * Unlink the interface, but don't free it here; the - * module which created it is responsible for freeing - * it - */ - __media_remove_intf_links(intf); - media_gobj_destroy(&intf->graph_obj); - } - mutex_unlock(&mdev->graph_mutex); device_remove_file(&mdev->devnode.dev, &dev_attr_model); From patchwork Wed Dec 20 10:37:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499909 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 837772136E for ; Wed, 20 Dec 2023 10:37:30 +0000 (UTC) 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="Im1EPPMx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068650; x=1734604650; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bNPcGQWQiPdDPUXvLZG+GLaS8C7SWTIVIHJbLUbtkHo=; b=Im1EPPMx40+tk/2aHVMgPHuLMQiA9cuwiO2oTSJAANMbyLmGh3jHelE6 cdqoQCgb3X/WvXEHgPnratqmIncfDsJjq8ooQTzr378nAg8LktMK+pwZ2 0EG1jU5ee2NzRs6akUfXCfgyTXOtmPT7579hwD0lCUBaKSJRtMHdkJa/a n2cJi4P77kzDD88kjGjVn8Chf60iR0r+j7YIeLkkMZi4oFHV5CaLij6Iw 8bdXm3gdK44w7DBN1swY9Mt0OC3GaxR1cFUtn1maF33HKM7tItyWcZAyw ER1ZACurUGYEBIxr0/Orz1AlgQqfCUHXT0Uds7xrg/JHs6YB1GOSVNwYI Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174372" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174372" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544270" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544270" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:28 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 3185E120706; Wed, 20 Dec 2023 12:37:26 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 19/29] media: omap3isp: Release the isp device struct by media device callback Date: Wed, 20 Dec 2023 12:37:03 +0200 Message-Id: <20231220103713.113386-20-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Use the media device release callback to release the isp device's data structure. This approach has the benefit of not releasing memory which may still be accessed through open file handles whilst the isp driver is being unbound. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/platform/ti/omap3isp/isp.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/ti/omap3isp/isp.c b/drivers/media/platform/ti/omap3isp/isp.c index 1cda23244c7b..ef6a781d6da1 100644 --- a/drivers/media/platform/ti/omap3isp/isp.c +++ b/drivers/media/platform/ti/omap3isp/isp.c @@ -649,8 +649,11 @@ static irqreturn_t isp_isr(int irq, void *_isp) return IRQ_HANDLED; } +static void isp_release(struct media_device *mdev); + static const struct media_device_ops isp_media_ops = { .link_notify = v4l2_pipeline_link_notify, + .release = isp_release, }; /* ----------------------------------------------------------------------------- @@ -1607,7 +1610,6 @@ static void isp_unregister_entities(struct isp_device *isp) omap3isp_stat_unregister_entities(&isp->isp_hist); v4l2_device_unregister(&isp->v4l2_dev); - media_device_cleanup(&isp->media_dev); } static int isp_link_entity( @@ -1955,6 +1957,19 @@ static void isp_detach_iommu(struct isp_device *isp) #endif } +static void isp_release(struct media_device *mdev) +{ + struct isp_device *isp = + container_of(mdev, struct isp_device, media_dev); + + isp_cleanup_modules(isp); + + media_entity_enum_cleanup(&isp->crashed); + v4l2_async_nf_cleanup(&isp->notifier); + + kfree(isp); +} + static int isp_attach_iommu(struct isp_device *isp) { #ifdef CONFIG_ARM_DMA_USE_IOMMU @@ -2004,16 +2019,15 @@ static void isp_remove(struct platform_device *pdev) v4l2_async_nf_unregister(&isp->notifier); v4l2_async_nf_cleanup(&isp->notifier); isp_unregister_entities(isp); - isp_cleanup_modules(isp); + isp_xclk_cleanup(isp); __omap3isp_get(isp, false); isp_detach_iommu(isp); __omap3isp_put(isp, false); - media_entity_enum_cleanup(&isp->crashed); - - kfree(isp); + /* May release isp immediately */ + media_device_put(&isp->media_dev); } enum isp_of_phy { From patchwork Wed Dec 20 10:37:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499910 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 DFF6421378 for ; Wed, 20 Dec 2023 10:37:30 +0000 (UTC) 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="GdMT92t3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068651; x=1734604651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OJv0/BwKZ5DTc28TXBnAuE0FG/a2mjeyCr2XuQmfLVc=; b=GdMT92t3iZrIo8tuEyn6vOReTPELO2nJ2A2j91IxfAXps3DLY26qowwu 8m9jKKqMrLAFd5hwGTDtS/NBU8hK8B5nWcdmWr0be2+NybOV+1Uk/e7BP xX1nb/PxYqS3oxzRfN13Si1jqDPK39PTMu4Mmfl/VydUN+OBp1X0gGEfU fajmqVUQkgZaWc0t9qAm31dRrA6wuJ2zyvicLj7Zp7jsCt+W+lGMF77Ki ao85azttM5SeDg4b1JJCu3hapPmqZjio7t2vnPGV7sNW9dcu4skRWVx5m 2HuAHap8BDSc0i+LRHoTO2TcmrJZ0gYgVGNM+/p3aijE7wIewuHuih8e7 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174377" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174377" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544271" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544271" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:29 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id BB6B7120788; Wed, 20 Dec 2023 12:37:26 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 20/29] media: ipu3-cio2: Call v4l2_device_unregister() earlier Date: Wed, 20 Dec 2023 12:37:04 +0200 Message-Id: <20231220103713.113386-21-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 v4l2_device_unregister() unregisters V4L2 sub-device nodes among other things. Call it before releasing memory and other resources. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 5d3b0ffd3d08..da82d09b46ab 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1827,11 +1827,11 @@ static void cio2_pci_remove(struct pci_dev *pci_dev) struct cio2_device *cio2 = pci_get_drvdata(pci_dev); media_device_unregister(&cio2->media_dev); + v4l2_device_unregister(&cio2->v4l2_dev); v4l2_async_nf_unregister(&cio2->notifier); v4l2_async_nf_cleanup(&cio2->notifier); cio2_queues_exit(cio2); cio2_fbpt_exit_dummy(cio2); - v4l2_device_unregister(&cio2->v4l2_dev); media_device_cleanup(&cio2->media_dev); mutex_destroy(&cio2->lock); From patchwork Wed Dec 20 10:37:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499911 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 8F07C219EA for ; Wed, 20 Dec 2023 10:37:31 +0000 (UTC) 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="WG/VJPVz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068651; x=1734604651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Mwzvb1h3V5fruDOZoYDmhDZh8/drmi6Hc+Wqgrki4lk=; b=WG/VJPVzG5+ZGKCFhOC7CukFtQI+ROqZ0Fk0xmKRQhj+Q29+nHJndBKq JlEhFWvm+8o6iznKeyDw/99mmEQH1xsjQlSAZv5NtU3RlE1lNU/lLua2t LXpREzGs+Y/bI4lU6vY+zHo7sYEZRXzPOMI1jdJ6bC9n0z2M0o6wlpSdk sMQqhtTlYj0iFU5JbZsZSowXQNqhW9ekKC5YOd8gkFbGrsnnkPILWP6/E Lp/P0myckh05CgGim13MwA96/1MNzKuBnitiE1hgOOGGgmcaVYVQVFEJj /F4EJZKtxrP+pQvrLTb8nWseqHzvPjSHBDIGslS3FHg2HpVSvjoZgfy52 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174383" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174383" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544272" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544272" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:30 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 509F311FB5E; Wed, 20 Dec 2023 12:37:27 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 21/29] media: ipu3-cio2: Request IRQ earlier Date: Wed, 20 Dec 2023 12:37:05 +0200 Message-Id: <20231220103713.113386-22-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Call devm_request_irq() before registering the async notifier, as otherwise it would be possible to use the device before the interrupts could be deliveted to the driver. Signed-off-by: Sakari Ailus --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index da82d09b46ab..3222ec5b8345 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1789,11 +1789,6 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, v4l2_async_nf_init(&cio2->notifier, &cio2->v4l2_dev); - /* Register notifier for subdevices we care */ - r = cio2_parse_firmware(cio2); - if (r) - goto fail_clean_notifier; - r = devm_request_irq(dev, pci_dev->irq, cio2_irq, IRQF_SHARED, CIO2_NAME, cio2); if (r) { @@ -1801,6 +1796,11 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, goto fail_clean_notifier; } + /* Register notifier for subdevices we care */ + r = cio2_parse_firmware(cio2); + if (r) + goto fail_clean_notifier; + pm_runtime_put_noidle(dev); pm_runtime_allow(dev); From patchwork Wed Dec 20 10:37:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499912 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 D8F7A219EF for ; Wed, 20 Dec 2023 10:37:31 +0000 (UTC) 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="WyZB2tKK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068652; x=1734604652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+M6yyO46Xtu1fwW0RMGaWr7x2lDqmtvQjpWHYItP3FY=; b=WyZB2tKK2PgenDKA3m8OkGxgmjLADSYDo4v9d9qspK7WVoqwvKtSobAt YSqReeBRCdE+Lw0jNsJH3CY2yqx8Qb3JbyHH8jZV5FjWgWkj3ZZOZ/81u VqV2Yj49daa8a/XjEP6wf+AjtiqkGEd7owewXr0HzMJ9PVb15SJ5/7caF gCpuBAQkCUhz+MhsRqN8XmmeuRUrEXjX1fIS8V9QDgjpMvY4YK2uZ5De8 75YD+oZwGrFteu6dQ1GRdWosQBK+Lc5SYvn18wBFZuE980waZrZ1JaseX RadqELlB9bIQ6a19sxVXVW+e9esMwWZI4ywfqAbItO8nDVSxvEX8fe1zk A==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174387" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174387" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544273" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544273" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:30 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id DB5E9120A70; Wed, 20 Dec 2023 12:37:27 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 22/29] media: ipu3-cio2: Release the cio2 device context by media device callback Date: Wed, 20 Dec 2023 12:37:06 +0200 Message-Id: <20231220103713.113386-23-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Use the media device release callback to release the cio2 device's data structure. This approach has the benefit of not releasing memory which may still be accessed through open file handles whilst the ipu3-cio2 driver is being unbound. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 58 ++++++++++++++++-------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 3222ec5b8345..bff66e6d3b1e 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -238,9 +238,15 @@ static int cio2_fbpt_init(struct cio2_device *cio2, struct cio2_queue *q) return 0; } -static void cio2_fbpt_exit(struct cio2_queue *q, struct device *dev) +static int cio2_fbpt_exit(struct cio2_queue *q, struct device *dev) { + if (!q->fbpt) + return -ENOENT; + dma_free_coherent(dev, CIO2_FBPT_SIZE, q->fbpt, q->fbpt_bus_addr); + q->fbpt = NULL; + + return 0; } /**************** CSI2 hardware setup ****************/ @@ -1643,13 +1649,13 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q) { - vb2_video_unregister_device(&q->vdev); media_entity_cleanup(&q->vdev.entity); v4l2_device_unregister_subdev(&q->subdev); media_entity_cleanup(&q->subdev.entity); - cio2_fbpt_exit(q, &cio2->pci_dev->dev); - mutex_destroy(&q->subdev_lock); - mutex_destroy(&q->lock); + if (!cio2_fbpt_exit(q, &cio2->pci_dev->dev)) { + mutex_destroy(&q->subdev_lock); + mutex_destroy(&q->lock); + } } static int cio2_queues_init(struct cio2_device *cio2) @@ -1695,6 +1701,23 @@ static int cio2_check_fwnode_graph(struct fwnode_handle *fwnode) return cio2_check_fwnode_graph(fwnode->secondary); } +static void cio2_media_release(struct media_device *mdev) +{ + struct cio2_device *cio2 = + container_of(mdev, struct cio2_device, media_dev); + + v4l2_async_nf_cleanup(&cio2->notifier); + cio2_queues_exit(cio2); + cio2_fbpt_exit_dummy(cio2); + mutex_destroy(&cio2->lock); + + kfree(cio2); +} + +static const struct media_device_ops cio2_mdev_ops = { + .release = cio2_media_release, +}; + /**************** PCI interface ****************/ static int cio2_pci_probe(struct pci_dev *pci_dev, @@ -1722,7 +1745,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, return r; } - cio2 = devm_kzalloc(dev, sizeof(*cio2), GFP_KERNEL); + cio2 = kzalloc(sizeof(*cio2), GFP_KERNEL); if (!cio2) return -ENOMEM; cio2->pci_dev = pci_dev; @@ -1767,6 +1790,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, mutex_init(&cio2->lock); cio2->media_dev.dev = dev; + cio2->media_dev.ops = &cio2_mdev_ops; strscpy(cio2->media_dev.model, CIO2_DEVICE_NAME, sizeof(cio2->media_dev.model)); cio2->media_dev.hw_revision = 0; @@ -1774,7 +1798,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, media_device_init(&cio2->media_dev); r = media_device_register(&cio2->media_dev); if (r < 0) - goto fail_mutex_destroy; + goto fail_media_device_put; cio2->v4l2_dev.mdev = &cio2->media_dev; r = v4l2_device_register(dev, &cio2->v4l2_dev); @@ -1808,35 +1832,33 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, fail_clean_notifier: v4l2_async_nf_unregister(&cio2->notifier); - v4l2_async_nf_cleanup(&cio2->notifier); - cio2_queues_exit(cio2); + fail_v4l2_device_unregister: v4l2_device_unregister(&cio2->v4l2_dev); + fail_media_device_unregister: media_device_unregister(&cio2->media_dev); - media_device_cleanup(&cio2->media_dev); -fail_mutex_destroy: - mutex_destroy(&cio2->lock); - cio2_fbpt_exit_dummy(cio2); +fail_media_device_put: + media_device_put(&cio2->media_dev); return r; } static void cio2_pci_remove(struct pci_dev *pci_dev) { struct cio2_device *cio2 = pci_get_drvdata(pci_dev); + unsigned int i; media_device_unregister(&cio2->media_dev); + for (i = 0; i < CIO2_QUEUES; i++) + vb2_video_unregister_device(&cio2->queue[i].vdev); v4l2_device_unregister(&cio2->v4l2_dev); v4l2_async_nf_unregister(&cio2->notifier); - v4l2_async_nf_cleanup(&cio2->notifier); - cio2_queues_exit(cio2); - cio2_fbpt_exit_dummy(cio2); - media_device_cleanup(&cio2->media_dev); - mutex_destroy(&cio2->lock); pm_runtime_forbid(&pci_dev->dev); pm_runtime_get_noresume(&pci_dev->dev); + + media_device_put(&cio2->media_dev); } static int __maybe_unused cio2_runtime_suspend(struct device *dev) From patchwork Wed Dec 20 10:37:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499913 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 6559E208C9 for ; Wed, 20 Dec 2023 10:37:32 +0000 (UTC) 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="HI98N/Yv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068652; x=1734604652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4vQ1P4LGqxbJ7uxsk6Jqsh18rVWDSKFSxKOC9Nf9ryM=; b=HI98N/YvWPaOa9C+P6JpTbs4iASLPFA0kd0WTBX+TF5c3DBCqF6n9s/M GfQ4KQHBbyikDH6wDjm9AqY9ci3LbyG3kgqABfpDMwFe1Np1mrpLIIr/T ihjRMJOq14HOEr39vxH+AeXbP0AA17lFvg/CfSJ0GAkgikp22mmK1J5DE qtdu6DdeNZo9Bv3G+S1SfDiqbs5Mm3/fdAMrYO5FHLzw55TmR6qWILN2G lKh6hpcm8GgLtsVWyIIELoB2clwGRI8rKEOe2be+8dFJ12oqbnuytK8VP KyD/Lp+7CxtpX60HblJ5efM3ID/yO5U5Y3Us3s8ufqls0RNCozBglwfKf g==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174392" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174392" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544274" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544274" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:31 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 7922D11FC49; Wed, 20 Dec 2023 12:37:28 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 23/29] media: vimc: Release resources on media device release Date: Wed, 20 Dec 2023 12:37:07 +0200 Message-Id: <20231220103713.113386-24-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Release all the resources when the media device is related, moving away form the struct v4l2_device used for that purpose. Signed-off-by: Sakari Ailus --- drivers/media/test-drivers/vimc/vimc-core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c index af127476e920..3e59f8c256c7 100644 --- a/drivers/media/test-drivers/vimc/vimc-core.c +++ b/drivers/media/test-drivers/vimc/vimc-core.c @@ -264,13 +264,12 @@ static int vimc_add_subdevs(struct vimc_device *vimc) return 0; } -static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev) +static void vimc_mdev_release(struct media_device *mdev) { struct vimc_device *vimc = - container_of(v4l2_dev, struct vimc_device, v4l2_dev); + container_of_const(mdev, struct vimc_device, mdev); vimc_release_subdevs(vimc); - media_device_cleanup(&vimc->mdev); kfree(vimc->ent_devs); kfree(vimc); } @@ -336,6 +335,10 @@ static int vimc_register_devices(struct vimc_device *vimc) return ret; } +static const struct media_device_ops vimc_mdev_ops = { + .release = vimc_mdev_release, +}; + static int vimc_probe(struct platform_device *pdev) { const struct font_desc *font = find_font("VGA8x16"); @@ -369,12 +372,12 @@ static int vimc_probe(struct platform_device *pdev) snprintf(vimc->mdev.bus_info, sizeof(vimc->mdev.bus_info), "platform:%s", VIMC_PDEV_NAME); vimc->mdev.dev = &pdev->dev; + vimc->mdev.ops = &vimc_mdev_ops; media_device_init(&vimc->mdev); ret = vimc_register_devices(vimc); if (ret) { - media_device_cleanup(&vimc->mdev); - kfree(vimc); + media_device_put(&vimc->mdev); return ret; } /* @@ -382,7 +385,6 @@ static int vimc_probe(struct platform_device *pdev) * if the registration fails, we release directly from probe */ - vimc->v4l2_dev.release = vimc_v4l2_dev_release; platform_set_drvdata(pdev, vimc); return 0; } @@ -397,6 +399,7 @@ static void vimc_remove(struct platform_device *pdev) media_device_unregister(&vimc->mdev); v4l2_device_unregister(&vimc->v4l2_dev); v4l2_device_put(&vimc->v4l2_dev); + media_device_put(&vimc->mdev); } static void vimc_dev_release(struct device *dev) From patchwork Wed Dec 20 10:37:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499914 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 B27DA22060 for ; Wed, 20 Dec 2023 10:37:33 +0000 (UTC) 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="ljVEerAw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068654; x=1734604654; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sRLZ1emkDYhb5x7smdmo1s2AjGA9Ic8j2ytBQpH0Jv4=; b=ljVEerAw9F3ZPadg8W14gGD3GW1o/XnwZr7SJdiSlfEoFJKw4xdI0qYx l6R0ARb8Av2S+QCwG3jeN3EjQeDE2CRuFt5aJU8yFSfPM0kpwHsJe4B1r 2oO91hlWNkFpxvVfsj98xY3LCCbk/XtmipuPz1AtbT6kLbOg3E+wrWx/u xRc3e81/c1Pwv+GOzbZCQEqwdX6/pWQN0Y9pARYBXKCGf+YzK7ctKWcPU qLOzsaaVkRdB8wP8rOidi0geqg8xT7iiInvt9rfE04y9OeFeCD/GunGrp xzbrjDnGrnYNiUPOXTclEN39Ly58DfAYzkWDdtuUs1wHBSwwKvP1ozkc2 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174398" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174398" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544275" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544275" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:32 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 3C1241201D0; Wed, 20 Dec 2023 12:37:29 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 24/29] media: Documentation: Document how Media device resources are released Date: Wed, 20 Dec 2023 12:37:08 +0200 Message-Id: <20231220103713.113386-25-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Document that after unregistering, Media device memory resources are released by the release() callback rather than by calling media_device_cleanup(). Also add that driver memory resources should be bound to the Media device, not V4L2 device. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- Documentation/driver-api/media/mc-core.rst | 18 ++++++++++++++++-- include/media/media-device.h | 6 ++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst index 2456950ce8ff..346f67760671 100644 --- a/Documentation/driver-api/media/mc-core.rst +++ b/Documentation/driver-api/media/mc-core.rst @@ -46,13 +46,27 @@ Drivers initialise media device instances by calling :c:func:`media_device_init()`. After initialising a media device instance, it is registered by calling :c:func:`__media_device_register()` via the macro ``media_device_register()`` and unregistered by calling -:c:func:`media_device_unregister()`. An initialised media device must be -eventually cleaned up by calling :c:func:`media_device_cleanup()`. +:c:func:`media_device_unregister()`. The resources of an unregistered media +device will be released by the ``release()`` callback of :c:type:`media_device` +ops, which will be called when the last user of the media device has released it +calling :c:func:`media_device_put()`. + +The ``release()`` callback is the way all the resources of the media device are +released once :c:func:`media_device_init()` has been called. This is also +relevant during device driver's probe function as the ``release()`` callback +will also have to be able to safely release the resources related to a partially +initialised media device. Note that it is not allowed to unregister a media device instance that was not previously registered, or clean up a media device instance that was not previously initialised. +Media device and driver's per-device context +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Drivers should use the struct media_device_ops ``release()`` callback to release +their own resources and not e.g. that of the struct v4l2_device. + Entities ^^^^^^^^ diff --git a/include/media/media-device.h b/include/media/media-device.h index c6816be0eee8..98e1892f1b51 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -250,8 +250,10 @@ void media_device_init(struct media_device *mdev); * * @mdev: pointer to struct &media_device * - * This function that will destroy the graph_mutex that is - * initialized in media_device_init(). + * This function that will destroy the graph_mutex that is initialized in + * media_device_init(). Note that *only* drivers that do not manage releasing + * the memory of th media device itself call this function. This function is + * thus effectively DEPRECATED. */ void media_device_cleanup(struct media_device *mdev); From patchwork Wed Dec 20 10:37:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499915 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 D2EFE22095 for ; Wed, 20 Dec 2023 10:37:33 +0000 (UTC) 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="ITN0I0zm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068654; x=1734604654; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Efa1tkqAq4Bbb7bmvP72snA5g2Goxea4SG3ZSO1mFaI=; b=ITN0I0zmylsQjHMWJRkzxIO8NTynR5Fw4HF7a0Xw1rNNIlFDgkcKV2NR oEFnLhJ1FLsFhW+8+bMQRWuQxtBXX+jlI+Qz/5sDmdIhxTAulvAwRSBV3 6geyCb/XB9f4Mc0jPbN2OJRqhL0aaIwC+f/n11jheN/Y8iC5r/gIbMGay 9nN4oyeyFAj+hCnTrxcEbvqsjul8wjKSkcvLrNR0KhwWLdU6BqIPAGUKZ MaY4znYS5j5VoSuT4VeKrm3Z/6GMTzX8HIKd9N/05GoiKDDDX9T8HgdmP isCNBqrK6rUsY0WBG0BnoInUkW2qX3bn9L9xduuANqzOCHVQMfUBkM9Bh w==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174403" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174403" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544276" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544276" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:32 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 0CF6812068E; Wed, 20 Dec 2023 12:37:29 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 25/29] media: mc: Add per-file-handle data support Date: Wed, 20 Dec 2023 12:37:09 +0200 Message-Id: <20231220103713.113386-26-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 4ea05e42dafb..04d376015526 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -150,6 +150,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 @@ -170,17 +171,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; } @@ -189,8 +188,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 98e1892f1b51..83b8ea44463d 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 d050f54f252a..b0efdde4ffd8 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 * @media_dev: pointer to struct &media_device @@ -137,7 +151,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 */ From patchwork Wed Dec 20 10:37:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499916 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 9E6F2208C9 for ; Wed, 20 Dec 2023 10:37:34 +0000 (UTC) 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="ZPs1opUt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068655; x=1734604655; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=na+12loNNkFs8gMbbIPJRpDsi4oBG8NL0QQSFhxlflY=; b=ZPs1opUtbqi7YdQ9QR/4oFFGfciBK9JQcnVtNKBXhPhkD7B90jq8zxHu 6pPaTTHgO1ArESP9L5r44CRMYevKrjSW0WtLzlvmi4hlQrFeZginyREp2 /ELvcqQG4Nd9YOpPQSZLUSOTIsdmbelRKDy0BMq9r+UMuOohNT2xpAga6 fn/r/xH3AGzfAP6AP5GHS2stLhfAYybud4AO2haAAKDpIrRJGW2GG4jwq dfkYgwcS0iAM29w89bmh/loPI0GqBei3bY7Zq5JNbD1wHm3LKpeRhPcfM XFtWQ0Gfw7aPni4H0uxAsSaO0AL2rfq168MkSdGHXtjoq49Q5niOgGs/+ Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174408" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174408" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544278" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544278" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:33 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 9721B120706; Wed, 20 Dec 2023 12:37:30 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 26/29] media: mc: Maintain a list of open file handles in a media device Date: Wed, 20 Dec 2023 12:37:10 +0200 Message-Id: <20231220103713.113386-27-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The list of file handles is needed to deliver media events as well as for other purposes in the future. Signed-off-by: Sakari Ailus --- drivers/media/mc/mc-device.c | 23 ++++++++++++++++++++++- drivers/media/mc/mc-devnode.c | 2 +- include/media/media-devnode.h | 4 +++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 67a39cb63f89..9cc055deeec9 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -45,9 +45,11 @@ static inline void __user *media_get_uptr(__u64 arg) return (void __user *)(uintptr_t)arg; } -static int media_device_open(struct file *filp) +static int media_device_open(struct media_devnode *devnode, struct file *filp) { + struct media_device *mdev = to_media_device(devnode); struct media_device_fh *fh; + unsigned long flags; fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (!fh) @@ -55,12 +57,23 @@ static int media_device_open(struct file *filp) filp->private_data = &fh->fh; + spin_lock_irqsave(&mdev->fh_list_lock, flags); + list_add(&fh->mdev_list, &mdev->fh_list); + spin_unlock_irqrestore(&mdev->fh_list_lock, flags); + return 0; } static int media_device_close(struct file *filp) { + struct media_devnode *devnode = media_devnode_data(filp); + struct media_device *mdev = to_media_device(devnode); struct media_device_fh *fh = media_device_fh(filp); + unsigned long flags; + + spin_lock_irqsave(&mdev->fh_list_lock, flags); + list_del(&fh->mdev_list); + spin_unlock_irqrestore(&mdev->fh_list_lock, flags); kfree(fh); @@ -769,11 +782,13 @@ void media_device_init(struct media_device *mdev) INIT_LIST_HEAD(&mdev->pads); INIT_LIST_HEAD(&mdev->links); INIT_LIST_HEAD(&mdev->entity_notify); + INIT_LIST_HEAD(&mdev->fh_list); mutex_init(&mdev->req_queue_mutex); mutex_init(&mdev->graph_mutex); ida_init(&mdev->entity_internal_idx); atomic_set(&mdev->request_id, 0); + spin_lock_init(&mdev->fh_list_lock); mdev->devnode.release = media_device_release; media_devnode_init(&mdev->devnode); @@ -824,6 +839,8 @@ EXPORT_SYMBOL_GPL(__media_device_register); void media_device_unregister(struct media_device *mdev) { + unsigned long flags; + if (mdev == NULL) return; @@ -834,6 +851,10 @@ void media_device_unregister(struct media_device *mdev) } mutex_unlock(&mdev->graph_mutex); + spin_lock_irqsave(&mdev->fh_list_lock, flags); + list_del_init(&mdev->fh_list); + spin_unlock_irqrestore(&mdev->fh_list_lock, flags); + device_remove_file(&mdev->devnode.dev, &dev_attr_model); dev_dbg(mdev->dev, "Media device unregistering\n"); media_devnode_unregister(&mdev->devnode); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 04d376015526..0b5c24828e24 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -171,7 +171,7 @@ static int media_open(struct inode *inode, struct file *filp) get_device(&devnode->dev); mutex_unlock(&media_devnode_lock); - ret = devnode->fops->open(filp); + ret = devnode->fops->open(devnode, filp); if (ret) { put_device(&devnode->dev); return ret; diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index b0efdde4ffd8..840f7ae852d3 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -21,6 +21,8 @@ #include #include +struct media_devnode; + /* * Flag to mark the media_devnode struct as registered. Drivers must not touch * this flag directly, it will be set and cleared by media_devnode_register and @@ -49,7 +51,7 @@ struct media_file_operations { __poll_t (*poll) (struct file *, struct poll_table_struct *); long (*ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); - int (*open) (struct file *); + int (*open) (struct media_devnode *, struct file *); int (*release) (struct file *); }; From patchwork Wed Dec 20 10:37:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499918 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 C4BC722060 for ; Wed, 20 Dec 2023 10:37:35 +0000 (UTC) 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="Yn0VU+th" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068656; x=1734604656; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nPi3JMGp0gtSZuI8E+B44cm0m6EVcZxK+vx4DPFzbts=; b=Yn0VU+thi3Ujm05tQtezKYK1+dTTiplatCTfPpaiOnwPcwvsCHRy24px LRo/xmea/dLiuAeGSOObPykXwVrpVQpKf+RunUlnH/0zzrguBIv3PExOV LLcGFd3OyAvHAt+BTx+Dbx36sr/VlDjMAyWvx8/+vjxjPOn0pTl+sJ8Sg jKjnHJtR3VvAO1UxnEeVaR9HoMugEh04QD3zEkNuakzVK0quJcTf0U5ND ZByrQvPXzGNtDEKq2/VSfLS1rhQBxwKx3KOqhs5/453jMtYWZt8InYmZ7 gYJ/UezLcqDHo9DVtmFTeoytV1hCjVM5brlmcmPL2p7qY8aFWC6cVuYK3 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174412" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174412" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544280" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544280" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:33 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 2E862120788; Wed, 20 Dec 2023 12:37:31 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 27/29] media: mc: Implement best effort media device removal safety sans refcount Date: Wed, 20 Dec 2023 12:37:11 +0200 Message-Id: <20231220103713.113386-28-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Add a new helper data structures media_devnode_compat_ref and media_devnode_cdev. The latter is used to prevent user space from calling IOCTLs or other system calls to the media device that has been already unregistered and the former to help with obtaining the container struct (either media_devnode_compat_ref or media_devnode) in media_open(). The media device's memory may of course still be released during the call but there is only so much that can be done to this without the driver managing the lifetime of the resources it needs somehow. This patch should be reverted once all drivers have been converted to manage their resources' lifetime. Signed-off-by: Sakari Ailus --- drivers/media/mc/mc-device.c | 55 ++++++++++---- drivers/media/mc/mc-devnode.c | 117 ++++++++++++++++++++++------- drivers/media/v4l2-core/v4l2-dev.c | 28 +++++-- include/media/media-devnode.h | 64 +++++++++++++++- 4 files changed, 210 insertions(+), 54 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 9cc055deeec9..97d63146b344 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -55,6 +55,8 @@ static int media_device_open(struct media_devnode *devnode, struct file *filp) if (!fh) return -ENOMEM; + fh->fh.ref = devnode->ref; + filp->private_data = &fh->fh; spin_lock_irqsave(&mdev->fh_list_lock, flags); @@ -66,14 +68,19 @@ static int media_device_open(struct media_devnode *devnode, struct file *filp) static int media_device_close(struct file *filp) { - struct media_devnode *devnode = media_devnode_data(filp); - struct media_device *mdev = to_media_device(devnode); - struct media_device_fh *fh = media_device_fh(filp); - unsigned long flags; + struct media_device_fh *fh; - spin_lock_irqsave(&mdev->fh_list_lock, flags); - list_del(&fh->mdev_list); - spin_unlock_irqrestore(&mdev->fh_list_lock, flags); + fh = media_device_fh(filp); + + if (!fh->fh.ref || atomic_read(&fh->fh.ref->registered)) { + struct media_devnode *devnode = media_devnode_data(filp); + struct media_device *mdev = to_media_device(devnode); + unsigned long flags; + + spin_lock_irqsave(&mdev->fh_list_lock, flags); + list_del(&fh->mdev_list); + spin_unlock_irqrestore(&mdev->fh_list_lock, flags); + } kfree(fh); @@ -812,28 +819,45 @@ EXPORT_SYMBOL_GPL(media_device_cleanup); int __must_check __media_device_register(struct media_device *mdev, struct module *owner) { + struct media_devnode_compat_ref *ref = NULL; int ret; + if (!mdev->ops || !mdev->ops->release) { + ref = kzalloc(sizeof(*mdev->devnode.ref), GFP_KERNEL); + if (!ref) + return -ENOMEM; + } + /* Register the device node. */ mdev->devnode.fops = &media_device_fops; mdev->devnode.parent = mdev->dev; + mdev->devnode.ref = ref; /* Set version 0 to indicate user-space that the graph is static */ mdev->topology_version = 0; ret = media_devnode_register(&mdev->devnode, owner); if (ret < 0) - return ret; + goto out_put_ref; + + ret = device_create_file(media_devnode_dev(&mdev->devnode), + &dev_attr_model); + if (ret < 0) + goto out_devnode_unregister; - ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); - if (ret < 0) { - media_devnode_unregister(&mdev->devnode); - return ret; - } dev_dbg(mdev->dev, "Media device registered\n"); return 0; + +out_devnode_unregister: + media_devnode_unregister(&mdev->devnode); + +out_put_ref: + if (ref) + put_device(&ref->dev); + + return ret; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -855,9 +879,12 @@ void media_device_unregister(struct media_device *mdev) list_del_init(&mdev->fh_list); spin_unlock_irqrestore(&mdev->fh_list_lock, flags); - device_remove_file(&mdev->devnode.dev, &dev_attr_model); + device_remove_file(media_devnode_dev(&mdev->devnode), &dev_attr_model); dev_dbg(mdev->dev, "Media device unregistering\n"); media_devnode_unregister(&mdev->devnode); + + if (mdev->devnode.ref) + put_device(&mdev->devnode.ref->dev); } EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 0b5c24828e24..d64bb501a3ee 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -71,19 +71,45 @@ static void media_devnode_release(struct device *cd) devnode->release(devnode); } +static void media_devnode_ref_release(struct device *cd) +{ + struct media_devnode_compat_ref *ref = + container_of_const(cd, struct media_devnode_compat_ref, dev); + + media_devnode_free_minor(ref->minor); + + kfree(ref); +} + +struct media_devnode *to_media_devnode(struct device *dev) +{ + if (dev->release == media_devnode_release) + return container_of(dev, struct media_devnode, dev); + + return container_of(dev, struct media_devnode_compat_ref, dev)->devnode; +} + static struct bus_type media_bus_type = { .name = MEDIA_NAME, }; +static bool media_devnode_is_registered_compat(struct media_devnode_fh *fh) +{ + if (fh->ref) + return atomic_read(&fh->ref->registered); + + return media_devnode_is_registered(fh->devnode); +} + static ssize_t media_read(struct file *filp, char __user *buf, size_t sz, loff_t *off) { struct media_devnode *devnode = media_devnode_data(filp); + if (!media_devnode_is_registered_compat(filp->private_data)) + return -EIO; if (!devnode->fops->read) return -EINVAL; - if (!media_devnode_is_registered(devnode)) - return -EIO; return devnode->fops->read(filp, buf, sz, off); } @@ -92,10 +118,10 @@ static ssize_t media_write(struct file *filp, const char __user *buf, { struct media_devnode *devnode = media_devnode_data(filp); + if (!media_devnode_is_registered_compat(filp->private_data)) + return -EIO; if (!devnode->fops->write) return -EINVAL; - if (!media_devnode_is_registered(devnode)) - return -EIO; return devnode->fops->write(filp, buf, sz, off); } @@ -104,7 +130,7 @@ static __poll_t media_poll(struct file *filp, { struct media_devnode *devnode = media_devnode_data(filp); - if (!media_devnode_is_registered(devnode)) + if (!media_devnode_is_registered_compat(filp->private_data)) return EPOLLERR | EPOLLHUP; if (!devnode->fops->poll) return DEFAULT_POLLMASK; @@ -116,14 +142,9 @@ __media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, long (*ioctl_func)(struct file *filp, unsigned int cmd, unsigned long arg)) { - struct media_devnode *devnode = media_devnode_data(filp); - if (!ioctl_func) return -ENOTTY; - if (!media_devnode_is_registered(devnode)) - return -EIO; - return ioctl_func(filp, cmd, arg); } @@ -131,6 +152,9 @@ static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct media_devnode *devnode = media_devnode_data(filp); + if (!media_devnode_is_registered_compat(filp->private_data)) + return -EIO; + return __media_ioctl(filp, cmd, arg, devnode->fops->ioctl); } @@ -141,6 +165,9 @@ static long media_compat_ioctl(struct file *filp, unsigned int cmd, { struct media_devnode *devnode = media_devnode_data(filp); + if (!media_devnode_is_registered_compat(filp->private_data)) + return -EIO; + return __media_ioctl(filp, cmd, arg, devnode->fops->compat_ioctl); } @@ -149,6 +176,7 @@ static long media_compat_ioctl(struct file *filp, unsigned int cmd, /* Override for the open function */ static int media_open(struct inode *inode, struct file *filp) { + struct media_devnode_cdev *mcdev; struct media_devnode *devnode; struct media_devnode_fh *fh; int ret; @@ -160,7 +188,12 @@ static int media_open(struct inode *inode, struct file *filp) * a crash. */ mutex_lock(&media_devnode_lock); - devnode = container_of(inode->i_cdev, struct media_devnode, cdev); + mcdev = container_of(inode->i_cdev, struct media_devnode_cdev, cdev); + if (mcdev->is_compat_ref) + devnode = container_of(mcdev, struct media_devnode_compat_ref, + mcdev)->devnode; + else + devnode = container_of(mcdev, struct media_devnode, mcdev); /* return ENXIO if the media device has been removed already or if it is not registered anymore. */ if (!media_devnode_is_registered(devnode)) { @@ -168,12 +201,12 @@ static int media_open(struct inode *inode, struct file *filp) return -ENXIO; } /* and increase the device refcount */ - get_device(&devnode->dev); + get_device(media_devnode_dev(devnode)); mutex_unlock(&media_devnode_lock); ret = devnode->fops->open(devnode, filp); if (ret) { - put_device(&devnode->dev); + put_device(media_devnode_dev(devnode)); return ret; } @@ -186,15 +219,21 @@ static int media_open(struct inode *inode, struct file *filp) /* Override for the release function */ static int media_release(struct inode *inode, struct file *filp) { - struct media_devnode *devnode = media_devnode_data(filp); - - devnode->fops->release(filp); + struct media_devnode_fh *fh = filp->private_data; + struct device *dev; + + if (!fh->ref) { + dev = &fh->devnode->dev; + fh->devnode->fops->release(filp); + } else { + dev = &fh->ref->dev; + fh->ref->release(filp); + } filp->private_data = NULL; - /* decrease the refcount unconditionally since the release() - return value is ignored. */ - put_device(&devnode->dev); + put_device(dev); + return 0; } @@ -222,6 +261,9 @@ void media_devnode_init(struct media_devnode *devnode) int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner) { + struct media_devnode_compat_ref *ref = devnode->ref; + struct cdev *cdev; + struct device *dev; int minor; int ret; @@ -243,18 +285,31 @@ int __must_check media_devnode_register(struct media_devnode *devnode, devnode->minor = minor; /* Part 2: Initialize the media and character devices */ - cdev_init(&devnode->cdev, &media_devnode_fops); - devnode->cdev.owner = owner; - kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); - - devnode->dev.bus = &media_bus_type; - devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor); + cdev = ref ? &ref->mcdev.cdev : &devnode->mcdev.cdev; + cdev_init(cdev, &media_devnode_fops); + cdev->owner = owner; + kobject_set_name(&cdev->kobj, "media%d", devnode->minor); + + if (!ref) { + dev = &devnode->dev; + } else { + ref->mcdev.is_compat_ref = true; + device_initialize(&ref->dev); + atomic_set(&ref->registered, 1); + ref->devnode = devnode; + ref->minor = devnode->minor; + ref->release = devnode->fops->release; + dev = &ref->dev; + dev->release = media_devnode_ref_release; + } + dev->bus = &media_bus_type; + dev->devt = MKDEV(MAJOR(media_dev_t), devnode->minor); if (devnode->parent) - devnode->dev.parent = devnode->parent; - dev_set_name(&devnode->dev, "media%d", devnode->minor); + dev->parent = devnode->parent; + dev_set_name(dev, "media%d", devnode->minor); /* Part 3: Add the media and character devices */ - ret = cdev_device_add(&devnode->cdev, &devnode->dev); + ret = cdev_device_add(cdev, dev); if (ret < 0) { pr_err("%s: cdev_device_add failed\n", __func__); goto cdev_add_error; @@ -279,11 +334,15 @@ void media_devnode_unregister(struct media_devnode *devnode) if (!media_devnode_is_registered(devnode)) return; + if (devnode->ref) + atomic_set(&devnode->ref->registered, 0); + mutex_lock(&media_devnode_lock); clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); mutex_unlock(&media_devnode_lock); - cdev_device_del(&devnode->cdev, &devnode->dev); + cdev_device_del(devnode->ref ? &devnode->ref->mcdev.cdev : + &devnode->mcdev.cdev, media_devnode_dev(devnode)); } /* diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index c1e4995eaf5c..e18e7199ed83 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -179,7 +179,7 @@ static void v4l2_device_release(struct device *cd) bool v4l2_dev_has_release = v4l2_dev->release; #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = v4l2_dev->mdev; - bool mdev_has_release = mdev && mdev->ops && mdev->ops->release; + bool mdev_has_ref = mdev && mdev->devnode.ref; #endif mutex_lock(&videodev_lock); @@ -212,12 +212,24 @@ static void v4l2_device_release(struct device *cd) } #endif - /* Release video_device and perform other - cleanups as needed. */ + /* + * Put struct media_devnode_compat_ref here as indicated by + * mdev_has_ref. mdev may be released by vdev->release() below. + */ +#ifdef CONFIG_MEDIA_CONTROLLER + if (mdev && mdev_has_ref) + media_device_put(mdev); +#endif + + /* Release video_device and perform other cleanups as needed. */ vdev->release(vdev); #ifdef CONFIG_MEDIA_CONTROLLER - if (mdev) + /* + * Put a reference to struct media_device acquired in + * video_register_media_controller(). + */ + if (mdev && !mdev_has_ref) media_device_put(mdev); /* @@ -225,16 +237,18 @@ static void v4l2_device_release(struct device *cd) * embedded in the same driver's context struct so having a release * callback in both is a bug. */ - WARN_ON(v4l2_dev_has_release && mdev_has_release); + WARN_ON(v4l2_dev_has_release && !mdev_has_ref); #endif /* * Decrease v4l2_device refcount, but only if the media device doesn't - * have a release callback. + * have a release callback. Otherwise one could expect accessing + * released memory --- driver's context struct refcounted already via + * struct media_device. */ if (v4l2_dev_has_release #ifdef CONFIG_MEDIA_CONTROLLER - && !mdev_has_release + && mdev_has_ref #endif ) v4l2_device_put(v4l2_dev); diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 840f7ae852d3..85d54e2c9a97 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -41,8 +41,6 @@ struct media_devnode; * @compat_ioctl: pointer to the function that will handle 32 bits userspace * calls to the ioctl() syscall on a Kernel compiled with 64 bits. * @open: pointer to the function that implements open() syscall - * @release: pointer to the function that will release the resources allocated - * by the @open function. */ struct media_file_operations { struct module *owner; @@ -55,9 +53,56 @@ struct media_file_operations { int (*release) (struct file *); }; +/** + * struct media_devnode_cdev - Workaround for drivers not managing media device + * lifetime - character device + * + * Store the characeter device and whether this is a compatibility reference or + * not. struct media_devnode_cdev is embedded in either struct + * media_devnode_compat_ref or struct media_devnode. + * + * @cdev: the chracter device + * @is_compat_ref: Is this a compatibility reference or not? + */ +struct media_devnode_cdev { + struct cdev cdev; + bool is_compat_ref; +}; + +/** + * struct media_devnode_compat_ref - Workaround for drivers not managing media + * device lifetime - reference + * + * The purpose if this struct is to support drivers that do not manage the + * lifetime of their respective media devices to avoid the worst effects of + * this, namely an IOCTL call on an open file handle to a device that has been + * unbound causing a kernel oops systematically. This is not a fix. The proper, + * reliable way to handle this is to manage the resources used by the + * driver. This struct and its use can be removed once all drivers have been + * converted. + * + * @dev: struct device that remains in place as long as any reference remains + * @cdev: the related character device + * @devnode: a pointer back to the devnode + * @release: pointer to the function that will release the resources + * allocated by the @open function. + * @registered: is this device registered? + * @minor: the minor number of the media devnode + */ +struct media_devnode_compat_ref { + struct device dev; + struct media_devnode_cdev mcdev; + struct media_devnode *devnode; + int (*release)(struct file *); + atomic_t registered; + unsigned int minor; +}; + /** * struct media_devnode_fh - Media device node file handle * @devnode: pointer to the media device node + * @ref: media device compat ref, if the driver does not manage media + * device lifetime * * 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 @@ -67,6 +112,7 @@ struct media_file_operations { */ struct media_devnode_fh { struct media_devnode *devnode; + struct media_devnode_compat_ref *ref; }; /** @@ -80,6 +126,8 @@ struct media_devnode_fh { * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants * @release: release callback called at the end of ``media_devnode_release()`` * routine at media-device.c. + * @ref: reference for providing best effort memory safety in device + * removal * * This structure represents a media-related device node. * @@ -92,7 +140,7 @@ struct media_devnode { /* sysfs */ struct device dev; /* media device */ - struct cdev cdev; /* character device */ + struct media_devnode_cdev mcdev; /* character device + compat status */ struct device *parent; /* device parent */ /* device info */ @@ -101,10 +149,18 @@ struct media_devnode { /* callbacks */ void (*release)(struct media_devnode *devnode); + + /* compat reference */ + struct media_devnode_compat_ref *ref; }; +static inline struct device *media_devnode_dev(struct media_devnode *devnode) +{ + return devnode->ref ? &devnode->ref->dev : &devnode->dev; +} + /* dev to media_devnode */ -#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) +struct media_devnode *to_media_devnode(struct device *dev); /** * media_devnode_init - initialise a media devnode From patchwork Wed Dec 20 10:37:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499917 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 0FC2A2231D for ; Wed, 20 Dec 2023 10:37:36 +0000 (UTC) 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="SL2ngBBW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068656; x=1734604656; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GM7xgpgktcL56dQNEFGyQPFoQmRP0ehv7t2mbRo1xzk=; b=SL2ngBBWGZpppEPIk68kbcvil+q+Vpj3KNJMOA3Jm8islVy+PdSoG3Tx qnH3aFgLnCHT8L0YxQXyPXhmmhVKZZ+73fz94eaRQ0zV0rnmPqLBRwtpP YZkKVK1dsRLBQX0OxsaYeNl6hqGBd0QAtROo05AstoxAKJOvkpHVO1i7K aCIABA5bUvWbtBszyoWG5yuA/Eg8MhgLjCj1a8VD+MZSHK+upEuEOxxm0 Kc6r9hm+agke9Rp8+852ye2s9c4neSdNM15xpvkGLgaDjlOywLhrTkNpf AobOMn/4KojENOfrzr8CGKPvO+Q7J+EmW8D1TKI7jNPIgML3l4oWhUqjf g==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174415" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174415" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544283" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544283" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:34 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id CB15D11FB5E; Wed, 20 Dec 2023 12:37:31 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 28/29] media: mc: Warn about drivers not releasing media device safely Date: Wed, 20 Dec 2023 12:37:12 +0200 Message-Id: <20231220103713.113386-29-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 The media device and associated resources may be released only when its memory is no longer used. Warn about drivers not doing this, but instead releasing the resources at driver unbind time. Signed-off-by: Sakari Ailus --- drivers/media/mc/mc-device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 97d63146b344..a1ca2a56269d 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -826,6 +826,9 @@ int __must_check __media_device_register(struct media_device *mdev, ref = kzalloc(sizeof(*mdev->devnode.ref), GFP_KERNEL); if (!ref) return -ENOMEM; + + dev_warn(mdev->dev, + "Set mdev release op to safely release resources!\n"); } /* Register the device node. */ From patchwork Wed Dec 20 10:37:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 13499919 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 3DC0622326 for ; Wed, 20 Dec 2023 10:37:37 +0000 (UTC) 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="iX9gECs1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703068657; x=1734604657; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sQFKBCLy6uAbidiSmPj8eSrjfRAtpGGhL2ie4zL4ztY=; b=iX9gECs1c3ZlXrXWS+jhWU2D6eq+pm4alniF2QymINc3sgUckv6T0Tz6 DlGz9t/1cIE9ce5n60otrshlmqNNflIF8PAOlAr+sXnrgJiHqbP+YLZuv pu/pDyIdeujAcTPilmIaxh1MqDABgVbvQJ+Jg/g8+zc3SAWsyfBRbuJZB 11H5cSH1t7NsvJx8aJhS9LuJKzR68PhanVjCdM2B27SHoRi54CCjeAVvX 0f2d2s+7O4VbHzsy5RjV0vNFX/AjgprzzPGnl7hIkyWv+aOz45mXaytKu 0E7CAg53aFUPYUlqCT055oYkzzfPc3VUCMJtsePO9nnKSe6ehaZwLKr3b Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="9174418" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="9174418" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="769544284" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="769544284" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 02:37:34 -0800 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 4F1A712098A; Wed, 20 Dec 2023 12:37:32 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Hans Verkuil Subject: [PATCH v2 29/29] media: Documentation: Document media device memory safety helper Date: Wed, 20 Dec 2023 12:37:13 +0200 Message-Id: <20231220103713.113386-30-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231220103713.113386-1-sakari.ailus@linux.intel.com> References: <20231220103713.113386-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 Document how the best effort memory safety helper for accessing media device works, and that drivers should be converted to refcount the media device. Signed-off-by: Sakari Ailus --- drivers/media/mc/mc-devnode.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index d64bb501a3ee..ef8e57a307a6 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -258,6 +258,32 @@ void media_devnode_init(struct media_devnode *devnode) devnode->minor = -1; } +/* + * Best effort media device lifetime management for old drivers + * + * Drivers that do not manage the lifetime of the media device are provided with + * a best effort lifetime management support. This means that as the driver does + * not release the media device once all users are gone but when the device is + * unbound, there are bound to be (brief) moments when released memory may get + * accessed. All drivers should be converted to release their memory at a safe + * time, i.e. provide a release callback in struct media_file_operations to do + * so. This is especially important for drivers for devices that are + * unpluggable, e.g. USB devices. + * + * A second struct device is used to manage the lifetime of a helper object, + * struct media_devnode_compat_ref. For a media device, one is initialised in + * media_devnode_register and put in media_devnode_unregister. This object is + * also used as the device of the media character device so file handles to the + * media device have a reference to this object. When the media device is + * released, any file handle retains a reference to this helper that also + * contains the media device's registration status. If a media device is + * released and a user space process attempts to access the file handle, an + * error is returned. + * + * The struct device in struct media_devnode is put at media_device_cleanup and + * uses an empty release callback, reflecting the expectation the driver will + * release the memory of the media device at unbind time. + */ int __must_check media_devnode_register(struct media_devnode *devnode, struct module *owner) {