qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Hanging when using hw/lsi53c895a.c


From: Brian Campbell
Subject: [Qemu-devel] Hanging when using hw/lsi53c895a.c
Date: Tue, 26 Feb 2008 22:36:25 +0000
User-agent: Gnus/5.1007 (Gnus v5.10.7) XEmacs/21.4.19 (linux)

When using qemu-system-arm from CVS or 0.9.1 I've noticed that the emulator
locks up occasionally on heavy disk access.  Forcing a fsck on start up is
normally enough to trigger it.  The root cause is that scsi_read_data can be
reentered before updating sector and sector_count:

lsi_do_dma calls
  scsi_read_data, which calls
    scsi_read_complete,
      lsi_command_complete,
        lsi_do_dma,
          scsi_read_data without updating sector and sector_count,
            and so on...

This results in an unending series of reads:

scsi-disk: Command: lun=0 tag=0x10049 data=0x28 0x00 0x00 0x24 0x24 0x97 0x00 
0x00 0x90 0x00
scsi-disk: Read (sector 2368663, count 144)
scsi-disk: Read tag=0x10049 sector_count=144
scsi-disk: Data ready tag=0x10049 len=65536
scsi-disk: Read tag=0x10049 sector_count=16
scsi-disk: Data ready tag=0x10049 len=8192
scsi-disk: Read tag=0x10049 sector_count=16
scsi-disk: Data ready tag=0x10049 len=8192
scsi-disk: Read tag=0x10049 sector_count=-16
scsi-disk: Data ready tag=0x10049 len=65536
scsi-disk: Read tag=0x10049 sector_count=-144
scsi-disk: Data ready tag=0x10049 len=65536
scsi-disk: Read tag=0x10049 sector_count=-272
scsi-disk: Data ready tag=0x10049 len=65536

The attached patch ensures that the scsi_read_complete call occurs at the
end on scsi_read_data.  I'm not sure if this is how it was intended to
work -- an alternative would be to prevent lsi_command_complete calling
lsi_do_dma.  But the patch does prevent the hanging.

Index: hw/scsi-disk.c
===================================================================
RCS file: /sources/qemu/qemu/hw/scsi-disk.c,v
retrieving revision 1.20
diff -u -r1.20 scsi-disk.c
--- hw/scsi-disk.c      3 Feb 2008 04:05:50 -0000       1.20
+++ hw/scsi-disk.c      26 Feb 2008 22:31:03 -0000
@@ -171,6 +171,7 @@
     SCSIDeviceState *s = d->state;
     SCSIRequest *r;
     uint32_t n; 
+    int sector; 

     r = scsi_find_request(s, tag);
     if (!r) {   
@@ -191,17 +192,19 @@
         return; 
     }

+    sector = r->sector;
+
     n = r->sector_count;
     if (n > SCSI_DMA_BUF_SIZE / 512)
         n = SCSI_DMA_BUF_SIZE / 512;
+    r->sector += n;
+    r->sector_count -= n;
 
     r->buf_len = n * 512;
-    r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
+    r->aiocb = bdrv_aio_read(s->bdrv, sector, r->dma_buf, n,
                              scsi_read_complete, r);
     if (r->aiocb == NULL)
         scsi_command_complete(r, SENSE_HARDWARE_ERROR);
-    r->sector += n;
-    r->sector_count -= n;
 }
 
 static void scsi_write_complete(void * opaque, int ret)

  Brian

reply via email to

[Prev in Thread] Current Thread [Next in Thread]