Commit 2dd7e10d authored by Evgeny Yakovlev's avatar Evgeny Yakovlev Committed by John Snow
Browse files

tests: in IDE and AHCI tests perform DMA write before flushing



Due to changes in flush behaviour clean disks stopped generating
flush_to_disk events and IDE and AHCI tests that test flush commands
started to fail.

This change adds additional DMA writes to affected tests before sending
flush commands so that bdrv_flush actually generates flush_to_disk event.

Signed-off-by: default avatarEvgeny Yakovlev <eyakovlev@virtuozzo.com>
Signed-off-by: default avatarDenis V. Lunev <den@openvz.org>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Message-id: 1468870792-7411-4-git-send-email-den@openvz.org
CC: Kevin Wolf <kwolf@redhat.com>
CC: Max Reitz <mreitz@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Fam Zheng <famz@redhat.com>
CC: John Snow <jsnow@redhat.com>
Signed-off-by: default avatarJohn Snow <jsnow@redhat.com>
parent 35f78ab4
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -1063,11 +1063,34 @@ static void test_dma_fragmented(void)
    g_free(tx);
}

/*
 * Write sector 1 with random data to make AHCI storage dirty
 * Needed for flush tests so that flushes actually go though the block layer
 */
static void make_dirty(AHCIQState* ahci, uint8_t port)
{
    uint64_t ptr;
    unsigned bufsize = 512;

    ptr = ahci_alloc(ahci, bufsize);
    g_assert(ptr);

    ahci_guest_io(ahci, port, CMD_WRITE_DMA, ptr, bufsize, 1);
    ahci_free(ahci, ptr);
}

static void test_flush(void)
{
    AHCIQState *ahci;
    uint8_t port;

    ahci = ahci_boot_and_enable(NULL);

    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);

    make_dirty(ahci, port);

    ahci_test_flush(ahci);
    ahci_shutdown(ahci);
}
@@ -1087,10 +1110,13 @@ static void test_flush_retry(void)
                                debug_path,
                                tmp_path, imgfmt);

    /* Issue Flush Command and wait for error */
    port = ahci_port_select(ahci);
    ahci_port_clear(ahci, port);

    /* Issue write so that flush actually goes to disk */
    make_dirty(ahci, port);

    /* Issue Flush Command and wait for error */
    cmd = ahci_guest_io_halt(ahci, port, CMD_FLUSH_CACHE, 0, 0, 0);
    ahci_guest_io_resume(ahci, cmd);

@@ -1343,9 +1369,13 @@ static void test_flush_migrate(void)

    set_context(src->parent);

    /* Issue Flush Command */
    px = ahci_port_select(src);
    ahci_port_clear(src, px);

    /* Dirty device so that flush reaches disk */
    make_dirty(src, px);

    /* Issue Flush Command */
    cmd = ahci_command_create(CMD_FLUSH_CACHE);
    ahci_command_commit(src, cmd, px);
    ahci_command_issue_async(src, cmd);
+43 −0
Original line number Diff line number Diff line
@@ -499,6 +499,39 @@ static void test_identify(void)
    ide_test_quit();
}

/*
 * Write sector 1 with random data to make IDE storage dirty
 * Needed for flush tests so that flushes actually go though the block layer
 */
static void make_dirty(uint8_t device)
{
    uint8_t status;
    size_t len = 512;
    uintptr_t guest_buf;
    void* buf;

    guest_buf = guest_alloc(guest_malloc, len);
    buf = g_malloc(len);
    g_assert(guest_buf);
    g_assert(buf);

    memwrite(guest_buf, buf, len);

    PrdtEntry prdt[] = {
        {
            .addr = cpu_to_le32(guest_buf),
            .size = cpu_to_le32(len | PRDT_EOT),
        },
    };

    status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
                              ARRAY_SIZE(prdt), NULL);
    g_assert_cmphex(status, ==, BM_STS_INTR);
    assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);

    g_free(buf);
}

static void test_flush(void)
{
    uint8_t data;
@@ -507,6 +540,11 @@ static void test_flush(void)
        "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
        tmp_path);

    qtest_irq_intercept_in(global_qtest, "ioapic");

    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
    make_dirty(0);

    /* Delay the completion of the flush request until we explicitly do it */
    g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\""));

@@ -549,6 +587,11 @@ static void test_retry_flush(const char *machine)
        "rerror=stop,werror=stop",
        debug_path, tmp_path);

    qtest_irq_intercept_in(global_qtest, "ioapic");

    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
    make_dirty(0);

    /* FLUSH CACHE command on device 0*/
    outb(IDE_BASE + reg_device, 0);
    outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);