Patchwork AHCI: Fix port reset race

login
register
mail settings
Submitter Alexander Graf
Date Jan. 30, 2012, 10:29 p.m.
Message ID <1327962588-5230-2-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/138667/
State New
Headers show

Comments

Alexander Graf - Jan. 30, 2012, 10:29 p.m.
bdrv_aio_cancel() can trigger bdrv_aio_flush() which makes all aio
that is currently in flight finish. So what we do is:

  port reset
  detect ncq in flight
  cancel ncq
  delete ncq sg list

at which point we have double freed the sg list. Instead, with this
patch we do:

  port reset
  detect ncq in flight
  cancel ncq
  check if we are really still in flight
  delete ncq sg list

which makes things work and gets rid of the race.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ide/ahci.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
Kevin Wolf - Feb. 9, 2012, 2:42 p.m.
Am 30.01.2012 23:29, schrieb Alexander Graf:
> bdrv_aio_cancel() can trigger bdrv_aio_flush() which makes all aio
> that is currently in flight finish. So what we do is:
> 
>   port reset
>   detect ncq in flight
>   cancel ncq
>   delete ncq sg list
> 
> at which point we have double freed the sg list. Instead, with this
> patch we do:
> 
>   port reset
>   detect ncq in flight
>   cancel ncq
>   check if we are really still in flight
>   delete ncq sg list
> 
> which makes things work and gets rid of the race.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>

Thanks, applied to the block branch.

Kevin

Patch

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 8869fd6..c2c168d 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -560,6 +560,11 @@  static void ahci_reset_port(AHCIState *s, int port)
             ncq_tfs->aiocb = NULL;
         }
 
+        /* Maybe we just finished the request thanks to bdrv_aio_cancel() */
+        if (!ncq_tfs->used) {
+            continue;
+        }
+
         qemu_sglist_destroy(&ncq_tfs->sglist);
         ncq_tfs->used = 0;
     }