summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-06-05 15:45:40 +0300
committerAlon Levy <alevy@redhat.com>2011-06-20 12:39:34 +0200
commit92cfe646fda85f3e7e2b9306bc0f2e1829a0f0bb (patch)
treeac692854be2568a0994d3428c985eb4b5d33ba18
parentcebf06e9d1a245c65bf6a9f92d48c50894bd584c (diff)
display/res: add helpers for clearing device memory
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@redhat.com>
-rw-r--r--display/res.c105
-rw-r--r--display/res.h3
2 files changed, 86 insertions, 22 deletions
diff --git a/display/res.c b/display/res.c
index 9872d6e..b70c645 100644
--- a/display/res.c
+++ b/display/res.c
@@ -370,6 +370,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)
@@ -508,6 +521,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;
@@ -557,30 +608,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);
@@ -1601,6 +1631,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;
@@ -2911,6 +2953,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;
@@ -3327,6 +3381,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