* [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests
@ 2015-07-30 13:16 Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 1/3] virtio-scsi: use virtqueue_map_sg() when loading requests Stefan Hajnoczi
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2015-07-30 13:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi
When requests fail the error policy (-drive rerror=,werror=) determines what
happens. The 'stop' policy pauses the guest and waits for the administrator to
resolve the storage problem. It is possible to live migrate during this time
and the failed requests can be restarted on the destination host.
Two bugs:
1. Segfault due to missing sgs mapping when loading migrated failed requests.
2. Incorrect error action due to broken is_read logic.
I also noticed that the unaligned WRITE SAME test case in
tests/virtio-scsi-test.c is broken. I've included a fix for that too.
Stefan Hajnoczi (3):
virtio-scsi: use virtqueue_map_sg() when loading requests
scsi-disk: fix cmd.mode field typo
tests: virtio-scsi: clear unit attention after reset
hw/scsi/scsi-disk.c | 2 +-
hw/scsi/virtio-scsi.c | 5 +++
tests/virtio-scsi-test.c | 90 +++++++++++++++++++++++++++++-------------------
3 files changed, 60 insertions(+), 37 deletions(-)
--
2.4.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH for-2.4 1/3] virtio-scsi: use virtqueue_map_sg() when loading requests
2015-07-30 13:16 [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Stefan Hajnoczi
@ 2015-07-30 13:16 ` Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 2/3] scsi-disk: fix cmd.mode field typo Stefan Hajnoczi
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2015-07-30 13:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi
The VirtQueueElement struct is serialized during migration but the
in_sg[]/out_sg[] iovec arrays are not usable on the destination host
because the pointers are meaningless.
Use virtqueue_map_sg() to refresh in_sg[]/out_sg[] to valid pointers
based on in_addr[]/out_addr[] hwaddrs.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/scsi/virtio-scsi.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 811c3da..a8bb1c6 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -217,6 +217,11 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
assert(req->elem.in_num <= ARRAY_SIZE(req->elem.in_sg));
assert(req->elem.out_num <= ARRAY_SIZE(req->elem.out_sg));
+ virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
+ req->elem.in_num, 1);
+ virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
+ req->elem.out_num, 0);
+
if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) {
error_report("invalid SCSI request migration data");
--
2.4.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH for-2.4 2/3] scsi-disk: fix cmd.mode field typo
2015-07-30 13:16 [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 1/3] virtio-scsi: use virtqueue_map_sg() when loading requests Stefan Hajnoczi
@ 2015-07-30 13:16 ` Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 3/3] tests: virtio-scsi: clear unit attention after reset Stefan Hajnoczi
2015-07-30 13:19 ` [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2015-07-30 13:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi
The cmd.xfer field is the data length. The cmd.mode field is the data
transfer direction.
scsi_handle_rw_error() was using the wrong error policy for read
requests.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/scsi/scsi-disk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 64f0694..73fed3f 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -399,7 +399,7 @@ static void scsi_read_data(SCSIRequest *req)
*/
static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
{
- bool is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV);
+ bool is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV);
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
is_read, error);
--
2.4.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH for-2.4 3/3] tests: virtio-scsi: clear unit attention after reset
2015-07-30 13:16 [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 1/3] virtio-scsi: use virtqueue_map_sg() when loading requests Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 2/3] scsi-disk: fix cmd.mode field typo Stefan Hajnoczi
@ 2015-07-30 13:16 ` Stefan Hajnoczi
2015-07-30 13:19 ` [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2015-07-30 13:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi
The unit attention after reset (power on) prevents normal commands from
running. The unaligned WRITE SAME test never executed its command!
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
tests/virtio-scsi-test.c | 90 +++++++++++++++++++++++++++++-------------------
1 file changed, 54 insertions(+), 36 deletions(-)
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 11ccdd6..6e91ca9 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -13,6 +13,7 @@
#include "libqtest.h"
#include "qemu/osdep.h"
#include <stdio.h>
+#include "block/scsi.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
#include "libqos/pci-pc.h"
@@ -71,40 +72,6 @@ static void qvirtio_scsi_stop(void)
qtest_end();
}
-static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
-{
- QVirtIOSCSI *vs;
- QVirtioPCIDevice *dev;
- void *addr;
- int i;
-
- vs = g_new0(QVirtIOSCSI, 1);
- vs->alloc = pc_alloc_init();
- vs->bus = qpci_init_pc();
-
- dev = qvirtio_pci_device_find(vs->bus, QVIRTIO_SCSI_DEVICE_ID);
- vs->dev = (QVirtioDevice *)dev;
- g_assert(dev != NULL);
- g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
-
- qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, vs->dev);
- qvirtio_set_acknowledge(&qvirtio_pci, vs->dev);
- qvirtio_set_driver(&qvirtio_pci, vs->dev);
-
- addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
- vs->num_queues = qvirtio_config_readl(&qvirtio_pci, vs->dev,
- (uint64_t)(uintptr_t)addr);
-
- g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES);
-
- for (i = 0; i < vs->num_queues + 2; i++) {
- vs->vq[i] = qvirtqueue_setup(&qvirtio_pci, vs->dev, vs->alloc, i);
- }
-
- return vs;
-}
-
static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
{
int i;
@@ -134,7 +101,8 @@ static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
const uint8_t *data_in,
size_t data_in_len,
- uint8_t *data_out, size_t data_out_len)
+ uint8_t *data_out, size_t data_out_len,
+ QVirtIOSCSICmdResp *resp_out)
{
QVirtQueue *vq;
QVirtIOSCSICmdReq req = { { 0 } };
@@ -174,6 +142,10 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
response = readb(resp_addr + offsetof(QVirtIOSCSICmdResp, response));
+ if (resp_out) {
+ memread(resp_addr, resp_out, sizeof(*resp_out));
+ }
+
guest_free(vs->alloc, req_addr);
guest_free(vs->alloc, resp_addr);
guest_free(vs->alloc, data_in_addr);
@@ -181,6 +153,52 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
return response;
}
+static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
+{
+ const uint8_t test_unit_ready_cdb[CDB_SIZE] = {};
+ QVirtIOSCSI *vs;
+ QVirtioPCIDevice *dev;
+ QVirtIOSCSICmdResp resp;
+ void *addr;
+ int i;
+
+ vs = g_new0(QVirtIOSCSI, 1);
+ vs->alloc = pc_alloc_init();
+ vs->bus = qpci_init_pc();
+
+ dev = qvirtio_pci_device_find(vs->bus, QVIRTIO_SCSI_DEVICE_ID);
+ vs->dev = (QVirtioDevice *)dev;
+ g_assert(dev != NULL);
+ g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
+
+ qvirtio_pci_device_enable(dev);
+ qvirtio_reset(&qvirtio_pci, vs->dev);
+ qvirtio_set_acknowledge(&qvirtio_pci, vs->dev);
+ qvirtio_set_driver(&qvirtio_pci, vs->dev);
+
+ addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
+ vs->num_queues = qvirtio_config_readl(&qvirtio_pci, vs->dev,
+ (uint64_t)(uintptr_t)addr);
+
+ g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES);
+
+ for (i = 0; i < vs->num_queues + 2; i++) {
+ vs->vq[i] = qvirtqueue_setup(&qvirtio_pci, vs->dev, vs->alloc, i);
+ }
+
+ /* Clear the POWER ON OCCURRED unit attention */
+ g_assert_cmpint(virtio_scsi_do_command(vs, test_unit_ready_cdb,
+ NULL, 0, NULL, 0, &resp),
+ ==, 0);
+ g_assert_cmpint(resp.status, ==, CHECK_CONDITION);
+ g_assert_cmpint(resp.sense[0], ==, 0x70); /* Fixed format sense buffer */
+ g_assert_cmpint(resp.sense[2], ==, UNIT_ATTENTION);
+ g_assert_cmpint(resp.sense[12], ==, 0x29); /* POWER ON */
+ g_assert_cmpint(resp.sense[13], ==, 0x00);
+
+ return vs;
+}
+
/* Tests only initialization so far. TODO: Replace with functional tests */
static void pci_nop(void)
{
@@ -231,7 +249,7 @@ static void test_unaligned_write_same(void)
vs = qvirtio_scsi_pci_init(PCI_SLOT);
g_assert_cmphex(0, ==,
- virtio_scsi_do_command(vs, write_same_cdb, NULL, 0, buf, 512));
+ virtio_scsi_do_command(vs, write_same_cdb, NULL, 0, buf, 512, NULL));
qvirtio_scsi_pci_free(vs);
qvirtio_scsi_stop();
--
2.4.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests
2015-07-30 13:16 [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Stefan Hajnoczi
` (2 preceding siblings ...)
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 3/3] tests: virtio-scsi: clear unit attention after reset Stefan Hajnoczi
@ 2015-07-30 13:19 ` Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2015-07-30 13:19 UTC (permalink / raw)
To: Stefan Hajnoczi, qemu-devel
On 30/07/2015 15:16, Stefan Hajnoczi wrote:
> When requests fail the error policy (-drive rerror=,werror=) determines what
> happens. The 'stop' policy pauses the guest and waits for the administrator to
> resolve the storage problem. It is possible to live migrate during this time
> and the failed requests can be restarted on the destination host.
>
> Two bugs:
> 1. Segfault due to missing sgs mapping when loading migrated failed requests.
> 2. Incorrect error action due to broken is_read logic.
>
> I also noticed that the unaligned WRITE SAME test case in
> tests/virtio-scsi-test.c is broken. I've included a fix for that too.
>
> Stefan Hajnoczi (3):
> virtio-scsi: use virtqueue_map_sg() when loading requests
> scsi-disk: fix cmd.mode field typo
> tests: virtio-scsi: clear unit attention after reset
>
> hw/scsi/scsi-disk.c | 2 +-
> hw/scsi/virtio-scsi.c | 5 +++
> tests/virtio-scsi-test.c | 90 +++++++++++++++++++++++++++++-------------------
> 3 files changed, 60 insertions(+), 37 deletions(-)
>
All good, thanks! I'll send a pull request asap.
Paolo
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-07-30 13:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-30 13:16 [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 1/3] virtio-scsi: use virtqueue_map_sg() when loading requests Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 2/3] scsi-disk: fix cmd.mode field typo Stefan Hajnoczi
2015-07-30 13:16 ` [Qemu-devel] [PATCH for-2.4 3/3] tests: virtio-scsi: clear unit attention after reset Stefan Hajnoczi
2015-07-30 13:19 ` [Qemu-devel] [PATCH for-2.4 0/3] scsi: fixes for failed requests Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).