qemu/hw/ide
Hanna Reitz 7e5cdb345f ide: Increment BB in-flight counter for TRIM BH
When we still have an AIOCB registered for DMA operations, we try to
settle the respective operation by draining the BlockBackend associated
with the IDE device.

However, this assumes that every DMA operation is associated with an
increment of the BlockBackend’s in-flight counter (e.g. through some
ongoing I/O operation), so that draining the BB until its in-flight
counter reaches 0 will settle all DMA operations.  That is not the case:
For TRIM, the guest can issue a zero-length operation that will not
result in any I/O operation forwarded to the BlockBackend, and also not
increment the in-flight counter in any other way.  In such a case,
blk_drain() will be a no-op if no other operations are in flight.

It is clear that if blk_drain() is a no-op, the value of
s->bus->dma->aiocb will not change between checking it in the `if`
condition and asserting that it is NULL after blk_drain().

The particular problem is that ide_issue_trim() creates a BH
(ide_trim_bh_cb()) to settle the TRIM request: iocb->common.cb() is
ide_dma_cb(), which will either create a new request, or find the
transfer to be done and call ide_set_inactive(), which clears
s->bus->dma->aiocb.  Therefore, the blk_drain() must wait for
ide_trim_bh_cb() to run, which currently it will not always do.

To fix this issue, we increment the BlockBackend's in-flight counter
when the TRIM operation begins (in ide_issue_trim(), when the
ide_trim_bh_cb() BH is created) and decrement it when ide_trim_bh_cb()
is done.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2029980
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220120142259.120189-1-hreitz@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Tested-by: John Snow <jsnow@redhat.com>
2022-03-07 09:19:20 +01:00
..
ahci_internal.h hw: Do not include hw/sysbus.h if it is not necessary 2021-05-02 17:24:50 +02:00
ahci-allwinner.c ahci: Move QOM macro to header 2020-08-27 14:04:54 -04:00
ahci.c hw/dma: Let dma_buf_read() / dma_buf_write() propagate MemTxResult 2022-01-18 12:56:29 +01:00
atapi.c ide: atapi: check logical block address and read size (CVE-2020-29443) 2021-01-23 09:26:40 -05:00
cmd646.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
core.c ide: Increment BB in-flight counter for TRIM BH 2022-03-07 09:19:20 +01:00
ich.c nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
ioport.c hw/ide: Fix crash when plugging a piix3-ide device into the x-remote machine 2021-07-19 10:08:45 +02:00
isa.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
Kconfig hw/ide/Kconfig: Add missing dependency PCI -> IDE_QDEV 2021-07-20 15:30:42 +02:00
macio.c dma: Let dma_memory_read/write() take MemTxAttrs argument 2021-12-30 17:16:32 +01:00
meson.build meson: convert hw/ide 2020-08-21 06:30:30 -04:00
microdrive.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
mmio.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
pci.c ide: rename cmd_write to ctrl_write 2020-10-01 13:04:16 -04:00
piix.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
qdev.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
sii3112.c ide: Rename ide_bus_new() to ide_bus_init() 2021-09-30 13:44:13 +01:00
trace-events docs: fix references to docs/devel/tracing.rst 2021-06-02 06:51:09 +02:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
via.c via-ide: Avoid using isa_get_irq() 2021-10-18 00:41:36 +02:00