tests/qtest: libqos: Rename malloc.h to libqos-malloc.h
authorXuzhou Cheng <xuzhou.cheng@windriver.com>
Wed, 24 Aug 2022 09:40:03 +0000 (17:40 +0800)
committerThomas Huth <thuth@redhat.com>
Mon, 29 Aug 2022 13:28:51 +0000 (15:28 +0200)
The qtest/libqos directory is included via the "-I" option to search
for header files when building qtest. Unfortunately the malloc.h has
a name conflict with the standard libc header, leading to a build
failure on the Windows host, due to the MinGW libc stdlib.h header
file includes malloc.h and it now gets wrongly pointed to the one
in the qtest/libqos directory.

Rename "qtest/libqos/malloc.h" to "qtest/libqos/libqos-malloc.h" to
avoid the namespace pollution.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20220824094029.1634519-26-bmeng.cn@gmail.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
30 files changed:
tests/qtest/e1000e-test.c
tests/qtest/fuzz/qos_fuzz.c
tests/qtest/libqos/aarch64-xlnx-zcu102-machine.c
tests/qtest/libqos/arm-imx25-pdk-machine.c
tests/qtest/libqos/arm-n800-machine.c
tests/qtest/libqos/arm-raspi2-machine.c
tests/qtest/libqos/arm-sabrelite-machine.c
tests/qtest/libqos/arm-smdkc210-machine.c
tests/qtest/libqos/arm-virt-machine.c
tests/qtest/libqos/arm-xilinx-zynq-a9-machine.c
tests/qtest/libqos/e1000e.c
tests/qtest/libqos/generic-pcihost.h
tests/qtest/libqos/libqos-malloc.c [new file with mode: 0644]
tests/qtest/libqos/libqos-malloc.h [new file with mode: 0644]
tests/qtest/libqos/libqos.h
tests/qtest/libqos/malloc-pc.h
tests/qtest/libqos/malloc-spapr.h
tests/qtest/libqos/malloc.c [deleted file]
tests/qtest/libqos/malloc.h [deleted file]
tests/qtest/libqos/meson.build
tests/qtest/libqos/pci-pc.h
tests/qtest/libqos/pci-spapr.h
tests/qtest/libqos/qgraph.h
tests/qtest/libqos/qos_external.c
tests/qtest/libqos/qos_external.h
tests/qtest/libqos/rtas.h
tests/qtest/libqos/virtio-mmio.c
tests/qtest/libqos/virtio-pci.c
tests/qtest/libqos/virtio.h
tests/qtest/qos-test.c

index c98779c7c0780a58245cd5b0025e4f9172e316ac..4cdd8238f2bcf768afb043ac1a101841deaa3eaa 100644 (file)
@@ -31,7 +31,7 @@
 #include "qemu/iov.h"
 #include "qemu/module.h"
 #include "qemu/bitops.h"
-#include "libqos/malloc.h"
+#include "libqos/libqos-malloc.h"
 #include "libqos/e1000e.h"
 
 static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
index c856d3d500e8f9ccce3cf3683228f35320f4ddd3..3a3d9c16dd3a929196bd9a8988f84a35d6729881 100644 (file)
@@ -23,7 +23,7 @@
 #include "qemu/main-loop.h"
 
 #include "tests/qtest/libqtest.h"
-#include "tests/qtest/libqos/malloc.h"
+#include "tests/qtest/libqos/libqos-malloc.h"
 #include "tests/qtest/libqos/qgraph.h"
 #include "tests/qtest/libqos/qgraph_internal.h"
 #include "tests/qtest/libqos/qos_external.h"
index c8a3ea11eb406c37deeafd425763f95f364df9a1..ab24add8eb867835a95a92f97ee47af2b94decb7 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "sdhci.h"
 
index 54d0c95330448780e84b6276175bba1240463770..8fe128fae865356844ed772d5ace5847c0776d5f 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "../libqtest.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "i2c.h"
 
index ecd46b1dafa0dea5a18c0e4fc559c944d121be06..4e5afe0164bf93c6c8d2be206f780e78349822e5 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "../libqtest.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "i2c.h"
 
index 0a2943440b28682174a56d56d8354c557cb24b96..367c6c17a5f9a68a623f646a23246a5bd2bc73b9 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "sdhci.h"
 
index ec19a01660c0f0452a336508695369947a63900b..94f6a20fc7cc78cd473c1ed91461893cf30b2832 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "sdhci.h"
 
index 4bff249ee89afff06c0a78067869c0db4fe44225..9bbce924ea1803bdae913948e14ad880d3d63de5 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "sdhci.h"
 
index 139eaba1421459dca092dedff852362bafad7d52..4e87405b58f2b2e77bc2ecb938ac49cbe593cc03 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "virtio-mmio.h"
 #include "generic-pcihost.h"
index 3be80020a6bc903fd6409866141cdb44c963f93f..daac762a062a1f21a2926ba5bc637f3c7b8e8004 100644 (file)
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "../libqtest.h"
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "sdhci.h"
 
index f87e0e84b2aad6186375bd8443f39108594bff72..fc14b078842e1b8f96ad840baadeaa7e502553be 100644 (file)
@@ -23,7 +23,7 @@
 #include "qemu/iov.h"
 #include "qemu/module.h"
 #include "qemu/bitops.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "e1000e.h"
 
index c693c769dfba1b9a589b1eee14cfa301b1a74904..6493a8712a67c01b2d956e51a2b7cc928afbe4fe 100644 (file)
@@ -14,7 +14,7 @@
 #define LIBQOS_GENERIC_PCIHOST_H
 
 #include "pci.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 
 typedef struct QGenericPCIBus {
diff --git a/tests/qtest/libqos/libqos-malloc.c b/tests/qtest/libqos/libqos-malloc.c
new file mode 100644 (file)
index 0000000..d756697
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * 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 "qemu/osdep.h"
+#include "libqos-malloc.h"
+#include "qemu/host-utils.h"
+
+typedef struct MemBlock {
+    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
+    uint64_t size;
+    uint64_t addr;
+} MemBlock;
+
+#define DEFAULT_PAGE_SIZE 4096
+
+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, 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 MemBlock *mlist_new(uint64_t addr, uint64_t size)
+{
+    MemBlock *block;
+
+    if (!size) {
+        return NULL;
+    }
+    block = g_new0(MemBlock, 1);
+
+    block->addr = addr;
+    block->size = size;
+
+    return block;
+}
+
+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);
+}
+
+/*
+ * Mostly for valgrind happiness, but it does offer
+ * a chokepoint for debugging guest memory leaks, too.
+ */
+void alloc_destroy(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->used);
+    g_free(allocator->free);
+}
+
+uint64_t guest_alloc(QGuestAllocator *allocator, size_t size)
+{
+    uint64_t rsize = size;
+    uint64_t naddr;
+
+    if (!size) {
+        return 0;
+    }
+
+    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)
+{
+    if (!addr) {
+        return;
+    }
+    mlist_free(allocator, addr);
+    if (allocator->opts & ALLOC_PARANOID) {
+        mlist_check(allocator);
+    }
+}
+
+void alloc_init(QGuestAllocator *s, QAllocOpts opts,
+                uint64_t start, uint64_t end,
+                size_t page_size)
+{
+    MemBlock *node;
+
+    s->opts = opts;
+    s->start = start;
+    s->end = end;
+
+    s->used = g_new(MemList, 1);
+    s->free = g_new(MemList, 1);
+    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);
+
+    s->page_size = page_size;
+}
+
+void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts)
+{
+    allocator->opts |= opts;
+}
+
+void migrate_allocator(QGuestAllocator *src,
+                       QGuestAllocator *dst)
+{
+    MemBlock *node, *tmp;
+    MemList *tmpused, *tmpfree;
+
+    /* The general memory layout should be equivalent,
+     * though opts can differ. */
+    g_assert_cmphex(src->start, ==, dst->start);
+    g_assert_cmphex(src->end, ==, dst->end);
+
+    /* Destroy (silently, regardless of options) the dest-list: */
+    QTAILQ_FOREACH_SAFE(node, dst->used, MLIST_ENTNAME, tmp) {
+        g_free(node);
+    }
+    QTAILQ_FOREACH_SAFE(node, dst->free, MLIST_ENTNAME, tmp) {
+        g_free(node);
+    }
+
+    tmpused = dst->used;
+    tmpfree = dst->free;
+
+    /* Inherit the lists of the source allocator: */
+    dst->used = src->used;
+    dst->free = src->free;
+
+    /* Source is now re-initialized, the source memory is 'invalid' now: */
+    src->used = tmpused;
+    src->free = tmpfree;
+    QTAILQ_INIT(src->used);
+    QTAILQ_INIT(src->free);
+    node = mlist_new(src->start, src->end - src->start);
+    QTAILQ_INSERT_HEAD(src->free, node, MLIST_ENTNAME);
+    return;
+}
diff --git a/tests/qtest/libqos/libqos-malloc.h b/tests/qtest/libqos/libqos-malloc.h
new file mode 100644 (file)
index 0000000..bbb8c74
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * libqos malloc support
+ *
+ * Copyright IBM, Corp. 2012-2013
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.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.
+ */
+
+#ifndef LIBQOS_MALLOC_H
+#define LIBQOS_MALLOC_H
+
+#include "qemu/queue.h"
+#include "../libqtest.h"
+
+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 QGuestAllocator {
+    QAllocOpts opts;
+    uint64_t start;
+    uint64_t end;
+    uint32_t page_size;
+
+    MemList *used;
+    MemList *free;
+} QGuestAllocator;
+
+/* Always returns page aligned values */
+uint64_t guest_alloc(QGuestAllocator *allocator, size_t size);
+void guest_free(QGuestAllocator *allocator, uint64_t addr);
+void migrate_allocator(QGuestAllocator *src, QGuestAllocator *dst);
+
+void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts);
+
+void alloc_init(QGuestAllocator *alloc, QAllocOpts flags,
+                uint64_t start, uint64_t end,
+                size_t page_size);
+void alloc_destroy(QGuestAllocator *allocator);
+
+#endif
index ba7df448cad7391dbc2bf4f5aa92ad997f76e538..9b4dd509f08e2b70248de4e9c2ec9ca53b581a1e 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "../libqtest.h"
 #include "pci.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 
 typedef struct QOSState QOSState;
 
index d8d79853c8442e0bd983de668af4199b4d806f83..e531473601cd8495200f0330e0e741cc1b7f2aa8 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef LIBQOS_MALLOC_PC_H
 #define LIBQOS_MALLOC_PC_H
 
-#include "malloc.h"
+#include "libqos-malloc.h"
 
 void pc_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags);
 
index f99572fd71d94944d31da5e4e953857ce0bf1603..f544c0d611ae855116eb62a957f9b4370bd20427 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef LIBQOS_MALLOC_SPAPR_H
 #define LIBQOS_MALLOC_SPAPR_H
 
-#include "malloc.h"
+#include "libqos-malloc.h"
 
 void spapr_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags);
 
diff --git a/tests/qtest/libqos/malloc.c b/tests/qtest/libqos/malloc.c
deleted file mode 100644 (file)
index f0c8f95..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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 "qemu/osdep.h"
-#include "malloc.h"
-#include "qemu/host-utils.h"
-
-typedef struct MemBlock {
-    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
-    uint64_t size;
-    uint64_t addr;
-} MemBlock;
-
-#define DEFAULT_PAGE_SIZE 4096
-
-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, 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 MemBlock *mlist_new(uint64_t addr, uint64_t size)
-{
-    MemBlock *block;
-
-    if (!size) {
-        return NULL;
-    }
-    block = g_new0(MemBlock, 1);
-
-    block->addr = addr;
-    block->size = size;
-
-    return block;
-}
-
-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);
-}
-
-/*
- * Mostly for valgrind happiness, but it does offer
- * a chokepoint for debugging guest memory leaks, too.
- */
-void alloc_destroy(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->used);
-    g_free(allocator->free);
-}
-
-uint64_t guest_alloc(QGuestAllocator *allocator, size_t size)
-{
-    uint64_t rsize = size;
-    uint64_t naddr;
-
-    if (!size) {
-        return 0;
-    }
-
-    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)
-{
-    if (!addr) {
-        return;
-    }
-    mlist_free(allocator, addr);
-    if (allocator->opts & ALLOC_PARANOID) {
-        mlist_check(allocator);
-    }
-}
-
-void alloc_init(QGuestAllocator *s, QAllocOpts opts,
-                uint64_t start, uint64_t end,
-                size_t page_size)
-{
-    MemBlock *node;
-
-    s->opts = opts;
-    s->start = start;
-    s->end = end;
-
-    s->used = g_new(MemList, 1);
-    s->free = g_new(MemList, 1);
-    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);
-
-    s->page_size = page_size;
-}
-
-void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts)
-{
-    allocator->opts |= opts;
-}
-
-void migrate_allocator(QGuestAllocator *src,
-                       QGuestAllocator *dst)
-{
-    MemBlock *node, *tmp;
-    MemList *tmpused, *tmpfree;
-
-    /* The general memory layout should be equivalent,
-     * though opts can differ. */
-    g_assert_cmphex(src->start, ==, dst->start);
-    g_assert_cmphex(src->end, ==, dst->end);
-
-    /* Destroy (silently, regardless of options) the dest-list: */
-    QTAILQ_FOREACH_SAFE(node, dst->used, MLIST_ENTNAME, tmp) {
-        g_free(node);
-    }
-    QTAILQ_FOREACH_SAFE(node, dst->free, MLIST_ENTNAME, tmp) {
-        g_free(node);
-    }
-
-    tmpused = dst->used;
-    tmpfree = dst->free;
-
-    /* Inherit the lists of the source allocator: */
-    dst->used = src->used;
-    dst->free = src->free;
-
-    /* Source is now re-initialized, the source memory is 'invalid' now: */
-    src->used = tmpused;
-    src->free = tmpfree;
-    QTAILQ_INIT(src->used);
-    QTAILQ_INIT(src->free);
-    node = mlist_new(src->start, src->end - src->start);
-    QTAILQ_INSERT_HEAD(src->free, node, MLIST_ENTNAME);
-    return;
-}
diff --git a/tests/qtest/libqos/malloc.h b/tests/qtest/libqos/malloc.h
deleted file mode 100644 (file)
index bbb8c74..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libqos malloc support
- *
- * Copyright IBM, Corp. 2012-2013
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.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.
- */
-
-#ifndef LIBQOS_MALLOC_H
-#define LIBQOS_MALLOC_H
-
-#include "qemu/queue.h"
-#include "../libqtest.h"
-
-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 QGuestAllocator {
-    QAllocOpts opts;
-    uint64_t start;
-    uint64_t end;
-    uint32_t page_size;
-
-    MemList *used;
-    MemList *free;
-} QGuestAllocator;
-
-/* Always returns page aligned values */
-uint64_t guest_alloc(QGuestAllocator *allocator, size_t size);
-void guest_free(QGuestAllocator *allocator, uint64_t addr);
-void migrate_allocator(QGuestAllocator *src, QGuestAllocator *dst);
-
-void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts);
-
-void alloc_init(QGuestAllocator *alloc, QAllocOpts flags,
-                uint64_t start, uint64_t end,
-                size_t page_size);
-void alloc_destroy(QGuestAllocator *allocator);
-
-#endif
index fd5d6e5ae1b3ad437808b10d1beda2f1f2dd7fea..cff83c86d99bdb37f59b3a658970590b0bcd47ae 100644 (file)
@@ -6,7 +6,7 @@ libqos_srcs = files(
         'qos_external.c',
         'pci.c',
         'fw_cfg.c',
-        'malloc.c',
+        'libqos-malloc.c',
         'libqos.c',
         'sdhci-cmd.c',
 
index 49ec9507f22de21a6c01f6023b39c2ac884cdc86..849bd493de0cd3cd31688d88075bdeddafe0272f 100644 (file)
@@ -14,7 +14,7 @@
 #define LIBQOS_PCI_PC_H
 
 #include "pci.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 
 typedef struct QPCIBusPC {
index 20a43718b7dbfce60c4cd568aea61fa00fd0717b..3dbf1e58ae6975e9f877a98774b3d960eb964a5b 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef LIBQOS_PCI_SPAPR_H
 #define LIBQOS_PCI_SPAPR_H
 
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "pci.h"
 #include "qgraph.h"
 
index 871740c0dc89d879050116e2f8e81ee995475b60..6e94824d090a5cac79d7dcd13974b85f612712dc 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <gmodule.h>
 #include "qemu/module.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 
 /* maximum path length */
 #define QOS_PATH_MAX_ELEMENT_SIZE 50
index b7a0b873a362918b4924e5754619d6843f89b7c2..c6bb8bff09eec09db880e2ca1d9336824adc1c37 100644 (file)
@@ -24,7 +24,7 @@
 #include "qapi/qmp/qstring.h"
 #include "qemu/module.h"
 #include "qapi/qmp/qlist.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "qgraph_internal.h"
 #include "qos_external.h"
index 8446e3df0b1ceacab01a4fdb186813771d1ea06f..ea373648874941e6a2eda427fe267a397fcade54 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "qgraph.h"
 
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qapi/qapi-types-machine.h"
 #include "qapi/qapi-types-qom.h"
 
index f38f99dfab84533f47e760b7b8d0f149b5a05802..be8353d505ffd1bf97cf0182c1a904ed9e6961b2 100644 (file)
@@ -5,7 +5,7 @@
 
 #ifndef LIBQOS_RTAS_H
 #define LIBQOS_RTAS_H
-#include "malloc.h"
+#include "libqos-malloc.h"
 
 int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc,
                           struct tm *tm, uint32_t *ns);
index a6cca8613b2c6db89173f15e6bc3b39c444a4e08..bd0b1d890b587d240d377259993f007ac58dd7df 100644 (file)
@@ -12,7 +12,7 @@
 #include "qemu/module.h"
 #include "virtio.h"
 #include "virtio-mmio.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "qgraph.h"
 #include "standard-headers/linux/virtio_ring.h"
 
index 67c2498c84af6996c2437f4f9b479d492f458cda..485b8f6b7e052d8e4a3f3b5f71e1077bd8779eb4 100644 (file)
@@ -13,7 +13,7 @@
 #include "virtio-pci.h"
 #include "pci.h"
 #include "pci-pc.h"
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "malloc-pc.h"
 #include "qgraph.h"
 #include "standard-headers/linux/virtio_ring.h"
index b8bd06e1b85118dfc83472fb389139aa414e3b2a..7adc7cbd10502e39affe8e0b485dce88e9a8f9b0 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef LIBQOS_VIRTIO_H
 #define LIBQOS_VIRTIO_H
 
-#include "malloc.h"
+#include "libqos-malloc.h"
 #include "standard-headers/linux/virtio_ring.h"
 
 #define QVIRTIO_F_BAD_FEATURE           0x40000000ull
index f97d0a08fd05c2ac5aca54dba73118a06f909439..831db5cf2a46758dcbd90a35ca15a2b6543934f9 100644 (file)
@@ -25,7 +25,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qapi-visit-machine.h"
 #include "qapi/qapi-visit-qom.h"
-#include "libqos/malloc.h"
+#include "libqos/libqos-malloc.h"
 #include "libqos/qgraph.h"
 #include "libqos/qgraph_internal.h"
 #include "libqos/qos_external.h"