提交 1c9431e2 编写于 作者: M Ming Lei 提交者: Zheng Zengkai

scsi: core: Put LLD module refcnt after SCSI device is released

stable inclusion
from stable-5.10.78
commit 7b57c38d12aed1b5d92f74748bed25e0d041729f
bugzilla: 185700 https://gitee.com/openeuler/kernel/issues/I4IAU2

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7b57c38d12aed1b5d92f74748bed25e0d041729f

--------------------------------

commit f2b85040 upstream.

SCSI host release is triggered when SCSI device is freed. We have to make
sure that the low-level device driver module won't be unloaded before SCSI
host instance is released because shost->hostt is required in the release
handler.

Make sure to put LLD module refcnt after SCSI device is released.

Fixes a kernel panic of 'BUG: unable to handle page fault for address'
reported by Changhui and Yi.

Link: https://lore.kernel.org/r/20211008050118.1440686-1-ming.lei@redhat.com
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reported-by: NChanghui Zhong <czhong@redhat.com>
Reported-by: NYi Zhang <yi.zhang@redhat.com>
Tested-by: NYi Zhang <yi.zhang@redhat.com>
Signed-off-by: NMing Lei <ming.lei@redhat.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 1560e123
......@@ -545,8 +545,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);
......
......@@ -450,9 +450,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;
......@@ -501,11 +504,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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册