From patchwork Fri Jul 28 12:33:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 9868663 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 67AC760382 for ; Fri, 28 Jul 2017 12:33:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6298E288DB for ; Fri, 28 Jul 2017 12:33:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51F98288E0; Fri, 28 Jul 2017 12:33:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E209E288DB for ; Fri, 28 Jul 2017 12:33:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751917AbdG1Mdg (ORCPT ); Fri, 28 Jul 2017 08:33:36 -0400 Received: from mout.gmx.net ([212.227.17.22]:52809 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751806AbdG1Mdf (ORCPT ); Fri, 28 Jul 2017 08:33:35 -0400 Received: from axis700.grange ([87.78.105.5]) by mail.gmx.com (mrgmx101 [212.227.17.168]) with ESMTPSA (Nemesis) id 0MdFwl-1dIiGE1gm3-00IQjr for ; Fri, 28 Jul 2017 14:33:33 +0200 Received: from 200r.grange (200r.grange [192.168.1.16]) by axis700.grange (Postfix) with ESMTP id 3F6928B119 for ; Fri, 28 Jul 2017 14:30:58 +0200 (CEST) Received: from lyakh (uid 1000) (envelope-from g.liakhovetski@gmx.de) id 8059ff by 200r.grange (DragonFly Mail Agent v0.9); Fri, 28 Jul 2017 14:33:25 +0200 From: Guennadi Liakhovetski To: linux-media@vger.kernel.org Cc: Laurent Pinchart , Hans Verkuil , Guennadi Liakhovetski Subject: [PATCH 3/6 v5] uvcvideo: convert from using an atomic variable to a reference count Date: Fri, 28 Jul 2017 14:33:22 +0200 Message-Id: <1501245205-15802-4-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1501245205-15802-1-git-send-email-g.liakhovetski@gmx.de> References: <1501245205-15802-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V03:K0:zHH7EL8yatwk7bejIKnLDxBvzhgsgHYeqfps4KLdgHE5k+yEhq+ X099883o1egIycrM0/HTO/TimetWmGKK8pYiAFjs3bCdS975XPixQthOlSq8UyuZlJtpFv1 1mRPnbhQaPNCVckmfNXauwIowBerh54JVw7ZV3YQVWrupXC8QAGrte1p68KIO61jBM1XeHK n59iCanbnhVlc2BeDf/iA== X-UI-Out-Filterresults: notjunk:1; V01:K0:vJetJba6hGc=:cMx2Mk4RKTYK5a5zH4Aeg5 ThDj79N71C1IMVvjnwasgQpELN8erEBUGisq9tFWRDxoKIzs/z2jbOkdCdPWWXVhfF71CGuNW DV3Amn56MOoe6D3tPvFoNXo+sjKTqhdbuCd2RRweZyI+x8aaxrpgygCbV70ZC3nB1Toi4WNjx aVUUesQVxhPoLpkNQ1V/vzCjTAQOv/5mj3anuANTnnVQolkqsvj1/OyEKo43xWoafmUTscXld x8ccoeDLSa9sM6TfGUzWE0+38xBK48KSJyhoHpixGmmzQeQ9cBVVPoA0eFg1Iz8cJboqqsO3Q bDAMxol2mnxcoAIJf6c49QSPiDBiAOIM3lsEo8fozYS8gsHAqQKDCvM+LKsjZJKS+AOVnwDPL C/XTxhrpSgUi0W08Ngso/UUmKKnFWv2dhAamXc0BfDlqzc0DJmQ6OBVruDYrEp5nr/sHZVk4y 4493voRco05UXcFwmQwkvT8prqmojeqBl6oe0LBArgIlOiIFk4jHrTY1gKmugt+Q77ywrZ9AI wPXMvzFro/nMHnrPuU2s0aIOSTAwsAx1/zTuzOZ9e2oO3tZ6cCVLXC/GcREKW/o/up9sYacEj 9Gurvp+BSGxfchmPAdzQwTqI13vB2fHqjwmZs7a4neaapowvW62rOjEajOlVUrQZ7ghBIKUTR DUYYDRmFxSYgEjJUAnCT2vEsW32xxyyEO/Y8/BYQ0+s4AfpvrE6AzXuB2MaXzH6/ZonWo1MaM 9ZSMTfjY96/1fq5cl3xp5Od6c8mgUrrcGxkL0o39VM0azgqSxk3JlmbfgqIG3RL1zOYFJNXLg 55RlvrL+hoEwhg1T24DEqJQ0HKQLQ== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When adding support for metadata nodes, we'll have to keep video devices registered until all metadata nodes are closed too. Since this has nothing to do with stream counting, replace the nstreams atomic variable with a reference counter. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Laurent Pinchart --- drivers/media/usb/uvc/uvc_driver.c | 31 +++++++++++++++++-------------- drivers/media/usb/uvc/uvcvideo.h | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 70842c5..cfe33bf 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1849,16 +1849,20 @@ static void uvc_delete(struct uvc_device *dev) kfree(dev); } +static void uvc_kref_release(struct kref *kref) +{ + struct uvc_device *dev = container_of(kref, struct uvc_device, ref); + + uvc_delete(dev); +} + static void uvc_release(struct video_device *vdev) { struct uvc_streaming *stream = video_get_drvdata(vdev); struct uvc_device *dev = stream->dev; - /* Decrement the registered streams count and delete the device when it - * reaches zero. - */ - if (atomic_dec_and_test(&dev->nstreams)) - uvc_delete(dev); + /* Decrement the refcount and delete the device when it reaches zero */ + kref_put(&dev->ref, uvc_kref_release); } /* @@ -1870,10 +1874,10 @@ static void uvc_unregister_video(struct uvc_device *dev) /* Unregistering all video devices might result in uvc_delete() being * called from inside the loop if there's no open file handle. To avoid - * that, increment the stream count before iterating over the streams - * and decrement it when done. + * that, increment the refcount before iterating over the streams and + * decrement it when done. */ - atomic_inc(&dev->nstreams); + kref_get(&dev->ref); list_for_each_entry(stream, &dev->streams, list) { if (!video_is_registered(&stream->vdev)) @@ -1884,11 +1888,10 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } - /* Decrement the stream count and call uvc_delete explicitly if there - * are no stream left. + /* Decrement the refcount and call uvc_delete explicitly if there are no + * stream left. */ - if (atomic_dec_and_test(&dev->nstreams)) - uvc_delete(dev); + kref_put(&dev->ref, uvc_kref_release); } static int uvc_register_video(struct uvc_device *dev, @@ -1946,7 +1949,7 @@ static int uvc_register_video(struct uvc_device *dev, else stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; - atomic_inc(&dev->nstreams); + kref_get(&dev->ref); return 0; } @@ -2031,7 +2034,7 @@ static int uvc_probe(struct usb_interface *intf, INIT_LIST_HEAD(&dev->entities); INIT_LIST_HEAD(&dev->chains); INIT_LIST_HEAD(&dev->streams); - atomic_set(&dev->nstreams, 0); + kref_init(&dev->ref); atomic_set(&dev->nmappings, 0); mutex_init(&dev->lock); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 15e415e..f157cf7 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -575,7 +575,7 @@ struct uvc_device { /* Video Streaming interfaces */ struct list_head streams; - atomic_t nstreams; + struct kref ref; /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep;