[Spice-devel] [PATCH] display/res: add helpers for clearing device memory

Alon Levy alevy at redhat.com
Wed Jul 6 05:34:56 PDT 2011


Refactors InitResources code called upon DrvEnableSurface so it can later be called
from AssertModeEnable. Introduces three helpers:

EmptyReleaseRing - no vmexit, goes over release ring and empties it all (as opposed to
OOM behavior that empties 50 resources).
InitDeviceMemoryResources - resets anything on the device memory (devram and vram pci bars).
ReleaseCacheDeviceMemoryResources - helper for clearing the cache (which points to devram
QXLImage's)

Cc: Yonit Halperin <yhalperi at redhat.com>
---
 display/res.c |  105 +++++++++++++++++++++++++++++++++++++++++++++------------
 display/res.h |    3 ++
 2 files changed, 86 insertions(+), 22 deletions(-)

diff --git a/display/res.c b/display/res.c
index d93a6af..0a9db0b 100644
--- a/display/res.c
+++ b/display/res.c
@@ -369,6 +369,19 @@ static void FlushReleaseRing(PDev *pdev)
     pdev->Res->free_outputs = output;
 }
 
+void EmptyReleaseRing(PDev *pdev)
+{
+    int count = 0;
+
+    EngAcquireSemaphore(pdev->Res->malloc_sem);
+    while (pdev->Res->free_outputs || !SPICE_RING_IS_EMPTY(pdev->release_ring)) {
+        FlushReleaseRing(pdev);
+        count++;
+    }
+    EngReleaseSemaphore(pdev->Res->malloc_sem);
+    DEBUG_PRINT((pdev, 3, "%s: complete after %d rounds\n", __FUNCTION__, count));
+}
+
 // todo: separate VRAM releases from DEVRAM releases
 #define AllocMem(pdev, mspace_type, size) __AllocMem(pdev, mspace_type, size, TRUE)
 static void *__AllocMem(PDev* pdev, UINT32 mspace_type, size_t size, BOOL force)
@@ -509,6 +522,44 @@ static void InitMspace(PDev *pdev, UINT32 mspace_type, UINT8 *start, size_t capa
     res->mspaces[mspace_type].mspace_end = start + capacity;
 }
 
+static void ResetCache(PDev *pdev)
+{
+    int i;
+
+    RtlZeroMemory(pdev->Res->image_key_lookup,
+                  sizeof(pdev->Res->image_key_lookup));
+    RtlZeroMemory(pdev->Res->cache_image_pool,
+                  sizeof(pdev->Res->cache_image_pool));
+    RingInit(&pdev->Res->cache_image_lru);
+    for (i = 0; i < IMAGE_POOL_SIZE; i++) {
+        RingAdd(pdev, &pdev->Res->cache_image_lru,
+                &pdev->Res->cache_image_pool[i].lru_link);
+    }
+
+    RtlZeroMemory(pdev->Res->image_cache, sizeof(pdev->Res->image_cache));
+    RtlZeroMemory(pdev->Res->cursor_cache, sizeof(pdev->Res->cursor_cache));
+    RingInit(&pdev->Res->cursors_lru);
+    pdev->Res->num_cursors = 0;
+    pdev->Res->last_cursor_id = 0;
+
+    RtlZeroMemory(pdev->Res->palette_cache, sizeof(pdev->Res->palette_cache));
+    RingInit(&pdev->Res->palette_lru);
+    pdev->Res->num_palettes = 0;
+}
+
+/* Init anything that resides on the device memory (pci vram and devram bars).
+ * NOTE: TODO better documentation of what is on the guest ram (saved during sleep)
+ * and what is on the pci device bars (bar 0 and 1, devram and vram)
+ */
+void InitDeviceMemoryResources(PDev *pdev)
+{
+    DEBUG_PRINT((pdev, 0, "%s: %d, %d\n", __FUNCTION__, pdev->num_io_pages * PAGE_SIZE,
+        pdev->fb_size));
+    InitMspace(pdev, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
+    InitMspace(pdev, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
+    ResetCache(pdev);
+}
+
 static void InitRes(PDev *pdev)
 {
     UINT32 i;
@@ -558,30 +609,9 @@ static void InitRes(PDev *pdev)
         PANIC(pdev, "Res cache sem creation failed\n");
     }
 
-    InitMspace(pdev, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
-    InitMspace(pdev, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
     pdev->Res->update_id = *pdev->dev_update_id;
+    InitDeviceMemoryResources(pdev);
 
-    RtlZeroMemory(pdev->Res->image_key_lookup,
-                  sizeof(pdev->Res->image_key_lookup));
-    RtlZeroMemory(pdev->Res->cache_image_pool,
-                  sizeof(pdev->Res->cache_image_pool));
-    RingInit(&pdev->Res->cache_image_lru);
-    for (i = 0; i < IMAGE_POOL_SIZE; i++) {
-        RingAdd(pdev, &pdev->Res->cache_image_lru,
-                &pdev->Res->cache_image_pool[i].lru_link);
-    }
-
-    RtlZeroMemory(pdev->Res->image_cache, sizeof(pdev->Res->image_cache));
-    RtlZeroMemory(pdev->Res->cursor_cache, sizeof(pdev->Res->cursor_cache));
-    RingInit(&pdev->Res->cursors_lru);
-    pdev->Res->num_cursors = 0;
-    pdev->Res->last_cursor_id = 0;
-
-    RtlZeroMemory(pdev->Res->palette_cache, sizeof(pdev->Res->palette_cache));
-    RingInit(&pdev->Res->palette_lru);
-    pdev->Res->num_palettes = 0;
-    
     pdev->Res->driver = pdev->driver;
 
     ONDBG(pdev->Res->num_outputs = 0);
@@ -1602,6 +1632,18 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique)
     return NULL;
 }
 
+static void PaletteCacheClear(PDev *pdev)
+{
+    DEBUG_PRINT((pdev, 1, "%s\n", __FUNCTION__));
+    EngAcquireSemaphore(pdev->Res->palette_cache_sem);
+    while(pdev->Res->num_palettes) {
+        ASSERT(pdev, RingGetTail(pdev, &pdev->Res->palette_lru));
+        PaletteCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->palette_lru),
+                                             InternalPalette, lru_link));
+    }
+    EngReleaseSemaphore(pdev->Res->palette_cache_sem);
+}
+
 static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette)
 {
     int key;
@@ -2912,6 +2954,18 @@ static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor)
 
 }
 
+static void CursorCacheClear(PDev *pdev)
+{
+    DEBUG_PRINT((pdev, 1, "%s\n", __FUNCTION__));
+    EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
+    while (pdev->Res->num_cursors) {
+        ASSERT(pdev, RingGetTail(pdev, &pdev->Res->cursors_lru));
+        CursorCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->cursors_lru),
+                                            InternalCursor, lru_link));
+    }
+    EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
+}
+
 static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor)
 {
     int key;
@@ -3328,6 +3382,13 @@ BOOL GetTransparentCursor(PDev *pdev, QXLCursorCmd *cmd)
     return TRUE;
 }
 
+void ReleaseCacheDeviceMemoryResources(PDev *pdev)
+{
+    DEBUG_PRINT((pdev, 0, "%s \n", __FUNCTION__));
+    PaletteCacheClear(pdev);
+    CursorCacheClear(pdev);
+}
+
 static void quic_usr_error(QuicUsrContext *usr, const char *format, ...)
 {
     QuicData *quic_data = (QuicData *)usr;
diff --git a/display/res.h b/display/res.h
index 769c02d..b38d5cf 100644
--- a/display/res.h
+++ b/display/res.h
@@ -70,6 +70,9 @@ void ResDestroyGlobals();
 void CheckAndSetSSE2();
 #endif
 void ResetAllDevices();
+void EmptyReleaseRing(PDev *pdev);
+void InitDeviceMemoryResources(PDev *pdev);
+void ReleaseCacheDeviceMemoryResources(PDev *pdev);
 extern DevRes **global_res;
 
 #endif
-- 
1.7.5.4



More information about the Spice-devel mailing list