Received: by 2002:ac0:e350:0:0:0:0:0 with SMTP id g16csp169451imn; Thu, 4 Aug 2022 01:02:53 -0700 (PDT) X-Google-Smtp-Source: AA6agR76EPAgyhSCD/v86TMmnss1oBJB4TakSGasiYcsZJF05sxAkvJ7Kj4cZozSFGEfwHP9KJBB X-Received: by 2002:aa7:cb87:0:b0:43b:e650:6036 with SMTP id r7-20020aa7cb87000000b0043be6506036mr818315edt.350.1659600173497; Thu, 04 Aug 2022 01:02:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659600173; cv=none; d=google.com; s=arc-20160816; b=Jvnpv/6Dg+BKtqZid1KJ0oCQtCqCqySltCqa7peDRgpaOw/nALYKXgjwcIu7l7lwEy yBltXMfMN8wsvSj3a+FBUryq5/Fr4rkP8Y3+WMIRUlMVt1yXtZn9S20HI8iFGsPWc/UG 60CZt+JRzR8BvQ5Efc23Cwmk8sUTW1pQr5Pf3O4dhm1WLkVwR96TIkHlFGxVGDgCHr7w LHSaNeysE1IN97oGA2rJk4HF0LtJnR9DW6MKroS2KOgCNIAMNjvDEkIBALO8phbWamiO q/8n0cwnaWxx0inGyww82cvRa8LFBD0QCTA4dZgfRdDPeGwotzDNfgGYNEWyu7k2vbmf mvsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=9TZHQcktm3QvM1NCb7e4x/dR11ax1XCqjFqzL2pGsCE=; b=kPq+9TLWOEGx5LhiduWiZrxq2rzPuUGKoI0Mg4NQK5z/5H7GttOb2utAbprEDWNumP qrUrpKP1WHGJaJPoQKZbeKH3RMRxG4u6j9ElTXaN4L5N7wVlqwkzFTCrk50kVw/vgIxr kFNo1TZ0Q/9Xr09wv3t0hnwNIvbvQvAPB/B/cw+gfxT2KjESzdhlO93GCYiMHTenLQp/ +sMymlhozJh/7+aYGu9efBCSNITzIGsSHv3CyawrMGC2BL0fWf+pXdDNKEpMBlD1IPOz RdaJM9yHb+IQXoS9m3RY0wZbzSMPR3bkCA7IO4meKlE+YHFmiwzideiudsLPnv6EiPXR olPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=Ke+V8Zju; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g11-20020a1709065d0b00b007262b2de87bsi61602ejt.839.2022.08.04.01.02.27; Thu, 04 Aug 2022 01:02:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=Ke+V8Zju; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239349AbiHDH6q (ORCPT + 99 others); Thu, 4 Aug 2022 03:58:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232615AbiHDH6g (ORCPT ); Thu, 4 Aug 2022 03:58:36 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F93E20F7E for ; Thu, 4 Aug 2022 00:58:35 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D8FEC3745B; Thu, 4 Aug 2022 07:58:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1659599913; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9TZHQcktm3QvM1NCb7e4x/dR11ax1XCqjFqzL2pGsCE=; b=Ke+V8ZjusffCbYuzxT0hFh1CxZ8n4Fers3FYUpY/zF2BtOrs20DwUvzJ1OnyqACokHaxm2 OfIauyXEPzXVAiAzs6/jBNmpXKT50HpTxFmCM2rjN3DQsleDu5h+OUYuo/NoPmpLPZWi9f we8R/TmVsZhpDmPgnlHRWFM/hs0ncJI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1659599913; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9TZHQcktm3QvM1NCb7e4x/dR11ax1XCqjFqzL2pGsCE=; b=pK2uoHfpvUX9m1tdfrTXouSuUoHtao5xaWO17wFI4XVojlN13DRH+HK97nLLmEG4c7/aJE tOPqdrbmDcjGqhCA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B478913AF2; Thu, 4 Aug 2022 07:58:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id UPtCKyl862IlJAAAMHmgww (envelope-from ); Thu, 04 Aug 2022 07:58:33 +0000 From: Takashi Iwai To: dri-devel@lists.freedesktop.org Cc: Dave Airlie , Sean Paul , Thomas Zimmermann , linux-kernel@vger.kernel.org Subject: [PATCH 1/4] drm/udl: Replace semaphore with a simple wait queue Date: Thu, 4 Aug 2022 09:58:23 +0200 Message-Id: <20220804075826.27036-2-tiwai@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220804075826.27036-1-tiwai@suse.de> References: <20220804075826.27036-1-tiwai@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org UDL driver uses a semaphore for controlling the emptiness of FIFO in a slightly funky way. This patch replaces it with a wait queue and controls the emptiness with the standard wait_event*() macro instead, which is a more straightforward implementation. While we are at it, drop the dead code for delayed semaphore down, too. Tested-by: Thomas Zimmermann Signed-off-by: Takashi Iwai --- drivers/gpu/drm/udl/udl_drv.h | 11 +++-- drivers/gpu/drm/udl/udl_main.c | 84 ++++++++++------------------------ 2 files changed, 31 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index cc16a13316e4..e008686ec738 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -34,14 +34,13 @@ struct udl_device; struct urb_node { struct list_head entry; struct udl_device *dev; - struct delayed_work release_urb_work; struct urb *urb; }; struct urb_list { struct list_head list; spinlock_t lock; - struct semaphore limit_sem; + wait_queue_head_t sleep; int available; int count; size_t size; @@ -75,7 +74,13 @@ static inline struct usb_device *udl_to_usb_device(struct udl_device *udl) int udl_modeset_init(struct drm_device *dev); struct drm_connector *udl_connector_init(struct drm_device *dev); -struct urb *udl_get_urb(struct drm_device *dev); +struct urb *udl_get_urb_timeout(struct drm_device *dev, long timeout); + +#define GET_URB_TIMEOUT HZ +static inline struct urb *udl_get_urb(struct drm_device *dev) +{ + return udl_get_urb_timeout(dev, GET_URB_TIMEOUT); +} int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len); void udl_urb_completion(struct urb *urb); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 853f147036f6..67fd41e59b80 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -23,9 +23,6 @@ #define WRITES_IN_FLIGHT (4) #define MAX_VENDOR_DESCRIPTOR_SIZE 256 -#define GET_URB_TIMEOUT HZ -#define FREE_URB_TIMEOUT (HZ*2) - static int udl_parse_vendor_descriptor(struct udl_device *udl) { struct usb_device *udev = udl_to_usb_device(udl); @@ -119,14 +116,6 @@ static int udl_select_std_channel(struct udl_device *udl) return ret < 0 ? ret : 0; } -static void udl_release_urb_work(struct work_struct *work) -{ - struct urb_node *unode = container_of(work, struct urb_node, - release_urb_work.work); - - up(&unode->dev->urbs.limit_sem); -} - void udl_urb_completion(struct urb *urb) { struct urb_node *unode = urb->context; @@ -150,23 +139,13 @@ void udl_urb_completion(struct urb *urb) udl->urbs.available++; spin_unlock_irqrestore(&udl->urbs.lock, flags); -#if 0 - /* - * When using fb_defio, we deadlock if up() is called - * while another is waiting. So queue to another process. - */ - if (fb_defio) - schedule_delayed_work(&unode->release_urb_work, 0); - else -#endif - up(&udl->urbs.limit_sem); + wake_up(&udl->urbs.sleep); } static void udl_free_urb_list(struct drm_device *dev) { struct udl_device *udl = to_udl(dev); int count = udl->urbs.count; - struct list_head *node; struct urb_node *unode; struct urb *urb; @@ -174,23 +153,15 @@ static void udl_free_urb_list(struct drm_device *dev) /* keep waiting and freeing, until we've got 'em all */ while (count--) { - down(&udl->urbs.limit_sem); - - spin_lock_irq(&udl->urbs.lock); - - node = udl->urbs.list.next; /* have reserved one with sem */ - list_del_init(node); - - spin_unlock_irq(&udl->urbs.lock); - - unode = list_entry(node, struct urb_node, entry); - urb = unode->urb; - + urb = udl_get_urb_timeout(dev, MAX_SCHEDULE_TIMEOUT); + if (WARN_ON(!urb)) + break; + unode = urb->context; /* Free each separately allocated piece */ usb_free_coherent(urb->dev, udl->urbs.size, urb->transfer_buffer, urb->transfer_dma); usb_free_urb(urb); - kfree(node); + kfree(unode); } udl->urbs.count = 0; } @@ -210,7 +181,7 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) udl->urbs.size = size; INIT_LIST_HEAD(&udl->urbs.list); - sema_init(&udl->urbs.limit_sem, 0); + init_waitqueue_head(&udl->urbs.sleep); udl->urbs.count = 0; udl->urbs.available = 0; @@ -220,9 +191,6 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) break; unode->dev = udl; - INIT_DELAYED_WORK(&unode->release_urb_work, - udl_release_urb_work); - urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { kfree(unode); @@ -250,7 +218,6 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) list_add_tail(&unode->entry, &udl->urbs.list); - up(&udl->urbs.limit_sem); udl->urbs.count++; udl->urbs.available++; } @@ -260,36 +227,31 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) return udl->urbs.count; } -struct urb *udl_get_urb(struct drm_device *dev) +struct urb *udl_get_urb_timeout(struct drm_device *dev, long timeout) { struct udl_device *udl = to_udl(dev); - int ret = 0; - struct list_head *entry; - struct urb_node *unode; - struct urb *urb = NULL; + struct urb_node *unode = NULL; - /* Wait for an in-flight buffer to complete and get re-queued */ - ret = down_timeout(&udl->urbs.limit_sem, GET_URB_TIMEOUT); - if (ret) { - DRM_INFO("wait for urb interrupted: %x available: %d\n", - ret, udl->urbs.available); - goto error; - } + if (!udl->urbs.count) + return NULL; + /* Wait for an in-flight buffer to complete and get re-queued */ spin_lock_irq(&udl->urbs.lock); + if (!wait_event_lock_irq_timeout(udl->urbs.sleep, + !list_empty(&udl->urbs.list), + udl->urbs.lock, timeout)) { + DRM_INFO("wait for urb interrupted: available: %d\n", + udl->urbs.available); + goto unlock; + } - BUG_ON(list_empty(&udl->urbs.list)); /* reserved one with limit_sem */ - entry = udl->urbs.list.next; - list_del_init(entry); + unode = list_first_entry(&udl->urbs.list, struct urb_node, entry); + list_del_init(&unode->entry); udl->urbs.available--; +unlock: spin_unlock_irq(&udl->urbs.lock); - - unode = list_entry(entry, struct urb_node, entry); - urb = unode->urb; - -error: - return urb; + return unode ? unode->urb : NULL; } int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len) -- 2.35.3