On 3/9/23 12:44, Hanna Czenczek wrote:
+ *
+ * Note that TRIM operations call blk_aio_pdiscard() multiple
+ * times (and finally increment s->blk's in-flight counter while
+ * ide_trim_bh_cb() is scheduled), so we have to loop blk_drain()
+ * until the whole operation is done.
*/
if (s->bus->dma->aiocb) {
trace_ide_cancel_dma_sync_remaining();
- blk_drain(s->blk);
- assert(s->bus->dma->aiocb == NULL);
+ while (s->bus->dma->aiocb) {
+ blk_drain(s->blk);
+ }
I think having to do this is problematic, because the blk_drain should
leave no pending operation.
Here it seems okay because you do it in a controlled situation, but the
main thread can also issue blk_drain(), or worse bdrv_drained_begin(),
and there would be pending I/O operations when it returns.
Unfortunately I don't have a solution (I'm not considering the idea of
using disable_request_queuing and having even more atomics magic in
block/block-backend.c), but I'll read the thread.
Paolo