[solution]
Fix by doing the queue removal in one place - in sas_rphy_remove() -
instead of unregistering the queue in sas_rphy_remove() and finally
cleaning up the queue in calling blk_cleanup_queue() from
sas_end_device_release() or sas_expander_release().
Function bsg_remove_queue() can handle a NULL pointer q, so remove the
precheck in sas_rphy_remove().
"
scsi: scsi_transport_sas: Fix memory leak when removing devices
"[Steps to reproduce] platform/ HISI0162: 01/host0/ port-0: 0/expander- 0:0/port- 0:0:10/ phy-0:0: 10/sas_ phy/phy- 0:0:10/ enable debug/kmemleak debug/kmemleak) debug/kmemleak ____ptrval_ ___)>] kmem_cache_ alloc+0x188/ 0x260 ____ptrval_ ___)>] bsg_setup_ queue+0x48/ 0x1a8 ____ptrval_ ___)>] sas_rphy_ add+0x108/ 0x2d0 ____ptrval_ ___)>] sas_probe_ devices+ 0x168/0x208 ____ptrval_ ___)>] sas_discover_ domain+ 0x660/0x9c8 ____ptrval_ ___)>] process_ one_work+ 0x3f8/0x690 ____ptrval_ ___)>] worker_ thread+ 0x70/0x6a0 ____ptrval_ ___)>] kthread+0x1b8/0x1c0 ____ptrval_ ___)>] ret_from_ fork+0x10/ 0x18 ____ptrval_ ___)>] __kmalloc_ node+0x1a8/ 0x2c8 ____ptrval_ ___)>] blk_mq_ realloc_ tag_set_ tags.part. 70+0x48/ 0xd8 ____ptrval_ ___)>] blk_mq_ alloc_tag_ set+0x1dc/ 0x530 ____ptrval_ ___)>] bsg_setup_ queue+0xe8/ 0x1a8 ____ptrval_ ___)>] sas_rphy_ add+0x108/ 0x2d0 ____ptrval_ ___)>] sas_probe_ devices+ 0x168/0x208 ____ptrval_ ___)>] sas_discover_ domain+ 0x660/0x9c8 ____ptrval_ ___)>] process_ one_work+ 0x3f8/0x690 ____ptrval_ ___)>] worker_ thread+ 0x70/0x6a0 ____ptrval_ ___)>] kthread+0x1b8/0x1c0 ____ptrval_ ___)>] ret_from_ fork+0x10/ 0x18 ____ptrval_ ___)>] __kmalloc_ node+0x1a8/ 0x2c8 ____ptrval_ ___)>] blk_mq_ alloc_tag_ set+0x254/ 0x530 ____ptrval_ ___)>] bsg_setup_ queue+0xe8/ 0x1a8 ____ptrval_ ___)>] sas_rphy_ add+0x108/ 0x2d0 ____ptrval_ ___)>] sas_probe_ devices+ 0x168/0x208 ____ptrval_ ___)>] sas_discover_ domain+ 0x660/0x9c8 ____ptrval_ ___)>] process_ one_work+ 0x3f8/0x690 ____ptrval_ ___)>] worker_ thread+ 0x70/0x6a0 ____ptrval_ ___)>] kthread+0x1b8/0x1c0 ____ptrval_ ___)>] ret_from_ fork+0x10/ 0x18
Enable memleak, and do as follows:
root@(none)$ echo 0 > /sys/devices/
[ 79.857888] hisi_sas_v2_hw HISI0162:01: dev[7:1] is gone
root@(none)$ echo scan > /sys/kernel/
[ 131.656603] kmemleak: 3 new suspected memory leaks (see /sys/kernel/
root@(none)$ more /sys/kernel/
unreferenced object 0xffff041da5c66000 (size 256):
comm ""kworker/u128:1"", pid 549, jiffies 4294898543 (age 113.728s)
hex dump (first 32 bytes):
00 5e c6 a5 1d 04 ff ff 01 00 00 00 00 00 00 00 .^..............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
unreferenced object 0xffff041d8c075400 (size 128):
comm ""kworker/u128:1"", pid 549, jiffies 4294898543 (age 113.728s)
hex dump (first 32 bytes):
00 40 25 97 1d 00 ff ff 00 00 00 00 00 00 00 00 .@%.............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
unreferenced object 0xffff041da5c65e00 (size 256):
comm ""kworker/u128:1"", pid 549, jiffies 4294898543 (age 113.728s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
[<(
root@(none)$
[solution] device_ release( ) or sas_expander_ release( ).
Fix by doing the queue removal in one place - in sas_rphy_remove() -
instead of unregistering the queue in sas_rphy_remove() and finally
cleaning up the queue in calling blk_cleanup_queue() from
sas_end_
Function bsg_remove_queue() can handle a NULL pointer q, so remove the
precheck in sas_rphy_remove().
"
scsi: scsi_transport_sas: Fix memory leak when removing devices