qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 18/18] block/pcache: debug build


From: Pavel Butsykin
Subject: [Qemu-devel] [PATCH v1 18/18] block/pcache: debug build
Date: Tue, 15 Nov 2016 09:37:15 +0300

This debug patch will help to identify problems with the leakage of the cache
memory.

Signed-off-by: Pavel Butsykin <address@hidden>
---
 block/pcache.c | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/block/pcache.c b/block/pcache.c
index 1821557..7c3a71b 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -16,6 +16,8 @@
 #include "qemu/rbcache.h"
 #include "trace.h"
 
+// #define PCACHE_DEBUG
+
 #define PCACHE_OPT_STATS_SIZE "pcache-stats-size"
 #define PCACHE_OPT_MAX_AIO_SIZE "pcache-max-aio-size"
 #define PCACHE_OPT_CACHE_SIZE "pcache-full-size"
@@ -66,6 +68,9 @@ typedef struct BDRVPCacheState {
     RBCache *cache;
     uint64_t max_aio_size;
     uint64_t readahead_size;
+#ifdef PCACHE_DEBUG
+    QTAILQ_HEAD(PCacheDeathNodeHead, RBCacheNode) death_node_list;
+#endif
 } BDRVPCacheState;
 
 typedef struct ACBLinkEntry {
@@ -124,13 +129,16 @@ static inline void pcache_node_ref(PCacheNode *node)
     node->ref++;
 }
 
-static void pcache_node_unref(PCacheNode *node)
+static void pcache_node_unref(PCacheNode *node, BDRVPCacheState *s)
 {
     assert(node->ref > 0);
     if (--node->ref == 0) {
         assert(node->status == NODE_STATUS_REMOVE);
         node->status = NODE_STATUS_DELETED;
 
+#ifdef PCACHE_DEBUG
+        QTAILQ_REMOVE(&s->death_node_list, &node->common, entry);
+#endif
         g_free(node->data);
         g_free(node);
     }
@@ -258,7 +266,7 @@ static void pcache_aio_readahead_cb(void *opaque, int ret)
         aio_read_complete(acb_read, ret);
     }
 
-    pcache_node_unref(node);
+    pcache_node_unref(node, acb->bs->opaque);
 
     qemu_coroutine_enter(acb->co);
 }
@@ -330,7 +338,11 @@ static void pcache_node_free(RBCacheNode *rbnode, void 
*opaque)
            node->status == NODE_STATUS_COMPLETED);
 
     node->status = NODE_STATUS_REMOVE;
-    pcache_node_unref(node);
+#ifdef PCACHE_DEBUG
+    BDRVPCacheState *s = opaque;
+    QTAILQ_INSERT_HEAD(&s->death_node_list, rbnode, entry);
+#endif
+    pcache_node_unref(node, opaque);
 }
 
 static RBCacheNode *pcache_node_alloc(uint64_t offset, uint64_t bytes,
@@ -658,6 +670,9 @@ static void pcache_state_init(QemuOpts *opts, 
BDRVPCacheState *s)
 
     trace_pcache_state_init(stats_size, s->max_aio_size, cache_size,
                             s->readahead_size);
+#ifdef PCACHE_DEBUG
+    QTAILQ_INIT(&s->death_node_list);
+#endif
 }
 
 static int pcache_file_open(BlockDriverState *bs, QDict *options, int flags,
@@ -697,6 +712,21 @@ static void pcache_close(BlockDriverState *bs)
 
     rbcache_destroy(s->req_stats);
     rbcache_destroy(s->cache);
+
+#ifdef PCACHE_DEBUG
+    RBCacheNode *rbnode, *next;
+    uint64_t cnt = 0;
+    QTAILQ_FOREACH_SAFE(rbnode, &s->death_node_list, entry, next) {
+        PCacheNode *node = container_of(rbnode, PCacheNode, common);
+        QTAILQ_REMOVE(&s->death_node_list, rbnode, entry);
+        fprintf(stderr, "death node: %jd - %jd, ref: %d, stauts: %d\n",
+                rbnode->offset, rbnode->bytes, node->ref, node->status);
+        g_free(node->data);
+        g_free(node);
+        cnt++;
+    }
+    fprintf(stderr, "death node list: %jd\n", cnt);
+#endif
 }
 
 static void pcache_parse_filename(const char *filename, QDict *options,
-- 
2.10.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]