]> git.proxmox.com Git - mirror_qemu.git/blobdiff - block/qed-l2-cache.c
block: drop bs->job
[mirror_qemu.git] / block / qed-l2-cache.c
index 57518a4e7fe8f6b8e89954d99ceb0b652f3ca91c..b5483623989601efacc79d038e3c78fdb3d74bbf 100644 (file)
@@ -50,6 +50,7 @@
  * table will be deleted in favor of the existing cache entry.
  */
 
+#include "qemu/osdep.h"
 #include "trace.h"
 #include "qed.h"
 
@@ -74,7 +75,7 @@ void qed_free_l2_cache(L2TableCache *l2_cache)
 
     QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next_entry) {
         qemu_vfree(entry->table);
-        qemu_free(entry);
+        g_free(entry);
     }
 }
 
@@ -89,7 +90,7 @@ CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache)
 {
     CachedL2Table *entry;
 
-    entry = qemu_mallocz(sizeof(*entry));
+    entry = g_malloc0(sizeof(*entry));
     entry->ref++;
 
     trace_qed_alloc_l2_cache_entry(l2_cache, entry);
@@ -100,6 +101,8 @@ CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache)
 /**
  * Decrease an entry's reference count and free if necessary when the reference
  * count drops to zero.
+ *
+ * Called with table_lock held.
  */
 void qed_unref_l2_cache_entry(CachedL2Table *entry)
 {
@@ -111,7 +114,7 @@ void qed_unref_l2_cache_entry(CachedL2Table *entry)
     trace_qed_unref_l2_cache_entry(entry, entry->ref);
     if (entry->ref == 0) {
         qemu_vfree(entry->table);
-        qemu_free(entry);
+        g_free(entry);
     }
 }
 
@@ -121,6 +124,8 @@ void qed_unref_l2_cache_entry(CachedL2Table *entry)
  *
  * For a cached entry, this function increases the reference count and returns
  * the entry.
+ *
+ * Called with table_lock held.
  */
 CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset)
 {
@@ -149,6 +154,8 @@ CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset)
  * N.B. This function steals a reference to the l2_table from the caller so the
  * caller must obtain a new reference by issuing a call to
  * qed_find_l2_cache_entry().
+ *
+ * Called with table_lock held.
  */
 void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table)
 {
@@ -161,11 +168,25 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table)
         return;
     }
 
+    /* Evict an unused cache entry so we have space.  If all entries are in use
+     * we can grow the cache temporarily and we try to shrink back down later.
+     */
     if (l2_cache->n_entries >= MAX_L2_CACHE_SIZE) {
-        entry = QTAILQ_FIRST(&l2_cache->entries);
-        QTAILQ_REMOVE(&l2_cache->entries, entry, node);
-        l2_cache->n_entries--;
-        qed_unref_l2_cache_entry(entry);
+        CachedL2Table *next;
+        QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next) {
+            if (entry->ref > 1) {
+                continue;
+            }
+
+            QTAILQ_REMOVE(&l2_cache->entries, entry, node);
+            l2_cache->n_entries--;
+            qed_unref_l2_cache_entry(entry);
+
+            /* Stop evicting when we've shrunk back to max size */
+            if (l2_cache->n_entries < MAX_L2_CACHE_SIZE) {
+                break;
+            }
+        }
     }
 
     l2_cache->n_entries++;