From patchwork Tue Aug 8 12:56:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 9888103 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 55B64601EB for ; Tue, 8 Aug 2017 12:56:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 474A8288B9 for ; Tue, 8 Aug 2017 12:56:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3BAF2288DE; Tue, 8 Aug 2017 12:56:24 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI 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 CDF8A288B9 for ; Tue, 8 Aug 2017 12:56:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752352AbdHHM4U (ORCPT ); Tue, 8 Aug 2017 08:56:20 -0400 Received: from galahad.ideasonboard.com ([185.26.127.97]:47382 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752341AbdHHM4T (ORCPT ); Tue, 8 Aug 2017 08:56:19 -0400 Received: from avalon.bb.dnainternet.fi (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804]) by galahad.ideasonboard.com (Postfix) with ESMTPSA id B82A8208F5; Tue, 8 Aug 2017 14:55:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1502196911; bh=obXepscjmEL2qvdZkYQGNdzHMXMyhqCmJygBJtrLIAk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vbt2GEZW6gvrItWldtHgb38XqTbRzrC8nXiTeJSRXGFta1QR7iykKDY4GTObqDyr4 T6mM40gdLZO3wts3dXo7SGsj4lr5DZaasZXKiTJseI0+/2izvuAoHJvEFQWbc/CnT2 AvGOeUaONNdsQDVMcPu2rEPBXGlF+BAex2GpY+kg= From: Laurent Pinchart To: Hans Verkuil Cc: linux-media@vger.kernel.org, Guennadi Liakhovetski Subject: [PATCH 4/5] uvcvideo: Convert from using an atomic variable to a reference count Date: Tue, 8 Aug 2017 15:56:23 +0300 Message-Id: <20170808125624.11328-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170808125624.11328-1-laurent.pinchart@ideasonboard.com> References: <20170808125624.11328-1-laurent.pinchart@ideasonboard.com> 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 From: Guennadi Liakhovetski 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 | 25 +++++++++---------------- drivers/media/usb/uvc/uvcvideo.h | 2 +- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 4f463bf2b877..0fc8a736ed17 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1802,8 +1802,9 @@ static int uvc_scan_device(struct uvc_device *dev) * already been canceled by the USB core. There is no need to kill the * interrupt URB manually. */ -static void uvc_delete(struct uvc_device *dev) +static void uvc_delete(struct kref *kref) { + struct uvc_device *dev = container_of(kref, struct uvc_device, ref); struct list_head *p, *n; uvc_status_cleanup(dev); @@ -1854,11 +1855,7 @@ 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); + kref_put(&dev->ref, uvc_delete); } /* @@ -1870,10 +1867,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 +1881,7 @@ 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. - */ - if (atomic_dec_and_test(&dev->nstreams)) - uvc_delete(dev); + kref_put(&dev->ref, uvc_delete); } static int uvc_register_video(struct uvc_device *dev, @@ -1946,7 +1939,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 +2024,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 296b69bb3fb2..34c7ee6cc9e5 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;