Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3378198pxj; Tue, 1 Jun 2021 04:03:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWTQ3DrnQWcqLrsVMomFZgcI1c1CUjYw74b32utqw1vg1B7f2nmDPDwkCBmcMq4qYEibi0 X-Received: by 2002:aa7:db93:: with SMTP id u19mr31957453edt.227.1622545437732; Tue, 01 Jun 2021 04:03:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622545437; cv=none; d=google.com; s=arc-20160816; b=m9YDlvZMmwvZ7okvvrzOghXt02BSO/VfNENukeFFVKLri4kl7DI5v5ciN0peP8hnxs t6HzP2+QM9JeX/MUvLJ0MnIShSbmriqFQd3MU3/3YCqIXjOxVIiCCMvATL9XS1PRnP5z fWIgKMy0byBZ2L2D/t2Agrsk4t8IKlJ0INE0g64pxSHqHX/QyyMaFowjkOQwNFGODnMc 811Bvrj5gScs/JI8iqVQHgi6QEljBMMpZSkSaug99UI14X8wfr/Rowm9j9Wz7W6/lK1U QU2NB6vDR5+u6odjR1deZW0wdtEd2sty+0l1P6+gOyfzy+b9K+yGY9soUzAGZw33RFmH UqvA== 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 :message-id:date:subject:cc:to:from:dkim-signature:dkim-signature; bh=OZt2SiQbqKVL9pvYj4mGQTWSD0tVMGOogS8NZiduT00=; b=lsj3aSxOkrWOm4eIR0JK04K0KTO9EEYkMptaCDTtvcNVFUMX6r2YcAZRxmKS9ir7Ti vApwNfEWUJbfKaGpV02c8iPwD2xnYYXv7iwTa0q1Wed2Mbzdv96El8KVylYQ7Mq5HUUc 7bwB5U0gI2wk+3LSlgd5h+ggc9E7tsgqseDZ+f1acc/Yfs+Yv0DfKrx5z8hLptmsEJMI 2RUb3WbzsA7WUJzEbxnt8MPaE5QawA1EFsU2bF/gT5L4h5oNQDzDKkB2YVkJC9VWWwNU I8eAYPhlkuF06xg/bts9Mk/sZMqfrCr4LXl50XWqoisx+6jBpt82whhadcru9rwk2ZBJ nrNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=MWNqQQTA; 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 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j23si6779015eje.551.2021.06.01.04.03.24; Tue, 01 Jun 2021 04:03:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=MWNqQQTA; 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 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233336AbhFALDq (ORCPT + 99 others); Tue, 1 Jun 2021 07:03:46 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]:58310 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233106AbhFALDo (ORCPT ); Tue, 1 Jun 2021 07:03:44 -0400 Received: from relay2.suse.de (unknown [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id CC74A21922; Tue, 1 Jun 2021 11:02:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1622545322; 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; bh=OZt2SiQbqKVL9pvYj4mGQTWSD0tVMGOogS8NZiduT00=; b=MWNqQQTAPWrmOlAtuvKa8WBdgp2iakD+tbr/NtWDR6pXNnAC/f3aEWeaC4cpYZMO0e01eX IG5j0UHFW/G9JiwC72ndoZoVYpwpwii95wm7a9fwnoVK9DWc0B12LcEEuUqRXUwBxqTUgE j06U5JTDpyl7WVHO71jnH62yLr+mOZk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1622545322; 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; bh=OZt2SiQbqKVL9pvYj4mGQTWSD0tVMGOogS8NZiduT00=; b=0zMTSVcAlHSBbCefV3296LrJgxy2vNFojd02hazCbBlWWKVxJEfGTipOSwBi72LI87YjLo 8hZ4VvZFZVOdyMDg== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id C4AE1A3B83; Tue, 1 Jun 2021 11:02:02 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 8FE9E516FA52; Tue, 1 Jun 2021 13:02:02 +0200 (CEST) From: Hannes Reinecke To: Jens Axboe Cc: Christoph Hellwig , linux-block@vger.kernel.org, Linux Kernel Mailinglist , Hannes Reinecke Subject: [PATCH] block/genhd: use atomic_t for disk_event->block Date: Tue, 1 Jun 2021 13:01:45 +0200 Message-Id: <20210601110145.113365-1-hare@suse.de> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org __disk_unblock_events() will call queue_delayed_work() with a '0' argument under a spin lock. This might cause the queue_work item to be executed immediately, and run into a deadlock in disk_check_events() waiting for the lock to be released. This patch converts the 'blocked' counter into an atomic variable, so we don't need to hold a spinlock anymore when scheduling the workqueue function. Signed-off-by: Hannes Reinecke --- block/genhd.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 9f8cb7beaad1..07e70f0c9c25 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1379,7 +1379,7 @@ struct disk_events { spinlock_t lock; struct mutex block_mutex; /* protects blocking */ - int block; /* event blocking depth */ + atomic_t block; /* event blocking depth */ unsigned int pending; /* events already sent out */ unsigned int clearing; /* events being cleared */ @@ -1439,8 +1439,6 @@ static unsigned long disk_events_poll_jiffies(struct gendisk *disk) void disk_block_events(struct gendisk *disk) { struct disk_events *ev = disk->ev; - unsigned long flags; - bool cancel; if (!ev) return; @@ -1451,11 +1449,7 @@ void disk_block_events(struct gendisk *disk) */ mutex_lock(&ev->block_mutex); - spin_lock_irqsave(&ev->lock, flags); - cancel = !ev->block++; - spin_unlock_irqrestore(&ev->lock, flags); - - if (cancel) + if (atomic_inc_return(&ev->block) == 1) cancel_delayed_work_sync(&disk->ev->dwork); mutex_unlock(&ev->block_mutex); @@ -1467,23 +1461,19 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now) unsigned long intv; unsigned long flags; + if (atomic_dec_return(&ev->block) <= 0) { + mutex_unlock(&ev->block_mutex); + return; + } spin_lock_irqsave(&ev->lock, flags); - - if (WARN_ON_ONCE(ev->block <= 0)) - goto out_unlock; - - if (--ev->block) - goto out_unlock; - intv = disk_events_poll_jiffies(disk); + spin_unlock_irqrestore(&ev->lock, flags); if (check_now) queue_delayed_work(system_freezable_power_efficient_wq, &ev->dwork, 0); else if (intv) queue_delayed_work(system_freezable_power_efficient_wq, &ev->dwork, intv); -out_unlock: - spin_unlock_irqrestore(&ev->lock, flags); } /** @@ -1523,10 +1513,10 @@ void disk_flush_events(struct gendisk *disk, unsigned int mask) spin_lock_irq(&ev->lock); ev->clearing |= mask; - if (!ev->block) + spin_unlock_irq(&ev->lock); + if (!atomic_read(&ev->block)) mod_delayed_work(system_freezable_power_efficient_wq, &ev->dwork, 0); - spin_unlock_irq(&ev->lock); } /** @@ -1638,11 +1628,11 @@ static void disk_check_events(struct disk_events *ev, *clearing_ptr &= ~clearing; intv = disk_events_poll_jiffies(disk); - if (!ev->block && intv) + spin_unlock_irq(&ev->lock); + if (!atomic_read(&ev->block) && intv) queue_delayed_work(system_freezable_power_efficient_wq, &ev->dwork, intv); - spin_unlock_irq(&ev->lock); /* * Tell userland about new events. Only the events listed in @@ -1807,7 +1797,7 @@ static void disk_alloc_events(struct gendisk *disk) ev->disk = disk; spin_lock_init(&ev->lock); mutex_init(&ev->block_mutex); - ev->block = 1; + atomic_set(&ev->block, 1); ev->poll_msecs = -1; INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); @@ -1851,6 +1841,6 @@ static void disk_del_events(struct gendisk *disk) static void disk_release_events(struct gendisk *disk) { /* the block count should be 1 from disk_del_events() */ - WARN_ON_ONCE(disk->ev && disk->ev->block != 1); + WARN_ON_ONCE(disk->ev && atomic_read(&disk->ev->block) != 1); kfree(disk->ev); } -- 2.29.2