All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/26] Block patches
@ 2015-01-09 10:16 Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 01/26] libqos: Convert malloc-pc allocator to a generic allocator Stefan Hajnoczi
                   ` (26 more replies)
  0 siblings, 27 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

This pull request depends on the previous block pull request which has not been
merged yet.  It was sent on Monday, 5th of January (Message-id:
<1420458696-1885-1-git-send-email-stefanha@redhat.com>).

The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:

  migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)

are available in the git repository at:

  git://github.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:

  NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)

----------------------------------------------------------------

----------------------------------------------------------------

Alex Friedman (1):
  nvme: Fix get/set number of queues feature

Anubhav Rakshit (1):
  NVMe: Set correct VS Value for 1.1 Compliant Controllers

Chrysostomos Nanakos (1):
  MAINTAINERS: Update email addresses for Chrysostomos Nanakos

Fam Zheng (7):
  .gitignore: Ignore generated "common.env"
  qemu-iotests: Replace "/bin/true" with "true"
  qemu-iotests: Add "_supported_os Linux" to 058
  tests/Makefile: Add check-block to make check on Linux
  qemu-iotests: Add supported os parameter for python tests
  block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE,
    TARGET}
  MAINTAINERS: Add migration/block* to block subsystem

John Snow (1):
  ide: Implement VPD response for ATAPI

Marc Marí (6):
  libqos: Convert malloc-pc allocator to a generic allocator
  libqos: Change use of pointers to uint64_t in virtio
  tests: Prepare virtio-blk-test for multi-arch implementation
  libqos: Remove PCI assumptions in constants of virtio driver
  libqos: Add malloc generic
  libqos: Add virtio MMIO support

Paolo Bonzini (6):
  coroutine-ucontext: use __thread
  qemu-thread: add per-thread atexit functions
  test-coroutine: avoid overflow on 32-bit systems
  QSLIST: add lock-free operations
  coroutine: rewrite pool to avoid mutex
  coroutine: drop qemu_coroutine_adjust_pool_size

Peter Lieven (2):
  coroutine: try harder not to delete coroutines
  block: limited request size in write zeroes unsupported path

Programmingkid (1):
  block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it
    reports the correct length of a real CD

 .gitignore                       |   1 +
 MAINTAINERS                      |   2 +-
 block.c                          |  11 +-
 block/block-backend.c            |   4 -
 block/raw-posix.c                |  18 ++-
 blockdev.c                       |   6 +-
 configure                        |   2 +-
 coroutine-ucontext.c             |  69 +++-------
 hw/block/dataplane/virtio-blk.c  |   3 +-
 hw/block/nvme.c                  |   8 +-
 hw/ide/atapi.c                   | 111 ++++++++++++++--
 hw/ide/internal.h                |   1 +
 include/block/block.h            |   3 +-
 include/block/coroutine.h        |  10 --
 include/qemu/queue.h             |  15 ++-
 include/qemu/thread.h            |   4 +
 qemu-coroutine.c                 | 103 +++++++-------
 tests/Makefile                   |   9 +-
 tests/libqos/malloc-generic.c    |  50 +++++++
 tests/libqos/malloc-generic.h    |  21 +++
 tests/libqos/malloc-pc.c         | 280 +--------------------------------------
 tests/libqos/malloc-pc.h         |  11 +-
 tests/libqos/malloc.c            | 270 +++++++++++++++++++++++++++++++++++++
 tests/libqos/malloc.h            |  45 ++++---
 tests/libqos/virtio-mmio.c       | 190 ++++++++++++++++++++++++++
 tests/libqos/virtio-mmio.h       |  46 +++++++
 tests/libqos/virtio-pci.c        |  50 +++----
 tests/libqos/virtio-pci.h        |  24 ++--
 tests/libqos/virtio.c            |   8 +-
 tests/libqos/virtio.h            |  16 +--
 tests/qemu-iotests/058           |   1 +
 tests/qemu-iotests/common.config |   2 +-
 tests/qemu-iotests/common.filter |   2 +-
 tests/qemu-iotests/common.rc     |   2 +-
 tests/qemu-iotests/iotests.py    |   5 +-
 tests/test-coroutine.c           |   2 +-
 tests/virtio-blk-test.c          | 249 +++++++++++++++++++++++-----------
 util/qemu-thread-posix.c         |  37 ++++++
 util/qemu-thread-win32.c         |  48 +++++--
 39 files changed, 1154 insertions(+), 585 deletions(-)
 create mode 100644 tests/libqos/malloc-generic.c
 create mode 100644 tests/libqos/malloc-generic.h
 create mode 100644 tests/libqos/malloc.c
 create mode 100644 tests/libqos/virtio-mmio.c
 create mode 100644 tests/libqos/virtio-mmio.h

-- 
2.1.0

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

* [Qemu-devel] [PULL 01/26] libqos: Convert malloc-pc allocator to a generic allocator
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 02/26] libqos: Change use of pointers to uint64_t in virtio Stefan Hajnoczi
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

The allocator in malloc-pc has been extracted, so it can be used in every arch.
This operation showed that both the alloc and free functions can be also
generic.
Because of this, the QGuestAllocator has been removed from is function to wrap
the alloc and free function, and now just contains the allocator parameters.
As a result, only the allocator initalizer and unitializer are arch dependent.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile           |   2 +-
 tests/libqos/malloc-pc.c | 280 +----------------------------------------------
 tests/libqos/malloc-pc.h |  11 +-
 tests/libqos/malloc.c    | 270 +++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/malloc.h    |  45 +++++---
 5 files changed, 309 insertions(+), 299 deletions(-)
 create mode 100644 tests/libqos/malloc.c

diff --git a/tests/Makefile b/tests/Makefile
index e4ddb6a..c2e2e52 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -298,7 +298,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) l
 tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a
 tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a
 
-libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o
+libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
 libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c
index f4218c6..c9c48fd 100644
--- a/tests/libqos/malloc-pc.c
+++ b/tests/libqos/malloc-pc.c
@@ -17,296 +17,28 @@
 #include "hw/nvram/fw_cfg.h"
 
 #include "qemu-common.h"
-#include "qemu/queue.h"
 #include <glib.h>
 
 #define PAGE_SIZE (4096)
 
-#define MLIST_ENTNAME entries
-typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
-typedef struct MemBlock {
-    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
-    uint64_t size;
-    uint64_t addr;
-} MemBlock;
-
-typedef struct PCAlloc
-{
-    QGuestAllocator alloc;
-    PCAllocOpts opts;
-    uint64_t start;
-    uint64_t end;
-
-    MemList used;
-    MemList free;
-} PCAlloc;
-
-static MemBlock *mlist_new(uint64_t addr, uint64_t size)
-{
-    MemBlock *block;
-
-    if (!size) {
-        return NULL;
-    }
-    block = g_malloc0(sizeof(MemBlock));
-
-    block->addr = addr;
-    block->size = size;
-
-    return block;
-}
-
-static void mlist_delete(MemList *list, MemBlock *node)
-{
-    g_assert(list && node);
-    QTAILQ_REMOVE(list, node, MLIST_ENTNAME);
-    g_free(node);
-}
-
-static MemBlock *mlist_find_key(MemList *head, uint64_t addr)
-{
-    MemBlock *node;
-    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
-        if (node->addr == addr) {
-            return node;
-        }
-    }
-    return NULL;
-}
-
-static MemBlock *mlist_find_space(MemList *head, uint64_t size)
-{
-    MemBlock *node;
-
-    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
-        if (node->size >= size) {
-            return node;
-        }
-    }
-    return NULL;
-}
-
-static MemBlock *mlist_sort_insert(MemList *head, MemBlock *insr)
-{
-    MemBlock *node;
-    g_assert(head && insr);
-
-    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
-        if (insr->addr < node->addr) {
-            QTAILQ_INSERT_BEFORE(node, insr, MLIST_ENTNAME);
-            return insr;
-        }
-    }
-
-    QTAILQ_INSERT_TAIL(head, insr, MLIST_ENTNAME);
-    return insr;
-}
-
-static inline uint64_t mlist_boundary(MemBlock *node)
-{
-    return node->size + node->addr;
-}
-
-static MemBlock *mlist_join(MemList *head, MemBlock *left, MemBlock *right)
-{
-    g_assert(head && left && right);
-
-    left->size += right->size;
-    mlist_delete(head, right);
-    return left;
-}
-
-static void mlist_coalesce(MemList *head, MemBlock *node)
-{
-    g_assert(node);
-    MemBlock *left;
-    MemBlock *right;
-    char merge;
-
-    do {
-        merge = 0;
-        left = QTAILQ_PREV(node, MemList, MLIST_ENTNAME);
-        right = QTAILQ_NEXT(node, MLIST_ENTNAME);
-
-        /* clowns to the left of me */
-        if (left && mlist_boundary(left) == node->addr) {
-            node = mlist_join(head, left, node);
-            merge = 1;
-        }
-
-        /* jokers to the right */
-        if (right && mlist_boundary(node) == right->addr) {
-            node = mlist_join(head, node, right);
-            merge = 1;
-        }
-
-    } while (merge);
-}
-
-static uint64_t pc_mlist_fulfill(PCAlloc *s, MemBlock *freenode, uint64_t size)
-{
-    uint64_t addr;
-    MemBlock *usednode;
-
-    g_assert(freenode);
-    g_assert_cmpint(freenode->size, >=, size);
-
-    addr = freenode->addr;
-    if (freenode->size == size) {
-        /* re-use this freenode as our used node */
-        QTAILQ_REMOVE(&s->free, freenode, MLIST_ENTNAME);
-        usednode = freenode;
-    } else {
-        /* adjust the free node and create a new used node */
-        freenode->addr += size;
-        freenode->size -= size;
-        usednode = mlist_new(addr, size);
-    }
-
-    mlist_sort_insert(&s->used, usednode);
-    return addr;
-}
-
-/* To assert the correctness of the list.
- * Used only if PC_ALLOC_PARANOID is set. */
-static void pc_mlist_check(PCAlloc *s)
-{
-    MemBlock *node;
-    uint64_t addr = s->start > 0 ? s->start - 1 : 0;
-    uint64_t next = s->start;
-
-    QTAILQ_FOREACH(node, &s->free, MLIST_ENTNAME) {
-        g_assert_cmpint(node->addr, >, addr);
-        g_assert_cmpint(node->addr, >=, next);
-        addr = node->addr;
-        next = node->addr + node->size;
-    }
-
-    addr = s->start > 0 ? s->start - 1 : 0;
-    next = s->start;
-    QTAILQ_FOREACH(node, &s->used, MLIST_ENTNAME) {
-        g_assert_cmpint(node->addr, >, addr);
-        g_assert_cmpint(node->addr, >=, next);
-        addr = node->addr;
-        next = node->addr + node->size;
-    }
-}
-
-static uint64_t pc_mlist_alloc(PCAlloc *s, uint64_t size)
-{
-    MemBlock *node;
-
-    node = mlist_find_space(&s->free, size);
-    if (!node) {
-        fprintf(stderr, "Out of guest memory.\n");
-        g_assert_not_reached();
-    }
-    return pc_mlist_fulfill(s, node, size);
-}
-
-static void pc_mlist_free(PCAlloc *s, uint64_t addr)
-{
-    MemBlock *node;
-
-    if (addr == 0) {
-        return;
-    }
-
-    node = mlist_find_key(&s->used, addr);
-    if (!node) {
-        fprintf(stderr, "Error: no record found for an allocation at "
-                "0x%016" PRIx64 ".\n",
-                addr);
-        g_assert_not_reached();
-    }
-
-    /* Rip it out of the used list and re-insert back into the free list. */
-    QTAILQ_REMOVE(&s->used, node, MLIST_ENTNAME);
-    mlist_sort_insert(&s->free, node);
-    mlist_coalesce(&s->free, node);
-}
-
-static uint64_t pc_alloc(QGuestAllocator *allocator, size_t size)
-{
-    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
-    uint64_t rsize = size;
-    uint64_t naddr;
-
-    rsize += (PAGE_SIZE - 1);
-    rsize &= -PAGE_SIZE;
-    g_assert_cmpint((s->start + rsize), <=, s->end);
-    g_assert_cmpint(rsize, >=, size);
-
-    naddr = pc_mlist_alloc(s, rsize);
-    if (s->opts & PC_ALLOC_PARANOID) {
-        pc_mlist_check(s);
-    }
-
-    return naddr;
-}
-
-static void pc_free(QGuestAllocator *allocator, uint64_t addr)
-{
-    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
-
-    pc_mlist_free(s, addr);
-    if (s->opts & PC_ALLOC_PARANOID) {
-        pc_mlist_check(s);
-    }
-}
-
 /*
  * Mostly for valgrind happiness, but it does offer
  * a chokepoint for debugging guest memory leaks, too.
  */
 void pc_alloc_uninit(QGuestAllocator *allocator)
 {
-    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
-    MemBlock *node;
-    MemBlock *tmp;
-    PCAllocOpts mask;
-
-    /* Check for guest leaks, and destroy the list. */
-    QTAILQ_FOREACH_SAFE(node, &s->used, MLIST_ENTNAME, tmp) {
-        if (s->opts & (PC_ALLOC_LEAK_WARN | PC_ALLOC_LEAK_ASSERT)) {
-            fprintf(stderr, "guest malloc leak @ 0x%016" PRIx64 "; "
-                    "size 0x%016" PRIx64 ".\n",
-                    node->addr, node->size);
-        }
-        if (s->opts & (PC_ALLOC_LEAK_ASSERT)) {
-            g_assert_not_reached();
-        }
-        g_free(node);
-    }
-
-    /* If we have previously asserted that there are no leaks, then there
-     * should be only one node here with a specific address and size. */
-    mask = PC_ALLOC_LEAK_ASSERT | PC_ALLOC_PARANOID;
-    QTAILQ_FOREACH_SAFE(node, &s->free, MLIST_ENTNAME, tmp) {
-        if ((s->opts & mask) == mask) {
-            if ((node->addr != s->start) ||
-                (node->size != s->end - s->start)) {
-                fprintf(stderr, "Free list is corrupted.\n");
-                g_assert_not_reached();
-            }
-        }
-
-        g_free(node);
-    }
-
-    g_free(s);
+    alloc_uninit(allocator);
 }
 
-QGuestAllocator *pc_alloc_init_flags(PCAllocOpts flags)
+QGuestAllocator *pc_alloc_init_flags(QAllocOpts flags)
 {
-    PCAlloc *s = g_malloc0(sizeof(*s));
+    QGuestAllocator *s = g_malloc0(sizeof(*s));
     uint64_t ram_size;
     QFWCFG *fw_cfg = pc_fw_cfg_init();
     MemBlock *node;
 
     s->opts = flags;
-    s->alloc.alloc = pc_alloc;
-    s->alloc.free = pc_free;
+    s->page_size = PAGE_SIZE;
 
     ram_size = qfw_cfg_get_u64(fw_cfg, FW_CFG_RAM_SIZE);
 
@@ -325,10 +57,10 @@ QGuestAllocator *pc_alloc_init_flags(PCAllocOpts flags)
     node = mlist_new(s->start, s->end - s->start);
     QTAILQ_INSERT_HEAD(&s->free, node, MLIST_ENTNAME);
 
-    return &s->alloc;
+    return s;
 }
 
 inline QGuestAllocator *pc_alloc_init(void)
 {
-    return pc_alloc_init_flags(PC_ALLOC_NO_FLAGS);
+    return pc_alloc_init_flags(ALLOC_NO_FLAGS);
 }
diff --git a/tests/libqos/malloc-pc.h b/tests/libqos/malloc-pc.h
index 9f525e3..86ab9f0 100644
--- a/tests/libqos/malloc-pc.h
+++ b/tests/libqos/malloc-pc.h
@@ -15,15 +15,8 @@
 
 #include "libqos/malloc.h"
 
-typedef enum {
-    PC_ALLOC_NO_FLAGS    = 0x00,
-    PC_ALLOC_LEAK_WARN   = 0x01,
-    PC_ALLOC_LEAK_ASSERT = 0x02,
-    PC_ALLOC_PARANOID    = 0x04
-} PCAllocOpts;
-
 QGuestAllocator *pc_alloc_init(void);
-QGuestAllocator *pc_alloc_init_flags(PCAllocOpts flags);
-void             pc_alloc_uninit(QGuestAllocator *allocator);
+QGuestAllocator *pc_alloc_init_flags(QAllocOpts flags);
+void pc_alloc_uninit(QGuestAllocator *allocator);
 
 #endif
diff --git a/tests/libqos/malloc.c b/tests/libqos/malloc.c
new file mode 100644
index 0000000..5debf18
--- /dev/null
+++ b/tests/libqos/malloc.c
@@ -0,0 +1,270 @@
+/*
+ * libqos malloc support
+ *
+ * Copyright (c) 2014
+ *
+ * Author:
+ *  John Snow <jsnow@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "libqos/malloc.h"
+#include "qemu-common.h"
+#include <stdio.h>
+#include <inttypes.h>
+#include <glib.h>
+
+static void mlist_delete(MemList *list, MemBlock *node)
+{
+    g_assert(list && node);
+    QTAILQ_REMOVE(list, node, MLIST_ENTNAME);
+    g_free(node);
+}
+
+static MemBlock *mlist_find_key(MemList *head, uint64_t addr)
+{
+    MemBlock *node;
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (node->addr == addr) {
+            return node;
+        }
+    }
+    return NULL;
+}
+
+static MemBlock *mlist_find_space(MemList *head, uint64_t size)
+{
+    MemBlock *node;
+
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (node->size >= size) {
+            return node;
+        }
+    }
+    return NULL;
+}
+
+static MemBlock *mlist_sort_insert(MemList *head, MemBlock *insr)
+{
+    MemBlock *node;
+    g_assert(head && insr);
+
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (insr->addr < node->addr) {
+            QTAILQ_INSERT_BEFORE(node, insr, MLIST_ENTNAME);
+            return insr;
+        }
+    }
+
+    QTAILQ_INSERT_TAIL(head, insr, MLIST_ENTNAME);
+    return insr;
+}
+
+static inline uint64_t mlist_boundary(MemBlock *node)
+{
+    return node->size + node->addr;
+}
+
+static MemBlock *mlist_join(MemList *head, MemBlock *left, MemBlock *right)
+{
+    g_assert(head && left && right);
+
+    left->size += right->size;
+    mlist_delete(head, right);
+    return left;
+}
+
+static void mlist_coalesce(MemList *head, MemBlock *node)
+{
+    g_assert(node);
+    MemBlock *left;
+    MemBlock *right;
+    char merge;
+
+    do {
+        merge = 0;
+        left = QTAILQ_PREV(node, MemList, MLIST_ENTNAME);
+        right = QTAILQ_NEXT(node, MLIST_ENTNAME);
+
+        /* clowns to the left of me */
+        if (left && mlist_boundary(left) == node->addr) {
+            node = mlist_join(head, left, node);
+            merge = 1;
+        }
+
+        /* jokers to the right */
+        if (right && mlist_boundary(node) == right->addr) {
+            node = mlist_join(head, node, right);
+            merge = 1;
+        }
+
+    } while (merge);
+}
+
+static uint64_t mlist_fulfill(QGuestAllocator *s, MemBlock *freenode,
+                                                                uint64_t size)
+{
+    uint64_t addr;
+    MemBlock *usednode;
+
+    g_assert(freenode);
+    g_assert_cmpint(freenode->size, >=, size);
+
+    addr = freenode->addr;
+    if (freenode->size == size) {
+        /* re-use this freenode as our used node */
+        QTAILQ_REMOVE(&s->free, freenode, MLIST_ENTNAME);
+        usednode = freenode;
+    } else {
+        /* adjust the free node and create a new used node */
+        freenode->addr += size;
+        freenode->size -= size;
+        usednode = mlist_new(addr, size);
+    }
+
+    mlist_sort_insert(&s->used, usednode);
+    return addr;
+}
+
+/* To assert the correctness of the list.
+ * Used only if ALLOC_PARANOID is set. */
+static void mlist_check(QGuestAllocator *s)
+{
+    MemBlock *node;
+    uint64_t addr = s->start > 0 ? s->start - 1 : 0;
+    uint64_t next = s->start;
+
+    QTAILQ_FOREACH(node, &s->free, MLIST_ENTNAME) {
+        g_assert_cmpint(node->addr, >, addr);
+        g_assert_cmpint(node->addr, >=, next);
+        addr = node->addr;
+        next = node->addr + node->size;
+    }
+
+    addr = s->start > 0 ? s->start - 1 : 0;
+    next = s->start;
+    QTAILQ_FOREACH(node, &s->used, MLIST_ENTNAME) {
+        g_assert_cmpint(node->addr, >, addr);
+        g_assert_cmpint(node->addr, >=, next);
+        addr = node->addr;
+        next = node->addr + node->size;
+    }
+}
+
+static uint64_t mlist_alloc(QGuestAllocator *s, uint64_t size)
+{
+    MemBlock *node;
+
+    node = mlist_find_space(&s->free, size);
+    if (!node) {
+        fprintf(stderr, "Out of guest memory.\n");
+        g_assert_not_reached();
+    }
+    return mlist_fulfill(s, node, size);
+}
+
+static void mlist_free(QGuestAllocator *s, uint64_t addr)
+{
+    MemBlock *node;
+
+    if (addr == 0) {
+        return;
+    }
+
+    node = mlist_find_key(&s->used, addr);
+    if (!node) {
+        fprintf(stderr, "Error: no record found for an allocation at "
+                "0x%016" PRIx64 ".\n",
+                addr);
+        g_assert_not_reached();
+    }
+
+    /* Rip it out of the used list and re-insert back into the free list. */
+    QTAILQ_REMOVE(&s->used, node, MLIST_ENTNAME);
+    mlist_sort_insert(&s->free, node);
+    mlist_coalesce(&s->free, node);
+}
+
+MemBlock *mlist_new(uint64_t addr, uint64_t size)
+{
+    MemBlock *block;
+
+    if (!size) {
+        return NULL;
+    }
+    block = g_malloc0(sizeof(MemBlock));
+
+    block->addr = addr;
+    block->size = size;
+
+    return block;
+}
+
+/*
+ * Mostly for valgrind happiness, but it does offer
+ * a chokepoint for debugging guest memory leaks, too.
+ */
+void alloc_uninit(QGuestAllocator *allocator)
+{
+    MemBlock *node;
+    MemBlock *tmp;
+    QAllocOpts mask;
+
+    /* Check for guest leaks, and destroy the list. */
+    QTAILQ_FOREACH_SAFE(node, &allocator->used, MLIST_ENTNAME, tmp) {
+        if (allocator->opts & (ALLOC_LEAK_WARN | ALLOC_LEAK_ASSERT)) {
+            fprintf(stderr, "guest malloc leak @ 0x%016" PRIx64 "; "
+                    "size 0x%016" PRIx64 ".\n",
+                    node->addr, node->size);
+        }
+        if (allocator->opts & (ALLOC_LEAK_ASSERT)) {
+            g_assert_not_reached();
+        }
+        g_free(node);
+    }
+
+    /* If we have previously asserted that there are no leaks, then there
+     * should be only one node here with a specific address and size. */
+    mask = ALLOC_LEAK_ASSERT | ALLOC_PARANOID;
+    QTAILQ_FOREACH_SAFE(node, &allocator->free, MLIST_ENTNAME, tmp) {
+        if ((allocator->opts & mask) == mask) {
+            if ((node->addr != allocator->start) ||
+                (node->size != allocator->end - allocator->start)) {
+                fprintf(stderr, "Free list is corrupted.\n");
+                g_assert_not_reached();
+            }
+        }
+
+        g_free(node);
+    }
+
+    g_free(allocator);
+}
+
+uint64_t guest_alloc(QGuestAllocator *allocator, size_t size)
+{
+    uint64_t rsize = size;
+    uint64_t naddr;
+
+    rsize += (allocator->page_size - 1);
+    rsize &= -allocator->page_size;
+    g_assert_cmpint((allocator->start + rsize), <=, allocator->end);
+    g_assert_cmpint(rsize, >=, size);
+
+    naddr = mlist_alloc(allocator, rsize);
+    if (allocator->opts & ALLOC_PARANOID) {
+        mlist_check(allocator);
+    }
+
+    return naddr;
+}
+
+void guest_free(QGuestAllocator *allocator, uint64_t addr)
+{
+    mlist_free(allocator, addr);
+    if (allocator->opts & ALLOC_PARANOID) {
+        mlist_check(allocator);
+    }
+}
diff --git a/tests/libqos/malloc.h b/tests/libqos/malloc.h
index 5565381..465efeb 100644
--- a/tests/libqos/malloc.h
+++ b/tests/libqos/malloc.h
@@ -15,24 +15,39 @@
 
 #include <stdint.h>
 #include <sys/types.h>
+#include "qemu/queue.h"
 
-typedef struct QGuestAllocator QGuestAllocator;
+#define MLIST_ENTNAME entries
 
-struct QGuestAllocator
-{
-    uint64_t (*alloc)(QGuestAllocator *allocator, size_t size);
-    void (*free)(QGuestAllocator *allocator, uint64_t addr);
-};
+typedef enum {
+    ALLOC_NO_FLAGS    = 0x00,
+    ALLOC_LEAK_WARN   = 0x01,
+    ALLOC_LEAK_ASSERT = 0x02,
+    ALLOC_PARANOID    = 0x04
+} QAllocOpts;
+
+typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
+typedef struct MemBlock {
+    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
+    uint64_t size;
+    uint64_t addr;
+} MemBlock;
+
+typedef struct QGuestAllocator {
+    QAllocOpts opts;
+    uint64_t start;
+    uint64_t end;
+    uint32_t page_size;
+
+    MemList used;
+    MemList free;
+} QGuestAllocator;
+
+MemBlock *mlist_new(uint64_t addr, uint64_t size);
+void alloc_uninit(QGuestAllocator *allocator);
 
 /* Always returns page aligned values */
-static inline uint64_t guest_alloc(QGuestAllocator *allocator, size_t size)
-{
-    return allocator->alloc(allocator, size);
-}
-
-static inline void guest_free(QGuestAllocator *allocator, uint64_t addr)
-{
-    allocator->free(allocator, addr);
-}
+uint64_t guest_alloc(QGuestAllocator *allocator, size_t size);
+void guest_free(QGuestAllocator *allocator, uint64_t addr);
 
 #endif
-- 
2.1.0

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

* [Qemu-devel] [PULL 02/26] libqos: Change use of pointers to uint64_t in virtio
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 01/26] libqos: Convert malloc-pc allocator to a generic allocator Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 03/26] tests: Prepare virtio-blk-test for multi-arch implementation Stefan Hajnoczi
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Convert use of pointers in functions of virtio to uint64_t in order to make it
platform-independent.

Add casting from pointers (in PCI functions) to uint64_t and vice versa through
uintptr_t.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/virtio-pci.c | 20 +++++++++++---------
 tests/libqos/virtio.c     |  8 ++++----
 tests/libqos/virtio.h     | 16 ++++++++--------
 tests/virtio-blk-test.c   | 21 ++++++++++++++-------
 4 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 788ebaf..92bcac1 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -60,25 +60,25 @@ static void qvirtio_pci_assign_device(QVirtioDevice *d, void *data)
     *vpcidev = (QVirtioPCIDevice *)d;
 }
 
-static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, void *addr)
+static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t addr)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readb(dev->pdev, addr);
+    return qpci_io_readb(dev->pdev, (void *)(uintptr_t)addr);
 }
 
-static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, void *addr)
+static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t addr)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readw(dev->pdev, addr);
+    return qpci_io_readw(dev->pdev, (void *)(uintptr_t)addr);
 }
 
-static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, void *addr)
+static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t addr)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readl(dev->pdev, addr);
+    return qpci_io_readl(dev->pdev, (void *)(uintptr_t)addr);
 }
 
-static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, void *addr)
+static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
     int i;
@@ -86,11 +86,13 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, void *addr)
 
     if (qtest_big_endian()) {
         for (i = 0; i < 8; ++i) {
-            u64 |= (uint64_t)qpci_io_readb(dev->pdev, addr + i) << (7 - i) * 8;
+            u64 |= (uint64_t)qpci_io_readb(dev->pdev,
+                                (void *)(uintptr_t)addr + i) << (7 - i) * 8;
         }
     } else {
         for (i = 0; i < 8; ++i) {
-            u64 |= (uint64_t)qpci_io_readb(dev->pdev, addr + i) << i * 8;
+            u64 |= (uint64_t)qpci_io_readb(dev->pdev,
+                                (void *)(uintptr_t)addr + i) << i * 8;
         }
     }
 
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index a061289..3205b88 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -12,25 +12,25 @@
 #include "libqos/virtio.h"
 
 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr)
+                                                                uint64_t addr)
 {
     return bus->config_readb(d, addr);
 }
 
 uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr)
+                                                                uint64_t addr)
 {
     return bus->config_readw(d, addr);
 }
 
 uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr)
+                                                                uint64_t addr)
 {
     return bus->config_readl(d, addr);
 }
 
 uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr)
+                                                                uint64_t addr)
 {
     return bus->config_readq(d, addr);
 }
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 29fbacb..2449fee 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -93,10 +93,10 @@ typedef struct QVRingIndirectDesc {
 } QVRingIndirectDesc;
 
 typedef struct QVirtioBus {
-    uint8_t (*config_readb)(QVirtioDevice *d, void *addr);
-    uint16_t (*config_readw)(QVirtioDevice *d, void *addr);
-    uint32_t (*config_readl)(QVirtioDevice *d, void *addr);
-    uint64_t (*config_readq)(QVirtioDevice *d, void *addr);
+    uint8_t (*config_readb)(QVirtioDevice *d, uint64_t addr);
+    uint16_t (*config_readw)(QVirtioDevice *d, uint64_t addr);
+    uint32_t (*config_readl)(QVirtioDevice *d, uint64_t addr);
+    uint64_t (*config_readq)(QVirtioDevice *d, uint64_t addr);
 
     /* Get features of the device */
     uint32_t (*get_features)(QVirtioDevice *d);
@@ -144,13 +144,13 @@ static inline uint32_t qvring_size(uint32_t num, uint32_t align)
 }
 
 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr);
+                                                                uint64_t addr);
 uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr);
+                                                                uint64_t addr);
 uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr);
+                                                                uint64_t addr);
 uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
-                                                                void *addr);
+                                                                uint64_t addr);
 uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d);
 void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
                                                             uint32_t features);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 89d7cbf..2424c84 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -157,7 +157,8 @@ static void pci_basic(void)
     /* MSI-X is not enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
@@ -303,7 +304,8 @@ static void pci_indirect(void)
     /* MSI-X is not enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
@@ -394,7 +396,8 @@ static void pci_config(void)
     /* MSI-X is not enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
@@ -403,7 +406,8 @@ static void pci_config(void)
                                                     " 'size': %d } }", n_size);
     qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, n_size / 512);
 
     qvirtio_pci_device_disable(dev);
@@ -438,7 +442,8 @@ static void pci_msix(void)
     /* MSI-X is enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
@@ -458,7 +463,8 @@ static void pci_msix(void)
 
     qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, n_size / 512);
 
     /* Write request */
@@ -547,7 +553,8 @@ static void pci_idx(void)
     /* MSI-X is enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
 
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
+                                                    (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
-- 
2.1.0

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

* [Qemu-devel] [PULL 03/26] tests: Prepare virtio-blk-test for multi-arch implementation
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 01/26] libqos: Convert malloc-pc allocator to a generic allocator Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 02/26] libqos: Change use of pointers to uint64_t in virtio Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 04/26] libqos: Remove PCI assumptions in constants of virtio driver Stefan Hajnoczi
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Modularize functions in virtio-blk-test and add PCI suffix for PCI specific
components.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/virtio-blk-test.c | 146 ++++++++++++++++++++++++++++--------------------
 1 file changed, 85 insertions(+), 61 deletions(-)

diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 2424c84..c48c058 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -55,11 +55,10 @@ typedef struct QVirtioBlkReq {
     uint8_t status;
 } QVirtioBlkReq;
 
-static QPCIBus *test_start(void)
+static char *drive_create(void)
 {
-    char *cmdline;
-    char tmp_path[] = "/tmp/qtest.XXXXXX";
     int fd, ret;
+    char *tmp_path = g_strdup("/tmp/qtest.XXXXXX");
 
     /* Create a temporary raw image */
     fd = mkstemp(tmp_path);
@@ -68,6 +67,16 @@ static QPCIBus *test_start(void)
     g_assert_cmpint(ret, ==, 0);
     close(fd);
 
+    return tmp_path;
+}
+
+static QPCIBus *pci_test_start(void)
+{
+    char *cmdline;
+    char *tmp_path;
+
+    tmp_path = drive_create();
+
     cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s,format=raw "
                               "-drive if=none,id=drive1,file=/dev/null,format=raw "
                               "-device virtio-blk-pci,id=drv0,drive=drive0,"
@@ -75,6 +84,7 @@ static QPCIBus *test_start(void)
                               tmp_path, PCI_SLOT, PCI_FN);
     qtest_start(cmdline);
     unlink(tmp_path);
+    g_free(tmp_path);
     g_free(cmdline);
 
     return qpci_init_pc();
@@ -85,7 +95,7 @@ static void test_end(void)
     qtest_end();
 }
 
-static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus, int slot)
+static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
 {
     QVirtioPCIDevice *dev;
 
@@ -135,14 +145,10 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
     return addr;
 }
 
-static void pci_basic(void)
+static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
+            QGuestAllocator *alloc, QVirtQueue *vq, uint64_t device_specific)
 {
-    QVirtioPCIDevice *dev;
-    QPCIBus *bus;
-    QVirtQueuePCI *vqpci;
-    QGuestAllocator *alloc;
     QVirtioBlkReq req;
-    void *addr;
     uint64_t req_addr;
     uint64_t capacity;
     uint32_t features;
@@ -150,28 +156,16 @@ static void pci_basic(void)
     uint8_t status;
     char *data;
 
-    bus = test_start();
-
-    dev = virtio_blk_init(bus, PCI_SLOT);
-
-    /* MSI-X is not enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
-
-    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
-                                                    (uint64_t)(uintptr_t)addr);
+    capacity = qvirtio_config_readq(bus, dev, device_specific);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
-    features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+    features = qvirtio_get_features(bus, dev);
     features = features & ~(QVIRTIO_F_BAD_FEATURE |
                     QVIRTIO_F_RING_INDIRECT_DESC | QVIRTIO_F_RING_EVENT_IDX |
                             QVIRTIO_BLK_F_SCSI);
-    qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+    qvirtio_set_features(bus, dev, features);
 
-    alloc = pc_alloc_init();
-    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
-                                                                    alloc, 0);
-
-    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+    qvirtio_set_driver_ok(bus, dev);
 
     /* Write and read with 2 descriptor layout */
     /* Write request */
@@ -185,12 +179,11 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+    free_head = qvirtqueue_add(vq, req_addr, 528, false, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(bus, dev, vq, free_head);
 
-    qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
-                           QVIRTIO_BLK_TIMEOUT_US);
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
 
@@ -206,13 +199,12 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 513, true, false);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+    qvirtqueue_kick(bus, dev, vq, free_head);
 
-    qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
-                           QVIRTIO_BLK_TIMEOUT_US);
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
 
@@ -233,14 +225,15 @@ static void pci_basic(void)
 
     req_addr = virtio_blk_request(alloc, &req, 512);
 
-    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    g_free(req.data);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 512, false, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
 
-    qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
-                           QVIRTIO_BLK_TIMEOUT_US);
+    qvirtqueue_kick(bus, dev, vq, free_head);
+
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
 
@@ -256,14 +249,13 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
-    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 512, true, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+    qvirtqueue_kick(bus, dev, vq, free_head);
 
-    qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
-                           QVIRTIO_BLK_TIMEOUT_US);
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
 
@@ -273,11 +265,35 @@ static void pci_basic(void)
     g_free(data);
 
     guest_free(alloc, req_addr);
+}
+
+static void pci_basic(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    QVirtQueuePCI *vqpci;
+    QGuestAllocator *alloc;
+    void *addr;
+
+    bus = pci_test_start();
+    dev = virtio_blk_pci_init(bus, PCI_SLOT);
+
+    alloc = pc_alloc_init();
+    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                                                    alloc, 0);
+
+    /* MSI-X is not enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+
+    test_basic(&qvirtio_pci, &dev->vdev, alloc, &vqpci->vq,
+                                                    (uint64_t)(uintptr_t)addr);
 
     /* End test */
     guest_free(alloc, vqpci->vq.desc);
+    pc_alloc_uninit(alloc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
+    qpci_free_pc(bus);
     test_end();
 }
 
@@ -297,9 +313,9 @@ static void pci_indirect(void)
     uint8_t status;
     char *data;
 
-    bus = test_start();
+    bus = pci_test_start();
 
-    dev = virtio_blk_init(bus, PCI_SLOT);
+    dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
@@ -376,8 +392,10 @@ static void pci_indirect(void)
 
     /* End test */
     guest_free(alloc, vqpci->vq.desc);
+    pc_alloc_uninit(alloc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
+    qpci_free_pc(bus);
     test_end();
 }
 
@@ -389,9 +407,9 @@ static void pci_config(void)
     void *addr;
     uint64_t capacity;
 
-    bus = test_start();
+    bus = pci_test_start();
 
-    dev = virtio_blk_init(bus, PCI_SLOT);
+    dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
     addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
@@ -412,6 +430,7 @@ static void pci_config(void)
 
     qvirtio_pci_device_disable(dev);
     g_free(dev);
+    qpci_free_pc(bus);
     test_end();
 }
 
@@ -431,10 +450,10 @@ static void pci_msix(void)
     uint8_t status;
     char *data;
 
-    bus = test_start();
+    bus = pci_test_start();
     alloc = pc_alloc_init();
 
-    dev = virtio_blk_init(bus, PCI_SLOT);
+    dev = virtio_blk_pci_init(bus, PCI_SLOT);
     qpci_msix_enable(dev->pdev);
 
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
@@ -520,10 +539,12 @@ static void pci_msix(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    guest_free(alloc, (uint64_t)vqpci->vq.desc);
+    guest_free(alloc, vqpci->vq.desc);
+    pc_alloc_uninit(alloc);
     qpci_msix_disable(dev->pdev);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
+    qpci_free_pc(bus);
     test_end();
 }
 
@@ -542,10 +563,10 @@ static void pci_idx(void)
     uint8_t status;
     char *data;
 
-    bus = test_start();
+    bus = pci_test_start();
     alloc = pc_alloc_init();
 
-    dev = virtio_blk_init(bus, PCI_SLOT);
+    dev = virtio_blk_pci_init(bus, PCI_SLOT);
     qpci_msix_enable(dev->pdev);
 
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
@@ -643,30 +664,33 @@ static void pci_idx(void)
 
     /* End test */
     guest_free(alloc, vqpci->vq.desc);
+    pc_alloc_uninit(alloc);
     qpci_msix_disable(dev->pdev);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
+    qpci_free_pc(bus);
     test_end();
 }
 
-static void hotplug(void)
+static void pci_hotplug(void)
 {
     QPCIBus *bus;
     QVirtioPCIDevice *dev;
 
-    bus = test_start();
+    bus = pci_test_start();
 
     /* plug secondary disk */
     qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP,
                           "'drive': 'drive1'");
 
-    dev = virtio_blk_init(bus, PCI_SLOT_HP);
+    dev = virtio_blk_pci_init(bus, PCI_SLOT_HP);
     g_assert(dev);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
 
     /* unplug secondary disk */
     qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
+    qpci_free_pc(bus);
     test_end();
 }
 
@@ -681,7 +705,7 @@ int main(int argc, char **argv)
     g_test_add_func("/virtio/blk/pci/config", pci_config);
     g_test_add_func("/virtio/blk/pci/msix", pci_msix);
     g_test_add_func("/virtio/blk/pci/idx", pci_idx);
-    g_test_add_func("/virtio/blk/pci/hotplug", hotplug);
+    g_test_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
 
     ret = g_test_run();
 
-- 
2.1.0

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

* [Qemu-devel] [PULL 04/26] libqos: Remove PCI assumptions in constants of virtio driver
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (2 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 03/26] tests: Prepare virtio-blk-test for multi-arch implementation Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 05/26] libqos: Add malloc generic Stefan Hajnoczi
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Convert PCI-specific constants names of libqos virtio driver.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/virtio-pci.c | 30 +++++++++++++++---------------
 tests/libqos/virtio-pci.h | 24 ++++++++++++------------
 tests/virtio-blk-test.c   | 11 ++++++-----
 3 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 92bcac1..046a316 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -102,31 +102,31 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
 static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_DEVICE_FEATURES);
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_FEATURES);
 }
 
 static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_GUEST_FEATURES, features);
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES, features);
 }
 
 static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_GUEST_FEATURES);
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES);
 }
 
 static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS);
+    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS);
 }
 
 static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS, status);
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS, status);
 }
 
 static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
@@ -146,7 +146,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
             return data == vqpci->msix_data;
         }
     } else {
-        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS) & 1;
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 1;
     }
 }
 
@@ -166,26 +166,26 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
             return data == dev->config_msix_data;
         }
     } else {
-        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS) & 2;
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 2;
     }
 }
 
 static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_QUEUE_SELECT, index);
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SELECT, index);
 }
 
 static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readw(dev->pdev, dev->addr + QVIRTIO_QUEUE_SIZE);
+    return qpci_io_readw(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SIZE);
 }
 
 static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_QUEUE_ADDRESS, pfn);
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_ADDRESS, pfn);
 }
 
 static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
@@ -227,7 +227,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writew(dev->pdev, dev->addr + QVIRTIO_QUEUE_NOTIFY, vq->index);
+    qpci_io_writew(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_NOTIFY, vq->index);
 }
 
 const QVirtioBus qvirtio_pci = {
@@ -307,8 +307,8 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
                                         control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
     qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
-    qpci_io_writew(d->pdev, d->addr + QVIRTIO_MSIX_QUEUE_VECTOR, entry);
-    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_MSIX_QUEUE_VECTOR);
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR);
     g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
 }
 
@@ -339,7 +339,7 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
     qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
                                         control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-    qpci_io_writew(d->pdev, d->addr + QVIRTIO_MSIX_CONF_VECTOR, entry);
-    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_MSIX_CONF_VECTOR);
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR);
     g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
 }
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 883f7ff..8f0e52a 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -13,18 +13,18 @@
 #include "libqos/virtio.h"
 #include "libqos/pci.h"
 
-#define QVIRTIO_DEVICE_FEATURES         0x00
-#define QVIRTIO_GUEST_FEATURES          0x04
-#define QVIRTIO_QUEUE_ADDRESS           0x08
-#define QVIRTIO_QUEUE_SIZE              0x0C
-#define QVIRTIO_QUEUE_SELECT            0x0E
-#define QVIRTIO_QUEUE_NOTIFY            0x10
-#define QVIRTIO_DEVICE_STATUS           0x12
-#define QVIRTIO_ISR_STATUS              0x13
-#define QVIRTIO_MSIX_CONF_VECTOR        0x14
-#define QVIRTIO_MSIX_QUEUE_VECTOR       0x16
-#define QVIRTIO_DEVICE_SPECIFIC_MSIX    0x18
-#define QVIRTIO_DEVICE_SPECIFIC_NO_MSIX 0x14
+#define QVIRTIO_PCI_DEVICE_FEATURES         0x00
+#define QVIRTIO_PCI_GUEST_FEATURES          0x04
+#define QVIRTIO_PCI_QUEUE_ADDRESS           0x08
+#define QVIRTIO_PCI_QUEUE_SIZE              0x0C
+#define QVIRTIO_PCI_QUEUE_SELECT            0x0E
+#define QVIRTIO_PCI_QUEUE_NOTIFY            0x10
+#define QVIRTIO_PCI_DEVICE_STATUS           0x12
+#define QVIRTIO_PCI_ISR_STATUS              0x13
+#define QVIRTIO_PCI_MSIX_CONF_VECTOR        0x14
+#define QVIRTIO_PCI_MSIX_QUEUE_VECTOR       0x16
+#define QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX    0x18
+#define QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX 0x14
 
 #define QVIRTIO_PCI_ALIGN   4096
 
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index c48c058..fd54f58 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -157,6 +157,7 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
     char *data;
 
     capacity = qvirtio_config_readq(bus, dev, device_specific);
+
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(bus, dev);
@@ -283,7 +284,7 @@ static void pci_basic(void)
                                                                     alloc, 0);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     test_basic(&qvirtio_pci, &dev->vdev, alloc, &vqpci->vq,
                                                     (uint64_t)(uintptr_t)addr);
@@ -318,7 +319,7 @@ static void pci_indirect(void)
     dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -412,7 +413,7 @@ static void pci_config(void)
     dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -459,7 +460,7 @@ static void pci_msix(void)
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
 
     /* MSI-X is enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -572,7 +573,7 @@ static void pci_idx(void)
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
 
     /* MSI-X is enabled */
-    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
-- 
2.1.0

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

* [Qemu-devel] [PULL 05/26] libqos: Add malloc generic
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (3 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 04/26] libqos: Remove PCI assumptions in constants of virtio driver Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 06/26] libqos: Add virtio MMIO support Stefan Hajnoczi
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

This malloc is a basic interface implementation that works for any platform.
It should be replaced in the future for a real malloc implementation for each
of the platforms.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/malloc-generic.c | 50 +++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/malloc-generic.h | 21 ++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 tests/libqos/malloc-generic.c
 create mode 100644 tests/libqos/malloc-generic.h

diff --git a/tests/libqos/malloc-generic.c b/tests/libqos/malloc-generic.c
new file mode 100644
index 0000000..a0878c5
--- /dev/null
+++ b/tests/libqos/malloc-generic.c
@@ -0,0 +1,50 @@
+/*
+ * Basic libqos generic malloc support
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include "libqos/malloc-generic.h"
+#include "libqos/malloc.h"
+
+/*
+ * Mostly for valgrind happiness, but it does offer
+ * a chokepoint for debugging guest memory leaks, too.
+ */
+void generic_alloc_uninit(QGuestAllocator *allocator)
+{
+    alloc_uninit(allocator);
+}
+
+QGuestAllocator *generic_alloc_init_flags(uint64_t base_addr, uint64_t size,
+                                        uint32_t page_size, QAllocOpts flags)
+{
+    QGuestAllocator *s = g_malloc0(sizeof(*s));
+    MemBlock *node;
+
+    s->opts = flags;
+    s->page_size = page_size;
+
+    /* Start at 1MB */
+    s->start = base_addr + (1 << 20);
+
+    s->end = s->start + size;
+
+    QTAILQ_INIT(&s->used);
+    QTAILQ_INIT(&s->free);
+
+    node = mlist_new(s->start, s->end - s->start);
+    QTAILQ_INSERT_HEAD(&s->free, node, MLIST_ENTNAME);
+
+    return s;
+}
+
+inline QGuestAllocator *generic_alloc_init(uint64_t base_addr, uint64_t size,
+                                                            uint32_t page_size)
+{
+    return generic_alloc_init_flags(base_addr, size, page_size, ALLOC_NO_FLAGS);
+}
diff --git a/tests/libqos/malloc-generic.h b/tests/libqos/malloc-generic.h
new file mode 100644
index 0000000..90104ec
--- /dev/null
+++ b/tests/libqos/malloc-generic.h
@@ -0,0 +1,21 @@
+/*
+ * Basic libqos generic malloc support
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_MALLOC_GENERIC_H
+#define LIBQOS_MALLOC_GENERIC_H
+
+#include "libqos/malloc.h"
+
+QGuestAllocator *generic_alloc_init(uint64_t base_addr, uint64_t size,
+                                                            uint32_t page_size);
+QGuestAllocator *generic_alloc_init_flags(uint64_t base_addr, uint64_t size,
+                                        uint32_t page_size, QAllocOpts flags);
+void generic_alloc_uninit(QGuestAllocator *allocator);
+
+#endif
-- 
2.1.0

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

* [Qemu-devel] [PULL 06/26] libqos: Add virtio MMIO support
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (4 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 05/26] libqos: Add malloc generic Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 07/26] block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it reports the correct length of a real CD Stefan Hajnoczi
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Add virtio MMIO support.
Add virtio-blk-test MMIO test case.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile             |   4 +-
 tests/libqos/virtio-mmio.c | 190 +++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/virtio-mmio.h |  46 +++++++++++
 tests/virtio-blk-test.c    |  81 +++++++++++++++++--
 4 files changed, 313 insertions(+), 8 deletions(-)
 create mode 100644 tests/libqos/virtio-mmio.c
 create mode 100644 tests/libqos/virtio-mmio.h

diff --git a/tests/Makefile b/tests/Makefile
index c2e2e52..77f995d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -185,6 +185,8 @@ gcov-files-sparc-y += hw/timer/m48t59.c
 gcov-files-sparc64-y += hw/timer/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
 gcov-files-arm-y += hw/misc/tmp105.c
+check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
+gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
 check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF)
@@ -303,8 +305,8 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
-libqos-virtio-obj-y = $(libqos-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o
 libqos-usb-obj-y = $(libqos-pc-obj-y) tests/libqos/usb.o
+libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
new file mode 100644
index 0000000..f5ca6c4
--- /dev/null
+++ b/tests/libqos/virtio-mmio.c
@@ -0,0 +1,190 @@
+/*
+ * libqos virtio MMIO driver
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include "libqtest.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-mmio.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-generic.h"
+
+static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t addr)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return readb(dev->addr + addr);
+}
+
+static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t addr)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return readw(dev->addr + addr);
+}
+
+static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t addr)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return readl(dev->addr + addr);
+}
+
+static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t addr)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return readq(dev->addr + addr);
+}
+
+static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    writel(dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
+    return readl(dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+}
+
+static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    dev->features = features;
+    writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
+    writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
+}
+
+static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return dev->features;
+}
+
+static uint8_t qvirtio_mmio_get_status(QVirtioDevice *d)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return (uint8_t)readl(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS);
+}
+
+static void qvirtio_mmio_set_status(QVirtioDevice *d, uint8_t status)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    writel(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS, (uint32_t)status);
+}
+
+static bool qvirtio_mmio_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    uint32_t isr;
+
+    isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 1;
+    writel(dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 1);
+    return isr != 0;
+}
+
+static bool qvirtio_mmio_get_config_isr_status(QVirtioDevice *d)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    uint32_t isr;
+
+    isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 2;
+    writel(dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 2);
+    return isr != 0;
+}
+
+static void qvirtio_mmio_queue_select(QVirtioDevice *d, uint16_t index)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    writel(dev->addr + QVIRTIO_MMIO_QUEUE_SEL, (uint32_t)index);
+
+    g_assert_cmphex(readl(dev->addr + QVIRTIO_MMIO_QUEUE_PFN), ==, 0);
+}
+
+static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice *d)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    return (uint16_t)readl(dev->addr + QVIRTIO_MMIO_QUEUE_NUM_MAX);
+}
+
+static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    writel(dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn);
+}
+
+static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t index)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    QVirtQueue *vq;
+    uint64_t addr;
+
+    vq = g_malloc0(sizeof(*vq));
+    qvirtio_mmio_queue_select(d, index);
+    writel(dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, dev->page_size);
+
+    vq->index = index;
+    vq->size = qvirtio_mmio_get_queue_size(d);
+    vq->free_head = 0;
+    vq->num_free = vq->size;
+    vq->align = dev->page_size;
+    vq->indirect = (dev->features & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+    vq->event = (dev->features & QVIRTIO_F_RING_EVENT_IDX) != 0;
+
+    writel(dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
+
+    /* Check different than 0 */
+    g_assert_cmpint(vq->size, !=, 0);
+
+    /* Check power of 2 */
+    g_assert_cmpint(vq->size & (vq->size - 1), ==, 0);
+
+    addr = guest_alloc(alloc, qvring_size(vq->size, dev->page_size));
+    qvring_init(alloc, vq, addr);
+    qvirtio_mmio_set_queue_address(d, vq->desc / dev->page_size);
+
+    return vq;
+}
+
+static void qvirtio_mmio_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
+{
+    QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+    writel(dev->addr + QVIRTIO_MMIO_QUEUE_NOTIFY, vq->index);
+}
+
+const QVirtioBus qvirtio_mmio = {
+    .config_readb = qvirtio_mmio_config_readb,
+    .config_readw = qvirtio_mmio_config_readw,
+    .config_readl = qvirtio_mmio_config_readl,
+    .config_readq = qvirtio_mmio_config_readq,
+    .get_features = qvirtio_mmio_get_features,
+    .set_features = qvirtio_mmio_set_features,
+    .get_guest_features = qvirtio_mmio_get_guest_features,
+    .get_status = qvirtio_mmio_get_status,
+    .set_status = qvirtio_mmio_set_status,
+    .get_queue_isr_status = qvirtio_mmio_get_queue_isr_status,
+    .get_config_isr_status = qvirtio_mmio_get_config_isr_status,
+    .queue_select = qvirtio_mmio_queue_select,
+    .get_queue_size = qvirtio_mmio_get_queue_size,
+    .set_queue_address = qvirtio_mmio_set_queue_address,
+    .virtqueue_setup = qvirtio_mmio_virtqueue_setup,
+    .virtqueue_kick = qvirtio_mmio_virtqueue_kick,
+};
+
+QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size)
+{
+    QVirtioMMIODevice *dev;
+    uint32_t magic;
+    dev = g_malloc0(sizeof(*dev));
+
+    magic = readl(addr + QVIRTIO_MMIO_MAGIC_VALUE);
+    g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24));
+
+    dev->addr = addr;
+    dev->page_size = page_size;
+    dev->vdev.device_type = readl(addr + QVIRTIO_MMIO_DEVICE_ID);
+
+    writel(addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size);
+
+    return dev;
+}
diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h
new file mode 100644
index 0000000..e3e52b9
--- /dev/null
+++ b/tests/libqos/virtio-mmio.h
@@ -0,0 +1,46 @@
+/*
+ * libqos virtio MMIO definitions
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_VIRTIO_MMIO_H
+#define LIBQOS_VIRTIO_MMIO_H
+
+#include "libqos/virtio.h"
+
+#define QVIRTIO_MMIO_MAGIC_VALUE        0x000
+#define QVIRTIO_MMIO_VERSION            0x004
+#define QVIRTIO_MMIO_DEVICE_ID          0x008
+#define QVIRTIO_MMIO_VENDOR_ID          0x00C
+#define QVIRTIO_MMIO_HOST_FEATURES      0x010
+#define QVIRTIO_MMIO_HOST_FEATURES_SEL  0x014
+#define QVIRTIO_MMIO_GUEST_FEATURES     0x020
+#define QVIRTIO_MMIO_GUEST_FEATURES_SEL 0x024
+#define QVIRTIO_MMIO_GUEST_PAGE_SIZE    0x028
+#define QVIRTIO_MMIO_QUEUE_SEL          0x030
+#define QVIRTIO_MMIO_QUEUE_NUM_MAX      0x034
+#define QVIRTIO_MMIO_QUEUE_NUM          0x038
+#define QVIRTIO_MMIO_QUEUE_ALIGN        0x03C
+#define QVIRTIO_MMIO_QUEUE_PFN          0x040
+#define QVIRTIO_MMIO_QUEUE_NOTIFY       0x050
+#define QVIRTIO_MMIO_INTERRUPT_STATUS   0x060
+#define QVIRTIO_MMIO_INTERRUPT_ACK      0x064
+#define QVIRTIO_MMIO_DEVICE_STATUS      0x070
+#define QVIRTIO_MMIO_DEVICE_SPECIFIC    0x100
+
+typedef struct QVirtioMMIODevice {
+    QVirtioDevice vdev;
+    uint64_t addr;
+    uint32_t page_size;
+    uint32_t features; /* As it cannot be read later, save it */
+} QVirtioMMIODevice;
+
+extern const QVirtioBus qvirtio_mmio;
+
+QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size);
+
+#endif
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index fd54f58..82346e5 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -16,9 +16,11 @@
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
+#include "libqos/virtio-mmio.h"
 #include "libqos/pci-pc.h"
 #include "libqos/malloc.h"
 #include "libqos/malloc-pc.h"
+#include "libqos/malloc-generic.h"
 #include "qemu/bswap.h"
 
 #define QVIRTIO_BLK_F_BARRIER       0x00000001
@@ -42,10 +44,14 @@
 
 #define TEST_IMAGE_SIZE         (64 * 1024 * 1024)
 #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
+#define PCI_SLOT_HP             0x06
 #define PCI_SLOT                0x04
 #define PCI_FN                  0x00
 
-#define PCI_SLOT_HP             0x06
+#define MMIO_PAGE_SIZE          4096
+#define MMIO_DEV_BASE_ADDR      0x0A003E00
+#define MMIO_RAM_ADDR           0x40000000
+#define MMIO_RAM_SIZE           0x20000000
 
 typedef struct QVirtioBlkReq {
     uint32_t type;
@@ -90,6 +96,21 @@ static QPCIBus *pci_test_start(void)
     return qpci_init_pc();
 }
 
+static void arm_test_start(void)
+{
+    char *cmdline;
+    char *tmp_path;
+
+    tmp_path = drive_create();
+
+    cmdline = g_strdup_printf("-machine virt -drive if=none,id=drive0,file=%s "
+                            "-device virtio-blk-device,drive=drive0", tmp_path);
+    qtest_start(cmdline);
+    unlink(tmp_path);
+    g_free(tmp_path);
+    g_free(cmdline);
+}
+
 static void test_end(void)
 {
     qtest_end();
@@ -695,18 +716,64 @@ static void pci_hotplug(void)
     test_end();
 }
 
+static void mmio_basic(void)
+{
+    QVirtioMMIODevice *dev;
+    QVirtQueue *vq;
+    QGuestAllocator *alloc;
+    int n_size = TEST_IMAGE_SIZE / 2;
+    uint64_t capacity;
+
+    arm_test_start();
+
+    dev = qvirtio_mmio_init_device(MMIO_DEV_BASE_ADDR, MMIO_PAGE_SIZE);
+    g_assert(dev != NULL);
+    g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
+
+    qvirtio_reset(&qvirtio_mmio, &dev->vdev);
+    qvirtio_set_acknowledge(&qvirtio_mmio, &dev->vdev);
+    qvirtio_set_driver(&qvirtio_mmio, &dev->vdev);
+
+    alloc = generic_alloc_init(MMIO_RAM_ADDR, MMIO_RAM_SIZE, MMIO_PAGE_SIZE);
+    vq = qvirtqueue_setup(&qvirtio_mmio, &dev->vdev, alloc, 0);
+
+    test_basic(&qvirtio_mmio, &dev->vdev, alloc, vq,
+                            QVIRTIO_MMIO_DEVICE_SPECIFIC);
+
+    qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
+                                                    " 'size': %d } }", n_size);
+
+    qvirtio_wait_queue_isr(&qvirtio_mmio, &dev->vdev, vq,
+                           QVIRTIO_BLK_TIMEOUT_US);
+
+    capacity = qvirtio_config_readq(&qvirtio_mmio, &dev->vdev,
+                                                QVIRTIO_MMIO_DEVICE_SPECIFIC);
+    g_assert_cmpint(capacity, ==, n_size / 512);
+
+    /* End test */
+    guest_free(alloc, vq->desc);
+    generic_alloc_uninit(alloc);
+    g_free(dev);
+    test_end();
+}
+
 int main(int argc, char **argv)
 {
     int ret;
+    const char *arch = qtest_get_arch();
 
     g_test_init(&argc, &argv, NULL);
 
-    g_test_add_func("/virtio/blk/pci/basic", pci_basic);
-    g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
-    g_test_add_func("/virtio/blk/pci/config", pci_config);
-    g_test_add_func("/virtio/blk/pci/msix", pci_msix);
-    g_test_add_func("/virtio/blk/pci/idx", pci_idx);
-    g_test_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
+    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+        qtest_add_func("/virtio/blk/pci/basic", pci_basic);
+        qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
+        qtest_add_func("/virtio/blk/pci/config", pci_config);
+        qtest_add_func("/virtio/blk/pci/msix", pci_msix);
+        qtest_add_func("/virtio/blk/pci/idx", pci_idx);
+        qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
+    } else if (strcmp(arch, "arm") == 0) {
+        qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
+    }
 
     ret = g_test_run();
 
-- 
2.1.0

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

* [Qemu-devel] [PULL 07/26] block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it reports the correct length of a real CD
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (5 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 06/26] libqos: Add virtio MMIO support Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 08/26] .gitignore: Ignore generated "common.env" Stefan Hajnoczi
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Programmingkid

From: Programmingkid <programmingkidx@gmail.com>

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/raw-posix.c | 18 +++++++++++++++++-
 configure         |  2 +-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index e51293a..16fa0a4 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1312,7 +1312,23 @@ again:
         if (size == 0)
 #endif
 #if defined(__APPLE__) && defined(__MACH__)
-        size = LLONG_MAX;
+    {
+         uint64_t sectors = 0;
+         uint32_t sector_size = 0;
+
+         /* Query the number of sectors on the disk */
+         ret = ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors);
+         if (ret == -1) {
+             return -errno;
+         }
+
+         /* Query the size of each sector */
+         ret = ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size);
+         if (ret == -1) {
+             return -errno;
+         }
+         size = sectors * sector_size;
+   }
 #else
         size = lseek(fd, 0LL, SEEK_END);
         if (size < 0) {
diff --git a/configure b/configure
index cae588c..32d3d3f 100755
--- a/configure
+++ b/configure
@@ -611,7 +611,7 @@ Darwin)
   cocoa="yes"
   audio_drv_list="coreaudio"
   audio_possible_drivers="coreaudio sdl fmod"
-  LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
+  LDFLAGS="-framework CoreFoundation -framework IOKit -framework ApplicationServices $LDFLAGS"
   libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
   # Disable attempts to use ObjectiveC features in os/object.h since they
   # won't work when we're compiling with gcc as a C compiler.
-- 
2.1.0

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

* [Qemu-devel] [PULL 08/26] .gitignore: Ignore generated "common.env"
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (6 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 07/26] block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it reports the correct length of a real CD Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 09/26] qemu-iotests: Replace "/bin/true" with "true" Stefan Hajnoczi
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index e32a584..090f974 100644
--- a/.gitignore
+++ b/.gitignore
@@ -109,3 +109,4 @@ cscope.*
 tags
 TAGS
 *~
+/tests/qemu-iotests/common.env
-- 
2.1.0

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

* [Qemu-devel] [PULL 09/26] qemu-iotests: Replace "/bin/true" with "true"
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (7 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 08/26] .gitignore: Ignore generated "common.env" Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 10/26] qemu-iotests: Add "_supported_os Linux" to 058 Stefan Hajnoczi
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

The former is not portable because on Mac OSX it is /usr/bin/true.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/qemu-iotests/common.config | 2 +-
 tests/qemu-iotests/common.filter | 2 +-
 tests/qemu-iotests/common.rc     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index 91a5ef6..a1973ad 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -155,4 +155,4 @@ _readlink()
 }
 
 # make sure this script returns success
-/bin/true
+true
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index bae96ef..b73c70b 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -224,4 +224,4 @@ _filter_qemu_img_map()
 }
 
 # make sure this script returns success
-/bin/true
+true
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 3b14053..aa093d9 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -490,4 +490,4 @@ _die()
 }
 
 # make sure this script returns success
-/bin/true
+true
-- 
2.1.0

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

* [Qemu-devel] [PULL 10/26] qemu-iotests: Add "_supported_os Linux" to 058
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (8 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 09/26] qemu-iotests: Replace "/bin/true" with "true" Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 11/26] tests/Makefile: Add check-block to make check on Linux Stefan Hajnoczi
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

Other cases have this, and this test is not portable as well, as we want
to add "make check-block" to "make check", it shouldn't fail on Mac OS
X.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/qemu-iotests/058 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
index 2d5ca85..a60b34b 100755
--- a/tests/qemu-iotests/058
+++ b/tests/qemu-iotests/058
@@ -87,6 +87,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt qcow2
 _supported_proto file
+_supported_os Linux
 _require_command QEMU_NBD
 
 # Use -f raw instead of -f $IMGFMT for the NBD connection
-- 
2.1.0

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

* [Qemu-devel] [PULL 11/26] tests/Makefile: Add check-block to make check on Linux
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (9 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 10/26] qemu-iotests: Add "_supported_os Linux" to 058 Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 12/26] qemu-iotests: Add supported os parameter for python tests Stefan Hajnoczi
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

"make check-block" does nothing on other platforms, but still takes some
time to enumerate all the tests. So let's only add it for Linux for now.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/Makefile b/tests/Makefile
index 77f995d..be91769 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -469,6 +469,9 @@ check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
 check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
 check: check-qapi-schema check-unit check-qtest
+ifeq ($(CONFIG_LINUX),y)
+check: check-block
+endif
 check-clean:
 	$(MAKE) -C tests/tcg clean
 	rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
-- 
2.1.0

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

* [Qemu-devel] [PULL 12/26] qemu-iotests: Add supported os parameter for python tests
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (10 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 11/26] tests/Makefile: Add check-block to make check on Linux Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 13/26] coroutine-ucontext: use __thread Stefan Hajnoczi
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

If I understand correctly, qemu-iotests never meant to be portable. We
only support Linux for all the shell cases, but didn't specify it for
python tests. Now add this and default all the python tests as Linux
only. If we cares enough later, we can override the parameter in
individual cases.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/qemu-iotests/iotests.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index f57f154..87002e0 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -282,12 +282,15 @@ def notrun(reason):
     print '%s not run: %s' % (seq, reason)
     sys.exit(0)
 
-def main(supported_fmts=[]):
+def main(supported_fmts=[], supported_oses=['linux']):
     '''Run tests'''
 
     if supported_fmts and (imgfmt not in supported_fmts):
         notrun('not suitable for this image format: %s' % imgfmt)
 
+    if sys.platform not in supported_oses:
+        notrun('not suitable for this OS: %s' % sys.platform)
+
     # We need to filter out the time taken from the output so that qemu-iotest
     # can reliably diff the results against master output.
     import StringIO
-- 
2.1.0

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

* [Qemu-devel] [PULL 13/26] coroutine-ucontext: use __thread
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (11 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 12/26] qemu-iotests: Add supported os parameter for python tests Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 14/26] qemu-thread: add per-thread atexit functions Stefan Hajnoczi
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

ELF thread local storage is about 10% faster on tests/test-coroutine's
perf/cost test.  The timing on my machine is 190ns per iteration with
pthread TLS, 170 with ELF TLS.

Based on a patch by Kevin Wolf and Peter Lieven, but redone to follow
the model of coroutine-win32.c (including the important "noinline"
attribute!).

Platforms without thread-local storage (OpenBSD probably?) will need
a new-enough GCC for this to compile, in order to use the same emutls
support that Windows already relies on.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-2-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 coroutine-ucontext.c | 69 +++++++++++++++-------------------------------------
 1 file changed, 19 insertions(+), 50 deletions(-)

diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index 4bf2cde..259fcb4 100644
--- a/coroutine-ucontext.c
+++ b/coroutine-ucontext.c
@@ -25,7 +25,6 @@
 #include <stdlib.h>
 #include <setjmp.h>
 #include <stdint.h>
-#include <pthread.h>
 #include <ucontext.h>
 #include "qemu-common.h"
 #include "block/coroutine_int.h"
@@ -48,15 +47,8 @@ typedef struct {
 /**
  * Per-thread coroutine bookkeeping
  */
-typedef struct {
-    /** Currently executing coroutine */
-    Coroutine *current;
-
-    /** The default coroutine */
-    CoroutineUContext leader;
-} CoroutineThreadState;
-
-static pthread_key_t thread_state_key;
+static __thread CoroutineUContext leader;
+static __thread Coroutine *current;
 
 /*
  * va_args to makecontext() must be type 'int', so passing
@@ -68,36 +60,6 @@ union cc_arg {
     int i[2];
 };
 
-static CoroutineThreadState *coroutine_get_thread_state(void)
-{
-    CoroutineThreadState *s = pthread_getspecific(thread_state_key);
-
-    if (!s) {
-        s = g_malloc0(sizeof(*s));
-        s->current = &s->leader.base;
-        pthread_setspecific(thread_state_key, s);
-    }
-    return s;
-}
-
-static void qemu_coroutine_thread_cleanup(void *opaque)
-{
-    CoroutineThreadState *s = opaque;
-
-    g_free(s);
-}
-
-static void __attribute__((constructor)) coroutine_init(void)
-{
-    int ret;
-
-    ret = pthread_key_create(&thread_state_key, qemu_coroutine_thread_cleanup);
-    if (ret != 0) {
-        fprintf(stderr, "unable to create leader key: %s\n", strerror(errno));
-        abort();
-    }
-}
-
 static void coroutine_trampoline(int i0, int i1)
 {
     union cc_arg arg;
@@ -193,15 +155,23 @@ void qemu_coroutine_delete(Coroutine *co_)
     g_free(co);
 }
 
-CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
-                                      CoroutineAction action)
+/* This function is marked noinline to prevent GCC from inlining it
+ * into coroutine_trampoline(). If we allow it to do that then it
+ * hoists the code to get the address of the TLS variable "current"
+ * out of the while() loop. This is an invalid transformation because
+ * the sigsetjmp() call may be called when running thread A but
+ * return in thread B, and so we might be in a different thread
+ * context each time round the loop.
+ */
+CoroutineAction __attribute__((noinline))
+qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
+                      CoroutineAction action)
 {
     CoroutineUContext *from = DO_UPCAST(CoroutineUContext, base, from_);
     CoroutineUContext *to = DO_UPCAST(CoroutineUContext, base, to_);
-    CoroutineThreadState *s = coroutine_get_thread_state();
     int ret;
 
-    s->current = to_;
+    current = to_;
 
     ret = sigsetjmp(from->env, 0);
     if (ret == 0) {
@@ -212,14 +182,13 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
 
 Coroutine *qemu_coroutine_self(void)
 {
-    CoroutineThreadState *s = coroutine_get_thread_state();
-
-    return s->current;
+    if (!current) {
+        current = &leader.base;
+    }
+    return current;
 }
 
 bool qemu_in_coroutine(void)
 {
-    CoroutineThreadState *s = pthread_getspecific(thread_state_key);
-
-    return s && s->current->caller;
+    return current && current->caller;
 }
-- 
2.1.0

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

* [Qemu-devel] [PULL 14/26] qemu-thread: add per-thread atexit functions
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (12 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 13/26] coroutine-ucontext: use __thread Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 15/26] test-coroutine: avoid overflow on 32-bit systems Stefan Hajnoczi
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

Destructors are the main additional feature of pthread TLS compared
to __thread.  If we were using C++ (hint, hint!) we could have used
thread-local objects with a destructor.  Since we are not, instead,
we add a simple Notifier-based API.

Note that the notifier must be per-thread as well.  We can add a
global list as well later, perhaps.

The Win32 implementation has some complications because a) detached
threads used not to have a QemuThreadData; b) the main thread does
not go through win32_start_routine, so we have to use atexit too.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-3-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/qemu/thread.h    |  4 ++++
 util/qemu-thread-posix.c | 37 +++++++++++++++++++++++++++++++++++++
 util/qemu-thread-win32.c | 48 +++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index f7e3b9b..e89fdc9 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -61,4 +61,8 @@ bool qemu_thread_is_self(QemuThread *thread);
 void qemu_thread_exit(void *retval);
 void qemu_thread_naming(bool enable);
 
+struct Notifier;
+void qemu_thread_atexit_add(struct Notifier *notifier);
+void qemu_thread_atexit_remove(struct Notifier *notifier);
+
 #endif
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index d05a649..41cb23d 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -26,6 +26,7 @@
 #endif
 #include "qemu/thread.h"
 #include "qemu/atomic.h"
+#include "qemu/notify.h"
 
 static bool name_threads;
 
@@ -401,6 +402,42 @@ void qemu_event_wait(QemuEvent *ev)
     }
 }
 
+static pthread_key_t exit_key;
+
+union NotifierThreadData {
+    void *ptr;
+    NotifierList list;
+};
+QEMU_BUILD_BUG_ON(sizeof(union NotifierThreadData) != sizeof(void *));
+
+void qemu_thread_atexit_add(Notifier *notifier)
+{
+    union NotifierThreadData ntd;
+    ntd.ptr = pthread_getspecific(exit_key);
+    notifier_list_add(&ntd.list, notifier);
+    pthread_setspecific(exit_key, ntd.ptr);
+}
+
+void qemu_thread_atexit_remove(Notifier *notifier)
+{
+    union NotifierThreadData ntd;
+    ntd.ptr = pthread_getspecific(exit_key);
+    notifier_remove(notifier);
+    pthread_setspecific(exit_key, ntd.ptr);
+}
+
+static void qemu_thread_atexit_run(void *arg)
+{
+    union NotifierThreadData ntd = { .ptr = arg };
+    notifier_list_notify(&ntd.list, NULL);
+}
+
+static void __attribute__((constructor)) qemu_thread_atexit_init(void)
+{
+    pthread_key_create(&exit_key, qemu_thread_atexit_run);
+}
+
+
 /* Attempt to set the threads name; note that this is for debug, so
  * we're not going to fail if we can't set it.
  */
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index c405c9b..406b52f 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -12,6 +12,7 @@
  */
 #include "qemu-common.h"
 #include "qemu/thread.h"
+#include "qemu/notify.h"
 #include <process.h>
 #include <assert.h>
 #include <limits.h>
@@ -268,6 +269,7 @@ struct QemuThreadData {
     void             *(*start_routine)(void *);
     void             *arg;
     short             mode;
+    NotifierList      exit;
 
     /* Only used for joinable threads. */
     bool              exited;
@@ -275,18 +277,40 @@ struct QemuThreadData {
     CRITICAL_SECTION  cs;
 };
 
+static bool atexit_registered;
+static NotifierList main_thread_exit;
+
 static __thread QemuThreadData *qemu_thread_data;
 
+static void run_main_thread_exit(void)
+{
+    notifier_list_notify(&main_thread_exit, NULL);
+}
+
+void qemu_thread_atexit_add(Notifier *notifier)
+{
+    if (!qemu_thread_data) {
+        if (!atexit_registered) {
+            atexit_registered = true;
+            atexit(run_main_thread_exit);
+        }
+        notifier_list_add(&main_thread_exit, notifier);
+    } else {
+        notifier_list_add(&qemu_thread_data->exit, notifier);
+    }
+}
+
+void qemu_thread_atexit_remove(Notifier *notifier)
+{
+    notifier_remove(notifier);
+}
+
 static unsigned __stdcall win32_start_routine(void *arg)
 {
     QemuThreadData *data = (QemuThreadData *) arg;
     void *(*start_routine)(void *) = data->start_routine;
     void *thread_arg = data->arg;
 
-    if (data->mode == QEMU_THREAD_DETACHED) {
-        g_free(data);
-        data = NULL;
-    }
     qemu_thread_data = data;
     qemu_thread_exit(start_routine(thread_arg));
     abort();
@@ -296,12 +320,14 @@ void qemu_thread_exit(void *arg)
 {
     QemuThreadData *data = qemu_thread_data;
 
-    if (data) {
-        assert(data->mode != QEMU_THREAD_DETACHED);
+    notifier_list_notify(&data->exit, NULL);
+    if (data->mode == QEMU_THREAD_JOINABLE) {
         data->ret = arg;
         EnterCriticalSection(&data->cs);
         data->exited = true;
         LeaveCriticalSection(&data->cs);
+    } else {
+        g_free(data);
     }
     _endthreadex(0);
 }
@@ -313,9 +339,10 @@ void *qemu_thread_join(QemuThread *thread)
     HANDLE handle;
 
     data = thread->data;
-    if (!data) {
+    if (data->mode == QEMU_THREAD_DETACHED) {
         return NULL;
     }
+
     /*
      * Because multiple copies of the QemuThread can exist via
      * qemu_thread_get_self, we need to store a value that cannot
@@ -329,7 +356,6 @@ void *qemu_thread_join(QemuThread *thread)
         CloseHandle(handle);
     }
     ret = data->ret;
-    assert(data->mode != QEMU_THREAD_DETACHED);
     DeleteCriticalSection(&data->cs);
     g_free(data);
     return ret;
@@ -347,6 +373,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
     data->arg = arg;
     data->mode = mode;
     data->exited = false;
+    notifier_list_init(&data->exit);
 
     if (data->mode != QEMU_THREAD_DETACHED) {
         InitializeCriticalSection(&data->cs);
@@ -358,7 +385,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
         error_exit(GetLastError(), __func__);
     }
     CloseHandle(hThread);
-    thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data;
+    thread->data = data;
 }
 
 void qemu_thread_get_self(QemuThread *thread)
@@ -373,11 +400,10 @@ HANDLE qemu_thread_get_handle(QemuThread *thread)
     HANDLE handle;
 
     data = thread->data;
-    if (!data) {
+    if (data->mode == QEMU_THREAD_DETACHED) {
         return NULL;
     }
 
-    assert(data->mode != QEMU_THREAD_DETACHED);
     EnterCriticalSection(&data->cs);
     if (!data->exited) {
         handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE,
-- 
2.1.0

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

* [Qemu-devel] [PULL 15/26] test-coroutine: avoid overflow on 32-bit systems
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (13 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 14/26] qemu-thread: add per-thread atexit functions Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 16/26] QSLIST: add lock-free operations Stefan Hajnoczi
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

unsigned long is not large enough to represent 1000000000 * duration there.
Just use floating point.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-4-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/test-coroutine.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index e22fae1..27d1b6f 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -337,7 +337,7 @@ static void perf_cost(void)
                    "%luns per coroutine",
                    maxcycles,
                    duration, ops,
-                   (unsigned long)(1000000000 * duration) / maxcycles);
+                   (unsigned long)(1000000000.0 * duration / maxcycles));
 }
 
 int main(int argc, char **argv)
-- 
2.1.0

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

* [Qemu-devel] [PULL 16/26] QSLIST: add lock-free operations
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (14 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 15/26] test-coroutine: avoid overflow on 32-bit systems Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 17/26] coroutine: rewrite pool to avoid mutex Stefan Hajnoczi
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

These operations are trivial to implement and do not have ABA problems.
They are enough to implement simple multiple-producer, single consumer
lock-free lists or, as in the next patch, the multiple consumers can
steal a whole batch of elements and process them at their leisure.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-5-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/qemu/queue.h | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 42bcadf..a98eb3a 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -191,8 +191,19 @@ struct {                                                                \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_INSERT_HEAD(head, elm, field) do {                        \
-        (elm)->field.sle_next = (head)->slh_first;                      \
-        (head)->slh_first = (elm);                                      \
+        (elm)->field.sle_next = (head)->slh_first;                       \
+        (head)->slh_first = (elm);                                       \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) do {                   \
+        do {                                                               \
+            (elm)->field.sle_next = (head)->slh_first;                     \
+        } while (atomic_cmpxchg(&(head)->slh_first, (elm)->field.sle_next, \
+                               (elm)) != (elm)->field.sle_next);           \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_MOVE_ATOMIC(dest, src) do {                               \
+        (dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL);        \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_REMOVE_HEAD(head, field) do {                             \
-- 
2.1.0

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

* [Qemu-devel] [PULL 17/26] coroutine: rewrite pool to avoid mutex
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (15 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 16/26] QSLIST: add lock-free operations Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 18/26] coroutine: drop qemu_coroutine_adjust_pool_size Stefan Hajnoczi
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

This patch removes the mutex by using fancy lock-free manipulation of
the pool.  Lock-free stacks and queues are not hard, but they can suffer
from the ABA problem so they are better avoided unless you have some
deferred reclamation scheme like RCU.  Otherwise you have to stick
with adding to a list, and emptying it completely.  This is what this
patch does, by coupling a lock-free global list of available coroutines
with per-CPU lists that are actually used on coroutine creation.

Whenever the destruction pool is big enough, the next thread that runs
out of coroutines will steal the whole destruction pool.  This is positive
in two ways:

1) the allocation does not have to do any atomic operation in the fast
path, it's entirely using thread-local storage.  Once every POOL_BATCH_SIZE
allocations it will do a single atomic_xchg.  Release does an atomic_cmpxchg
loop, that hopefully doesn't cause any starvation, and an atomic_inc.

A later patch will also remove atomic operations from the release path,
and try to avoid the atomic_xchg altogether---succeeding in doing so if
all devices either use ioeventfd or are not submitting requests actively.

2) in theory this should be completely adaptive.  The number of coroutines
around should be a little more than POOL_BATCH_SIZE * number of allocating
threads; so this also empties qemu_coroutine_adjust_pool_size.  (The previous
pool size was POOL_BATCH_SIZE * number of block backends, so it was a bit
more generous.  But if you actually have many high-iodepth disks, it's better
to put them in different iothreads, which will also use separate thread
pools and aio=native file descriptors).

This speeds up perf/cost (in tests/test-coroutine) by a factor of ~1.33.
No matter if we end with some kind of coroutine bypass scheme or not,
it cannot hurt to optimize hot code.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-6-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-coroutine.c | 92 +++++++++++++++++++++++++-------------------------------
 1 file changed, 41 insertions(+), 51 deletions(-)

diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index bd574aa..93fddc7 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -15,31 +15,57 @@
 #include "trace.h"
 #include "qemu-common.h"
 #include "qemu/thread.h"
+#include "qemu/atomic.h"
 #include "block/coroutine.h"
 #include "block/coroutine_int.h"
 
 enum {
-    POOL_DEFAULT_SIZE = 64,
+    POOL_BATCH_SIZE = 64,
 };
 
 /** Free list to speed up creation */
-static QemuMutex pool_lock;
-static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
-static unsigned int pool_size;
-static unsigned int pool_max_size = POOL_DEFAULT_SIZE;
+static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
+static unsigned int release_pool_size;
+static __thread QSLIST_HEAD(, Coroutine) alloc_pool = QSLIST_HEAD_INITIALIZER(pool);
+static __thread Notifier coroutine_pool_cleanup_notifier;
+
+static void coroutine_pool_cleanup(Notifier *n, void *value)
+{
+    Coroutine *co;
+    Coroutine *tmp;
+
+    QSLIST_FOREACH_SAFE(co, &alloc_pool, pool_next, tmp) {
+        QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);
+        qemu_coroutine_delete(co);
+    }
+}
 
 Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
 {
     Coroutine *co = NULL;
 
     if (CONFIG_COROUTINE_POOL) {
-        qemu_mutex_lock(&pool_lock);
-        co = QSLIST_FIRST(&pool);
+        co = QSLIST_FIRST(&alloc_pool);
+        if (!co) {
+            if (release_pool_size > POOL_BATCH_SIZE) {
+                /* Slow path; a good place to register the destructor, too.  */
+                if (!coroutine_pool_cleanup_notifier.notify) {
+                    coroutine_pool_cleanup_notifier.notify = coroutine_pool_cleanup;
+                    qemu_thread_atexit_add(&coroutine_pool_cleanup_notifier);
+                }
+
+                /* This is not exact; there could be a little skew between
+                 * release_pool_size and the actual size of release_pool.  But
+                 * it is just a heuristic, it does not need to be perfect.
+                 */
+                release_pool_size = 0;
+                QSLIST_MOVE_ATOMIC(&alloc_pool, &release_pool);
+                co = QSLIST_FIRST(&alloc_pool);
+            }
+        }
         if (co) {
-            QSLIST_REMOVE_HEAD(&pool, pool_next);
-            pool_size--;
+            QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);
         }
-        qemu_mutex_unlock(&pool_lock);
     }
 
     if (!co) {
@@ -53,39 +79,19 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
 
 static void coroutine_delete(Coroutine *co)
 {
+    co->caller = NULL;
+
     if (CONFIG_COROUTINE_POOL) {
-        qemu_mutex_lock(&pool_lock);
-        if (pool_size < pool_max_size) {
-            QSLIST_INSERT_HEAD(&pool, co, pool_next);
-            co->caller = NULL;
-            pool_size++;
-            qemu_mutex_unlock(&pool_lock);
+        if (release_pool_size < POOL_BATCH_SIZE * 2) {
+            QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next);
+            atomic_inc(&release_pool_size);
             return;
         }
-        qemu_mutex_unlock(&pool_lock);
     }
 
     qemu_coroutine_delete(co);
 }
 
-static void __attribute__((constructor)) coroutine_pool_init(void)
-{
-    qemu_mutex_init(&pool_lock);
-}
-
-static void __attribute__((destructor)) coroutine_pool_cleanup(void)
-{
-    Coroutine *co;
-    Coroutine *tmp;
-
-    QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
-        QSLIST_REMOVE_HEAD(&pool, pool_next);
-        qemu_coroutine_delete(co);
-    }
-
-    qemu_mutex_destroy(&pool_lock);
-}
-
 static void coroutine_swap(Coroutine *from, Coroutine *to)
 {
     CoroutineAction ret;
@@ -140,20 +146,4 @@ void coroutine_fn qemu_coroutine_yield(void)
 
 void qemu_coroutine_adjust_pool_size(int n)
 {
-    qemu_mutex_lock(&pool_lock);
-
-    pool_max_size += n;
-
-    /* Callers should never take away more than they added */
-    assert(pool_max_size >= POOL_DEFAULT_SIZE);
-
-    /* Trim oversized pool down to new max */
-    while (pool_size > pool_max_size) {
-        Coroutine *co = QSLIST_FIRST(&pool);
-        QSLIST_REMOVE_HEAD(&pool, pool_next);
-        pool_size--;
-        qemu_coroutine_delete(co);
-    }
-
-    qemu_mutex_unlock(&pool_lock);
 }
-- 
2.1.0

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

* [Qemu-devel] [PULL 18/26] coroutine: drop qemu_coroutine_adjust_pool_size
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (16 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 17/26] coroutine: rewrite pool to avoid mutex Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:16 ` [Qemu-devel] [PULL 19/26] coroutine: try harder not to delete coroutines Stefan Hajnoczi
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

This is not needed anymore.  The new TLS-based algorithm is adaptive.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-7-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/block-backend.c     |  4 ----
 include/block/coroutine.h | 10 ----------
 qemu-coroutine.c          |  4 ----
 3 files changed, 18 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index ef16d73..d00c129 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -260,9 +260,6 @@ int blk_attach_dev(BlockBackend *blk, void *dev)
     blk_ref(blk);
     blk->dev = dev;
     bdrv_iostatus_reset(blk->bs);
-
-    /* We're expecting I/O from the device so bump up coroutine pool size */
-    qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
     return 0;
 }
 
@@ -290,7 +287,6 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
     blk->dev_ops = NULL;
     blk->dev_opaque = NULL;
     bdrv_set_guest_block_size(blk->bs, 512);
-    qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
     blk_unref(blk);
 }
 
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 793df0e..20c027a 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -216,14 +216,4 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
  */
 void coroutine_fn yield_until_fd_readable(int fd);
 
-/**
- * Add or subtract from the coroutine pool size
- *
- * The coroutine implementation keeps a pool of coroutines to be reused by
- * qemu_coroutine_create().  This makes coroutine creation cheap.  Heavy
- * coroutine users should call this to reserve pool space.  Call it again with
- * a negative number to release pool space.
- */
-void qemu_coroutine_adjust_pool_size(int n);
-
 #endif /* QEMU_COROUTINE_H */
diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 93fddc7..da1b961 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -143,7 +143,3 @@ void coroutine_fn qemu_coroutine_yield(void)
     self->caller = NULL;
     coroutine_swap(self, to);
 }
-
-void qemu_coroutine_adjust_pool_size(int n)
-{
-}
-- 
2.1.0

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

* [Qemu-devel] [PULL 19/26] coroutine: try harder not to delete coroutines
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (17 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 18/26] coroutine: drop qemu_coroutine_adjust_pool_size Stefan Hajnoczi
@ 2015-01-09 10:16 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 20/26] block: limited request size in write zeroes unsupported path Stefan Hajnoczi
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Peter Lieven, Stefan Hajnoczi, Paolo Bonzini

From: Peter Lieven <pl@kamp.de>

Placing coroutines on the global pool should be preferrable, because it
can help all threads.  But if the global pool is full, we can still
try to save some allocations by stashing completed coroutines on the
local pool.  This is quite cheap too, because it does not require
atomic operations, and provides a gain of 15% in the best case.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1417518350-6167-8-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-coroutine.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index da1b961..525247b 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -27,6 +27,7 @@ enum {
 static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
 static unsigned int release_pool_size;
 static __thread QSLIST_HEAD(, Coroutine) alloc_pool = QSLIST_HEAD_INITIALIZER(pool);
+static __thread unsigned int alloc_pool_size;
 static __thread Notifier coroutine_pool_cleanup_notifier;
 
 static void coroutine_pool_cleanup(Notifier *n, void *value)
@@ -58,13 +59,14 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
                  * release_pool_size and the actual size of release_pool.  But
                  * it is just a heuristic, it does not need to be perfect.
                  */
-                release_pool_size = 0;
+                alloc_pool_size = atomic_xchg(&release_pool_size, 0);
                 QSLIST_MOVE_ATOMIC(&alloc_pool, &release_pool);
                 co = QSLIST_FIRST(&alloc_pool);
             }
         }
         if (co) {
             QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);
+            alloc_pool_size--;
         }
     }
 
@@ -87,6 +89,11 @@ static void coroutine_delete(Coroutine *co)
             atomic_inc(&release_pool_size);
             return;
         }
+        if (alloc_pool_size < POOL_BATCH_SIZE) {
+            QSLIST_INSERT_HEAD(&alloc_pool, co, pool_next);
+            alloc_pool_size++;
+            return;
+        }
     }
 
     qemu_coroutine_delete(co);
-- 
2.1.0

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

* [Qemu-devel] [PULL 20/26] block: limited request size in write zeroes unsupported path
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (18 preceding siblings ...)
  2015-01-09 10:16 ` [Qemu-devel] [PULL 19/26] coroutine: try harder not to delete coroutines Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 21/26] block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET} Stefan Hajnoczi
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Peter Lieven, Stefan Hajnoczi

From: Peter Lieven <pl@kamp.de>

If bs->bl.max_write_zeroes is large and we end up in the unsupported
path we might allocate a lot of memory for the iovector and/or even
generate an oversized requests.

Fix this by limiting the request by the minimum of the reported
maximum transfer size or 16MB (32768 sectors).

Reported-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Message-id: 1420457389-16332-1-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index e76a223..371d0f6 100644
--- a/block.c
+++ b/block.c
@@ -3244,6 +3244,9 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
 
         if (ret == -ENOTSUP) {
             /* Fall back to bounce buffer if write zeroes is unsupported */
+            int max_xfer_len = MIN_NON_ZERO(bs->bl.max_transfer_length,
+                                            MAX_WRITE_ZEROES_DEFAULT);
+            num = MIN(num, max_xfer_len);
             iov.iov_len = num * BDRV_SECTOR_SIZE;
             if (iov.iov_base == NULL) {
                 iov.iov_base = qemu_try_blockalign(bs, num * BDRV_SECTOR_SIZE);
@@ -3260,7 +3263,7 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
             /* Keep bounce buffer around if it is big enough for all
              * all future requests.
              */
-            if (num < max_write_zeroes) {
+            if (num < max_xfer_len) {
                 qemu_vfree(iov.iov_base);
                 iov.iov_base = NULL;
             }
-- 
2.1.0

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

* [Qemu-devel] [PULL 21/26] block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET}
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (19 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 20/26] block: limited request size in write zeroes unsupported path Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 22/26] ide: Implement VPD response for ATAPI Stefan Hajnoczi
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

Like BLOCK_OP_TYPE_BACKUP_SOURCE and BLOCK_OP_TYPE_BACKUP_TARGET,
block-commit involves two asymmetric devices.

This change is not user-visible (yet), because commit only works with
device names.

But once we enable backing reference in blockdev-add, or specifying
node-name in block-commit command, we don't want the user to start two
commit jobs on the same backing chain, which will corrupt things because
of the final bdrv_swap.

Before we have per category blockers, splitting this type is still
better.

[Resolved virtio-blk dataplane conflict by replacing
BLOCK_OP_TYPE_COMMIT with both BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET}.
They are safe since the block job runs in the same AioContext as the
dataplane IOThread.
--Stefan]

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c                         | 6 +++---
 blockdev.c                      | 6 +++++-
 hw/block/dataplane/virtio-blk.c | 3 ++-
 include/block/block.h           | 3 ++-
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index 371d0f6..cbe4a32 100644
--- a/block.c
+++ b/block.c
@@ -1200,7 +1200,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
 
     bdrv_op_block_all(bs->backing_hd, bs->backing_blocker);
     /* Otherwise we won't be able to commit due to check in bdrv_commit */
-    bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT,
+    bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
                     bs->backing_blocker);
 out:
     bdrv_refresh_limits(bs, NULL);
@@ -2216,8 +2216,8 @@ int bdrv_commit(BlockDriverState *bs)
         return -ENOTSUP;
     }
 
-    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT, NULL) ||
-        bdrv_op_is_blocked(bs->backing_hd, BLOCK_OP_TYPE_COMMIT, NULL)) {
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
+        bdrv_op_is_blocked(bs->backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) {
         return -EBUSY;
     }
 
diff --git a/blockdev.c b/blockdev.c
index f2b3b25..d59efd3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2218,7 +2218,7 @@ void qmp_block_commit(const char *device,
     /* drain all i/o before commits */
     bdrv_drain_all();
 
-    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT, errp)) {
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) {
         goto out;
     }
 
@@ -2251,6 +2251,10 @@ void qmp_block_commit(const char *device,
 
     assert(bdrv_get_aio_context(base_bs) == aio_context);
 
+    if (bdrv_op_is_blocked(base_bs, BLOCK_OP_TYPE_COMMIT_TARGET, errp)) {
+        goto out;
+    }
+
     /* Do not allow attempts to commit an image into itself */
     if (top_bs == base_bs) {
         error_setg(errp, "cannot commit an image into itself");
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 2a28978..39c5d71 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -198,7 +198,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker);
-    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker);
+    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE, s->blocker);
+    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT_TARGET, s->blocker);
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker);
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, s->blocker);
     blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, s->blocker);
diff --git a/include/block/block.h b/include/block/block.h
index 760e78b..3082d2b 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -133,7 +133,8 @@ typedef enum BlockOpType {
     BLOCK_OP_TYPE_BACKUP_SOURCE,
     BLOCK_OP_TYPE_BACKUP_TARGET,
     BLOCK_OP_TYPE_CHANGE,
-    BLOCK_OP_TYPE_COMMIT,
+    BLOCK_OP_TYPE_COMMIT_SOURCE,
+    BLOCK_OP_TYPE_COMMIT_TARGET,
     BLOCK_OP_TYPE_DATAPLANE,
     BLOCK_OP_TYPE_DRIVE_DEL,
     BLOCK_OP_TYPE_EJECT,
-- 
2.1.0

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

* [Qemu-devel] [PULL 22/26] ide: Implement VPD response for ATAPI
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (20 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 21/26] block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET} Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 23/26] nvme: Fix get/set number of queues feature Stefan Hajnoczi
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

SCSI devices have multiple kinds of queries they need to respond
to, as defined in the "cmd inquiry" section in MMC-6 and SPC-3.

Relevent sections:
MMC-6 revision 2g:
      Non-VPD response data and pointer to SPC-3;
      Section 6.8 "Inquiry Command"
SPC-3 revision 23:
      Inquiry command and error handling:
      Section 6.4 "INQUIRY command"
      VPD data pages format:
      Section 7.6 "Vital product data parameters"

We implement these Vital Product Data queries for SCSI, but not for
ATAPI through IDE. The result is that if you are looking for the WWN
identifier via tools such as sg3_utils, you will be unable to query
our CD/DVD rom device to obtain it.

This patch adds the minimum number of mandatory responses as defined
by SPC-3, which include the "supported pages" response (page 0x00)
and the "Device Identification" response (page 0x83). It also correctly
responds when it receives a request for an illegal page to improve
error output from related tools.

The Device ID page contains an arbitrary list of identification
strings of various formats; the ID strings included in this patch
were chosen to mimic those provided by the libata driver when
emulating this SCSI query (model, serial, and wwn when present.)

Example:

# libata emulated response
[root@localhost ~]# sg_inq --id /dev/sda
VPD INQUIRY: Device Identification page
  Designation descriptor number 1, descriptor length: 24
    designator_type: vendor specific [0x0],  code_set: ASCII
    associated with the addressed logical unit
      vendor specific: QM00001
  Designation descriptor number 2, descriptor length: 72
    designator_type: T10 vendor identification,  code_set: ASCII
    associated with the addressed logical unit
      vendor id: ATA
      vendor specific: QEMU HARDDISK                           QM00001

# QEMU generated ATAPI response, with WWN
[root@localhost ~]# sg_inq --id /dev/sr0
VPD INQUIRY: Device Identification page
  Designation descriptor number 1, descriptor length: 24
    designator_type: vendor specific [0x0],  code_set: ASCII
    associated with the addressed logical unit
      vendor specific: QM00005
  Designation descriptor number 2, descriptor length: 72
    designator_type: T10 vendor identification,  code_set: ASCII
    associated with the addressed logical unit
      vendor id: ATA
      vendor specific: QEMU DVD-ROM                            QM00005
  Designation descriptor number 3, descriptor length: 12
    designator_type: NAA,  code_set: Binary
    associated with the addressed logical unit
      NAA 5, IEEE Company_id: 0xc50
      Vendor Specific Identifier: 0x15ea71bb
      [0x5000c50015ea71bb]

See also: hw/scsi/scsi-disk.c, scsi_disk_emulate_inquiry()

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/ide/atapi.c    | 111 ++++++++++++++++++++++++++++++++++++++++++++++++------
 hw/ide/internal.h |   1 +
 2 files changed, 100 insertions(+), 12 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index c63b7e5..a71e6e0 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -621,20 +621,107 @@ static void cmd_request_sense(IDEState *s, uint8_t *buf)
 
 static void cmd_inquiry(IDEState *s, uint8_t *buf)
 {
+    uint8_t page_code = buf[2];
     int max_len = buf[4];
 
-    buf[0] = 0x05; /* CD-ROM */
-    buf[1] = 0x80; /* removable */
-    buf[2] = 0x00; /* ISO */
-    buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
-    buf[4] = 31; /* additional length */
-    buf[5] = 0; /* reserved */
-    buf[6] = 0; /* reserved */
-    buf[7] = 0; /* reserved */
-    padstr8(buf + 8, 8, "QEMU");
-    padstr8(buf + 16, 16, "QEMU DVD-ROM");
-    padstr8(buf + 32, 4, s->version);
-    ide_atapi_cmd_reply(s, 36, max_len);
+    unsigned idx = 0;
+    unsigned size_idx;
+    unsigned preamble_len;
+
+    /* If the EVPD (Enable Vital Product Data) bit is set in byte 1,
+     * we are being asked for a specific page of info indicated by byte 2. */
+    if (buf[1] & 0x01) {
+        preamble_len = 4;
+        size_idx = 3;
+
+        buf[idx++] = 0x05;      /* CD-ROM */
+        buf[idx++] = page_code; /* Page Code */
+        buf[idx++] = 0x00;      /* reserved */
+        idx++;                  /* length (set later) */
+
+        switch (page_code) {
+        case 0x00:
+            /* Supported Pages: List of supported VPD responses. */
+            buf[idx++] = 0x00; /* 0x00: Supported Pages, and: */
+            buf[idx++] = 0x83; /* 0x83: Device Identification. */
+            break;
+
+        case 0x83:
+            /* Device Identification. Each entry is optional, but the entries
+             * included here are modeled after libata's VPD responses.
+             * If the response is given, at least one entry must be present. */
+
+            /* Entry 1: Serial */
+            if (idx + 24 > max_len) {
+                /* Not enough room for even the first entry: */
+                /* 4 byte header + 20 byte string */
+                ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
+                                    ASC_DATA_PHASE_ERROR);
+                return;
+            }
+            buf[idx++] = 0x02; /* Ascii */
+            buf[idx++] = 0x00; /* Vendor Specific */
+            buf[idx++] = 0x00;
+            buf[idx++] = 20;   /* Remaining length */
+            padstr8(buf + idx, 20, s->drive_serial_str);
+            idx += 20;
+
+            /* Entry 2: Drive Model and Serial */
+            if (idx + 72 > max_len) {
+                /* 4 (header) + 8 (vendor) + 60 (model & serial) */
+                goto out;
+            }
+            buf[idx++] = 0x02; /* Ascii */
+            buf[idx++] = 0x01; /* T10 Vendor */
+            buf[idx++] = 0x00;
+            buf[idx++] = 68;
+            padstr8(buf + idx, 8, "ATA"); /* Generic T10 vendor */
+            idx += 8;
+            padstr8(buf + idx, 40, s->drive_model_str);
+            idx += 40;
+            padstr8(buf + idx, 20, s->drive_serial_str);
+            idx += 20;
+
+            /* Entry 3: WWN */
+            if (s->wwn && (idx + 12 <= max_len)) {
+                /* 4 byte header + 8 byte wwn */
+                buf[idx++] = 0x01; /* Binary */
+                buf[idx++] = 0x03; /* NAA */
+                buf[idx++] = 0x00;
+                buf[idx++] = 0x08;
+                stq_be_p(&buf[idx], s->wwn);
+                idx += 8;
+            }
+            break;
+
+        default:
+            /* SPC-3, revision 23 sec. 6.4 */
+            ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
+                                ASC_INV_FIELD_IN_CMD_PACKET);
+            return;
+        }
+    } else {
+        preamble_len = 5;
+        size_idx = 4;
+
+        buf[0] = 0x05; /* CD-ROM */
+        buf[1] = 0x80; /* removable */
+        buf[2] = 0x00; /* ISO */
+        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
+        /* buf[size_idx] set below. */
+        buf[5] = 0;    /* reserved */
+        buf[6] = 0;    /* reserved */
+        buf[7] = 0;    /* reserved */
+        padstr8(buf + 8, 8, "QEMU");
+        padstr8(buf + 16, 16, "QEMU DVD-ROM");
+        padstr8(buf + 32, 4, s->version);
+        idx = 36;
+    }
+
+ out:
+    buf[size_idx] = idx - preamble_len;
+    ide_atapi_cmd_reply(s, idx, max_len);
+    return;
 }
 
 static void cmd_get_configuration(IDEState *s, uint8_t *buf)
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 8a3eca4..c998003 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -296,6 +296,7 @@ typedef struct IDEDMAOps IDEDMAOps;
 #define ASC_INCOMPATIBLE_FORMAT              0x30
 #define ASC_MEDIUM_NOT_PRESENT               0x3a
 #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
+#define ASC_DATA_PHASE_ERROR                 0x4b
 #define ASC_MEDIA_REMOVAL_PREVENTED          0x53
 
 #define CFA_NO_ERROR            0x00
-- 
2.1.0

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

* [Qemu-devel] [PULL 23/26] nvme: Fix get/set number of queues feature
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (21 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 22/26] ide: Implement VPD response for ATAPI Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 24/26] MAINTAINERS: Update email addresses for Chrysostomos Nanakos Stefan Hajnoczi
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Alex Friedman, Stefan Hajnoczi

From: Alex Friedman <alex@e8storage.com>

According to the specification, the low 16 bits should contain the number of
I/O submission queues, and the high 16 bits should contain the number of
I/O completion queues.

Signed-off-by: Alex Friedman <alex@e8storage.com>
Acked-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/block/nvme.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index aa1ed98..4f70f91 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -476,7 +476,8 @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 
     switch (dw10) {
     case NVME_NUMBER_OF_QUEUES:
-        req->cqe.result = cpu_to_le32(n->num_queues);
+        req->cqe.result =
+            cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16));
         break;
     default:
         return NVME_INVALID_FIELD | NVME_DNR;
@@ -490,7 +491,8 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 
     switch (dw10) {
     case NVME_NUMBER_OF_QUEUES:
-        req->cqe.result = cpu_to_le32(n->num_queues);
+        req->cqe.result =
+            cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16));
         break;
     default:
         return NVME_INVALID_FIELD | NVME_DNR;
-- 
2.1.0

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

* [Qemu-devel] [PULL 24/26] MAINTAINERS: Update email addresses for Chrysostomos Nanakos
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (22 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 23/26] nvme: Fix get/set number of queues feature Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 25/26] MAINTAINERS: Add migration/block* to block subsystem Stefan Hajnoczi
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Chrysostomos Nanakos

From: Chrysostomos Nanakos <chris@include.gr>

Remove first email address and let the one from which I am contributing.

Signed-off-by: Chrysostomos Nanakos <chris@include.gr>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 01cfb05..e7a59ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1099,7 +1099,6 @@ S: Supported
 F: block/ssh.c
 
 ARCHIPELAGO
-M: Chrysostomos Nanakos <cnanakos@grnet.gr>
 M: Chrysostomos Nanakos <chris@include.gr>
 S: Maintained
 F: block/archipelago.c
-- 
2.1.0

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

* [Qemu-devel] [PULL 25/26] MAINTAINERS: Add migration/block* to block subsystem
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (23 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 24/26] MAINTAINERS: Update email addresses for Chrysostomos Nanakos Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-09 10:17 ` [Qemu-devel] [PULL 26/26] NVMe: Set correct VS Value for 1.1 Compliant Controllers Stefan Hajnoczi
  2015-01-10 19:05 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

We are moving block-migration.c to the separated migration directory,
keep this file watched by block maintainers is a good idea.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e7a59ff..c8695ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -751,6 +751,7 @@ F: aio-*.c
 F: block*
 F: block/
 F: hw/block/
+F: migration/block*
 F: qemu-img*
 F: qemu-io*
 F: tests/image-fuzzer/
-- 
2.1.0

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

* [Qemu-devel] [PULL 26/26] NVMe: Set correct VS Value for 1.1 Compliant Controllers
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (24 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 25/26] MAINTAINERS: Add migration/block* to block subsystem Stefan Hajnoczi
@ 2015-01-09 10:17 ` Stefan Hajnoczi
  2015-01-10 19:05 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  26 siblings, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Anubhav Rakshit

From: Anubhav Rakshit <anubhav.rakshit@gmail.com>

According to NVMe specifications Bits 15:08 represent Minor Version number.

Signed-off-by: Anubhav Rakshit <anubhav.rakshit@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/block/nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 4f70f91..ce079ae 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -815,7 +815,7 @@ static int nvme_init(PCIDevice *pci_dev)
     NVME_CAP_SET_CSS(n->bar.cap, 1);
     NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
 
-    n->bar.vs = 0x00010001;
+    n->bar.vs = 0x00010100;
     n->bar.intmc = n->bar.intms = 0;
 
     for (i = 0; i < n->num_namespaces; i++) {
-- 
2.1.0

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (25 preceding siblings ...)
  2015-01-09 10:17 ` [Qemu-devel] [PULL 26/26] NVMe: Set correct VS Value for 1.1 Compliant Controllers Stefan Hajnoczi
@ 2015-01-10 19:05 ` Peter Maydell
  2015-01-10 19:10   ` Peter Maydell
  2015-01-12 14:25   ` Stefan Hajnoczi
  26 siblings, 2 replies; 32+ messages in thread
From: Peter Maydell @ 2015-01-10 19:05 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers

On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> This pull request depends on the previous block pull request which has not been
> merged yet.  It was sent on Monday, 5th of January (Message-id:
> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>
> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>
>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>
> are available in the git repository at:
>
>   git://github.com/stefanha/qemu.git tags/block-pull-request
>
> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>
>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)

I'm confused. You say this pull depends on the other one, but
the emails give the same tag name for both, so I can't pull
the other one first. (In fact, if not for this one failing I
would have applied it under the assumption that it *was* the
previous pullreq...)

In any case, this one fails 'make check':

GTESTER check-qtest-arm
WARNING: Image format was not specified for '/tmp/qtest.ZDWVz0' and
probing guessed raw.
         Automatically detecting the format is dangerous for raw
images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
**
ERROR:/home/petmay01/linaro/qemu-for-merges/tests/libqos/virtio.c:91:qvirtio_wait_queue_isr:
assertion failed: (g_get_monotonic_time() - start_time <= timeout_us)
GTester: last random seed: R02Scf242b6e43396cc299f6f06431644f8f
make: *** [check-qtest-arm] Error 1
make: Leaving directory `/home/petmay01/linaro/qemu-for-merges/build/all'

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:05 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
@ 2015-01-10 19:10   ` Peter Maydell
  2015-01-12  9:52     ` Fam Zheng
  2015-01-12 14:25   ` Stefan Hajnoczi
  1 sibling, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2015-01-10 19:10 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers

On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>> This pull request depends on the previous block pull request which has not been
>> merged yet.  It was sent on Monday, 5th of January (Message-id:
>> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>>
>> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>>
>>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>>
>> are available in the git repository at:
>>
>>   git://github.com/stefanha/qemu.git tags/block-pull-request
>>
>> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>>
>>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
>
> I'm confused. You say this pull depends on the other one, but
> the emails give the same tag name for both, so I can't pull
> the other one first. (In fact, if not for this one failing I
> would have applied it under the assumption that it *was* the
> previous pullreq...)
>
> In any case, this one fails 'make check':

Failed also and differently on my 32 bit ARM board, though that
may just be because I run this set with V=1; last part
of the log below. Looks like something is trying to run
qemu-system-arm without specifying a machine to use...

 === Testing plain filename for blkdebug ===

-blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT

 === Testing plain filename for blkdebug without configuration file ===

-blkdebug::TEST_DIR/t.IMGFMT
 *** done
100                [20:40:41] [20:40:45]
101                [20:40:45] [20:40:45] [not run]
        101 -- not suitable for this image format: qcow2
102                [20:40:45] [20:40:46] [failed, exit status 141] -
output mismatch (see 102.out.bad)
--- /root/qemu/tests/qemu-iotests/102.out       2014-11-03
18:34:23.000000000 +0000
+++ 102.out.bad 2015-01-09 20:40:46.000000000 +0000
@@ -15,7 +15,6 @@
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Image resized.
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qemu-io drv0 map
-[                       0]      128/     128 sectors     allocated at
offset 0 bytes (1)
-*** done
+No machine specified, and there is no default.
+Use -machine help to list supported machines!
+Timeout waiting for allocated on handle 0
103                [20:40:46] [20:40:47]
105                [20:40:47] [20:40:48]
107                [20:40:48] [20:40:49]
108                [20:40:49] [20:40:52]
110                [20:40:52] [20:40:53]
111                [20:40:53] [20:40:53]
113                [20:40:53] [20:40:53] [not run]
        113 -- not suitable for this image format: qcow2
114                [20:40:53] [20:40:54]
Not run: 016 045 059 064 065 070 075 077 078 081 084 088 092 101 113
Failures: 028 067 068 071 087 095 099 102
Failed 8 of 65 tests
make: *** [check-tests/qemu-iotests-quick.sh] Error 1


-- PMM

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:10   ` Peter Maydell
@ 2015-01-12  9:52     ` Fam Zheng
  2015-01-12 10:32       ` Paolo Bonzini
  0 siblings, 1 reply; 32+ messages in thread
From: Fam Zheng @ 2015-01-12  9:52 UTC (permalink / raw)
  To: Stefan Hajnoczi, Peter Maydell; +Cc: QEMU Developers

On Sat, 01/10 19:10, Peter Maydell wrote:
> On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
> > On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> >> This pull request depends on the previous block pull request which has not been
> >> merged yet.  It was sent on Monday, 5th of January (Message-id:
> >> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
> >>
> >> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
> >>
> >>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
> >>
> >> are available in the git repository at:
> >>
> >>   git://github.com/stefanha/qemu.git tags/block-pull-request
> >>
> >> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
> >>
> >>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
> >
> > I'm confused. You say this pull depends on the other one, but
> > the emails give the same tag name for both, so I can't pull
> > the other one first. (In fact, if not for this one failing I
> > would have applied it under the assumption that it *was* the
> > previous pullreq...)
> >
> > In any case, this one fails 'make check':
> 
> Failed also and differently on my 32 bit ARM board, though that
> may just be because I run this set with V=1; last part
> of the log below. Looks like something is trying to run
> qemu-system-arm without specifying a machine to use...
> 

Ouch! This is something that proves really hard to do.

Stefan, please drop the make check-block series in next revision.

Fam

>  === Testing plain filename for blkdebug ===
> 
> -blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT
> 
>  === Testing plain filename for blkdebug without configuration file ===
> 
> -blkdebug::TEST_DIR/t.IMGFMT
>  *** done
> 100                [20:40:41] [20:40:45]
> 101                [20:40:45] [20:40:45] [not run]
>         101 -- not suitable for this image format: qcow2
> 102                [20:40:45] [20:40:46] [failed, exit status 141] -
> output mismatch (see 102.out.bad)
> --- /root/qemu/tests/qemu-iotests/102.out       2014-11-03
> 18:34:23.000000000 +0000
> +++ 102.out.bad 2015-01-09 20:40:46.000000000 +0000
> @@ -15,7 +15,6 @@
>  wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  Image resized.
> -QEMU X.Y.Z monitor - type 'help' for more information
> -(qemu) qemu-io drv0 map
> -[                       0]      128/     128 sectors     allocated at
> offset 0 bytes (1)
> -*** done
> +No machine specified, and there is no default.
> +Use -machine help to list supported machines!
> +Timeout waiting for allocated on handle 0
> 103                [20:40:46] [20:40:47]
> 105                [20:40:47] [20:40:48]
> 107                [20:40:48] [20:40:49]
> 108                [20:40:49] [20:40:52]
> 110                [20:40:52] [20:40:53]
> 111                [20:40:53] [20:40:53]
> 113                [20:40:53] [20:40:53] [not run]
>         113 -- not suitable for this image format: qcow2
> 114                [20:40:53] [20:40:54]
> Not run: 016 045 059 064 065 070 075 077 078 081 084 088 092 101 113
> Failures: 028 067 068 071 087 095 099 102
> Failed 8 of 65 tests
> make: *** [check-tests/qemu-iotests-quick.sh] Error 1
> 
> 
> -- PMM
> 

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-12  9:52     ` Fam Zheng
@ 2015-01-12 10:32       ` Paolo Bonzini
  0 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2015-01-12 10:32 UTC (permalink / raw)
  To: Fam Zheng, Stefan Hajnoczi, Peter Maydell; +Cc: QEMU Developers



On 12/01/2015 10:52, Fam Zheng wrote:
> On Sat, 01/10 19:10, Peter Maydell wrote:
>> On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>>>> This pull request depends on the previous block pull request which has not been
>>>> merged yet.  It was sent on Monday, 5th of January (Message-id:
>>>> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>>>>
>>>> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>>>>
>>>>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>>>>
>>>> are available in the git repository at:
>>>>
>>>>   git://github.com/stefanha/qemu.git tags/block-pull-request
>>>>
>>>> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>>>>
>>>>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
>>>
>>> I'm confused. You say this pull depends on the other one, but
>>> the emails give the same tag name for both, so I can't pull
>>> the other one first. (In fact, if not for this one failing I
>>> would have applied it under the assumption that it *was* the
>>> previous pullreq...)
>>>
>>> In any case, this one fails 'make check':
>>
>> Failed also and differently on my 32 bit ARM board, though that
>> may just be because I run this set with V=1; last part
>> of the log below. Looks like something is trying to run
>> qemu-system-arm without specifying a machine to use...
>>
> 
> Ouch! This is something that proves really hard to do.
> 
> Stefan, please drop the make check-block series in next revision.

No need to drop the bug fixes.  One can just drop patch 11
("tests/Makefile: Add check-block to make check on Linux").

Paolo

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:05 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  2015-01-10 19:10   ` Peter Maydell
@ 2015-01-12 14:25   ` Stefan Hajnoczi
  1 sibling, 0 replies; 32+ messages in thread
From: Stefan Hajnoczi @ 2015-01-12 14:25 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 1448 bytes --]

On Sat, Jan 10, 2015 at 07:05:47PM +0000, Peter Maydell wrote:
> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> > This pull request depends on the previous block pull request which has not been
> > merged yet.  It was sent on Monday, 5th of January (Message-id:
> > <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
> >
> > The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
> >
> >   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
> >
> > are available in the git repository at:
> >
> >   git://github.com/stefanha/qemu.git tags/block-pull-request
> >
> > for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
> >
> >   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
> 
> I'm confused. You say this pull depends on the other one, but
> the emails give the same tag name for both, so I can't pull
> the other one first. (In fact, if not for this one failing I
> would have applied it under the assumption that it *was* the
> previous pullreq...)

I used a script that overwrites the pull request tag.

Sorry for the confusion.  You can look at the "for you to fetch changes
up to 4cba4284918145de66e27959725559f8aaf764ef" lines to identify which
commits are part of each pull request.

I'm resending a new (combined) revision without the make check-block
commit.

Stefan

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

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

end of thread, other threads:[~2015-01-12 14:25 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-09 10:16 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 01/26] libqos: Convert malloc-pc allocator to a generic allocator Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 02/26] libqos: Change use of pointers to uint64_t in virtio Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 03/26] tests: Prepare virtio-blk-test for multi-arch implementation Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 04/26] libqos: Remove PCI assumptions in constants of virtio driver Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 05/26] libqos: Add malloc generic Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 06/26] libqos: Add virtio MMIO support Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 07/26] block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it reports the correct length of a real CD Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 08/26] .gitignore: Ignore generated "common.env" Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 09/26] qemu-iotests: Replace "/bin/true" with "true" Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 10/26] qemu-iotests: Add "_supported_os Linux" to 058 Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 11/26] tests/Makefile: Add check-block to make check on Linux Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 12/26] qemu-iotests: Add supported os parameter for python tests Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 13/26] coroutine-ucontext: use __thread Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 14/26] qemu-thread: add per-thread atexit functions Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 15/26] test-coroutine: avoid overflow on 32-bit systems Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 16/26] QSLIST: add lock-free operations Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 17/26] coroutine: rewrite pool to avoid mutex Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 18/26] coroutine: drop qemu_coroutine_adjust_pool_size Stefan Hajnoczi
2015-01-09 10:16 ` [Qemu-devel] [PULL 19/26] coroutine: try harder not to delete coroutines Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 20/26] block: limited request size in write zeroes unsupported path Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 21/26] block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET} Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 22/26] ide: Implement VPD response for ATAPI Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 23/26] nvme: Fix get/set number of queues feature Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 24/26] MAINTAINERS: Update email addresses for Chrysostomos Nanakos Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 25/26] MAINTAINERS: Add migration/block* to block subsystem Stefan Hajnoczi
2015-01-09 10:17 ` [Qemu-devel] [PULL 26/26] NVMe: Set correct VS Value for 1.1 Compliant Controllers Stefan Hajnoczi
2015-01-10 19:05 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
2015-01-10 19:10   ` Peter Maydell
2015-01-12  9:52     ` Fam Zheng
2015-01-12 10:32       ` Paolo Bonzini
2015-01-12 14:25   ` Stefan Hajnoczi

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.