qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC] scsi-disk: add -device scsi-disk, slow=on propert


From: Denis V. Lunev
Subject: Re: [Qemu-devel] [RFC] scsi-disk: add -device scsi-disk, slow=on property
Date: Tue, 13 Oct 2015 17:31:27 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0

On 10/13/2015 05:10 PM, Stefan Hajnoczi wrote:
The 'slow' bool property simulates an 8 second delay in responding to
simple SCSI commands that do not transfer data.

This means non-READ/WRITE commands will take 8 seconds to complete so
slow SCSI LUNs can be simulated.

Signed-off-by: Stefan Hajnoczi <address@hidden>
---
This is a quick hack and probably buggy too.  Not worth merging, but I wanted
to archive it on the mailing list in case someone wants to use it for debugging
in the future.

  hw/scsi/scsi-disk.c | 28 +++++++++++++++++++++++++++-
  1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index bada9a7..3aaa215 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -88,6 +88,9 @@ struct SCSIDiskState
      char *product;
      bool tray_open;
      bool tray_locked;
+    bool is_slow;
+    QEMUTimer *slow_timer;
+    SCSIDiskReq *slow_req;
  };
static int scsi_handle_rw_error(SCSIDiskReq *r, int error);
@@ -1833,6 +1836,17 @@ static void scsi_disk_emulate_write_data(SCSIRequest 
*req)
      }
  }
+static void scsi_disk_slow_timer_cb(void *opaque)
+{
+    SCSIDiskState *s = opaque;
+    SCSIDiskReq *r = s->slow_req;
+
+    s->slow_req = NULL;
+
+    fprintf(stderr, "%s called\n", __func__);
+    scsi_req_complete(&r->req, GOOD);
+}
+
  static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
  {
      SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
@@ -2092,7 +2106,15 @@ static int32_t scsi_disk_emulate_command(SCSIRequest 
*req, uint8_t *buf)
      assert(!r->req.aiocb);
      r->iov.iov_len = MIN(r->buflen, req->cmd.xfer);
      if (r->iov.iov_len == 0) {
-        scsi_req_complete(&r->req, GOOD);
+        if (s->is_slow) {
+            fprintf(stderr, "delaying scsi_req_complete...\n");
+            assert(!s->slow_req);

general note.
do we really such fprintf's?

+            s->slow_req = r;
+            timer_mod(s->slow_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                                     8 * 1000ULL * 1000ULL * 1000ULL);

AFAIK SCSI has a FIFO for commands thus in this case the
request that is already in the queue will be lagged
additionally

This is a simple probably lame opinion for the question.

From my POW you should follow the way I have used in
the deadline series. You should queue the request into
the slow queue and start the timer. In timer callback
you should complete expired requests and reschedule
the timer with appropriate timeout.

Den

+        } else {
+            scsi_req_complete(&r->req, GOOD);
+        }
      }
      if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
          assert(r->iov.iov_len == req->cmd.xfer);
@@ -2335,6 +2357,9 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
      blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
blk_iostatus_enable(s->qdev.conf.blk);
+
+    s->slow_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                 scsi_disk_slow_timer_cb, s);
  }
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -2773,6 +2798,7 @@ static Property scsi_disk_properties[] = {
                         DEFAULT_MAX_UNMAP_SIZE),
      DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
                         DEFAULT_MAX_IO_SIZE),
+    DEFINE_PROP_BOOL("slow", SCSIDiskState, is_slow, false),
      DEFINE_PROP_END_OF_LIST(),
  };




reply via email to

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