Message ID | 20200114091634.60856-1-pannengyuan@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] scsi-disk: define props in scsi_block_disk to avoid memleaks | expand |
On 14/01/20 10:16, pannengyuan@huawei.com wrote: > From: Pan Nengyuan <pannengyuan@huawei.com> > > scsi_block_realize() use scsi_realize() to init some props, but > these props is not defined in scsi_block_disk_properties, so they will > not be freed. > > This patch defines these prop in scsi_block_disk_properties and aslo > calls scsi_unrealize to avoid memleaks, the leak stack as > follow(it's easy to reproduce by attaching/detaching scsi-block-disks): > > ================================================================= > ==qemu-system-x86_64==32195==ERROR: LeakSanitizer: detected memory leaks > > Direct leak of 57 byte(s) in 3 object(s) allocated from: > #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? > #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? > #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? > #3 0x55975366e596 (qemu-system-x86_64+0x35c0596) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2399 > #4 0x559753671201 (emu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 > #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 > #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 > #7 0x5597532a7840 (qemu-system-x86_64+0x31f9840) /mnt/sdb/qemu/hw/core/qdev.c:876 > > Direct leak of 15 byte(s) in 3 object(s) allocated from: > #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? > #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? > #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? > #3 0x55975366e06f (qemu-system-x86_64+0x35c006f) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2388 > #4 0x559753671201 (qemu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 > #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 > #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 > > @@ -3079,9 +3080,8 @@ static const TypeInfo scsi_cd_info = { > > #ifdef __linux__ > static Property scsi_block_properties[] = { > - DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ > + DEFINE_SCSI_DISK_PROPERTIES(),. The properties defined there shouldn't apply to scsi-block. Can you explain what exactly is being leaked? Paolo
On 1/22/2020 1:05 AM, Paolo Bonzini wrote: > On 14/01/20 10:16, pannengyuan@huawei.com wrote: >> From: Pan Nengyuan <pannengyuan@huawei.com> >> >> scsi_block_realize() use scsi_realize() to init some props, but >> these props is not defined in scsi_block_disk_properties, so they will >> not be freed. >> >> This patch defines these prop in scsi_block_disk_properties and aslo >> calls scsi_unrealize to avoid memleaks, the leak stack as >> follow(it's easy to reproduce by attaching/detaching scsi-block-disks): >> >> ================================================================= >> ==qemu-system-x86_64==32195==ERROR: LeakSanitizer: detected memory leaks >> >> Direct leak of 57 byte(s) in 3 object(s) allocated from: >> #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? >> #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? >> #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? >> #3 0x55975366e596 (qemu-system-x86_64+0x35c0596) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2399 >> #4 0x559753671201 (emu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 >> #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 >> #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 >> #7 0x5597532a7840 (qemu-system-x86_64+0x31f9840) /mnt/sdb/qemu/hw/core/qdev.c:876 >> >> Direct leak of 15 byte(s) in 3 object(s) allocated from: >> #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? >> #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? >> #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? >> #3 0x55975366e06f (qemu-system-x86_64+0x35c006f) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2388 >> #4 0x559753671201 (qemu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 >> #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 >> #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 >> >> @@ -3079,9 +3080,8 @@ static const TypeInfo scsi_cd_info = { >> >> #ifdef __linux__ >> static Property scsi_block_properties[] = { >> - DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ >> + DEFINE_SCSI_DISK_PROPERTIES(),. > The properties defined there shouldn't apply to scsi-block. > > Can you explain what exactly is being leaked? Ohh, I'm sorry, I missed this email and reply it so late. When we attach a scsi-block disk, the props(version/vender/device_id) are malloced in scsi_realize() which it's called by scsi_block_realize(), but we don't define these props in scsi_block_properties. So these props will not be released when we detach the scsi-block disk. This patch will reuse scsi_disk_properties to define those props in scsi_block_properties to fix it. Similarly to scsi_hd, this patch aslo set unrealize to call del_boot_device_lchs(). Thanks. > > Paolo > > . >
Hi Paolo, On 2/19/2020 3:52 PM, Pan Nengyuan wrote: > > > On 1/22/2020 1:05 AM, Paolo Bonzini wrote: >> On 14/01/20 10:16, pannengyuan@huawei.com wrote: >>> From: Pan Nengyuan <pannengyuan@huawei.com> >>> >>> scsi_block_realize() use scsi_realize() to init some props, but >>> these props is not defined in scsi_block_disk_properties, so they will >>> not be freed. >>> >>> This patch defines these prop in scsi_block_disk_properties and aslo >>> calls scsi_unrealize to avoid memleaks, the leak stack as >>> follow(it's easy to reproduce by attaching/detaching scsi-block-disks): >>> >>> ================================================================= >>> ==qemu-system-x86_64==32195==ERROR: LeakSanitizer: detected memory leaks >>> >>> Direct leak of 57 byte(s) in 3 object(s) allocated from: >>> #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? >>> #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? >>> #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? >>> #3 0x55975366e596 (qemu-system-x86_64+0x35c0596) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2399 >>> #4 0x559753671201 (emu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 >>> #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 >>> #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 >>> #7 0x5597532a7840 (qemu-system-x86_64+0x31f9840) /mnt/sdb/qemu/hw/core/qdev.c:876 >>> >>> Direct leak of 15 byte(s) in 3 object(s) allocated from: >>> #0 0x7f19f8bed768 (/lib64/libasan.so.5+0xef768) ??:? >>> #1 0x7f19f64d9445 (/lib64/libglib-2.0.so.0+0x52445) ??:? >>> #2 0x7f19f64f2d92 (/lib64/libglib-2.0.so.0+0x6bd92) ??:? >>> #3 0x55975366e06f (qemu-system-x86_64+0x35c006f) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2388 >>> #4 0x559753671201 (qemu-system-x86_64+0x35c3201) /mnt/sdb/qemu/hw/scsi/scsi-disk.c:2681 >>> #5 0x559753687e3e (qemu-system-x86_64+0x35d9e3e) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:58 >>> #6 0x55975368ac44 (qemu-system-x86_64+0x35dcc44) /mnt/sdb/qemu/hw/scsi/scsi-bus.c:216 >>> >>> @@ -3079,9 +3080,8 @@ static const TypeInfo scsi_cd_info = { >>> >>> #ifdef __linux__ >>> static Property scsi_block_properties[] = { >>> - DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ >>> + DEFINE_SCSI_DISK_PROPERTIES(),. >> The properties defined there shouldn't apply to scsi-block. >> >> Can you explain what exactly is being leaked? > > Ohh, I'm sorry, I missed this email and reply it so late. > > When we attach a scsi-block disk, the props(version/vender/device_id) are malloced in scsi_realize() which it's called by scsi_block_realize(), > but we don't define these props in scsi_block_properties. So these props will not be released when we detach the scsi-block disk. > > This patch will reuse scsi_disk_properties to define those props in scsi_block_properties to fix it. > Similarly to scsi_hd, this patch aslo set unrealize to call del_boot_device_lchs(). > > Thanks. > Maybe you missed this patch due to my late reply. Actually it will cause a memleak when we attach/detach a scsi-block disk. Reproducer: (qemu) device_add virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x7 (qemu) drive_add 1 file=/dev/sdc,format=raw,if=none,id=drive-scsi1-0-0-12,cache=none,aio=native OK (qemu) device_add scsi-block,bus=scsi1.0,channel=0,scsi-id=0,lun=10,share-rw=on,drive=drive-scsi1-0-0-12,id=scsi1-0-0-10 (qemu) device_del scsi1-0-0-10 (qemu) drive_del drive-scsi1-0-0-12 I'm not sure why the properties defined shouldn't be applied, can you give some more suggestions? Thanks. >> >> Paolo >> >> . >>
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e44c61eeb4..a1194b9fa7 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2981,7 +2981,6 @@ static const TypeInfo scsi_disk_base_info = { }; #define DEFINE_SCSI_DISK_PROPERTIES() \ - DEFINE_PROP_DRIVE_IOTHREAD("drive", SCSIDiskState, qdev.conf.blk), \ DEFINE_BLOCK_PROPERTIES_BASE(SCSIDiskState, qdev.conf), \ DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ DEFINE_PROP_STRING("ver", SCSIDiskState, version), \ @@ -2992,6 +2991,7 @@ static const TypeInfo scsi_disk_base_info = { static Property scsi_hd_properties[] = { + DEFINE_PROP_DRIVE_IOTHREAD("drive", SCSIDiskState, qdev.conf.blk), DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, features, SCSI_DISK_F_REMOVABLE, false), @@ -3047,6 +3047,7 @@ static const TypeInfo scsi_hd_info = { }; static Property scsi_cd_properties[] = { + DEFINE_PROP_DRIVE_IOTHREAD("drive", SCSIDiskState, qdev.conf.blk), DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0), DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0), @@ -3079,9 +3080,8 @@ static const TypeInfo scsi_cd_info = { #ifdef __linux__ static Property scsi_block_properties[] = { - DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ + DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), - DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false), DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size, DEFAULT_MAX_UNMAP_SIZE), @@ -3099,6 +3099,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data) SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass); sc->realize = scsi_block_realize; + sc->unrealize = scsi_unrealize; sc->alloc_req = scsi_block_new_request; sc->parse_cdb = scsi_block_parse_cdb; sdc->dma_readv = scsi_block_dma_readv; @@ -3118,6 +3119,7 @@ static const TypeInfo scsi_block_info = { #endif static Property scsi_disk_properties[] = { + DEFINE_PROP_DRIVE_IOTHREAD("drive", SCSIDiskState, qdev.conf.blk), DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, features, SCSI_DISK_F_REMOVABLE, false),