dma: Avoid reentrancy in DMA transfer handlers
With the conversion of the block layer to coroutines, bdrv_read/write have changed to run a nested event loop that calls qemu_bh_poll. Consequently a scheduled BH can be called while a DMA transfer handler runs and this means that DMA_run becomes reentrant. Devices haven't been designed to cope with that, so instead of running a nested transfer handler just wait for the next invocation of the BH from the main loop. This fixes some problems with the floppy device. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
67403dbba7
commit
acae6f1c4c
10
hw/dma.c
10
hw/dma.c
@ -358,6 +358,14 @@ static void DMA_run (void)
|
||||
struct dma_cont *d;
|
||||
int icont, ichan;
|
||||
int rearm = 0;
|
||||
static int running = 0;
|
||||
|
||||
if (running) {
|
||||
rearm = 1;
|
||||
goto out;
|
||||
} else {
|
||||
running = 1;
|
||||
}
|
||||
|
||||
d = dma_controllers;
|
||||
|
||||
@ -374,6 +382,8 @@ static void DMA_run (void)
|
||||
}
|
||||
}
|
||||
|
||||
running = 0;
|
||||
out:
|
||||
if (rearm)
|
||||
qemu_bh_schedule_idle(dma_bh);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user