All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO
@ 2016-12-01 20:25 Peter
  2016-12-06 11:30 ` [Qemu-devel] [Bug 1646610] " Thomas Huth
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Peter @ 2016-12-01 20:25 UTC (permalink / raw)
  To: qemu-devel

Public bug reported:

We've hit this issue twice so far, but don't have an obvious repro yet.
It's pretty rare for us to hit it but I'm still trying so I can get a
core and backtrace. The guest was Windows running a constant workload.
We were using VirtIO SCSI drivers in both cases.

In both cases we hit the assert here:

hw/scsi/scsi-generic.c:

static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    qemu_put_sbe32s(f, &r->buflen);
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
***     assert(!r->req.sg);
        qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
    }
}

>From code inspection, it seems that this will always happen if
scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

static void scsi_req_enqueue_internal(SCSIRequest *req)
{
    assert(!req->enqueued);
    scsi_req_ref(req);
    if (req->bus->info->get_sg_list) {
        req->sg = req->bus->info->get_sg_list(req);
    } else {
        req->sg = NULL;
    }
    req->enqueued = true;
    QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
}

req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi bus
since it's a method stored on the SCSIBusInfo struct. I didn't see
anything that would clear the req->sg if scsi_req_enqueue_internal is
called at least once.

I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
bus.c is called. The only other location I see scsi_req_enqueue_internal
is on the load side for the destination of a migration.

static void scsi_dma_restart_bh(void *opaque)
{
    SCSIDevice *s = opaque;
    SCSIRequest *req, *next;

    qemu_bh_delete(s->bh);
    s->bh = NULL;

    QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
        scsi_req_ref(req);
        if (req->retry) {
            req->retry = false;
            switch (req->cmd.mode) {
            case SCSI_XFER_FROM_DEV:
            case SCSI_XFER_TO_DEV:
                scsi_req_continue(req);
                break;
            case SCSI_XFER_NONE:
                scsi_req_dequeue(req);
                scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                break;
            }
        }
        scsi_req_unref(req);
    }
}

Finally when put_scsi_requests is called for migration, it seems like it
will call both virtio_scsi_save_request (from bus->info->save_request)
and scsi_generic_save_request (from req->ops->save_request) and trigger
the assert.

I searched for a bit, but didn't find anyone else reporting this. Has
anyone else seen this? It seems to me like that assert should check that
the sg list is empty instead of checking that it exists. Is this an
appropriate assessment? Assuming I find a repro, I'll try to test this
solution.

Thanks!

** Affects: qemu
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  New

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [Bug 1646610] Re: "Assertion `!r->req.sg' failed." during live migration with VirtIO
  2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
@ 2016-12-06 11:30 ` Thomas Huth
  2016-12-06 18:30 ` Peter
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Thomas Huth @ 2016-12-06 11:30 UTC (permalink / raw)
  To: qemu-devel

Which version of QEMU are you using?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  New

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [Bug 1646610] Re: "Assertion `!r->req.sg' failed." during live migration with VirtIO
  2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
  2016-12-06 11:30 ` [Qemu-devel] [Bug 1646610] " Thomas Huth
@ 2016-12-06 18:30 ` Peter
  2016-12-06 21:06 ` Thomas Huth
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Peter @ 2016-12-06 18:30 UTC (permalink / raw)
  To: qemu-devel

Hi Thomas,

Thanks for looking. We're using version 2.3.0.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  New

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [Bug 1646610] Re: "Assertion `!r->req.sg' failed." during live migration with VirtIO
  2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
  2016-12-06 11:30 ` [Qemu-devel] [Bug 1646610] " Thomas Huth
  2016-12-06 18:30 ` Peter
@ 2016-12-06 21:06 ` Thomas Huth
  2016-12-06 21:33 ` Peter
  2017-02-05  4:18 ` Launchpad Bug Tracker
  4 siblings, 0 replies; 6+ messages in thread
From: Thomas Huth @ 2016-12-06 21:06 UTC (permalink / raw)
  To: qemu-devel

OK. QEMU version 2.3 is not maintained by the QEMU project any more. Can
you reproduce it with the latest version (release candidate of 2.8
preferably, or at least 2.7)?

** Changed in: qemu
       Status: New => Incomplete

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  Incomplete

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [Bug 1646610] Re: "Assertion `!r->req.sg' failed." during live migration with VirtIO
  2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
                   ` (2 preceding siblings ...)
  2016-12-06 21:06 ` Thomas Huth
@ 2016-12-06 21:33 ` Peter
  2017-02-05  4:18 ` Launchpad Bug Tracker
  4 siblings, 0 replies; 6+ messages in thread
From: Peter @ 2016-12-06 21:33 UTC (permalink / raw)
  To: qemu-devel

Thanks Thomas. Will do.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  Incomplete

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [Bug 1646610] Re: "Assertion `!r->req.sg' failed." during live migration with VirtIO
  2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
                   ` (3 preceding siblings ...)
  2016-12-06 21:33 ` Peter
@ 2017-02-05  4:18 ` Launchpad Bug Tracker
  4 siblings, 0 replies; 6+ messages in thread
From: Launchpad Bug Tracker @ 2017-02-05  4:18 UTC (permalink / raw)
  To: qemu-devel

[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
       Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1646610

Title:
  "Assertion `!r->req.sg' failed." during live migration with VirtIO

Status in QEMU:
  Expired

Bug description:
  We've hit this issue twice so far, but don't have an obvious repro
  yet. It's pretty rare for us to hit it but I'm still trying so I can
  get a core and backtrace. The guest was Windows running a constant
  workload. We were using VirtIO SCSI drivers in both cases.

  In both cases we hit the assert here:

  hw/scsi/scsi-generic.c:

  static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  {
      SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

      qemu_put_sbe32s(f, &r->buflen);
      if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  ***     assert(!r->req.sg);
          qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
      }
  }

  From code inspection, it seems that this will always happen if
  scsi_req_enqueue_internal in hw/scsi/scsi-bus.c is ever invoked.

  static void scsi_req_enqueue_internal(SCSIRequest *req)
  {
      assert(!req->enqueued);
      scsi_req_ref(req);
      if (req->bus->info->get_sg_list) {
          req->sg = req->bus->info->get_sg_list(req);
      } else {
          req->sg = NULL;
      }
      req->enqueued = true;
      QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
  }

  req->bus->info->get_sg_list will return &req->qsgl for a virtio-scsi
  bus since it's a method stored on the SCSIBusInfo struct. I didn't see
  anything that would clear the req->sg if scsi_req_enqueue_internal is
  called at least once.

  I think this can only happen if scsi_dma_restart_bh in hw/scsi/scsi-
  bus.c is called. The only other location I see
  scsi_req_enqueue_internal is on the load side for the destination of a
  migration.

  static void scsi_dma_restart_bh(void *opaque)
  {
      SCSIDevice *s = opaque;
      SCSIRequest *req, *next;

      qemu_bh_delete(s->bh);
      s->bh = NULL;

      QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
          scsi_req_ref(req);
          if (req->retry) {
              req->retry = false;
              switch (req->cmd.mode) {
              case SCSI_XFER_FROM_DEV:
              case SCSI_XFER_TO_DEV:
                  scsi_req_continue(req);
                  break;
              case SCSI_XFER_NONE:
                  scsi_req_dequeue(req);
                  scsi_req_enqueue(req); // *** this calls scsi_req_enqueue_internal
                  break;
              }
          }
          scsi_req_unref(req);
      }
  }

  Finally when put_scsi_requests is called for migration, it seems like
  it will call both virtio_scsi_save_request (from
  bus->info->save_request) and scsi_generic_save_request (from
  req->ops->save_request) and trigger the assert.

  I searched for a bit, but didn't find anyone else reporting this. Has
  anyone else seen this? It seems to me like that assert should check
  that the sg list is empty instead of checking that it exists. Is this
  an appropriate assessment? Assuming I find a repro, I'll try to test
  this solution.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1646610/+subscriptions

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-02-05  4:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-01 20:25 [Qemu-devel] [Bug 1646610] [NEW] "Assertion `!r->req.sg' failed." during live migration with VirtIO Peter
2016-12-06 11:30 ` [Qemu-devel] [Bug 1646610] " Thomas Huth
2016-12-06 18:30 ` Peter
2016-12-06 21:06 ` Thomas Huth
2016-12-06 21:33 ` Peter
2017-02-05  4:18 ` Launchpad Bug Tracker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.