From patchwork Fri Oct 8 05:01:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 12544395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34F2BC433EF for ; Fri, 8 Oct 2021 05:01:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0DE7660F22 for ; Fri, 8 Oct 2021 05:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229674AbhJHFDf (ORCPT ); Fri, 8 Oct 2021 01:03:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:45240 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229540AbhJHFDe (ORCPT ); Fri, 8 Oct 2021 01:03:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633669296; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=87B+XO1SFZLcJ+mrL3HimxygVo2EX2coss4i46ltjM4=; b=iApsexHSj8kP1LE3K1t8OOh0N9xXFXxnuwYpSIjvzCEHl5ReGRa3fvN2GIP+Y42JZPqAkY NPkkD6z1t2E54VLPpqCO2+EbRXP9S3rVg9fQh4vJCK2kx+azVUcU617oNAnBhRCygMZNcy /Wi8ZjBnUw9IMUd4BZG2HmWZrCl4OmE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-381-QjWRd093PeK5ndFu0IhSlg-1; Fri, 08 Oct 2021 01:01:35 -0400 X-MC-Unique: QjWRd093PeK5ndFu0IhSlg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 85F8B800480; Fri, 8 Oct 2021 05:01:34 +0000 (UTC) Received: from localhost (ovpn-8-29.pek2.redhat.com [10.72.8.29]) by smtp.corp.redhat.com (Postfix) with ESMTP id D4E1B5C1B4; Fri, 8 Oct 2021 05:01:22 +0000 (UTC) From: Ming Lei To: "Martin K . Petersen" , linux-scsi@vger.kernel.org Cc: Ming Lei , Changhui Zhong , Yi Zhang , Greg Kroah-Hartman Subject: [PATCH V4] scsi: core: put LLD module refcnt after SCSI device is released Date: Fri, 8 Oct 2021 13:01:18 +0800 Message-Id: <20211008050118.1440686-1-ming.lei@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org SCSI host release is triggered when SCSI device is freed, and we have to make sure that LLD module won't be unloaded before SCSI host instance is released because shost->hostt is required in host release handler. So make sure to put LLD module refcnt after SCSI device is released. Fix one kernel panic of 'BUG: unable to handle page fault for address' reported by Changhui and Yi. Reported-by: Changhui Zhong Reported-by: Yi Zhang Tested-by: Yi Zhang Cc: Greg Kroah-Hartman Signed-off-by: Ming Lei --- V4: - set module pointer as NULL in case that grabbing mod is failed in sdev release handler, suggested by Greg V3: - change to fix the issue by grabbing module during release V2: - add one atomic counter for covering put device drivers/scsi/scsi.c | 4 +++- drivers/scsi/scsi_sysfs.c | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index b241f9e3885c..291ecc33b1fe 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -553,8 +553,10 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { - module_put(sdev->host->hostt->module); + struct module *mod = sdev->host->hostt->module; + put_device(&sdev->sdev_gendev); + module_put(mod); } EXPORT_SYMBOL(scsi_device_put); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 86793259e541..a35841b34bfd 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -449,9 +449,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; unsigned long flags; + struct module *mod; sdev = container_of(work, struct scsi_device, ew.work); + mod = sdev->host->hostt->module; + scsi_dh_release_device(sdev); parent = sdev->sdev_gendev.parent; @@ -502,11 +505,17 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) if (parent) put_device(parent); + module_put(mod); } static void scsi_device_dev_release(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); + + /* Set module pointer as NULL in case of module unloading */ + if (!try_module_get(sdp->host->hostt->module)) + sdp->host->hostt->module = NULL; + execute_in_process_context(scsi_device_dev_release_usercontext, &sdp->ew); }