[Spice-devel] [PATCH 17/17] Protect palette cache agains concurrent access

alexl at redhat.com alexl at redhat.com
Tue Sep 14 12:09:07 PDT 2010


From: Alexander Larsson <alexl at redhat.com>

---
 display/qxldd.h |    1 +
 display/res.c   |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/display/qxldd.h b/display/qxldd.h
index 28df205..876fc11 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -185,6 +185,7 @@ typedef struct DevRes {
     HSEMAPHORE surface_sem; /* Protects surfaces allocation */
     HSEMAPHORE image_cache_sem; /* Protects image cache */
     HSEMAPHORE cursor_cache_sem; /* Protects cursor cache */
+    HSEMAPHORE palette_cache_sem; /* Protects palette cache */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index e780d51..f0f480a 100644
--- a/display/res.c
+++ b/display/res.c
@@ -411,6 +411,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->cursor_cache_sem);
                     res->cursor_cache_sem = NULL;
                 }
+                if (res->palette_cache_sem) {
+                    EngDeleteSemaphore(res->palette_cache_sem);
+                    res->palette_cache_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -484,6 +488,10 @@ static void InitRes(PDev *pdev)
     if (!pdev->Res->cursor_cache_sem) {
         PANIC(pdev, "Res cache sem creation failed\n");
     }
+    pdev->Res->palette_cache_sem = EngCreateSemaphore();
+    if (!pdev->Res->palette_cache_sem) {
+        PANIC(pdev, "Res cache sem creation failed\n");
+    }
 
     InitMspace(pdev->Res, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
     InitMspace(pdev->Res, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
@@ -1454,6 +1462,7 @@ static _inline void ReleasePalette(PDev *pdev, InternalPalette *palette)
     }
 }
 
+/* Called with palette_cache_sem held */
 static _inline void PaletteCacheRemove(PDev *pdev, InternalPalette *palette)
 {
     InternalPalette **internal;
@@ -1485,6 +1494,7 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique)
     if (!unique) {
         return NULL;
     }
+    EngAcquireSemaphore(pdev->Res->palette_cache_sem);
 
     now = pdev->Res->palette_cache[PALETTE_HASH_VAL(unique)];
     while (now) {
@@ -1492,12 +1502,14 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique)
             RingRemove(pdev, &now->lru_link);
             RingAdd(pdev, &pdev->Res->palette_lru, &now->lru_link);
             now->refs++;
+            EngReleaseSemaphore(pdev->Res->palette_cache_sem);
             DEBUG_PRINT((pdev, 13, "%s: found\n", __FUNCTION__));
             return now;
         }
         now = now->next;
     }
     DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__));
+    EngReleaseSemaphore(pdev->Res->palette_cache_sem);
     return NULL;
 }
 
@@ -1512,6 +1524,7 @@ static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette)
         return;
     }
 
+    EngAcquireSemaphore(pdev->Res->palette_cache_sem);
     if (pdev->Res->num_palettes == PALETTE_CACHE_SIZE) {
         ASSERT(pdev, RingGetTail(pdev, &pdev->Res->palette_lru));
         PaletteCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->palette_lru),
@@ -1525,6 +1538,7 @@ static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette)
     RingAdd(pdev, &pdev->Res->palette_lru, &palette->lru_link);
     palette->refs++;
     pdev->Res->num_palettes++;
+    EngReleaseSemaphore(pdev->Res->palette_cache_sem);
     DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__));
 }
 
-- 
1.7.2.2



More information about the Spice-devel mailing list