qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Denis V. Lunev" <den@openvz.org>
To: qemu-devel@nongnu.org
Cc: den@openvz.org, John Snow <jsnow@redhat.com>,
	Pavel Butsykin <pbutsykin@virtuozzo.com>
Subject: [Qemu-devel] [PATCH 3/3] ide: really restart pending and in-flight atapi dma
Date: Wed, 23 Mar 2016 13:26:32 +0300	[thread overview]
Message-ID: <1458728792-15779-4-git-send-email-den@openvz.org> (raw)
In-Reply-To: <1458728792-15779-1-git-send-email-den@openvz.org>

From: Pavel Butsykin <pbutsykin@virtuozzo.com>

Restart of ATAPI DMA used to be unreachable, because the request to do
so wasn't indicated in bus->error_status due to the lack of spare bits, and
ide_restart_bh() would return early doing nothing.

This patch makes use of the observation that not all bit combinations were
possible in ->error_status. In particular, IDE_RETRY_READ only made sense
together with IDE_RETRY_DMA or IDE_RETRY_PIO. This allows to re-use
IDE_RETRY_READ alone as an indicator of ATAPI DMA restart request.

As a means against confusion, macros are added to test the state of
->error_status.

The patch fixes the restart of both in-flight and pending ATAPI DMA,
following the scheme similar to that of IDE DMA.

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: John Snow <jsnow@redhat.com>
---
 hw/ide/atapi.c    | 15 +++++++--------
 hw/ide/core.c     | 23 ++++++++++-------------
 hw/ide/internal.h | 18 ++++++++++++++++++
 3 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 8816b38..0d51b44 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -375,22 +375,25 @@ static void ide_atapi_cmd_check_status(IDEState *s)
 }
 /* ATAPI DMA support */
 
-/* XXX: handle read errors */
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 {
     IDEState *s = opaque;
     int data_offset, n;
 
-    if (ret < 0) { /* XXX: handle -ESTATESAVE for migration */
+    if (ret < 0) {
         if (ret == -ESTATESAVE) {
             /*
              * This case is not really an error
              * but a request to save the state.
              */
+            s->bus->error_status = IDE_RETRY_ATAPI;
             return;
+        } else if (ide_handle_rw_error(s, -ret, IDE_RETRY_ATAPI)) {
+            if (s->bus->error_status) {
+                return;
+            }
+            goto eot;
         }
-        ide_atapi_io_error(s, ret);
-        goto eot;
     }
 
     if (s->io_buffer_size > 0) {
@@ -488,10 +491,6 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
     }
 }
 
-
-/* Called by *_restart_bh when the transfer function points
- * to ide_atapi_cmd
- */
 void ide_atapi_dma_restart(IDEState *s)
 {
     /*
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 872e11f..6d7533f 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -56,7 +56,6 @@ static const int smart_attributes[][12] = {
     { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
 };
 
-static int ide_handle_rw_error(IDEState *s, int error, int op);
 static void ide_dummy_transfer_stop(IDEState *s);
 
 static void padstr(char *str, const char *src, int len)
@@ -772,7 +771,7 @@ void ide_dma_error(IDEState *s)
     ide_set_irq(s->bus);
 }
 
-static int ide_handle_rw_error(IDEState *s, int error, int op)
+int ide_handle_rw_error(IDEState *s, int error, int op)
 {
     bool is_read = (op & IDE_RETRY_READ) != 0;
     BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
@@ -782,8 +781,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
         s->bus->error_status = op;
     } else if (action == BLOCK_ERROR_ACTION_REPORT) {
         block_acct_failed(blk_get_stats(s->blk), &s->acct);
-        if (op & IDE_RETRY_DMA) {
+        if (IS_IDE_RETRY_DMA(op)) {
             ide_dma_error(s);
+        } else if (IS_IDE_RETRY_ATAPI(op)) {
+            ide_atapi_io_error(s, -error);
         } else {
             ide_rw_error(s);
         }
@@ -2533,13 +2534,13 @@ static void ide_restart_bh(void *opaque)
         }
     }
 
-    if (error_status & IDE_RETRY_DMA) {
+    if (IS_IDE_RETRY_DMA(error_status)) {
         if (error_status & IDE_RETRY_TRIM) {
             ide_restart_dma(s, IDE_DMA_TRIM);
         } else {
             ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
         }
-    } else if (error_status & IDE_RETRY_PIO) {
+    } else if (IS_IDE_RETRY_PIO(error_status)) {
         if (is_read) {
             ide_sector_read(s);
         } else {
@@ -2547,15 +2548,11 @@ static void ide_restart_bh(void *opaque)
         }
     } else if (error_status & IDE_RETRY_FLUSH) {
         ide_flush_cache(s);
+    } else if (IS_IDE_RETRY_ATAPI(error_status)) {
+        assert(s->end_transfer_func == ide_atapi_cmd);
+        ide_atapi_dma_restart(s);
     } else {
-        /*
-         * We've not got any bits to tell us about ATAPI - but
-         * we do have the end_transfer_func that tells us what
-         * we're trying to do.
-         */
-        if (s->end_transfer_func == ide_atapi_cmd) {
-            ide_atapi_dma_restart(s);
-        }
+        abort();
     }
 }
 
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index dcd8627..2e845d0 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -508,11 +508,27 @@ struct IDEDevice {
 /* These are used for the error_status field of IDEBus */
 #define IDE_RETRY_DMA  0x08
 #define IDE_RETRY_PIO  0x10
+#define IDE_RETRY_ATAPI 0x20 /* reused IDE_RETRY_READ bit */
 #define IDE_RETRY_READ  0x20
 #define IDE_RETRY_FLUSH 0x40
 #define IDE_RETRY_TRIM 0x80
 #define IDE_RETRY_HBA  0x100
 
+#define IS_IDE_RETRY_DMA(_status) \
+    ((_status) & IDE_RETRY_DMA)
+
+#define IS_IDE_RETRY_PIO(_status) \
+    ((_status) & IDE_RETRY_PIO)
+
+/*
+ * The method of the IDE_RETRY_ATAPI determination is to use a previously
+ * impossible bit combination as a new status value.
+ */
+#define IS_IDE_RETRY_ATAPI(_status)   \
+    (((_status) & IDE_RETRY_ATAPI) && \
+     !IS_IDE_RETRY_DMA(_status) &&    \
+     !IS_IDE_RETRY_PIO(_status))
+
 /*
  * a code to trigger entering error path and save/restore the "ready to DMA"
  * state just like DMA-ing state. (Ab)use EINPROGRESS as it's not supposed to
@@ -604,4 +620,6 @@ void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
                  int bus_id, int max_units);
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
 
+int ide_handle_rw_error(IDEState *s, int error, int op);
+
 #endif /* HW_IDE_INTERNAL_H */
-- 
2.1.4

  parent reply	other threads:[~2016-03-23 10:27 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-23 10:26 [Qemu-devel] [PATCH for 2.6 0/3] ide: fix loss of the dma/atapi state during migration Denis V. Lunev
2016-03-23 10:26 ` [Qemu-devel] [PATCH 1/3] ide: don't loose pending dma state Denis V. Lunev
2016-03-23 20:34   ` Paolo Bonzini
2016-03-24  9:24     ` Pavel Butsykin
2016-03-24 11:23       ` Paolo Bonzini
2016-03-24 13:38         ` Pavel Butsykin
2016-03-24 14:07           ` Paolo Bonzini
2016-03-24 15:11             ` Pavel Butsykin
2016-03-24 15:12               ` Paolo Bonzini
2016-03-24 15:20                 ` Pavel Butsykin
2016-03-24 14:47       ` Eric Blake
2016-03-24 15:40         ` Pavel Butsykin
2016-03-30 17:35   ` John Snow
2016-03-30 17:38     ` Denis V. Lunev
2016-03-30 17:44       ` John Snow
2016-03-23 10:26 ` [Qemu-devel] [PATCH 2/3] ide: restart atapi dma by re-evaluating command packet Denis V. Lunev
2016-03-23 10:26 ` Denis V. Lunev [this message]
2016-03-23 19:36   ` [Qemu-devel] [PATCH 3/3] ide: really restart pending and in-flight atapi dma John Snow
2016-03-24  8:34     ` Pavel Butsykin
  -- strict thread matches above, loose matches on Subject: below --
2016-03-28 11:48 [Qemu-devel] [PATCH v2 for 2.6 0/3] ide: fix loss of the dma/atapi state during migration Denis V. Lunev
2016-03-28 11:48 ` [Qemu-devel] [PATCH 3/3] ide: really restart pending and in-flight atapi dma Denis V. Lunev
2016-03-30 18:41   ` John Snow
2016-04-01 14:32 [Qemu-devel] [PATCH v3 0/3] ide: fix loss of the dma/atapi state during migration Denis V. Lunev
2016-04-01 14:32 ` [Qemu-devel] [PATCH 3/3] ide: really restart pending and in-flight atapi dma Denis V. Lunev
2016-04-01 22:34   ` John Snow
2016-04-04 10:32     ` Pavel Butsykin
2016-04-04 16:24       ` John Snow
2016-04-04 16:54         ` Pavel Butsykin
2016-04-04 18:12           ` John Snow
2016-04-06  6:40 [Qemu-devel] [PATCH for 2.6 v4 0/3] ide: fix loss of the dma/atapi state during migration Denis V. Lunev
2016-04-06  6:40 ` [Qemu-devel] [PATCH 3/3] ide: really restart pending and in-flight atapi dma Denis V. Lunev
2016-04-11 22:18   ` Eric Blake
2016-04-12 12:17     ` Pavel Butsykin
2016-04-12 16:47       ` John Snow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1458728792-15779-4-git-send-email-den@openvz.org \
    --to=den@openvz.org \
    --cc=jsnow@redhat.com \
    --cc=pbutsykin@virtuozzo.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).