Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2687838imm; Wed, 16 May 2018 18:02:47 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpzr3WVdEE7yF6Cz27nKK7PaAACfHcGCVnfRViQZW9ZJo62IbtYXcDPScmWj7EVHbE5/+no X-Received: by 2002:a17:902:6e4:: with SMTP id 91-v6mr3077621plh.63.1526518967253; Wed, 16 May 2018 18:02:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526518967; cv=none; d=google.com; s=arc-20160816; b=jFQC91R2fQFcSEaZCtggP1ob6ckarH6X8+fbCy2g++Dn5OqoH845NKz+yMnLZ1qEdI uiXqpGfUkEgfqhLQy4IiNLc7Qg6Q4V+EjdxKG7AhRuaybfAym4Onf8EFLHrBubm5qcYZ QF2fJ9T05FoEr3dGdnhUPG4F0xVfEmlfoET/6Hm0LBvDdd+jHtHI5ZmJLDeUwTbaUZrQ wAGKW74QApgXHjiMzoK3BuNEuM2kpEfVxUdTF1G7RYc8PioTWflzr4AkqISy2Kcds+lX iCJT+D9VK81uo/WRj3T0HyKmQuY8HL3itc1aSjYbxgGFRcTHrskHc+mxJoZxURR0UytO 0Zaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:content-disposition :mime-version:message-id:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=5vn5CLugzmKbTVYKew/XAGPhjhhytVYE0r1/odGvkQc=; b=X3px7eCFzF1uC2iCaOfgGP/0SwT7GWmc+ysbkQOF8jHPi5l6mDJJSt00wrntxNIcl9 K2o4DlUt+juCJLfPJxdzlHwPWW7KCzmUux/nCfD0wiDVTYuBfxZSEGH2mYA/LB2rCPCH Pfwbl2XQKEf1FXU+kMvz+GH7ZIxNEFHY9rtJRqekEWToAKwSLbr0S0R7wxkRhvUCnrp5 QHBgQq8L9U31DON5hoZichoLzo58cU+ZCDM89BqWXunK2zxY0QbrDO/QZvaDud/gu+Bi c7dUiv8PlShXg/jQszjERk7iIR4AOgbDfrGhd6t1tS7Vjk82gt28DAQkzY19HT5frQni otQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=aDvVrmBL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b29-v6si377012pge.638.2018.05.16.18.02.32; Wed, 16 May 2018 18:02:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=aDvVrmBL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751595AbeEQBCY (ORCPT + 99 others); Wed, 16 May 2018 21:02:24 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:46460 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751259AbeEQBCV (ORCPT ); Wed, 16 May 2018 21:02:21 -0400 Received: by mail-pf0-f196.google.com with SMTP id p12-v6so1194875pff.13; Wed, 16 May 2018 18:02:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=5vn5CLugzmKbTVYKew/XAGPhjhhytVYE0r1/odGvkQc=; b=aDvVrmBL0nAs3LqxbQgoK5Xuq3vj+irbjqfMUi0W52iN7tmcC4VgnAwQ5mJtisBKC3 tDKJyApFlulNPDzVdmmxmn3XEFQOtfCqZ+qedPUG9Brcpop+UJYNeI8EutnBm4UihLQl Awpx08lCO6fTjl0Nyr56g4dE4joMotEQatOw/yIaODQuRQrpOYyWXq/KxZXMWMst16Rf 4qjvTx8hI+1VCLDjgY/4/4zhELJXJnTjokTNJxGlr/Trvpmmx0TF3Ndrwc1Agi5qsgJ6 g9r36x5X4SK74yt3fULyZ7EojaEVKizKdI/x2Pv5OesnF2f2WwzD9tvIsUqHx7P1SEL7 4JYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=5vn5CLugzmKbTVYKew/XAGPhjhhytVYE0r1/odGvkQc=; b=JYB3kvTNJp6zYqFtH+quAxMtCH+4V58QJkfdsakEaAKg1AkVjq/kRTZ5mQOJboOPkN Iw49hSFDeMguhm3bOA4eLBJhKM4D2Xsg/2Q6nR5PpHu7EApYPn/MW0ceSkBWp8d4YqFR /n2D9m9OqhShrcny3kq/Wi8tXO3q+4XX7lZmT6lIQotQ2vA7qxFVO2n3pcnWiBGPRsSR /VGFhBKfzPxTMsgO/H0Fipv/BEQtFsUuBHA8+cGftF/+o5+HMRl9oQydDOBjWzqz8XhI k5Qao9FnhYcc3LsITY02omJUnfHSNgbDK1var5BbbhSYW+pEiZAu4S+IEyywqewo169B OqOQ== X-Gm-Message-State: ALKqPwd22oRt+WZ7vln5sOfQJfTlPyZTQXITpy9ptG7FH/0amquULkJW J+m669ictjh+ufDYaNg4Ks1NDw== X-Received: by 2002:a63:7807:: with SMTP id t7-v6mr2446760pgc.125.1526518940030; Wed, 16 May 2018 18:02:20 -0700 (PDT) Received: from xldev-tmpl.dev.purestorage.com ([192.30.188.252]) by smtp.gmail.com with ESMTPSA id p24-v6sm7380954pfk.58.2018.05.16.18.02.18 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 16 May 2018 18:02:19 -0700 (PDT) Date: Wed, 16 May 2018 19:02:17 -0600 From: Anatoliy Glagolev To: linux-scsi@vger.kernel.org, FUJITA Tomonori , Jens Axboe , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Cc: James.Bottomley@hansenpartnership.com Subject: [PATCH] Bsg referencing parent device Message-ID: <20180517010214.GA18978@xldev-tmpl.dev.purestorage.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A follow-up on earlier discussions: [PATCH] bsg referencing bus driver module https://www.spinics.net/lists/linux-scsi/msg119631.html [PATCH] Waiting for scsi_host_template release https://www.spinics.net/lists/linux-scsi/msg119432.html All these discussions are attempts to fix a crash after SCSI transport driver unload if a user-mode process holds a handle in BSG layer towards the unloaded driver via SCSI mid-layer: [16834.636216,07] Call Trace: ... scsi_proc_hostdir_rm [16834.641944,07] [] scsi_host_dev_release+0x3f/0x130 [16834.647740,07] [] device_release+0x32/0xa0 [16834.653423,07] [] kobject_cleanup+0x77/0x190 [16834.659002,07] [] kobject_put+0x25/0x50 [16834.664430,07] [] put_device+0x17/0x20 [16834.669740,07] [] bsg_kref_release_function+0x24/0x30 [16834.675007,07] [] bsg_release+0x166/0x1d0 [16834.680148,07] [] __fput+0xcb/0x1d0 [16834.685156,07] [] ____fput+0xe/0x10 [16834.690017,07] [] task_work_run+0x86/0xb0 [16834.694781,07] [] exit_to_usermode_loop+0x6b/0x9a [16834.699466,07] [] syscall_return_slowpath+0x55/0x60 [16834.704110,07] [] int_ret_from_sys_call+0x25/0x9f The latest input from earlier discussions was to cut off access to the unloaded driver at bsg_unregister_queue time by calling blk_cleanup_queue. If we do that we still have to release the reference to the parent device (otherwise we crash with the same stack). The next logical step is, rather than maintaining a "part-time" reference to be dropped early, we discard referencing completely. Discarding the reference turns out to be the only thing needed to fix the problem: all transport drivers already do blk_cleanup_queue before releasing their reference to the parent device. From 7eaa9b43f0b99766b1d197044eb4d2e549d11a24 Mon Sep 17 00:00:00 2001 From: Anatoliy Glagolev Date: Wed, 16 May 2018 17:03:09 -0600 Subject: [PATCH] Bsg referencing parent device Signed-off-by: Anatoliy Glagolev Bsg holding reference to a parent device may result in a crash if user closes a bsg file handle after the parent device driver has unloaded. Holding a reference is not really needed: parent device must exist between bsg_register_queue and bsg_unregister_queue. Before the device goes away the caller does blk_cleanup_queue so that all in-flight requests to the device are gone and all new requests cannot pass beyond the queue. The queue itself is a refcounted object and it will stay alive with a bsg file. --- block/bsg.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index defa06c..f9e4b91 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -650,18 +650,6 @@ static struct bsg_device *bsg_alloc_device(void) return bd; } -static void bsg_kref_release_function(struct kref *kref) -{ - struct bsg_class_device *bcd = - container_of(kref, struct bsg_class_device, ref); - struct device *parent = bcd->parent; - - if (bcd->release) - bcd->release(bcd->parent); - - put_device(parent); -} - static int bsg_put_device(struct bsg_device *bd) { int ret = 0, do_free; @@ -694,7 +682,6 @@ static int bsg_put_device(struct bsg_device *bd) kfree(bd); out: - kref_put(&q->bsg_dev.ref, bsg_kref_release_function); if (do_free) blk_put_queue(q); return ret; @@ -760,8 +747,6 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) */ mutex_lock(&bsg_mutex); bcd = idr_find(&bsg_minor_idr, iminor(inode)); - if (bcd) - kref_get(&bcd->ref); mutex_unlock(&bsg_mutex); if (!bcd) @@ -772,8 +757,6 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) return bd; bd = bsg_add_device(inode, bcd->queue, file); - if (IS_ERR(bd)) - kref_put(&bcd->ref, bsg_kref_release_function); return bd; } @@ -902,6 +885,8 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) void bsg_unregister_queue(struct request_queue *q) { + struct device *parent; + void (*release)(struct device *dev); struct bsg_class_device *bcd = &q->bsg_dev; if (!bcd->class_dev) @@ -913,8 +898,21 @@ void bsg_unregister_queue(struct request_queue *q) sysfs_remove_link(&q->kobj, "bsg"); device_unregister(bcd->class_dev); bcd->class_dev = NULL; - kref_put(&bcd->ref, bsg_kref_release_function); + parent = bcd->parent; + release = bcd->release; + bcd->parent = NULL; + bcd->release = NULL; mutex_unlock(&bsg_mutex); + + /* + * The caller of bsg_[un]register_queue must hold a reference + * to the parent device between ..register.. and ..unregister.. + * so we do not maintain a refcount to parent here. + * Note: the caller is expected to blk_cleanup_queue(q) + * before releasing the reference to the parent device. + */ + if (release) + release(parent); } EXPORT_SYMBOL_GPL(bsg_unregister_queue); @@ -955,10 +953,9 @@ int bsg_register_queue(struct request_queue *q, struct device *parent, bcd->minor = ret; bcd->queue = q; - bcd->parent = get_device(parent); + bcd->parent = parent; bcd->release = release; bcd->ops = ops; - kref_init(&bcd->ref); dev = MKDEV(bsg_major, bcd->minor); class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname); if (IS_ERR(class_dev)) { -- 1.9.1