[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