From patchwork Mon Jun 10 10:05:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803148 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 D84B0768EF for ; Mon, 10 Jun 2024 10:05:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013950; cv=none; b=ODGfV0hktUWK5LXlj9nQqovcLuUYRT0zHz8t1IaBmPn3AujGLZTbxRROv9c+AgHoZhX0jgd64lXSQwqn7B5DOCRxJ0TMrKIuAV6/E01df8a2509gOjH3pCfY2fp59ZnTh3WBCqhHOZIwycindaqb9YPzeC39kEe++CEv3RhLkS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013950; c=relaxed/simple; bh=Q2vBl9qOunJV4jY8YF3rus/ZAZLYNDmEVjWtREu/9So=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Srqw6c808iL3pWy7Sz5otsSW/sTsVoI3by6utUOnPM2rDtiEoOOPGBbuZwYTKf/H+EAQjD+j5iiWfHyPACj79xUelES40UPeZq3O2ruoGabv9wcMC/3w8HQmVYWGGWtqMYC0Zd9flXg4Pzc39yIvGJlLNuZoP8M1ZsjSdMI8Iyc= 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=a68ShmmO; arc=none smtp.client-ip=198.175.65.18 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="a68ShmmO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013949; x=1749549949; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Q2vBl9qOunJV4jY8YF3rus/ZAZLYNDmEVjWtREu/9So=; b=a68ShmmOoxLvkmjbttCBYbCXyz6VJIVbTFx5DlfQkgKTL8PWkr1VAHso KwwdFKrckEhEnbyKDeVBe1nVfYNA1/21vq8EVANPsCgIoBteS3tvgDcBY DEocMBNkuNVnuRZZS7RtksptHONGuh6n5SehUdnk3SgbWePQHaLJQKb9y GybW0jLRSIbeFL9UmarjSmZ5VZDOHPSDskDROw87dJr+4jrfOIczY+XWa cGdKO7IOHbpBP8wnRRXXuud8qV3QmK6yS/pqPjGVbTdCpSWzwGdXCaPBu sIYSH5dalvgxG+VoSV7hTTElKr0Y1MzO2IgFSN5/YBVBD2KhfBZJMS9q9 g==; X-CSE-ConnectionGUID: +Ondn74cSuy5TtBf9GzDHQ== X-CSE-MsgGUID: EhdziyChQ4uyI11rx7s2gA== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819876" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819876" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:45 -0700 X-CSE-ConnectionGUID: 5KGUSuijTrSqB6lq2xBw9Q== X-CSE-MsgGUID: 03PPfaLmR/mlW8Ta992+9Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137333" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:43 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id D6366120381; Mon, 10 Jun 2024 13:05:40 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuG-004eCS-2m; Mon, 10 Jun 2024 13:05:40 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 02/26] Revert "media: utilize new cdev_device_add helper function" Date: Mon, 10 Jun 2024 13:05:06 +0300 Message-Id: <20240610100530.1107771-3-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 | 22 ++++++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 6f940df0230c..3bacfd0ecd83 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 22905c1d86e8..d36bc9891f3f 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -239,22 +239,31 @@ 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 */ set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - ret = cdev_device_add(&devnode->cdev, &devnode->dev); + ret = cdev_add(&devnode->cdev, MKDEV(MAJOR(media_dev_t), + devnode->minor), 1); if (ret < 0) { - clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - 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; + } + return 0; +device_add_error: + cdev_del(&devnode->cdev); cdev_add_error: mutex_lock(&media_devnode_lock); clear_bit(devnode->minor, media_devnode_nums); @@ -274,9 +283,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 Mon Jun 10 10:05:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803150 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 1ED691DA4C for ; Mon, 10 Jun 2024 10:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013946; cv=none; b=qWahvFUwS32BxjMZg6rkGn+Gs6gQIqxgj54raH69Uw60oaj4wecmSXgqf8QAnjcC2TpVU1LGMDajOe0QZ52Kk8FR8QHtbj3oBg5M9IypQn1gs5I86mb1/LP9l0G/a+1beJxFu7RrH31Q0lVHbKHRNhzfGQ9PWc5N6qlms1Ea2BM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013946; c=relaxed/simple; bh=KsvJRKZ9Llu3UpzHCID3iW6gYGU4lT98FRuSYvLZ5IQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NpmAVl046BwH77/tRa41zr9GdUIiVO4ZZ6hiR+K01DLYokgdhdgUn278ljIFLBpIaY0T82vXEjwZkuu1uISKinrRJiyKBUUDkROPt83mr5eTyB5DsD3p9vN9hHVolPiP4DZS1Prn/lfLoX2ChyfjSOHazK/OzkUADxABX3DgCRA= 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=AGjAoNhP; arc=none smtp.client-ip=198.175.65.18 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="AGjAoNhP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013945; x=1749549945; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KsvJRKZ9Llu3UpzHCID3iW6gYGU4lT98FRuSYvLZ5IQ=; b=AGjAoNhPYPbLXkuA6k195e6wopdrtAQP4PNkwc7yxuBqVA4z2SMUGler osP2tg8t/0UuOjJE+1iTS2V2AJFpSfOtArFxa3CZTl8CpY5VPqRXfCJZb 33rtnfpqpiGr7MOY6LSUGoRyxRntBikHk1rsa36vKPqtm5Dfv5FzQjZ4J cEDZix1MXGn2MxIAiNJ+eJ9HbGKbittu3J4R42b8gltTpswI/Q6v3tjha 0XWLh98yk/OQhy5zLoL383bcsunUv3liTsF38bOt8oOLB+jF98+pjP5YJ zPrFaFd6BO0oLH8RzziTx8OQiWcl86/WaBjuAzImZPqkETp5UYZNNK7jA w==; X-CSE-ConnectionGUID: 70Jp25wLT5yNHZy8sPefSw== X-CSE-MsgGUID: XmEp34JaQJS4aKCpIaMufw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819864" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819864" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:45 -0700 X-CSE-ConnectionGUID: cXCoFxygS52rAACont8haw== X-CSE-MsgGUID: Fi9FtNaIRD6mq9sKPWbExg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137329" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:43 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id DB48A1205BF; Mon, 10 Jun 2024 13:05:40 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuG-004eCW-2p; Mon, 10 Jun 2024 13:05:40 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 03/26] Revert "[media] media: fix use-after-free in cdev_put() when app exits after driver unbind" Date: Mon, 10 Jun 2024 13:05:07 +0300 Message-Id: <20240610100530.1107771-4-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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. 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 | 6 ++--- drivers/media/mc/mc-devnode.c | 47 ++++++++++++++--------------------- 2 files changed, 21 insertions(+), 32 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 d36bc9891f3f..bc223a427020 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 const struct bus_type media_bus_type = { @@ -189,7 +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); - return 0; } @@ -220,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; } @@ -230,19 +232,9 @@ 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); set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); @@ -250,27 +242,30 @@ int __must_check media_devnode_register(struct media_device *mdev, 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; } 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; } @@ -282,13 +277,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 Mon Jun 10 10:05:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803147 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 623B775817 for ; Mon, 10 Jun 2024 10:05:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013952; cv=none; b=HZg+XflUZOZx/uoZ/Yl4L/S/Z3qWSJ7y9+hp1WujdQhGRGrKzChYz8H+ra9rPsuTPOCJ1T8ZmdlnN8SZ3/LHxq0Zfcy+H3iSKy3ykXd/0XRNgwB//6OFBxvdypaGQzt5rknezkOziFa5a39IIxrbtxsU3DehhXKEhe7nCK8d88k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013952; c=relaxed/simple; bh=HyOG+obzA3lxQt6iGtMe16dffGHTQG1lkMpum4Twabs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iuzJercx49DNwNab7NM+YGw+E6c7vqmInL62GayizGt9NGY2Iiitgw5EuQPNPoLbdSiB4rhsXXcAKDAhshwAt34CXYQZAjzR7yO2z3PR/MXDs4CK74gi6uw5f+/Tut1r4+LA5sYd8FYfcYGmcTczPvZLI1daFZSy2AQfSpzUj2A= 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=YKK9IR8m; arc=none smtp.client-ip=198.175.65.18 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="YKK9IR8m" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013952; x=1749549952; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HyOG+obzA3lxQt6iGtMe16dffGHTQG1lkMpum4Twabs=; b=YKK9IR8mh/l0ci87v/jhZwkP9usitGYQu/B6VEnNjVxhOnEMMVhXubvt OV0WJ/Vaz3EuSyhLrVIgnDbQDIJpxEsit/+7NN8pdVWHV70DpGfBxlTGP 7r8q/EGUml9IVLtbvbep6VK89KyWSAIWPBkYiC37L23O65V8SdD0QbzNY MMyMbb/1Y7gDethizNFQ0mJaDVtT4nRcDz53Bhrhp2TL2NvK+kU+SXEm8 fLk3HeU6nCBBYkQHXQR9dx0gpCAfes22BzSHitX+6tutR8G28wV64nZob Zq++d/xTWJFqoYorUOIePY7xRoHBnf66zdLCt+lGDJLAPADTjfzVqnaaZ A==; X-CSE-ConnectionGUID: +nreRy9CRMenWCdlJyc/Jg== X-CSE-MsgGUID: B2bu/vDsSt+DPkNgRW6LJw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819908" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819908" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 X-CSE-ConnectionGUID: 3pSihWtIT6igVFjbmvLGqw== X-CSE-MsgGUID: 8LKtv7RnQTaAculyrVk5yQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137340" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:47 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id EC35212074D; Mon, 10 Jun 2024 13:05:40 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuG-004eCs-33; Mon, 10 Jun 2024 13:05:40 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 07/26] media: mc: Drop media_dev description from struct media_devnode Date: Mon, 10 Jun 2024 13:05:11 +0300 Message-Id: <20240610100530.1107771-8-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- include/media/media-devnode.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 1117d1dfd6bf..024dfb98a6fd 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -55,7 +55,6 @@ struct media_file_operations { /** * struct media_devnode - Media device node - * @media_dev: pointer to struct &media_device * @fops: pointer to struct &media_file_operations with media device ops * @dev: pointer to struct &device containing the media controller device * @cdev: struct cdev pointer character device From patchwork Mon Jun 10 10:05:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803145 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 8E4A678C7A for ; Mon, 10 Jun 2024 10:05:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013954; cv=none; b=haehEQUfeNR5iMGRu7HhFFF3DQDJiw8DUCCISGH5mLgtO5ZpskASsgFbtJsQ8zKe9yaEhi33YF3zaSal2xhkQ4j30tqJ/u/3ebTQAtYjWI/13PF+WMHbCB54U4zkeSv7jAveiSk2swyqRMDx1c9kKvzgFp29cC2fa5xa+EtW3ac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013954; c=relaxed/simple; bh=TKR1odmfIubdY4xEWjZh17liN+dbJy2GC6GvZT/yQT8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=He5xdgHQozPWyTgPPVb3P0c2oIi7rh/MhoSZGW23lLd2ztNd3gM1BkZkx6nD2yZkIMNDlKHmEt029sCLpunfRxFAwRcQVA8L+4wgCi7FJJpLNrplDeQNdUGsqTIJBS61U1Nqi6rUcWm7n2n66/NFPq9BR1psSwDIz6tVrP77hdE= 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=WunF74uw; arc=none smtp.client-ip=198.175.65.18 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="WunF74uw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013954; x=1749549954; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TKR1odmfIubdY4xEWjZh17liN+dbJy2GC6GvZT/yQT8=; b=WunF74uw2WMLAaDzEOvEDxWp4goMgPdzzSA9LH045QSfH3e1PSe6iW/J Vm54OkxEeO8xq7ZaEmjRpdthfvF0YNirXE25t8B6I+HaMbO/qf1BUwYOo yJpb7mukLogQmPJJEMaz06FwoFpJKs236NXkzlS8zma6pWK2NJM8JPBji DqHV+FpjJRZA8Mq+g2kc/EmAgXdUfCDAEnr2hgXCiL6//ARP/qvdQJd4x iUu2PqAup6WDBFKN+W1I/Sz6aXW4jlI7w6Pnta59gen8TxDG/X97I3j4l P9TYLFQPguBwgu96ABDXIduDjPEM7y1c/L6kJcLK3y4S0hQpBwyhYZR+m w==; X-CSE-ConnectionGUID: YhFDgSt9S4u7ga2pY+o9cw== X-CSE-MsgGUID: Kzsm06BHTxiU04fNQt2baw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819916" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819916" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 X-CSE-ConnectionGUID: edNiaai9TFqlQ89EdfDuXQ== X-CSE-MsgGUID: 57ecsFn3QW2/jQ4x8hYKgw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137345" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:47 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 0D59B120AD4; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eD7-05; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 10/26] media: mc: Clear minor number reservation at unregistration time Date: Mon, 10 Jun 2024 13:05:14 +0300 Message-Id: <20240610100530.1107771-11-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 Clear the media device's minor number reservation at unregister time as there's no need to keep it reserved for longer. This makes it possible to reserve the same minor right after unregistration. Signed-off-by: Sakari Ailus --- drivers/media/mc/mc-devnode.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 38c472498f9e..f7ecabe469a4 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -49,13 +49,6 @@ static void media_devnode_release(struct device *cd) { 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); - - mutex_unlock(&media_devnode_lock); - /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) devnode->release(devnode); @@ -268,6 +261,10 @@ void media_devnode_unregister(struct media_devnode *devnode) cdev_del(&devnode->cdev); device_unregister(&devnode->dev); + + mutex_lock(&media_devnode_lock); + clear_bit(devnode->minor, media_devnode_nums); + mutex_unlock(&media_devnode_lock); } /* From patchwork Mon Jun 10 10:05:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803146 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 D47BD78C66 for ; Mon, 10 Jun 2024 10:05:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013954; cv=none; b=qsRKQMZpbxtrVKQfq9F1C4RKRIAN9snNTOjGMHE8pkRSFes2xsO8pXnSfgRGkyM+plHrRJRJulbwnof21+QUiGy0/ywKpBS7ia7yh8ORcjHVe1ahuEnyqRbM7kopmRB0WpVH/fN1BWgezgW5dcq/mGq01z9QM4DH/2PNb5+FQZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013954; c=relaxed/simple; bh=PmCwrMROkTUi8FldAYOCFWn7IoFdAP7YQppK8BOWf4Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TY9WliRL9r7H9jx1WMQuEZUtp+oeDaAW//KcwBOj+NipTjd5LKCfKUYo2z+8aXiZv51bzxYc5GCZ4+cSC9BvEp/vLFf0pnweIFCBlT/GsSDqKMuckbYf8bu+QH+k1I5gc4JIkkLcp/Aar0a4KEH9YboR3BR64y6l01KCa/UkemA= 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=czSvHTsU; arc=none smtp.client-ip=198.175.65.18 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="czSvHTsU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013953; x=1749549953; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PmCwrMROkTUi8FldAYOCFWn7IoFdAP7YQppK8BOWf4Y=; b=czSvHTsU/ub1ZnEqD3U9CGX5c9MIVo/4BQ9q+pVujavKTdhbSHCMaYA9 s9a4ElpolV8axb84U7PN2muBa+n3KIiVduWt0Snc6qDZ0/tbJVW8g8vWf 2rdlF1n4wWu33ogQ39SzxUOksW1+ViV5e+JIHGTmlZsZqnY5bWWiOmadb ET/D8Qpog22apEA8mACMM8BiYQlPrfRcGtbkm3mawpLIO4IFmDXt5rFZH h63rD2WhxRry1lu+i/6bojjhJGK42u/ZQKo13NERDaVedUcr7yPKQairl PUKr3K3OD5SJ/eESWZWhJ3LZVQ7v/0+ZBn9w/sQJUp7J7ITaoYMIlyqUE g==; X-CSE-ConnectionGUID: RkPtjgPTTHGB+ioLjepneg== X-CSE-MsgGUID: oXJDVL+cQHyoudfPYpqJzQ== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819915" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819915" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 X-CSE-ConnectionGUID: x6cf/17qQNW7l+lbKU0flw== X-CSE-MsgGUID: kdUqRprqTUqHDLk9Io7SHw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137344" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:47 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 12FB1120B7D; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eDC-0B; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 11/26] media: mc: Split initialising and adding media devnode Date: Mon, 10 Jun 2024 13:05:15 +0300 Message-Id: <20240610100530.1107771-12-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 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 propagate the effects of these changes to drivers yet, we want to expose media_device refcounting with media_device_get() and media_device_put() functions first. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- drivers/media/mc/mc-device.c | 18 +++++++++++++----- drivers/media/mc/mc-devnode.c | 18 ++++++++++-------- include/media/media-devnode.h | 19 ++++++++++++++----- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index c0ea08a8fc31..dd4d589a6701 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 err_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 err_unregister; dev_dbg(mdev->dev, "Media device registered\n"); return 0; + +err_unregister: + media_devnode_unregister(&mdev->devnode); +err_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 f7ecabe469a4..214b9b142d90 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -197,6 +197,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) { @@ -228,7 +233,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 */ set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); @@ -244,7 +248,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode, mutex_lock(&media_devnode_lock); clear_bit(devnode->minor, media_devnode_nums); mutex_unlock(&media_devnode_lock); - put_device(&devnode->dev); return ret; } @@ -259,8 +262,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); + cdev_device_del(&devnode->cdev, &devnode->dev); mutex_lock(&media_devnode_lock); clear_bit(devnode->minor, media_devnode_nums); @@ -270,7 +272,7 @@ void media_devnode_unregister(struct media_devnode *devnode) /* * Initialise media for linux */ -static int __init media_devnode_init(void) +static int __init media_devnode_module_init(void) { int ret; @@ -292,14 +294,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 024dfb98a6fd..113c317e6a0e 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -89,6 +89,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 * @@ -99,11 +110,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 Mon Jun 10 10:05:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803144 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 9711C78C98 for ; Mon, 10 Jun 2024 10:05:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013956; cv=none; b=o3O+qDi6+61fPCTlWpFGYICKeQRQK92NoPhd9NG5sm0ye85dL3ujnsOSV00mS2Gpgs98eswquSymUlDXJu3T2Vn+AivwFEFylw2fy9HjZ1ORAdLo6EaIHquAE3n8StzhXiA5gLIa1twXK4FNJmGL992TKiMcrIoytXQBlNjotsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013956; c=relaxed/simple; bh=II6lz7idmJWX19uPmLqcUf7Hfulwjv5ymsaQBoCu7Zc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=j3+p3DKR7ZtxKJY/HvHA/gBIngl7EGevREPSwEAQlyaMinwqeX0OH+u4BfXMpM7mUm2LCbW9zrmBTPnlKSlkZOujMzxvTZzWqpWy2xAwo0Q2GsksB3jwOCA7AlVOtS/HOuWomeJgyL/wP7fx4F+ItJGDbnbJkWgdvrObpgPMN/o= 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=GK7MdAvy; arc=none smtp.client-ip=198.175.65.18 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="GK7MdAvy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013955; x=1749549955; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=II6lz7idmJWX19uPmLqcUf7Hfulwjv5ymsaQBoCu7Zc=; b=GK7MdAvyTKmww9xb/ozfdiX8MZPlw5FQSUdKfGDG3AQOFr1MI/VSp6pi 5YZ04/G7Cj6qxJgKVX1PQ1fzYetj4E0Sj+Uk4dGgrCoigssdKTp70d34B aWzkJSdkGIpcZ6oeEJcFOCh3CSmDhZ5dEhXyVHcyb4h892SMp4+sfIOqy L9k8f0eHvE/qxLedclsyaC+gD0ExQqYM62gLfqvKj4+YbY3UfkPapyYc6 z2x4r7+WpizCPbtTGpm3heHvHXvvWufdZQdA7N4fUBDR4sFt4ODMQbxpo eALVu6szbWnmtK3vLGuVpg1nlWXSCgU6u1Cn/bS7IjRZBW308gFyfdOvV g==; X-CSE-ConnectionGUID: g/4JFNrJS9eGqJdDwmlvhw== X-CSE-MsgGUID: VEu5kitbSkqY6NJkPVQuHw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819921" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819921" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 X-CSE-ConnectionGUID: Dd5fcmnDQsidX2nJbvz/gA== X-CSE-MsgGUID: hIdMH4ltQvOp59f4rUMcrg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137346" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:47 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 1E826120B9A; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eDM-0K; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 13/26] media: mc: Initialise media devnode in media_device_init() Date: Mon, 10 Jun 2024 13:05:17 +0300 Message-Id: <20240610100530.1107771-14-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index f1f3addf7932..f1d89d940fe1 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -711,9 +711,10 @@ 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), mdev->dev); @@ -729,6 +730,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 +746,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 err_put; + return ret; ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); - if (ret < 0) - goto err_unregister; + if (ret < 0) { + media_devnode_unregister(&mdev->devnode); + return ret; + } dev_dbg(mdev->dev, "Media device registered\n"); return 0; - -err_unregister: - media_devnode_unregister(&mdev->devnode); -err_put: - put_device(&mdev->devnode.dev); - - return ret; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -810,7 +805,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 Mon Jun 10 10:05:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803143 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 EB25B7A705 for ; Mon, 10 Jun 2024 10:05:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013957; cv=none; b=I8Tj+UPZAvRXl9ZNjy34c7/Oqm6fxtBhgk6zi1NjuyLXPQWGpwXChY0uKcCdNyVpj5GAkhRBDIjkTEscWrVUkW52YZSJ4ng42fIoMm7jDhTKoB1GsNdKHr5UvldlJa+KFgZvM1Ok9gMmoCRpqxrUka7zYSAvYxvEceUg8iFEkg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013957; c=relaxed/simple; bh=oneBxfx/LYGFbEe8UyCN6amVIqf8WCaK8FFBAKy+UGQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ra9gDXEv7AVGqVXYOAPxh3eUzJijoyP8NphzbnIo2XOBd0eBqubWe6fDawdJW075JdxAR0FUBThz7FHny2shFDziWTGv4Sfzcx/oXmmtoI34ohBhcr2BGy5QRJjfbeF4vSJyXSBThalnvNVBZZwJPf9MdJ9kIBlI6A1F4QuR0sU= 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=mEpNyXx4; arc=none smtp.client-ip=198.175.65.18 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="mEpNyXx4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013956; x=1749549956; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oneBxfx/LYGFbEe8UyCN6amVIqf8WCaK8FFBAKy+UGQ=; b=mEpNyXx4eTLWc/98Z3lUeujKVYX1NUHktZd2fxJZsKuek1BFQbMAr2wC bOEkOapHmHcIAbB99F9JNwMo4TbwbzGJawbR2KuAF/73dQHgXTmHHpFLd N+qLgPIp1x7ovu3SQGXlljrvGOlIXlS4m+oDbG00EAgJU+Sc8aAewasHp XoBFJK4lt/pE8i6e3pycbISwvHvCNSKwUgeX1UNM4BEHIkOAYs+JO9Jgi qbWQquWjXAE+WkxV0ku0Y8C8sirhcI5JTIcw8LkINpjeCMEU6Vd8MRPCk wjXd8mM7gQZtWYv/0dPW1ykhAip1Kqv/m7TFZ8Zcq9gVhA+c/nzoXnC7T A==; X-CSE-ConnectionGUID: HDb+hCCgQTWBC7pztdbGbQ== X-CSE-MsgGUID: PoI3OV9sSeiTCH9AcEyKsw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819931" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819931" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:52 -0700 X-CSE-ConnectionGUID: i6mSsOp/RkqWAMJyMx7NTg== X-CSE-MsgGUID: WDJ6qNJlRe2fT/zvXcDKag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137356" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 2D915120BC1; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eDb-0Y; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 16/26] media: mc: Postpone graph object removal until free Date: Mon, 10 Jun 2024 13:05:20 +0300 Message-Id: <20240610100530.1107771-17-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 | 59 ++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index bbc233e726d2..f1a88edb7573 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,43 +812,11 @@ 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); + if (!media_devnode_is_registered(&mdev->devnode)) 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); dev_dbg(mdev->dev, "Media device unregistering\n"); From patchwork Mon Jun 10 10:05:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803141 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 A64CD7CF16 for ; Mon, 10 Jun 2024 10:05:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013959; cv=none; b=VNvhXjOFSkQaapC2ijmuwAWWWSUoFdW361AHXnFCabIPelWlCzyCl1KqiYqh8afDXOuwy7WbRn6lVBk01U68UyL2viZsQAQBj5iJCC0a4z7Y8GXpWyzXgXvul9CqUpmiV6gC0bKcS8pn+wwkpI2BzQi7uqpsmvLX6BJL+DOD3zU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013959; c=relaxed/simple; bh=+rG7vchsA0u3MasKBPPJoNX+GZxQlI7TKYCl1XWjqSk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nB3lex/MhCGsSsTBcykbzHeG5snqKkUYkiCCtJ0BRn6QSOuApgR3lPo0d0dzyC2tU8pUr74jdYpJw+Nur45mpIO8WY/J6sbplrk8s3HbBj7fgCzXgvWrlMbUomIpkYGF8rAysz2jbQUDxtvDV0h3V54awD0YhlUBM7iq2Enhtks= 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=NSbV51Qq; arc=none smtp.client-ip=198.175.65.18 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="NSbV51Qq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013958; x=1749549958; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+rG7vchsA0u3MasKBPPJoNX+GZxQlI7TKYCl1XWjqSk=; b=NSbV51Qq8lNs30XmsCFkp+WVTXPLr30OAiWeDuieaOrsQ4FHqZDCCq8d tIvHI0royZ6Lur6hHuGwKp3REYyCzFthDiIUUTiZqexvG1uxW0uEWFpKY a0INQy02xNkE2GaAyNc9rWNzTEE7Lryv1ovjTlqlGhThx0xFacylWB4B0 qx/X1clOGb1QREp5tPk+SgfqQ7cxXvGIxgSGIv1iH4wjRurIXY+s19q2f B27+d/ZhZbCyEWP+KBY8NvWYJLQ09ChEbCZ2Eygn9gXlwjtjSzBEI7lIf fzV92hEnOOeOo3MOetn9cVNSr//Gv8K8CJvmTYXQLG4tug1bbJF/GeRIc Q==; X-CSE-ConnectionGUID: 0Gs7KIDyRQauh+c8sQy0vA== X-CSE-MsgGUID: nh9UCBDERPCu77XcSESTOw== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819938" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819938" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:52 -0700 X-CSE-ConnectionGUID: VPT1G7l/TQmJcCWPUhnvZA== X-CSE-MsgGUID: wmEsBFFrQFCzZeUFtbND+w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137358" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 3DE25120BD7; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eDq-0j; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 19/26] media: vimc: Release resources on media device release Date: Mon, 10 Jun 2024 13:05:23 +0300 Message-Id: <20240610100530.1107771-20-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 released, moving away from the struct v4l2_device used for that purpose. This is done to exemplify the use of the media device's release callback. Switch to container_of_const(), too, while we're changing the code anyway. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- 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 Mon Jun 10 10:05:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803140 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 C80D37D3F1 for ; Mon, 10 Jun 2024 10:05:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013960; cv=none; b=i9MCsivCb/hHmo2TItlxHgVMTVdMG/DogFXUxIuiDC+rsTTx/4srtBpOb2V3pHx6WbFoMGYBzjGq1ROT7qF2GYSTEbExClW1f/y5W4plpE9Od1KUYiWBiaV/jk/tpOWF3Xi0C3uGJooAocuKhpnweZB3/d7vTtzdRV91QDhaD5A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013960; c=relaxed/simple; bh=WBJkQRl6HUUCoBTVYVQygl04ebZa2GrobqlbR0Xm2nk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bcm94s6OQFxmmymReno79zkeaWuLd4mmVKLBflz9ll2jKXlMug1uhsctFlkQJCj8Ij5EivETalnPMShlri+mhtoM+q3vpptCCNzOvtUtjFi3tBm4YKPyh6oTpEtJzPiYTrfS5RWnm3IGRAEXy3dldlS7q8q6cJCYzeZr5ij/www= 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=ZYb8fI6H; arc=none smtp.client-ip=198.175.65.18 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="ZYb8fI6H" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013959; x=1749549959; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WBJkQRl6HUUCoBTVYVQygl04ebZa2GrobqlbR0Xm2nk=; b=ZYb8fI6HgSSE3O/EvqvQgMw1eIskazxCNOlRAXvCpVjlmMIA7lbj6goi j5FDMt3K86esCAlpYTyeh7WeNyxkwFTtRRE+dwDwRyP6sBXviPsb9tWt2 HI9JRfO4RNxZUWSLZ3gOd4HA2D6Jwf0y/ouFbZcb0QrJ5FCS4MQDhHvZt NE8AGfbIR4JxkgWIq9wFBolOvLcvAroFPTZo9b4M/53328OhUhg8NlJl8 7kRbb7xcQY5SM0tXxJP6E9ECg9yjtFXlOI+jsaiEE1HzpM5mV2140dvVk 39t5sy1fC0HzV37sDCkAEptg013juwTFyjMwxuXW7HaNr4PB2PiKGmoYc Q==; X-CSE-ConnectionGUID: vBeLtpIiTU6fKVZ0dZQmyg== X-CSE-MsgGUID: f9nUPbecTfqMD1/uB8vCyA== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819955" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819955" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:53 -0700 X-CSE-ConnectionGUID: cF3N9HyXSyOnR16Pn2oDbA== X-CSE-MsgGUID: KFmbbviUSDWwV7lLoB+EKA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137367" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 45CA5120BE5; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eDv-0p; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 20/26] media: Documentation: Document how Media device resources are released Date: Mon, 10 Jun 2024 13:05:24 +0300 Message-Id: <20240610100530.1107771-21-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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..f9108f14d1ed 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 a newly 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 f1afbfc4dca2..fe4625f3f62b 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -252,8 +252,10 @@ static inline void media_device_put(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 Mon Jun 10 10:05:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803139 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 84E347E0FB for ; Mon, 10 Jun 2024 10:05:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013961; cv=none; b=hpWKPxg2reZ0LDnQqLv1pUarTqYseRJYgv1aZIHmDhs8zq2xmy1T57lD+52BSaMtvQ3Sq1WUiGUR/QN5zQ4Ce2NyS3y2obSrZk3t+nWWqD84kof8ldFNygQaoFE5WGzS2Ek+tphEANMpzq/SmK/+VQVwNYPkJlquQQUivehf6Sg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013961; c=relaxed/simple; bh=cniRpn7w2v+7IheGd9rZi7LiUXu7Zbk/Tbks8P8VpEs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=E52Cl6kTQ6wLSkC4YZFItVqYVPLhIe1TOfCQjLTAuMu/Qr3lRG0HFWvRj14qK4KtDVughIwF+OPEKPvZhNRlTIGHAeUR+bdjiK4vDrvj9coRwfFdsodx3p3aqmI+gxVC7438WTSN0RB1oFoBPAJV7XcYNdiq34jd1zP2DNQOGCU= 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=Ant2ii7t; arc=none smtp.client-ip=198.175.65.18 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="Ant2ii7t" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013960; x=1749549960; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cniRpn7w2v+7IheGd9rZi7LiUXu7Zbk/Tbks8P8VpEs=; b=Ant2ii7tLU2iomUjpWGnNXPQvOY0hKfrKRNMrgcjBoSb9Q7bYru3hd1w jeJdwP7wHyxWaGnIzA9lZyvtwSCW26WlkDGNe6ht/qt56jGaY4o1Fluu4 /OkMknDPbqGK4nA7fGeVv7Qws/cbp5sEWuyXYLv9pjSxd9EdTWnscasDq nrnPVe1eeZmUM5tNTZwiwdvKnZBabColPmTmahnNny/VIryiipcqRZef3 syTG4Ts94T+3/m5NPJvvutRhL8Mg80arp2FFTlVR2QAjorAoKHYk8Jsdu 7flXWaB7WTL4jD6YfMFs5pU4S9ImeJ/G8BoZvTeRPfQFN8FdXPpvMuB+8 w==; X-CSE-ConnectionGUID: FcGD2asdTEC+Udcy2HJ/cA== X-CSE-MsgGUID: 7GREwbhNSzuXfhVfh6CfTg== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819951" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819951" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:52 -0700 X-CSE-ConnectionGUID: uboZ+2mLTn+bgSSV8CZ7tw== X-CSE-MsgGUID: s06zcdF6TImZajgSpQLb5Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137361" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 4D4B9120BF8; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eE0-0v; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 21/26] media: mc: Add per-file-handle data support Date: Mon, 10 Jun 2024 13:05:25 +0300 Message-Id: <20240610100530.1107771-22-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 f1a88edb7573..a9505ab4412d 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 f27d5d288a38..26491daaba96 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -133,6 +133,7 @@ static long media_compat_ioctl(struct file *filp, unsigned int cmd, static int media_open(struct inode *inode, struct file *filp) { struct media_devnode *devnode; + struct media_devnode_fh *fh; int ret; /* Check if the media device is available. This needs to be done with @@ -153,17 +154,15 @@ static int media_open(struct inode *inode, struct file *filp) get_device(&devnode->dev); mutex_unlock(&media_devnode_lock); - filp->private_data = devnode; - - if (devnode->fops->open) { - ret = devnode->fops->open(filp); - if (ret) { - put_device(&devnode->dev); - filp->private_data = NULL; - return ret; - } + ret = devnode->fops->open(filp); + if (ret) { + put_device(&devnode->dev); + return ret; } + fh = filp->private_data; + fh->devnode = devnode; + return 0; } @@ -172,8 +171,7 @@ static int media_release(struct inode *inode, struct file *filp) { struct media_devnode *devnode = media_devnode_data(filp); - if (devnode->fops->release) - devnode->fops->release(filp); + devnode->fops->release(filp); filp->private_data = NULL; diff --git a/include/media/media-device.h b/include/media/media-device.h index fe4625f3f62b..f9f7c37e7d57 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -110,6 +110,10 @@ struct media_device_ops { * other operations that stop or start streaming. * @request_id: Used to generate unique request IDs * + * @fh_list: List of file handles in the media device + * (struct media_device_fh.mdev_list). + * @fh_list_lock: Serialise access to fh_list list. + * * This structure represents an abstract high-level media device. It allows easy * access to entities and provides basic media device-level support. The * structure can be allocated directly or embedded in a larger structure. @@ -182,6 +186,9 @@ struct media_device { struct mutex req_queue_mutex; atomic_t request_id; + + struct list_head fh_list; + spinlock_t fh_list_lock; }; /* We don't need to include usb.h here */ diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 113c317e6a0e..e4e8552598eb 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -53,6 +53,20 @@ struct media_file_operations { int (*release) (struct file *); }; +/** + * struct media_devnode_fh - Media device node file handle + * @devnode: pointer to the media device node + * + * This structure serves as a base for per-file-handle data storage. Media + * device node users embed media_devnode_fh in their custom file handle data + * structures and store the media_devnode_fh in the file private_data in order + * to let the media device node core locate the media_devnode corresponding to a + * file handle. + */ +struct media_devnode_fh { + struct media_devnode *devnode; +}; + /** * struct media_devnode - Media device node * @fops: pointer to struct &media_file_operations with media device ops @@ -136,7 +150,9 @@ void media_devnode_unregister(struct media_devnode *devnode); */ static inline struct media_devnode *media_devnode_data(struct file *filp) { - return filp->private_data; + struct media_devnode_fh *fh = filp->private_data; + + return fh->devnode; } /** diff --git a/include/media/media-fh.h b/include/media/media-fh.h new file mode 100644 index 000000000000..6f00744b81d6 --- /dev/null +++ b/include/media/media-fh.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Media device file handle + * + * Copyright (C) 2019--2023 Intel Corporation + */ + +#ifndef MEDIA_FH_H +#define MEDIA_FH_H + +#include +#include + +#include + +/** + * struct media_device_fh - File handle specific information on MC + * + * @fh: The media device file handle + * @mdev_list: This file handle in media device's list of file handles + */ +struct media_device_fh { + struct media_devnode_fh fh; + struct list_head mdev_list; +}; + +static inline struct media_device_fh *media_device_fh(struct file *filp) +{ + return container_of(filp->private_data, struct media_device_fh, fh); +} + +#endif /* MEDIA_FH_H */ From patchwork Mon Jun 10 10:05:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803142 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 93A627BB0A for ; Mon, 10 Jun 2024 10:05:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013958; cv=none; b=eSPi+f0eQwybDAVmAi2vXS1GD1AvOC4/um6Bv6jslEf5V/zMKxjs1GUasVZ89++2EzFYbsxyYHRp0n/+k5kCm9YBu27ID0+XcMmEn4svQXZ0HY2I+aT8pYokCGhk1BuXT84JMibipIkV5xLojXDDvzaHng1lRTHUk633jeLfE+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013958; c=relaxed/simple; bh=K2/wxLLlNsYl2dcQwp+2q7FJblVGtsb+ULyd3kdCsSc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Qvbh4nAyTjDC9r8axSLA5MZunCEWMA1/5WW1r03i8B9EUhb0B2p5zMSjSwiHXk9GqpQom8gBIrvacHLUCILejP2MoE/ZIIeitJjPHsA3rYrXcjjsIK5vtyMJxa0GjEtY1m8a31PVyoV7c4G7mSD6jhpr5c0GZLeOfxoKtmMOXrQ= 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=Q2+IPRri; arc=none smtp.client-ip=198.175.65.18 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="Q2+IPRri" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013957; x=1749549957; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=K2/wxLLlNsYl2dcQwp+2q7FJblVGtsb+ULyd3kdCsSc=; b=Q2+IPRriWkJ6Igy78EwWjcqYq6GovDNzoNx6PbeGecC/+kn7ICjq2KcR wwWwbI9vrJ81hZqBzx8He03MKoIDcrjmg+FIAu/1zZM3fsLJNvTMkvC8w I8ilrwG8ywI3LXmSFr6IqPHy7eID67awriGYtWgjaRBve/o7+pWh+C9dp pc48mfzkc9QoRAWSIAAryG6vEJkdAvJkZu8RrrqLnzpQEpdcTrFLEG5IX rdsUU95SHY+N62eJMf3gUVUUPo0dGsX4h6iX+4WknWKjkLpV4Aq7SUOcM 9S2jLO+/RI0ohYrBvtGrBJ4UQk3k7YSvucx2ofXaPQzpdR7EA+L1dYqgb g==; X-CSE-ConnectionGUID: lWs6KlplT+OidWPdkSFDgQ== X-CSE-MsgGUID: tQkPRs6jSSOM9DMrAFEaUg== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819948" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819948" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:52 -0700 X-CSE-ConnectionGUID: X6XinmKWQfy+2e2Ya4rYcw== X-CSE-MsgGUID: 8dyxWG/cRRmVjDhfyToW3Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137362" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 53754120BFE; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eE5-11; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 22/26] media: mc: Maintain a list of open file handles in a media device Date: Mon, 10 Jun 2024 13:05:26 +0300 Message-Id: <20240610100530.1107771-23-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 | 19 ++++++++++++++++++- drivers/media/mc/mc-devnode.c | 2 +- include/media/media-devnode.h | 4 +++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index a9505ab4412d..46d1b0c9d8be 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -45,8 +45,9 @@ 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; fh = kzalloc(sizeof(*fh), GFP_KERNEL); @@ -55,13 +56,23 @@ static int media_device_open(struct file *filp) filp->private_data = &fh->fh; + spin_lock_irq(&mdev->fh_list_lock); + list_add(&fh->mdev_list, &mdev->fh_list); + spin_unlock_irq(&mdev->fh_list_lock); + 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); + spin_lock_irq(&mdev->fh_list_lock); + list_del(&fh->mdev_list); + spin_unlock_irq(&mdev->fh_list_lock); + kfree(fh); return 0; @@ -769,11 +780,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); @@ -830,6 +843,10 @@ void media_device_unregister(struct media_device *mdev) if (!media_devnode_is_registered(&mdev->devnode)) return; + spin_lock_irq(&mdev->fh_list_lock); + list_del_init(&mdev->fh_list); + spin_unlock_irq(&mdev->fh_list_lock); + 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 26491daaba96..617156963911 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -154,7 +154,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 e4e8552598eb..898fa67ca090 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 Mon Jun 10 10:05:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 803138 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 4B0797E567 for ; Mon, 10 Jun 2024 10:06:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013962; cv=none; b=m8E6I3NHOjERqgUlXC+OY24sB6PdXgOK3g5KKT0mb5wpYZcByDhsvzppeZj0SA2KqE9s6jUe9ZrDy7RAdYO5SQ/EJPs/9AQu4EN6ZtsQcN5iCilNnPYxfrX5V2xDYPB5ktJqzBieJvXJHo7iDvCs9Xmlmh0OtEtok13Bzn04jMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718013962; c=relaxed/simple; bh=LHLQKg3cEBmf6Z/PCGQwI9WkreeyPZoVX5RsiFeOur8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CvHJt9E85Fl/oHx/4Br7g4IzES+Bnq9SrZOvGKdAsxb8Z+qaPRTUilXJ/KmbcZJLT44JWgDnmI4BkCnlMSDY+hiGz7YHXCG2lb1S1V1QlQa/rPjr/zzDnF0QuPl0odAsQRV/nqYqqBv2kCB9dFcwu8vFIvawk7AbqA5z8ek7BaY= 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=eKvNotGE; arc=none smtp.client-ip=198.175.65.18 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="eKvNotGE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718013961; x=1749549961; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LHLQKg3cEBmf6Z/PCGQwI9WkreeyPZoVX5RsiFeOur8=; b=eKvNotGERJZDnECOdohtBOeuyvGXuYz48fCIVFyPXWdqMguYXggHW1Zh Ox1cL1ZJWAcBH3AWPlcWquLZ7Dp8p+aVxNVljE+n72HquQKvqpPWjMSyy 7Vb7+RxD/ixvoTqduI/sxHy2sF0N8S9MMoXVBkAqG5udVXihqGFmcT3n8 6abk5EH7CBdkWTmSV+FDoQpD/hYzLqBi9BfnKyB+qRpm5FtK7KQ/KHR+K teTPseoVgVrqfVmuZ3xihmhpHnjFxTBxwetgcRHrJB2XFlIg7P8n5ElAO BPNML0tk+lVBuAMr4BfXsJ4a5Ri2jg1aBCge1wTdREYi++nGUrYCScQOq A==; X-CSE-ConnectionGUID: 8emCkd+TQyq+9X63cQ4MRA== X-CSE-MsgGUID: IA8ZLxrESHmvPBPnLD0Hng== X-IronPort-AV: E=McAfee;i="6600,9927,11098"; a="14819966" X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="14819966" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:53 -0700 X-CSE-ConnectionGUID: 52EzcAkRQTSt5wkZcNXZpw== X-CSE-MsgGUID: v/GQ2P+qRKas44F3NAcccg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,227,1712646000"; d="scan'208";a="39137363" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jun 2024 03:05:50 -0700 Received: from punajuuri.localdomain (punajuuri.localdomain [192.168.240.130]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 5A08E120C71; Mon, 10 Jun 2024 13:05:41 +0300 (EEST) Received: from sailus by punajuuri.localdomain with local (Exim 4.96) (envelope-from ) id 1sGbuH-004eEA-16; Mon, 10 Jun 2024 13:05:41 +0300 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl Subject: [PATCH v4 23/26] media: mc: Implement best effort media device removal safety sans refcount Date: Mon, 10 Jun 2024 13:05:27 +0300 Message-Id: <20240610100530.1107771-24-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240610100530.1107771-1-sakari.ailus@linux.intel.com> References: <20240610100530.1107771-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 | 49 +++++++++--- drivers/media/mc/mc-devnode.c | 118 ++++++++++++++++++++++------- drivers/media/v4l2-core/v4l2-dev.c | 26 +++++-- include/media/media-device.h | 8 +- include/media/media-devnode.h | 65 ++++++++++++++-- 5 files changed, 210 insertions(+), 56 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 46d1b0c9d8be..8cdd0d46e865 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -54,6 +54,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_irq(&mdev->fh_list_lock); @@ -65,13 +67,16 @@ 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); - spin_lock_irq(&mdev->fh_list_lock); - list_del(&fh->mdev_list); - spin_unlock_irq(&mdev->fh_list_lock); + 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); + + spin_lock_irq(&mdev->fh_list_lock); + list_del(&fh->mdev_list); + spin_unlock_irq(&mdev->fh_list_lock); + } kfree(fh); @@ -810,28 +815,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); @@ -847,9 +869,12 @@ void media_device_unregister(struct media_device *mdev) list_del_init(&mdev->fh_list); spin_unlock_irq(&mdev->fh_list_lock); - 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 617156963911..8cb4e0eec17f 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -49,24 +49,52 @@ 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; + /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) 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); + + 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 const 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); } @@ -75,10 +103,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); } @@ -87,7 +115,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; @@ -99,14 +127,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); } @@ -114,6 +137,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); } @@ -124,6 +150,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); } @@ -132,6 +161,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; @@ -143,7 +173,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)) { @@ -151,12 +186,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; } @@ -169,15 +204,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; } @@ -204,6 +245,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; @@ -222,19 +266,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->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 */ set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - 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; @@ -256,11 +312,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)); mutex_lock(&media_devnode_lock); clear_bit(devnode->minor, media_devnode_nums); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 4bf4398fd2fe..2b19a845c3a4 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_call_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,13 +237,15 @@ 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. */ - if (WARN_ON(v4l2_dev_call_release && mdev_has_release)) + if (WARN_ON(v4l2_dev_call_release && !mdev_has_ref)) v4l2_dev_call_release = false; #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_call_release) v4l2_device_put(v4l2_dev); diff --git a/include/media/media-device.h b/include/media/media-device.h index f9f7c37e7d57..30f9b78d1ce7 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -259,10 +259,10 @@ static inline void media_device_put(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(). 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. + * This function will destroy the graph_mutex that is initialized in + * media_device_init(). Note that only drivers that do not have a proper release + * callback of the struct media_device call this function. This function is thus + * effectively DEPRECATED. */ void media_device_cleanup(struct media_device *mdev); diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 898fa67ca090..5dee1acbc3f7 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -41,8 +41,7 @@ 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. + * @release: pointer to the function that implements release() syscall */ struct media_file_operations { struct module *owner; @@ -55,9 +54,54 @@ 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 + * @mcdev: 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? + */ +struct media_devnode_compat_ref { + struct device dev; + struct media_devnode_cdev mcdev; + struct media_devnode *devnode; + int (*release)(struct file *); + atomic_t registered; +}; + /** * 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,18 +111,21 @@ struct media_file_operations { */ struct media_devnode_fh { struct media_devnode *devnode; + struct media_devnode_compat_ref *ref; }; /** * struct media_devnode - Media device node * @fops: pointer to struct &media_file_operations with media device ops * @dev: pointer to struct &device containing the media controller device - * @cdev: struct cdev pointer character device + * @mcdev: related to the character device * @parent: parent device * @minor: device node minor number * @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. * @@ -91,7 +138,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 */ @@ -100,10 +147,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