ia64/xen-unstable

changeset 8112:3c687c6905e7

Fix a race condition for multi-thread qemu dma, where vmx linux guests
show warning "dma interrupt lost" and dma becomes very slow.

root cause: In the time between set ide irq and set dma status, if guest
receive the irq and query the status, it will find the status is not
ready and therefore treat it as pseudo interrupt. Change the order of
set irq and set dma status fixes this issue.

Signed-off-by: Ke Yu <ke.yu@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Nov 29 11:38:53 2005 +0100 (2005-11-29)
parents ec370b3d2df3
children 3a54c21b65de
files tools/ioemu/hw/ide.c
line diff
     1.1 --- a/tools/ioemu/hw/ide.c	Tue Nov 29 01:00:10 2005 +0000
     1.2 +++ b/tools/ioemu/hw/ide.c	Tue Nov 29 11:38:53 2005 +0100
     1.3 @@ -669,6 +669,8 @@ static int ide_read_dma_cb(IDEState *s,
     1.4      }
     1.5      if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
     1.6          s->status = READY_STAT | SEEK_STAT;
     1.7 +        s->bmdma->status &= ~BM_STATUS_DMAING;
     1.8 +        s->bmdma->status |= BM_STATUS_INT;
     1.9          ide_set_irq(s);
    1.10  #ifdef DEBUG_IDE_ATAPI
    1.11          printf("dma status=0x%x\n", s->status);
    1.12 @@ -736,6 +738,8 @@ static int ide_write_dma_cb(IDEState *s,
    1.13              if (n == 0) {
    1.14                  /* end of transfer */
    1.15                  s->status = READY_STAT | SEEK_STAT;
    1.16 +                s->bmdma->status &= ~BM_STATUS_DMAING;
    1.17 +                s->bmdma->status |= BM_STATUS_INT;
    1.18                  ide_set_irq(s);
    1.19                  return 0;
    1.20              }
    1.21 @@ -983,6 +987,8 @@ static int ide_atapi_cmd_read_dma_cb(IDE
    1.22      if (s->packet_transfer_size <= 0) {
    1.23          s->status = READY_STAT;
    1.24          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
    1.25 +        s->bmdma->status &= ~BM_STATUS_DMAING;
    1.26 +        s->bmdma->status |= BM_STATUS_INT;
    1.27          ide_set_irq(s);
    1.28  #ifdef DEBUG_IDE_ATAPI
    1.29          printf("dma status=0x%x\n", s->status);
    1.30 @@ -2065,8 +2071,6 @@ static void ide_dma_loop(BMDMAState *bm)
    1.31      }
    1.32      /* end of transfer */
    1.33   the_end:
    1.34 -    bm->status &= ~BM_STATUS_DMAING;
    1.35 -    bm->status |= BM_STATUS_INT;
    1.36      bm->dma_cb = NULL;
    1.37      bm->ide_if = NULL;
    1.38  }