From patchwork Tue Mar 12 10:34:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 779901 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E00FC58AC8 for ; Tue, 12 Mar 2024 10:34:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710239673; cv=none; b=PAWEmWlVMuTFQDfLlYgKDJAZ9pM1ws/4HlRJtoDSwwIwRMycOLaCbTOkHFbdDzt/Hgv/FZ1Bvhi5MW0uG5Urq6P/dHXPwm/Umbi/c/VADX4zLP2IRux6gTYLDCmDAJ8thJ3vB/yxgLPVLTt4HQ024n2FQxEPdo0F3JhzhyIwT98= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710239673; c=relaxed/simple; bh=NfyHwqteI3KUApRl+uZSf6G0mbjzscxxSse4risGnh0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QjTSMFfgJWPPofS7OmE+5KreGPVGTmBtYhwmBMJCEbeh2/ffKMzR6zeX3v9QTUKFTxpFeOqWUSMGjNPfeuyfaR/5Suoshxs4dkVqUhRYlXWVQ3/eFb3v2gZdvtHRZCOXxbRBSrEl76ISdoIsDv2WD0RAcqLT+KdnOMyr/3aWxYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Ygw7pKxn; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Ygw7pKxn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1710239672; x=1741775672; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NfyHwqteI3KUApRl+uZSf6G0mbjzscxxSse4risGnh0=; b=Ygw7pKxnM7/Z/x1wTShGBeZFgnyE3tGFKJuzWB/9WApYZSdM1p0HZR9i nyQ/N9Sr2/k0PysUUKvxG7Bow4Jx/vMWt06+6ozpeMJTK9TqjTz0B5v9S SMbN2FPg0lgK2piLHbCVcXbUKg1Y9W9XmxlJ3/YL6ytVwBcGcqYnZdRd9 89JrSUO+dgcfQ96lE0OetrKG7OFRQMA2aEI6bjgIvtwdC+KvMivPLthiS AK7N4PE2wzcBOBrP38drEp241uZ1BepS2EO00u0mbq+lyCwPuEv4Nb5Fp Z7tdAX5qv0TJAHJ+of2ENYtXGAnIUHRrK61rObe7saydtDMsSnhq/ywvk g==; X-IronPort-AV: E=McAfee;i="6600,9927,11010"; a="4794273" X-IronPort-AV: E=Sophos;i="6.07,119,1708416000"; d="scan'208";a="4794273" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Mar 2024 03:34:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,119,1708416000"; d="scan'208";a="16194064" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Mar 2024 03:34:30 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 02300120619; Tue, 12 Mar 2024 12:34:26 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v3 05/26] Revert "[media] media-device: dynamically allocate struct media_devnode" Date: Tue, 12 Mar 2024 12:34:01 +0200 Message-Id: <20240312103422.216484-6-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312103422.216484-1-sakari.ailus@linux.intel.com> References: <20240312103422.216484-1-sakari.ailus@linux.intel.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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. This revert is performed to roll back to a state which is more suitable for the objective: making media device refcountable. 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 +------ sound/usb/media.c | 8 ++-- 8 files changed, 29 insertions(+), 58 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 60dafd3d48ba..186f585545c2 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 const 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 bbd90123a4e7..7add92f45329 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1922,7 +1922,7 @@ static void uvc_unregister_video(struct uvc_device *dev) 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); #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 53d2a16a70b0..c791f3d5ad77 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); } diff --git a/sound/usb/media.c b/sound/usb/media.c index d48db6f3ae65..f97e937378ee 100644 --- a/sound/usb/media.c +++ b/sound/usb/media.c @@ -122,7 +122,7 @@ void snd_media_stream_delete(struct snd_usb_substream *subs) struct media_device *mdev; mdev = mctl->media_dev; - if (mdev && media_devnode_is_registered(mdev->devnode)) { + if (mdev && media_devnode_is_registered(&mdev->devnode)) { media_devnode_remove(mctl->intf_devnode); media_device_unregister_entity(&mctl->media_entity); media_entity_cleanup(&mctl->media_entity); @@ -239,14 +239,14 @@ static void snd_media_mixer_delete(struct snd_usb_audio *chip) if (!mixer->media_mixer_ctl) continue; - if (media_devnode_is_registered(mdev->devnode)) { + if (media_devnode_is_registered(&mdev->devnode)) { media_device_unregister_entity(&mctl->media_entity); media_entity_cleanup(&mctl->media_entity); } kfree(mctl); mixer->media_mixer_ctl = NULL; } - if (media_devnode_is_registered(mdev->devnode)) + if (media_devnode_is_registered(&mdev->devnode)) media_devnode_remove(chip->ctl_intf_media_devnode); chip->ctl_intf_media_devnode = NULL; } @@ -284,7 +284,7 @@ int snd_media_device_create(struct snd_usb_audio *chip, "Couldn't create media mixer entities. Error: %d\n", ret); - if (!media_devnode_is_registered(mdev->devnode)) { + if (!media_devnode_is_registered(&mdev->devnode)) { /* don't register if snd_media_mixer_init() failed */ if (ret) goto create_fail;