From patchwork Fri Jun 19 20:47:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615083 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 64B86913 for ; Fri, 19 Jun 2020 20:48:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CB7121531 for ; Fri, 19 Jun 2020 20:48:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599711; bh=M3Y9qjq1IYVGWHeSUHNlJod1XBpYY7djWBt6/Vj9Qow=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=MLLdnScp5A+PbLjoMr7p99VrGlYYJnzgoVwbb0+CYswI8W0KA4ffL+GojetZSZMoX hm9CmxaI8oLehhgAPrJYVzJSzzdYcQqccTyCq6TnNC6Kl52xK2Plf5FL1/RGy5cRlU oBJsLPU1a2qOq/IhsYg4RJ5MpTof/A01bnZt/OWc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390636AbgFSUrf (ORCPT ); Fri, 19 Jun 2020 16:47:35 -0400 Received: from mail-pf1-f193.google.com ([209.85.210.193]:46253 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390439AbgFSUrf (ORCPT ); Fri, 19 Jun 2020 16:47:35 -0400 Received: by mail-pf1-f193.google.com with SMTP id b16so4902043pfi.13; Fri, 19 Jun 2020 13:47:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IR8sE8tegFIZFEE9c+9scyuraOZnu4HrFVBH9bLfdFU=; b=BWiTdHtVZURnZz2zUnOZRqyEN4IAj8ni9Tx+85K0mzyck6nx7/CCv6SvE7adtf3suG jpgRAH27IUQTZvs9JlHlv6jIoFuiV/4S0O3sreJ8VJyQDHljXrMyj/WS7ntduWJXVjFG C854TL7m2c1Pg7C2dEu6HMPGrMyi5ioYSyY3HrWvgNM3RlvysGxr6RsURbZsoCdudp97 t0E5y434Zn9KVKkLlIWtH+9P0gkD9mRS9cJNX3F8x/oujX4FEeFqZRE+X0BE/YgX5LJJ 7dv7bCrcFUaZeEWv3ATSzj0phS0tEYJulSSSFI49A0sk2OXBOXGgiKtJbdWjV6ESQnJ3 HkxA== X-Gm-Message-State: AOAM5302q1wELOyZ1DKDZcD2JlLsf+fJGB3m7FSSqi6xyPSGICJPiivQ uYxO+HCaDwhCVIwTUKWFwQQ= X-Google-Smtp-Source: ABdhPJyVHEmV58NGZTznpaBP/xgk4sbNqpUUFbscfauH7CNuFRiXIQShxRF2mjNHNu7Ts1PNNvwYJQ== X-Received: by 2002:a63:20d:: with SMTP id 13mr629527pgc.166.1592599654228; Fri, 19 Jun 2020 13:47:34 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id 127sm4494638pgf.5.2020.06.19.13.47.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:32 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 2A5FE40B6C; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain , Christoph Hellwig Subject: [PATCH v7 1/8] block: add docs for gendisk / request_queue refcount helpers Date: Fri, 19 Jun 2020 20:47:23 +0000 Message-Id: <20200619204730.26124-2-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This adds documentation for the gendisk / request_queue refcount helpers. Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Luis Chamberlain --- block/blk-core.c | 13 +++++++++++++ block/genhd.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 62a4904db921..a0760aac110a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -321,6 +321,13 @@ void blk_clear_pm_only(struct request_queue *q) } EXPORT_SYMBOL_GPL(blk_clear_pm_only); +/** + * blk_put_queue - decrement the request_queue refcount + * @q: the request_queue structure to decrement the refcount for + * + * Decrements the refcount of the request_queue kobject. When this reaches 0 + * we'll have blk_release_queue() called. + */ void blk_put_queue(struct request_queue *q) { kobject_put(&q->kobj); @@ -598,6 +605,12 @@ struct request_queue *blk_alloc_queue(make_request_fn make_request, int node_id) } EXPORT_SYMBOL(blk_alloc_queue); +/** + * blk_get_queue - increment the request_queue refcount + * @q: the request_queue structure to increment the refcount for + * + * Increment the refcount of the request_queue kobject. + */ bool blk_get_queue(struct request_queue *q) { if (likely(!blk_queue_dying(q))) { diff --git a/block/genhd.c b/block/genhd.c index 1a7659327664..f741613d731f 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -876,6 +876,20 @@ static void invalidate_partition(struct gendisk *disk, int partno) bdput(bdev); } +/** + * del_gendisk - remove the gendisk + * @disk: the struct gendisk to remove + * + * Removes the gendisk and all its associated resources. This deletes the + * partitions associated with the gendisk, and unregisters the associated + * request_queue. + * + * This is the counter to the respective __device_add_disk() call. + * + * The final removal of the struct gendisk happens when its refcount reaches 0 + * with put_disk(), which should be called after del_gendisk(), if + * __device_add_disk() was used. + */ void del_gendisk(struct gendisk *disk) { struct disk_part_iter piter; @@ -1514,6 +1528,23 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno) return 0; } +/** + * disk_release - releases all allocated resources of the gendisk + * @dev: the device representing this disk + * + * This function releases all allocated resources of the gendisk. + * + * The struct gendisk refcount is incremented with get_gendisk() or + * get_disk_and_module(), and its refcount is decremented with + * put_disk_and_module() or put_disk(). Once the refcount reaches 0 this + * function is called. + * + * Drivers which used __device_add_disk() have a gendisk with a request_queue + * assigned. Since the request_queue sits on top of the gendisk for these + * drivers we also call blk_put_queue() for them, and we expect the + * request_queue refcount to reach 0 at this point, and so the request_queue + * will also be freed prior to the disk. + */ static void disk_release(struct device *dev) { struct gendisk *disk = dev_to_disk(dev); @@ -1727,6 +1758,13 @@ struct gendisk *__alloc_disk_node(int minors, int node_id) } EXPORT_SYMBOL(__alloc_disk_node); +/** + * get_disk_and_module - increments the gendisk and gendisk fops module refcount + * @disk: the struct gendisk to to increment the refcount for + * + * This increments the refcount for the struct gendisk, and the gendisk's + * fops module owner. + */ struct kobject *get_disk_and_module(struct gendisk *disk) { struct module *owner; @@ -1747,6 +1785,13 @@ struct kobject *get_disk_and_module(struct gendisk *disk) } EXPORT_SYMBOL(get_disk_and_module); +/** + * put_disk - decrements the gendisk refcount + * @disk: the struct gendisk to to decrement the refcount for + * + * This decrements the refcount for the struct gendisk. When this reaches 0 + * we'll have disk_release() called. + */ void put_disk(struct gendisk *disk) { if (disk) @@ -1754,7 +1799,10 @@ void put_disk(struct gendisk *disk) } EXPORT_SYMBOL(put_disk); -/* +/** + * put_disk_and_module - decrements the module and gendisk refcount + * @disk: the struct gendisk to to decrement the refcount for + * * This is a counterpart of get_disk_and_module() and thus also of * get_gendisk(). */ From patchwork Fri Jun 19 20:47:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615079 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1DEB3912 for ; Fri, 19 Jun 2020 20:48:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0664121532 for ; Fri, 19 Jun 2020 20:48:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599709; bh=ezmY6GG7N7R5TA87zG71AETUtzEOHo2C5MHAftMq7+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=mrZaf1V+HqeFKXGRwligo0qX5gGqTZilJjomEU32BLJ8oLoq0ypEOOsYbgl8by9yO +M3UARyPpx2VsRWEKJy3dEtFGrhew2uVhVS3mVo+9Z9I9FLrJJPt9Rk4sY8ItNESoR pGj3g8cdqBncRjfjPDk/+jPIVt6xVUQEjkSCxloc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390806AbgFSUrh (ORCPT ); Fri, 19 Jun 2020 16:47:37 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:34728 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390467AbgFSUrf (ORCPT ); Fri, 19 Jun 2020 16:47:35 -0400 Received: by mail-pg1-f196.google.com with SMTP id v14so4995438pgl.1; Fri, 19 Jun 2020 13:47:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZlpRC/Mpz8aVWhkWOBV4KQndGPE3w8KEQwXgj5xVC8o=; b=XT6D8W6pqVvesiZxqE2XkjaJbUJvhUSR5bL4gLRW/8wuxUcCVLK9/hzJsvkk85hMJw DY2Ei+Yp5ne19uG4eWUvIlrQZiwDWo7pLdha/6A78NKLJ+RfXjz38G5rGao5htcEe5gz kLmiu+37NdDH5Sr9THVC1t51XIs9+1hV2zQ9eYXCyJ+HtnvnmoPWyNaU3v/COnBCZj9u +fX7cdY+gxlohFCVT75beacYUt77slhDqtLQHs2ooJGz+9MBx4kcISH2IoYA5mtwyXvt O1SD8vA6OTOds1wkpc4+QfgI8sVgEOKZ5yrYVznh3yNViIBtrX0ppskjjcloZvp+oZyh SVwQ== X-Gm-Message-State: AOAM5306gm1SxP/WO2PBX2BcITyHGiyC4HeL+/Q0HY+RId+YyQxm9Uw8 m1JqZEAeCy0dGtE5SWDLCb4= X-Google-Smtp-Source: ABdhPJyEOMPI7dRp2zsaFrfUBNU9hX4Hv01VXR4E79Tt8FRLBZbwnTJwnov/PttgARJDYchOL+CQpw== X-Received: by 2002:aa7:952a:: with SMTP id c10mr10162941pfp.252.1592599655068; Fri, 19 Jun 2020 13:47:35 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id v7sm6569138pfn.147.2020.06.19.13.47.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:32 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 4556A41C23; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain , Christoph Hellwig Subject: [PATCH v7 2/8] block: clarify context for refcount increment helpers Date: Fri, 19 Jun 2020 20:47:24 +0000 Message-Id: <20200619204730.26124-3-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Let us clarify the context under which the helpers to increment the refcount for the gendisk and request_queue can be called under. We make this explicit on the places where we may sleep with might_sleep(). We don't address the decrement context yet, as that needs some extra work and fixes, but will be addressed in the next patch. Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Luis Chamberlain --- block/blk-core.c | 2 ++ block/genhd.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/block/blk-core.c b/block/blk-core.c index a0760aac110a..14c09daf55f3 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -610,6 +610,8 @@ EXPORT_SYMBOL(blk_alloc_queue); * @q: the request_queue structure to increment the refcount for * * Increment the refcount of the request_queue kobject. + * + * Context: Any context. */ bool blk_get_queue(struct request_queue *q) { diff --git a/block/genhd.c b/block/genhd.c index f741613d731f..1be86b1f43ec 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -985,11 +985,15 @@ static ssize_t disk_badblocks_store(struct device *dev, * * This function gets the structure containing partitioning * information for the given device @devt. + * + * Context: can sleep */ struct gendisk *get_gendisk(dev_t devt, int *partno) { struct gendisk *disk = NULL; + might_sleep(); + if (MAJOR(devt) != BLOCK_EXT_MAJOR) { struct kobject *kobj; @@ -1764,6 +1768,8 @@ EXPORT_SYMBOL(__alloc_disk_node); * * This increments the refcount for the struct gendisk, and the gendisk's * fops module owner. + * + * Context: Any context. */ struct kobject *get_disk_and_module(struct gendisk *disk) { From patchwork Fri Jun 19 20:47:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615075 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4A543913 for ; Fri, 19 Jun 2020 20:48:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3294A21532 for ; Fri, 19 Jun 2020 20:48:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599705; bh=mc2ATErO7Mbyy0pgHDQWYmSoFOY+NZLS2nkxRKrRLMw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=HFV1zOmrF7FdSPLP94IYZoZTstvynKGCk9mdt95FCL6y3oWp/LjUUcfdwKkQN27jV 9wKehR4oGr2itjQzE02NHHXiT3oDQZNCSiVLj0GHCH/hzX6scKnsaJOnQFnxrW18qj JWIecMR8Cku/m00mgOrnbjhMSkrtMk+qQMaFPaAo= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391480AbgFSUsW (ORCPT ); Fri, 19 Jun 2020 16:48:22 -0400 Received: from mail-pj1-f66.google.com ([209.85.216.66]:55531 "EHLO mail-pj1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390846AbgFSUrj (ORCPT ); Fri, 19 Jun 2020 16:47:39 -0400 Received: by mail-pj1-f66.google.com with SMTP id ne5so4532577pjb.5; Fri, 19 Jun 2020 13:47:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=y2yimRzl8Lw3YXqKnlvPORVOiA/F0uPiDUWZ3ls2daA=; b=HCTVEt2+mSLqPeZ4IEPM96KM9vpsSKoyzAlVW9mlGNxFe8pRHyJ7oyYRxQ/FJdy7Up p/gt0vPwtJHmdksUs02iiuOxvzRJAMtRQ0PJv0qGge5soNSDJndI81+GpoeChVFIiPFw 079S1CxLQaAg1Sb5wbHoKCsJZ0H2QZGaHSrEU0LGhoAnuerC5gwfHuh+Cd/nz9Gwhkmg b6TbV1JELo3KMe3Dgyu3c8Ev5LSisYNzmF2925N94j5wlFAmlf/A9vLymx0LJVDSMNFm aAOV3QVz4hLDXwfAUHR0osjak6pmIS9vf89WQWhFIk7uKnxSHT1d6tgdNBZE3FJCv0bX komg== X-Gm-Message-State: AOAM5338OJYiCbFfW+BXxcSmVM1mwc+/kJRotVetixx3ayk9qTYmQuha m6fJuVeh6lWBsg23hyOvyjE= X-Google-Smtp-Source: ABdhPJxFRWJeGBF/KVpIZjDjuYUsWmT39p655O9+P8pTa/kXrFWjOjoAArzLFFiiosUU3pALUbXUqw== X-Received: by 2002:a17:90a:21a2:: with SMTP id q31mr5337450pjc.230.1592599656355; Fri, 19 Jun 2020 13:47:36 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id z8sm5863127pjr.41.2020.06.19.13.47.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:33 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 5665341D25; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain , Omar Sandoval , Hannes Reinecke , Michal Hocko , Christoph Hellwig Subject: [PATCH v7 3/8] block: revert back to synchronous request_queue removal Date: Fri, 19 Jun 2020 20:47:25 +0000 Message-Id: <20200619204730.26124-4-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Commit dc9edc44de6c ("block: Fix a blk_exit_rl() regression") merged on v4.12 moved the work behind blk_release_queue() into a workqueue after a splat floated around which indicated some work on blk_release_queue() could sleep in blk_exit_rl(). This splat would be possible when a driver called blk_put_queue() or blk_cleanup_queue() (which calls blk_put_queue() as its final call) from an atomic context. blk_put_queue() decrements the refcount for the request_queue kobject, and upon reaching 0 blk_release_queue() is called. Although blk_exit_rl() is now removed through commit db6d99523560 ("block: remove request_list code") on v5.0, we reserve the right to be able to sleep within blk_release_queue() context. The last reference for the request_queue must not be called from atomic context. *When* the last reference to the request_queue reaches 0 varies, and so let's take the opportunity to document when that is expected to happen and also document the context of the related calls as best as possible so we can avoid future issues, and with the hopes that the synchronous request_queue removal sticks. We revert back to synchronous request_queue removal because asynchronous removal creates a regression with expected userspace interaction with several drivers. An example is when removing the loopback driver, one uses ioctls from userspace to do so, but upon return and if successful, one expects the device to be removed. Likewise if one races to add another device the new one may not be added as it is still being removed. This was expected behavior before and it now fails as the device is still present and busy still. Moving to asynchronous request_queue removal could have broken many scripts which relied on the removal to have been completed if there was no error. Document this expectation as well so that this doesn't regress userspace again. Using asynchronous request_queue removal however has helped us find other bugs. In the future we can test what could break with this arrangement by enabling CONFIG_DEBUG_KOBJECT_RELEASE. While at it, update the docs with the context expectations for the request_queue / gendisk refcount decrement, and make these expectations explicit by using might_sleep(). Cc: Bart Van Assche Cc: Omar Sandoval Cc: Hannes Reinecke Cc: Nicolai Stange Cc: Greg Kroah-Hartman Cc: Michal Hocko Cc: yu kuai Suggested-by: Nicolai Stange Fixes: dc9edc44de6c ("block: Fix a blk_exit_rl() regression") Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Luis Chamberlain --- block/blk-core.c | 8 ++++++++ block/blk-sysfs.c | 43 +++++++++++++++++++++--------------------- block/genhd.c | 17 +++++++++++++++++ include/linux/blkdev.h | 2 -- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 14c09daf55f3..a5126c0be777 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -327,6 +327,9 @@ EXPORT_SYMBOL_GPL(blk_clear_pm_only); * * Decrements the refcount of the request_queue kobject. When this reaches 0 * we'll have blk_release_queue() called. + * + * Context: Any context, but the last reference must not be dropped from + * atomic context. */ void blk_put_queue(struct request_queue *q) { @@ -359,9 +362,14 @@ EXPORT_SYMBOL_GPL(blk_set_queue_dying); * * Mark @q DYING, drain all pending requests, mark @q DEAD, destroy and * put it. All future requests will be failed immediately with -ENODEV. + * + * Context: can sleep */ void blk_cleanup_queue(struct request_queue *q) { + /* cannot be called from atomic context */ + might_sleep(); + WARN_ON_ONCE(blk_queue_registered(q)); /* mark @q DYING, no new request or merges will be allowed afterwards */ diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 02643e149d5e..561624d4cc4e 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -873,22 +873,32 @@ static void blk_exit_queue(struct request_queue *q) bdi_put(q->backing_dev_info); } - /** - * __blk_release_queue - release a request queue - * @work: pointer to the release_work member of the request queue to be released + * blk_release_queue - releases all allocated resources of the request_queue + * @kobj: pointer to a kobject, whose container is a request_queue + * + * This function releases all allocated resources of the request queue. + * + * The struct request_queue refcount is incremented with blk_get_queue() and + * decremented with blk_put_queue(). Once the refcount reaches 0 this function + * is called. + * + * For drivers that have a request_queue on a gendisk and added with + * __device_add_disk() the refcount to request_queue will reach 0 with + * the last put_disk() called by the driver. For drivers which don't use + * __device_add_disk() this happens with blk_cleanup_queue(). * - * Description: - * This function is called when a block device is being unregistered. The - * process of releasing a request queue starts with blk_cleanup_queue, which - * set the appropriate flags and then calls blk_put_queue, that decrements - * the reference counter of the request queue. Once the reference counter - * of the request queue reaches zero, blk_release_queue is called to release - * all allocated resources of the request queue. + * Drivers exist which depend on the release of the request_queue to be + * synchronous, it should not be deferred. + * + * Context: can sleep */ -static void __blk_release_queue(struct work_struct *work) +static void blk_release_queue(struct kobject *kobj) { - struct request_queue *q = container_of(work, typeof(*q), release_work); + struct request_queue *q = + container_of(kobj, struct request_queue, kobj); + + might_sleep(); if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags)) blk_stat_remove_callback(q, q->poll_cb); @@ -917,15 +927,6 @@ static void __blk_release_queue(struct work_struct *work) call_rcu(&q->rcu_head, blk_free_queue_rcu); } -static void blk_release_queue(struct kobject *kobj) -{ - struct request_queue *q = - container_of(kobj, struct request_queue, kobj); - - INIT_WORK(&q->release_work, __blk_release_queue); - schedule_work(&q->release_work); -} - static const struct sysfs_ops queue_sysfs_ops = { .show = queue_attr_show, .store = queue_attr_store, diff --git a/block/genhd.c b/block/genhd.c index 1be86b1f43ec..60ae4e1b4d38 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -889,12 +889,19 @@ static void invalidate_partition(struct gendisk *disk, int partno) * The final removal of the struct gendisk happens when its refcount reaches 0 * with put_disk(), which should be called after del_gendisk(), if * __device_add_disk() was used. + * + * Drivers exist which depend on the release of the gendisk to be synchronous, + * it should not be deferred. + * + * Context: can sleep */ void del_gendisk(struct gendisk *disk) { struct disk_part_iter piter; struct hd_struct *part; + might_sleep(); + blk_integrity_del(disk); disk_del_events(disk); @@ -1548,11 +1555,15 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno) * drivers we also call blk_put_queue() for them, and we expect the * request_queue refcount to reach 0 at this point, and so the request_queue * will also be freed prior to the disk. + * + * Context: can sleep */ static void disk_release(struct device *dev) { struct gendisk *disk = dev_to_disk(dev); + might_sleep(); + blk_free_devt(dev->devt); disk_release_events(disk); kfree(disk->random); @@ -1797,6 +1808,9 @@ EXPORT_SYMBOL(get_disk_and_module); * * This decrements the refcount for the struct gendisk. When this reaches 0 * we'll have disk_release() called. + * + * Context: Any context, but the last reference must not be dropped from + * atomic context. */ void put_disk(struct gendisk *disk) { @@ -1811,6 +1825,9 @@ EXPORT_SYMBOL(put_disk); * * This is a counterpart of get_disk_and_module() and thus also of * get_gendisk(). + * + * Context: Any context, but the last reference must not be dropped from + * atomic context. */ void put_disk_and_module(struct gendisk *disk) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 6e067dca94cf..780d6fa94746 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -584,8 +584,6 @@ struct request_queue { size_t cmd_size; - struct work_struct release_work; - #define BLK_MAX_WRITE_HINTS 5 u64 write_hints[BLK_MAX_WRITE_HINTS]; }; From patchwork Fri Jun 19 20:47:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615041 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A79513B1 for ; Fri, 19 Jun 2020 20:47:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E689E2158C for ; Fri, 19 Jun 2020 20:47:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599663; bh=JIvSaQCuTivG77Ol+r11lGBAkb1PDMgs80TnxNHRlsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=ZcTkRFeiQwUirruiCnd5fS/7q5N5zzHBLC5fy1QI295j2nZbUNjXKoIWeGJHT6eix PbyZiiJXB0vdwTDBaTXMO/+3Kq48AgAT2JuSRUDi1ks0eXwrPR/zd1drkBf3CY83DV AU49/yb4qKQ9NvgLNozzJG6VtKNhf0VNv4UCTJxE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391070AbgFSUrl (ORCPT ); Fri, 19 Jun 2020 16:47:41 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:39886 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390831AbgFSUri (ORCPT ); Fri, 19 Jun 2020 16:47:38 -0400 Received: by mail-pf1-f196.google.com with SMTP id d66so4927060pfd.6; Fri, 19 Jun 2020 13:47:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jH2CPsvsaNzRGDf+QoUv0Reklj4c8N9GM5jBSfoalww=; b=EtMRTWjSA/XS/Sj0DF7zU5HchaXyxTbxxShmaD0xKI2F5Bwav1WbC/6+ykbZDAZpY5 3F8TGjiOgxE6YEqxXA6Gpr+w+yeHcORkGlc1hW7eujvW2NK8ndMTJVkv67VtyFG8U722 I5wU4dpAaMivjvD1RvZhRakdQL6zubdLzvz6oypQXckaKdx3y4WFFEedMXd9I+KbJlFw 96GWjcugF+szq5tzOCxckol7oXOn0EmBmRh47+iUzDDbaM8U0bzGHkZxAwbfIH9Gp9QX OHLWXqnSqI5mVkDitD6GD7YIE+ckxFqt1Sr0H/7DeJDAlggMnx+A4NgXC8JQ1JWru15i GVOw== X-Gm-Message-State: AOAM533EQ6oTZ6pqrWTvRuLZOguJQ71BtPhnXki9vIzFyliKVoQnhad5 GUU45iVGXAP2OU8xfDE2nrg= X-Google-Smtp-Source: ABdhPJw+rxutY1uGOaVhJTaFSz863dhub5gLBJTRgN2o19CWJtfQJo8NFso3QjofJ3IY9132mgZ6aQ== X-Received: by 2002:aa7:981d:: with SMTP id e29mr727732pfl.298.1592599657521; Fri, 19 Jun 2020 13:47:37 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id u14sm7353047pfk.211.2020.06.19.13.47.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:33 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 657E241DAA; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain Subject: [PATCH v7 4/8] blktrace: annotate required lock on do_blk_trace_setup() Date: Fri, 19 Jun 2020 20:47:26 +0000 Message-Id: <20200619204730.26124-5-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Ensure it is clear which lock is required on do_blk_trace_setup(). Suggested-by: Bart Van Assche Signed-off-by: Luis Chamberlain Reviewed-by: Bart Van Assche --- kernel/trace/blktrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 7f60029bdaff..7ff2ea5cd05e 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -483,6 +483,8 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, struct dentry *dir = NULL; int ret; + lockdep_assert_held(&q->blk_trace_mutex); + if (!buts->buf_size || !buts->buf_nr) return -EINVAL; From patchwork Fri Jun 19 20:47:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615063 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BEACB913 for ; Fri, 19 Jun 2020 20:48:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A5D8521531 for ; Fri, 19 Jun 2020 20:48:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599691; bh=GFDS5ZeXJWKepPtGtYd1p8VC4NzatXMF4WFN56n95Xc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=LsjWi733qwx6V3Mwz+y7DO93+SeWitmHO0Xi2kbyWlcAjnsm6lf8cXKLb8KtoIgau w5u0+wjNJjVolIlumRmXTSMutOLR9LVn3h+bM3FR5+pg0qESkTElezuN3eXGu/MYOb tTMS+/nCz0huAHGJ2EtoNZ2AXXeHvLKELSxJLZ2o= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391154AbgFSUrr (ORCPT ); Fri, 19 Jun 2020 16:47:47 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:35810 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391113AbgFSUrn (ORCPT ); Fri, 19 Jun 2020 16:47:43 -0400 Received: by mail-pl1-f196.google.com with SMTP id k1so4385638pls.2; Fri, 19 Jun 2020 13:47:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f88bEORI++QIsnJdKm2ca64CmhxGUzC3g+SSrwClYUg=; b=b597umi/vwQhZzxLMDHbVDwgdPWBKhCvCp4M01vq276lf1KR8jDcUF058/2qmLGs/3 zyGtULDU824dglz2AvD0OHy0l6HmqBwJ1rYigiWiRtbUrQcQz4rGnLmH92s95CAFvgTH UB3N41EPWoNpUqlso6CmVTwEr/eIEr1GEg+A4sW8al8AhwMyfUkIaq4NLyH7B25VjEFd hru93WuDmgMrbn88iON5pAeBoCRXONHlddX/t5TaLdcJi0loWUj/FhQL4NbKDxQccNAO GOuCdGxHBBYZOMlQxu6386i8aXVaoa+kI5hCVAYr8Zx12IwBItDDOiPGDlUJZIoRQ3P9 QaVw== X-Gm-Message-State: AOAM532f0wYUxQEaiopXZcaukXN4eTb/3VruOK97Io0KNAUyBtOmcSrd 7YqEyuGYevviWu/I+zIV7AY= X-Google-Smtp-Source: ABdhPJyoZ4/dvNRCLnarrxnxISmW+vu/kyGF815p5j84q6q1BrSobxtKcghLOojyOlj8eKMv/rwguw== X-Received: by 2002:a17:90a:8083:: with SMTP id c3mr5595094pjn.83.1592599661138; Fri, 19 Jun 2020 13:47:41 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id m10sm5741217pjs.27.2020.06.19.13.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:39 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 792F241DAB; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain , Christoph Hellwig Subject: [PATCH v7 5/8] loop: be paranoid on exit and prevent new additions / removals Date: Fri, 19 Jun 2020 20:47:27 +0000 Message-Id: <20200619204730.26124-6-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Be pedantic on removal as well and hold the mutex. This should prevent uses of addition while we exit. Reviewed-by: Ming Lei Reviewed-by: Christoph Hellwig Signed-off-by: Luis Chamberlain --- drivers/block/loop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c33bbbfd1bd9..d55e1b52f076 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2402,6 +2402,8 @@ static void __exit loop_exit(void) range = max_loop ? max_loop << part_shift : 1UL << MINORBITS; + mutex_lock(&loop_ctl_mutex); + idr_for_each(&loop_index_idr, &loop_exit_cb, NULL); idr_destroy(&loop_index_idr); @@ -2409,6 +2411,8 @@ static void __exit loop_exit(void) unregister_blkdev(LOOP_MAJOR, "loop"); misc_deregister(&loop_misc); + + mutex_unlock(&loop_ctl_mutex); } module_init(loop_init); From patchwork Fri Jun 19 20:47:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615061 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6783F912 for ; Fri, 19 Jun 2020 20:48:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49DCD21556 for ; Fri, 19 Jun 2020 20:48:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599689; bh=QjywpvGCxY9ZZqtGLaAUK4SSpXbZkHR2ZMEbOQDydsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=IYV4ze+bZEpa1Xx9RciGIrYHqo2NY3TyrGdegGWARdrfxhV9XRP6HsFDWo1eVgInv 6hid+EQMNxyGqfmt4XSv0ahkYx8Ex4XayYui9WFPE1pYmf0uGWVAsNAehafiWAbBE2 nmL/w/7+fL6VMcSEXhVQJTAF0SFEZ4TYrA4kswoM= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391318AbgFSUrs (ORCPT ); Fri, 19 Jun 2020 16:47:48 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:35881 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391162AbgFSUrp (ORCPT ); Fri, 19 Jun 2020 16:47:45 -0400 Received: by mail-pl1-f193.google.com with SMTP id j4so4386851plk.3; Fri, 19 Jun 2020 13:47:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=U5SB3lTS6myB9B6BB7rLonydPqzm5GLIIyuTS5YLBZU=; b=QJEGKcziSduTYrm5U4qCWhMVZAOckdMKn/B0LW9i8RZfoAiR/uAUwN1FT0aAjqRxEL //jwCfJl5vSO8WBXOkSV8PuOIMfDwnhpVW73Hm9bDhNcrpzyxSjH1fXrOqOczRfaIu+5 U4bO86/4DZPbwG9tBx9qo59MoQAjsd8xUeAEBKPNgtwtND1OqJELISgKiErKj+7zMgKt e02+00xmSiTUfPhXsf2htmTZr2BLmdtQ2owQfdUPyW8wccuqjTwtBAooRbZjcdCPO1R6 4ffVG3MZrPx/dGLQzq2VZUCkgh/bRgBMWi4d8s70kWpo2Vsny8e0XTkAxuy1iRPAfvIC CzHA== X-Gm-Message-State: AOAM533AdMiZtffu1D0r48hgvWFjMVjago6tOdyuqkh1oadtVFsLybL1 wrpvBd6/wWhnupVEFLQDl7Y= X-Google-Smtp-Source: ABdhPJw7CPnlRQTMIjEA8iDVo7A2b7Za9fcMJ4niTv0x4xjQwIHZ50kN8lA8oRygHsnFvZn6cbXTFw== X-Received: by 2002:a17:902:be06:: with SMTP id r6mr3736717pls.310.1592599664519; Fri, 19 Jun 2020 13:47:44 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id l14sm6030320pjh.50.2020.06.19.13.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:39 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 8508E42337; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain , Omar Sandoval , Hannes Reinecke , Michal Hocko , syzbot+603294af2d01acfdd6da@syzkaller.appspotmail.com Subject: [PATCH v7 6/8] blktrace: fix debugfs use after free Date: Fri, 19 Jun 2020 20:47:28 +0000 Message-Id: <20200619204730.26124-7-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org On commit 6ac93117ab00 ("blktrace: use existing disk debugfs directory") merged on v4.12 Omar fixed the original blktrace code for request-based drivers (multiqueue). This however left in place a possible crash, if you happen to abuse blktrace while racing to remove / add a device. We used to use asynchronous removal of the request_queue, and with that the issue was easier to reproduce. Now that we have reverted to synchronous removal of the request_queue, the issue is still possible to reproduce, its however just a bit more difficult. We essentially run two instances of break-blktrace which add/remove a loop device, and setup a blktrace and just never tear the blktrace down. We do this twice in parallel. This is easily reproduced with the script run_0004.sh from break-blktrace [0]. We can end up with two types of panics each reflecting where we race, one a failed blktrace setup: [ 252.426751] debugfs: Directory 'loop0' with parent 'block' already present! [ 252.432265] BUG: kernel NULL pointer dereference, address: 00000000000000a0 [ 252.436592] #PF: supervisor write access in kernel mode [ 252.439822] #PF: error_code(0x0002) - not-present page [ 252.442967] PGD 0 P4D 0 [ 252.444656] Oops: 0002 [#1] SMP NOPTI [ 252.446972] CPU: 10 PID: 1153 Comm: break-blktrace Tainted: G E 5.7.0-rc2-next-20200420+ #164 [ 252.452673] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014 [ 252.456343] RIP: 0010:down_write+0x15/0x40 [ 252.458146] Code: eb ca e8 ae 22 8d ff cc cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 55 48 89 fd e8 52 db ff ff 31 c0 ba 01 00 00 00 48 0f b1 55 00 75 0f 48 8b 04 25 c0 8b 01 00 48 89 45 08 5d [ 252.463638] RSP: 0018:ffffa626415abcc8 EFLAGS: 00010246 [ 252.464950] RAX: 0000000000000000 RBX: ffff958c25f0f5c0 RCX: ffffff8100000000 [ 252.466727] RDX: 0000000000000001 RSI: ffffff8100000000 RDI: 00000000000000a0 [ 252.468482] RBP: 00000000000000a0 R08: 0000000000000000 R09: 0000000000000001 [ 252.470014] R10: 0000000000000000 R11: ffff958d1f9227ff R12: 0000000000000000 [ 252.471473] R13: ffff958c25ea5380 R14: ffffffff8cce15f1 R15: 00000000000000a0 [ 252.473346] FS: 00007f2e69dee540(0000) GS:ffff958c2fc80000(0000) knlGS:0000000000000000 [ 252.475225] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 252.476267] CR2: 00000000000000a0 CR3: 0000000427d10004 CR4: 0000000000360ee0 [ 252.477526] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 252.478776] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 252.479866] Call Trace: [ 252.480322] simple_recursive_removal+0x4e/0x2e0 [ 252.481078] ? debugfs_remove+0x60/0x60 [ 252.481725] ? relay_destroy_buf+0x77/0xb0 [ 252.482662] debugfs_remove+0x40/0x60 [ 252.483518] blk_remove_buf_file_callback+0x5/0x10 [ 252.484328] relay_close_buf+0x2e/0x60 [ 252.484930] relay_open+0x1ce/0x2c0 [ 252.485520] do_blk_trace_setup+0x14f/0x2b0 [ 252.486187] __blk_trace_setup+0x54/0xb0 [ 252.486803] blk_trace_ioctl+0x90/0x140 [ 252.487423] ? do_sys_openat2+0x1ab/0x2d0 [ 252.488053] blkdev_ioctl+0x4d/0x260 [ 252.488636] block_ioctl+0x39/0x40 [ 252.489139] ksys_ioctl+0x87/0xc0 [ 252.489675] __x64_sys_ioctl+0x16/0x20 [ 252.490380] do_syscall_64+0x52/0x180 [ 252.491032] entry_SYSCALL_64_after_hwframe+0x44/0xa9 And the other on the device removal: [ 128.528940] debugfs: Directory 'loop0' with parent 'block' already present! [ 128.615325] BUG: kernel NULL pointer dereference, address: 00000000000000a0 [ 128.619537] #PF: supervisor write access in kernel mode [ 128.622700] #PF: error_code(0x0002) - not-present page [ 128.625842] PGD 0 P4D 0 [ 128.627585] Oops: 0002 [#1] SMP NOPTI [ 128.629871] CPU: 12 PID: 544 Comm: break-blktrace Tainted: G E 5.7.0-rc2-next-20200420+ #164 [ 128.635595] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014 [ 128.640471] RIP: 0010:down_write+0x15/0x40 [ 128.643041] Code: eb ca e8 ae 22 8d ff cc cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 55 48 89 fd e8 52 db ff ff 31 c0 ba 01 00 00 00 48 0f b1 55 00 75 0f 65 48 8b 04 25 c0 8b 01 00 48 89 45 08 5d [ 128.650180] RSP: 0018:ffffa9c3c05ebd78 EFLAGS: 00010246 [ 128.651820] RAX: 0000000000000000 RBX: ffff8ae9a6370240 RCX: ffffff8100000000 [ 128.653942] RDX: 0000000000000001 RSI: ffffff8100000000 RDI: 00000000000000a0 [ 128.655720] RBP: 00000000000000a0 R08: 0000000000000002 R09: ffff8ae9afd2d3d0 [ 128.657400] R10: 0000000000000056 R11: 0000000000000000 R12: 0000000000000000 [ 128.659099] R13: 0000000000000000 R14: 0000000000000003 R15: 00000000000000a0 [ 128.660500] FS: 00007febfd995540(0000) GS:ffff8ae9afd00000(0000) knlGS:0000000000000000 [ 128.662204] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 128.663426] CR2: 00000000000000a0 CR3: 0000000420042003 CR4: 0000000000360ee0 [ 128.664776] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 128.666022] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 128.667282] Call Trace: [ 128.667801] simple_recursive_removal+0x4e/0x2e0 [ 128.668663] ? debugfs_remove+0x60/0x60 [ 128.669368] debugfs_remove+0x40/0x60 [ 128.669985] blk_trace_free+0xd/0x50 [ 128.670593] __blk_trace_remove+0x27/0x40 [ 128.671274] blk_trace_shutdown+0x30/0x40 [ 128.671935] blk_release_queue+0x95/0xf0 [ 128.672589] kobject_put+0xa5/0x1b0 [ 128.673188] disk_release+0xa2/0xc0 [ 128.673786] device_release+0x28/0x80 [ 128.674376] kobject_put+0xa5/0x1b0 [ 128.674915] loop_remove+0x39/0x50 [loop] [ 128.675511] loop_control_ioctl+0x113/0x130 [loop] [ 128.676199] ksys_ioctl+0x87/0xc0 [ 128.676708] __x64_sys_ioctl+0x16/0x20 [ 128.677274] do_syscall_64+0x52/0x180 [ 128.677823] entry_SYSCALL_64_after_hwframe+0x44/0xa9 The common theme here is: debugfs: Directory 'loop0' with parent 'block' already present This crash happens because of how blktrace uses the debugfs directory where it places its files. Upon init we always create the same directory which would be needed by blktrace but we only do this for make_request drivers (multiqueue) block drivers. When you race a removal of these devices with a blktrace setup you end up in a situation where the make_request recursive debugfs removal will sweep away the blktrace files and then later blktrace will also try to remove individual dentries which are already NULL. The inverse is also possible and hence the two types of use after frees. We don't create the block debugfs directory on init for these types of block devices: * request-based block driver block devices * every possible partition * scsi-generic And so, this race should in theory only be possible with make_request drivers. We can fix the UAF by simply re-using the debugfs directory for make_request drivers (multiqueue) and only creating the ephemeral directory for the other type of block devices. The new clarifications on relying on the q->blk_trace_mutex *and* also checking for q->blk_trace *prior* to processing a blktrace ensures the debugfs directories are only created if no possible directory name clashes are possible. This goes tested with: o nvme partitions o ISCSI with tgt, and blktracing against scsi-generic with: o block o tape o cdrom o media changer o blktests This patch is part of the work which disputes the severity of CVE-2019-19770 which shows this issue is not a core debugfs issue, but a misuse of debugfs within blktace. Cc: Bart Van Assche Cc: Omar Sandoval Cc: Hannes Reinecke Cc: Nicolai Stange Cc: Greg Kroah-Hartman Cc: Michal Hocko Cc: "Martin K. Petersen" Cc: "James E.J. Bottomley" Cc: yu kuai Reported-by: syzbot+603294af2d01acfdd6da@syzkaller.appspotmail.com Fixes: 6ac93117ab00 ("blktrace: use existing disk debugfs directory") Signed-off-by: Luis Chamberlain Reviewed-by: Christoph Hellwig --- kernel/trace/blktrace.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 7ff2ea5cd05e..e6e2d25fdbd6 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -524,10 +524,18 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!bt->msg_data) goto err; - ret = -ENOENT; - - dir = debugfs_lookup(buts->name, blk_debugfs_root); - if (!dir) +#ifdef CONFIG_BLK_DEBUG_FS + /* + * When tracing whole make_request drivers (multiqueue) block devices, + * reuse the existing debugfs directory created by the block layer on + * init. For request-based block devices, all partitions block devices, + * and scsi-generic block devices we create a temporary new debugfs + * directory that will be removed once the trace ends. + */ + if (queue_is_mq(q) && bdev && bdev == bdev->bd_contains) + dir = q->debugfs_dir; + else +#endif bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); bt->dev = dev; @@ -565,8 +573,6 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ret = 0; err: - if (dir && !bt->dir) - dput(dir); if (ret) blk_trace_free(bt); return ret; From patchwork Fri Jun 19 20:47:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615065 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ED498912 for ; Fri, 19 Jun 2020 20:48:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D28EF21556 for ; Fri, 19 Jun 2020 20:48:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599692; bh=zqWGiZrPP2UkxxMFtdWDADZiBysETtZKvJ2GgHDTwPI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=NUQ4GSRljQ5yUPhirVYa3Rd83qzYPX9KrDl0rDA5RuwDD/X8Z4PDx2JvYxtIsB96o wZw3pK08ikuBxlG+CaGmzPsA31WtkltPwNV8Z2s4aYe72E4hKL/3XXUru41b7B6LGJ kYVDtRmbLavrbWInA41/p0fjddTBxAMdw1Ytq7iM= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393462AbgFSUsM (ORCPT ); Fri, 19 Jun 2020 16:48:12 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:32969 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391138AbgFSUro (ORCPT ); Fri, 19 Jun 2020 16:47:44 -0400 Received: by mail-pl1-f196.google.com with SMTP id 35so4395999ple.0; Fri, 19 Jun 2020 13:47:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WAnSKbcOgD9mh5TKczvQeK3USc0HG+X2VK1Fl/2VodI=; b=NJztYQ3dF5tG17nEQ57jCHuTNRW67BWYB2fB9cLpIJVsKIxctZYmjrJVU7IpumzS+c lkBju4CWzlimvSLy+t8jLS0dv4Ic3axv6zVf9l1BCliiF8FNZDdHd6+k99Bo3hgFESP7 Cf6dZJG7E9JjoLCs5UIxME5HkEJe6auk8ayycofvtAoo7LVs/eTJvizqwiDSXQ9UbSQI sW29GHUd8zBdHJT6nQlB50S9BoGc/WHnmmhBBKJRHCzg5/7OzCubp7R0NcYbaHoRBspo ojlVOOSysR/rK9tf8DdtdgdlrBG2Ann/uFQX/zGaMabCjxIwOiR0FA0AY4PXugrAo08m H9AA== X-Gm-Message-State: AOAM533IQcgHTw1RINrplwlTeEhOVmW8roir8FmczreOeFh4oqIzv3hC KZ/+/w5NHYbSOyoVuLc0tJM= X-Google-Smtp-Source: ABdhPJyt+q2/jgY/ucUkJNHL+DMXosz4eR8RKCOdVty3Tudmz1nHdpy8UFn8y3lmFu7CwHtJNrHb/w== X-Received: by 2002:a17:902:d889:: with SMTP id b9mr9091448plz.206.1592599663520; Fri, 19 Jun 2020 13:47:43 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id d189sm6688611pfc.51.2020.06.19.13.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:39 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id 99B6242340; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain Subject: [PATCH v7 7/8] blktrace: ensure our debugfs dir exists Date: Fri, 19 Jun 2020 20:47:29 +0000 Message-Id: <20200619204730.26124-8-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We make an assumption that a debugfs directory exists, but since this can fail ensure it exists before allowing blktrace setup to complete. Otherwise we end up stuffing blktrace files on the debugfs root directory. In the worst case scenario this *in theory* can create an eventual panic *iff* in the future a similarly named file is created prior on the debugfs root directory. This theoretical crash can happen due to a recursive removal followed by a specific dentry removal. This doesn't fix any known crash, however I have seen the files go into the main debugfs root directory in cases where the debugfs directory was not created due to other internal bugs with blktrace now fixed. blktrace is also completely useless without this directory, so this ensures to userspace we only setup blktrace if the kernel can stuff files where they are supposed to go into. debugfs directory creations typically aren't checked for, and we have maintainers doing sweep removals of these checks, but since we need this check to ensure proper userspace blktrace functionality we make sure to annotate the justification for the check. Signed-off-by: Luis Chamberlain Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche --- kernel/trace/blktrace.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index e6e2d25fdbd6..098780ec018f 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -538,6 +538,18 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, #endif bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); + /* + * As blktrace relies on debugfs for its interface the debugfs directory + * is required, contrary to the usual mantra of not checking for debugfs + * files or directories. + */ + if (IS_ERR_OR_NULL(dir)) { + pr_warn("debugfs_dir not present for %s so skipping\n", + buts->name); + ret = -ENOENT; + goto err; + } + bt->dev = dev; atomic_set(&bt->dropped, 0); INIT_LIST_HEAD(&bt->running_list); From patchwork Fri Jun 19 20:47:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Chamberlain X-Patchwork-Id: 11615055 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4D9A4913 for ; Fri, 19 Jun 2020 20:47:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2907321531 for ; Fri, 19 Jun 2020 20:47:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592599672; bh=/WzLCaaZ9LYQAOg9EGhcEBaVH4mi1yJUrvvDYkZxI4Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=VvYcVImYUuO0fj0LVUpehcwdcXupcAhGcV0cKCVweA9KovOuIUebdqauC3SwBdBzG 13i45t5oKFqLjVbpN1zhxfq+8VIRas8tpcNISb+ZdAiKQz9t5+CNWuRzWUQIFpHS7g uTMZK3rNd+h4xksdnPNGwN2+mmimXcOQ+lH8sYCQ= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391699AbgFSUru (ORCPT ); Fri, 19 Jun 2020 16:47:50 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:43965 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391177AbgFSUrs (ORCPT ); Fri, 19 Jun 2020 16:47:48 -0400 Received: by mail-pf1-f194.google.com with SMTP id j12so2705491pfn.10; Fri, 19 Jun 2020 13:47:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TwB6gnPxFEFUDI+liWG4HJoGOtS0QfTmlU5ZCBzuVTA=; b=GRri9G9fJKLoYS/9IsW8GwFxIyYGAhl0zIeCRXlT9XrkcIp6VCYNhz6VoW3GKTw7th ABxHvMP6Idto+P5eWnal1XdXY3xMjP+uCvDYGrg6lQNfcm0jikZng4D2PgKmsRmsjxKo pz9Iihg3bkzZji9wb3mAgJe49k7RPxZpX5uh++9DoCVouncVWam4sDmdJx7+CeYurRJ4 ZPrLQdbugY0pAEmdloNFpZb00Tgro3RTARRBMJXdVEDd6bN+Vq9iYyTz2n3pBVXzOqcQ rNl0GMizMiAMIIhK9W26DiS4aor/T03tF2Sy7xNJWVEMbOl82ZJRNFb5XuXxScV9AZYS p5ew== X-Gm-Message-State: AOAM531ghR8u8muw709KYXZdgqdyo35+iYiprBNzCrKORFpHGQgQUA91 IRa1x5ja0cj9PnmXbjbpAnM= X-Google-Smtp-Source: ABdhPJwn8wt+BXh8B2nnHFar7t2dCSA/MFrp9clSb4i0NMrHautUwplhSeTzGZ2gQSMi9eioBFJIug== X-Received: by 2002:a63:f804:: with SMTP id n4mr3951220pgh.302.1592599665524; Fri, 19 Jun 2020 13:47:45 -0700 (PDT) Received: from 42.do-not-panic.com (42.do-not-panic.com. [157.230.128.187]) by smtp.gmail.com with ESMTPSA id s41sm6246108pjc.51.2020.06.19.13.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Jun 2020 13:47:39 -0700 (PDT) Received: by 42.do-not-panic.com (Postfix, from userid 1000) id ADCAE42341; Fri, 19 Jun 2020 20:47:32 +0000 (UTC) From: Luis Chamberlain To: axboe@kernel.dk, viro@zeniv.linux.org.uk, bvanassche@acm.org, gregkh@linuxfoundation.org, rostedt@goodmis.org, mingo@redhat.com, jack@suse.cz, ming.lei@redhat.com, nstange@suse.de, akpm@linux-foundation.org Cc: mhocko@suse.com, yukuai3@huawei.com, martin.petersen@oracle.com, jejb@linux.ibm.com, linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Luis Chamberlain Subject: [PATCH v7 8/8] block: create the request_queue debugfs_dir on registration Date: Fri, 19 Jun 2020 20:47:30 +0000 Message-Id: <20200619204730.26124-9-mcgrof@kernel.org> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20200619204730.26124-1-mcgrof@kernel.org> References: <20200619204730.26124-1-mcgrof@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We were only creating the request_queue debugfs_dir only for make_request block drivers (multiqueue), but never for request-based block drivers. We did this as we were only creating non-blktrace additional debugfs files on that directory for make_request drivers. However, since blktrace *always* creates that directory anyway, we special-case the use of that directory on blktrace. Other than this being an eye-sore, this exposes request-based block drivers to the same debugfs fragile race that used to exist with make_request block drivers where if we start adding files onto that directory we can later run a race with a double removal of dentries on the directory if we don't deal with this carefully on blktrace. Instead, just simplify things by always creating the request_queue debugfs_dir on request_queue registration. Rename the mutex also to reflect the fact that this is used outside of the blktrace context. Signed-off-by: Luis Chamberlain Reviewed-by: Christoph Hellwig --- block/blk-core.c | 8 +----- block/blk-mq-debugfs.c | 5 ---- block/blk-sysfs.c | 9 +++++++ block/blk.h | 2 -- include/linux/blkdev.h | 5 ++-- kernel/trace/blktrace.c | 58 ++++++++++++++++++----------------------- 6 files changed, 39 insertions(+), 48 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index a5126c0be777..72b102a389a5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -51,9 +51,7 @@ #include "blk-pm.h" #include "blk-rq-qos.h" -#ifdef CONFIG_DEBUG_FS struct dentry *blk_debugfs_root; -#endif EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); @@ -555,9 +553,7 @@ struct request_queue *__blk_alloc_queue(int node_id) kobject_init(&q->kobj, &blk_queue_ktype); -#ifdef CONFIG_BLK_DEV_IO_TRACE - mutex_init(&q->blk_trace_mutex); -#endif + mutex_init(&q->debugfs_mutex); mutex_init(&q->sysfs_lock); mutex_init(&q->sysfs_dir_lock); spin_lock_init(&q->queue_lock); @@ -1937,9 +1933,7 @@ int __init blk_dev_init(void) blk_requestq_cachep = kmem_cache_create("request_queue", sizeof(struct request_queue), 0, SLAB_PANIC, NULL); -#ifdef CONFIG_DEBUG_FS blk_debugfs_root = debugfs_create_dir("block", NULL); -#endif return 0; } diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 15df3a36e9fa..a2800bc56fb4 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -824,9 +824,6 @@ void blk_mq_debugfs_register(struct request_queue *q) struct blk_mq_hw_ctx *hctx; int i; - q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), - blk_debugfs_root); - debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs); /* @@ -857,9 +854,7 @@ void blk_mq_debugfs_register(struct request_queue *q) void blk_mq_debugfs_unregister(struct request_queue *q) { - debugfs_remove_recursive(q->debugfs_dir); q->sched_debugfs_dir = NULL; - q->debugfs_dir = NULL; } static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx, diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 561624d4cc4e..be67952e7be2 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "blk.h" #include "blk-mq.h" @@ -917,6 +918,9 @@ static void blk_release_queue(struct kobject *kobj) blk_mq_release(q); blk_trace_shutdown(q); + mutex_lock(&q->debugfs_mutex); + debugfs_remove_recursive(q->debugfs_dir); + mutex_unlock(&q->debugfs_mutex); if (queue_is_mq(q)) blk_mq_debugfs_unregister(q); @@ -989,6 +993,11 @@ int blk_register_queue(struct gendisk *disk) goto unlock; } + mutex_lock(&q->debugfs_mutex); + q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), + blk_debugfs_root); + mutex_unlock(&q->debugfs_mutex); + if (queue_is_mq(q)) { __blk_mq_register_dev(dev, q); blk_mq_debugfs_register(q); diff --git a/block/blk.h b/block/blk.h index b5d1f0fc6547..499308c6ab3b 100644 --- a/block/blk.h +++ b/block/blk.h @@ -14,9 +14,7 @@ /* Max future timer expiry for timeouts */ #define BLK_MAX_TIMEOUT (5 * HZ) -#ifdef CONFIG_DEBUG_FS extern struct dentry *blk_debugfs_root; -#endif struct blk_flush_queue { unsigned int flush_pending_idx:1; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 780d6fa94746..e70e03d2cd8c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -528,9 +528,9 @@ struct request_queue { unsigned int sg_timeout; unsigned int sg_reserved_size; int node; + struct mutex debugfs_mutex; #ifdef CONFIG_BLK_DEV_IO_TRACE struct blk_trace __rcu *blk_trace; - struct mutex blk_trace_mutex; #endif /* * for flush operations @@ -574,8 +574,9 @@ struct request_queue { struct list_head tag_set_list; struct bio_set bio_split; -#ifdef CONFIG_BLK_DEBUG_FS struct dentry *debugfs_dir; + +#ifdef CONFIG_BLK_DEBUG_FS struct dentry *sched_debugfs_dir; struct dentry *rqos_debugfs_dir; #endif diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 098780ec018f..12e1d52f1d17 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -348,7 +348,7 @@ static int __blk_trace_remove(struct request_queue *q) struct blk_trace *bt; bt = rcu_replace_pointer(q->blk_trace, NULL, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); if (!bt) return -EINVAL; @@ -362,9 +362,9 @@ int blk_trace_remove(struct request_queue *q) { int ret; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); ret = __blk_trace_remove(q); - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); return ret; } @@ -483,14 +483,11 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, struct dentry *dir = NULL; int ret; - lockdep_assert_held(&q->blk_trace_mutex); + lockdep_assert_held(&q->debugfs_mutex); if (!buts->buf_size || !buts->buf_nr) return -EINVAL; - if (!blk_debugfs_root) - return -ENOENT; - strncpy(buts->name, name, BLKTRACE_BDEV_SIZE); buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0'; @@ -505,7 +502,7 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, * we can be. */ if (rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex))) { + lockdep_is_held(&q->debugfs_mutex))) { pr_warn("Concurrent blktraces are not allowed on %s\n", buts->name); return -EBUSY; @@ -524,18 +521,15 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!bt->msg_data) goto err; -#ifdef CONFIG_BLK_DEBUG_FS /* - * When tracing whole make_request drivers (multiqueue) block devices, - * reuse the existing debugfs directory created by the block layer on - * init. For request-based block devices, all partitions block devices, + * When tracing the whole disk reuse the existing debugfs directory + * created by the block layer on init. For partitions block devices, * and scsi-generic block devices we create a temporary new debugfs * directory that will be removed once the trace ends. */ - if (queue_is_mq(q) && bdev && bdev == bdev->bd_contains) + if (bdev && bdev == bdev->bd_contains) dir = q->debugfs_dir; else -#endif bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); /* @@ -617,9 +611,9 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, { int ret; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); ret = __blk_trace_setup(q, name, dev, bdev, arg); - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); return ret; } @@ -665,7 +659,7 @@ static int __blk_trace_startstop(struct request_queue *q, int start) struct blk_trace *bt; bt = rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); if (bt == NULL) return -EINVAL; @@ -705,9 +699,9 @@ int blk_trace_startstop(struct request_queue *q, int start) { int ret; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); ret = __blk_trace_startstop(q, start); - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); return ret; } @@ -736,7 +730,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) if (!q) return -ENXIO; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); switch (cmd) { case BLKTRACESETUP: @@ -763,7 +757,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) break; } - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); return ret; } @@ -774,14 +768,14 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) **/ void blk_trace_shutdown(struct request_queue *q) { - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); if (rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex))) { + lockdep_is_held(&q->debugfs_mutex))) { __blk_trace_startstop(q, 0); __blk_trace_remove(q); } - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); } #ifdef CONFIG_BLK_CGROUP @@ -1662,7 +1656,7 @@ static int blk_trace_remove_queue(struct request_queue *q) struct blk_trace *bt; bt = rcu_replace_pointer(q->blk_trace, NULL, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); if (bt == NULL) return -EINVAL; @@ -1837,10 +1831,10 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); bt = rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); if (attr == &dev_attr_enable) { ret = sprintf(buf, "%u\n", !!bt); goto out_unlock_bdev; @@ -1858,7 +1852,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, ret = sprintf(buf, "%llu\n", bt->end_lba); out_unlock_bdev: - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); out_bdput: bdput(bdev); out: @@ -1901,10 +1895,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&q->blk_trace_mutex); + mutex_lock(&q->debugfs_mutex); bt = rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); if (attr == &dev_attr_enable) { if (!!value == !!bt) { ret = 0; @@ -1921,7 +1915,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, if (bt == NULL) { ret = blk_trace_setup_queue(q, bdev); bt = rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->blk_trace_mutex)); + lockdep_is_held(&q->debugfs_mutex)); } if (ret == 0) { @@ -1936,7 +1930,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } out_unlock_bdev: - mutex_unlock(&q->blk_trace_mutex); + mutex_unlock(&q->debugfs_mutex); out_bdput: bdput(bdev); out: