[Spice-commits] 15 commits - display/driver.c display/qxldd.h display/res.c display/res.h display/rop.c display/surface.h

Alexander Larsson alexl at kemper.freedesktop.org
Tue Sep 21 10:04:12 PDT 2010


 display/driver.c  |   22 ------
 display/qxldd.h   |   16 ++--
 display/res.c     |  197 +++++++++++++++++++++++++++++++++++++++++++-----------
 display/res.h     |    2 
 display/rop.c     |   12 +--
 display/surface.h |   19 ++++-
 6 files changed, 192 insertions(+), 76 deletions(-)

New commits:
commit 55d64c02de69f49fc4d3e9f38fdfaf6ad8f606c9
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 16:37:10 2010 +0200

    Protect palette cache agains concurrent access

diff --git a/display/qxldd.h b/display/qxldd.h
index 8b07f1d..6fd84c4 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -189,6 +189,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 93ab05b..3b8a81e 100644
--- a/display/res.c
+++ b/display/res.c
@@ -415,6 +415,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);
             }
         }
@@ -488,6 +492,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);
@@ -1458,6 +1466,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;
@@ -1489,6 +1498,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) {
@@ -1496,12 +1506,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;
 }
 
@@ -1516,6 +1528,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),
@@ -1529,6 +1542,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__));
 }
 
commit 1f2b0bc13355bb18454eebf45ba2bdb199ec4b13
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 16:31:53 2010 +0200

    Protect cursor cache against concurrent access

diff --git a/display/qxldd.h b/display/qxldd.h
index 51ace78..8b07f1d 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -188,6 +188,7 @@ typedef struct DevRes {
     HSEMAPHORE cursor_sem; /* Protects cursor_ring */
     HSEMAPHORE surface_sem; /* Protects surfaces allocation */
     HSEMAPHORE image_cache_sem; /* Protects image cache */
+    HSEMAPHORE cursor_cache_sem; /* Protects cursor cache */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index 4488340..93ab05b 100644
--- a/display/res.c
+++ b/display/res.c
@@ -411,6 +411,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->image_cache_sem);
                     res->image_cache_sem = NULL;
                 }
+                if (res->cursor_cache_sem) {
+                    EngDeleteSemaphore(res->cursor_cache_sem);
+                    res->cursor_cache_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -480,6 +484,10 @@ static void InitRes(PDev *pdev)
     if (!pdev->Res->image_cache_sem) {
         PANIC(pdev, "Res cache sem creation failed\n");
     }
+    pdev->Res->cursor_cache_sem = EngCreateSemaphore();
+    if (!pdev->Res->cursor_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);
@@ -2769,6 +2777,7 @@ typedef struct InternalCursor {
 
 #define CURSOR_HASH_VAL(hsurf) (HSURF_HASH_VAL(hsurf) & CURSOR_HASH_NASKE)
 
+/* Called with cursor_cache_sem held */
 static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor)
 {
     InternalCursor **internal;
@@ -2785,7 +2794,7 @@ static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor)
                 RingRemove(pdev, &cursor->lru_link);
                 RELEASE_RES(pdev, (Resource *)((UINT8 *)cursor - sizeof(Resource)));
                 pdev->Res->num_cursors--;
-                return;
+                break;
             }
             DEBUG_PRINT((pdev, 0, "%s: unexpected\n", __FUNCTION__));
         }
@@ -2804,6 +2813,7 @@ static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor)
         return;
     }
 
+    EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
     if (pdev->Res->num_cursors == CURSOR_CACHE_SIZE) {
         ASSERT(pdev, RingGetTail(pdev, &pdev->Res->cursors_lru));
         CursorCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->cursors_lru),
@@ -2817,6 +2827,7 @@ static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor)
     RingAdd(pdev, &pdev->Res->cursors_lru, &cursor->lru_link);
     GET_RES((Resource *)((UINT8 *)cursor - sizeof(Resource)));
     pdev->Res->num_cursors++;
+    EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
 }
 
 static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
@@ -2828,6 +2839,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
         return NULL;
     }
 
+    EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
     internal = &pdev->Res->cursor_cache[CURSOR_HASH_VAL(hsurf)];
     while (*internal) {
         InternalCursor *now = *internal;
@@ -2835,6 +2847,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
             if (now->unique == unique) {
                 RingRemove(pdev, &now->lru_link);
                 RingAdd(pdev, &pdev->Res->cursors_lru, &now->lru_link);
+                EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
                 return now;
             }
             CursorCacheRemove(pdev, now);
@@ -2842,6 +2855,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
         }
         internal = &now->next;
     }
+    EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
     return NULL;
 }
 
@@ -2950,7 +2964,9 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
 
     cursor = info->cursor = &internal->cursor;
     cursor->header.type = type;
+    EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
     cursor->header.unique = unique ? ++pdev->Res->last_cursor_id : 0;
+    EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
     cursor->header.width = (UINT16)local_surf->sizlBitmap.cx;
     cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)local_surf->sizlBitmap.cy >> 1 :
                             (UINT16)local_surf->sizlBitmap.cy;
commit 6355188f854e9024dd0edfb4f4f926d85482ec8b
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 16:20:39 2010 +0200

    Protect image cache from concurrent access

diff --git a/display/qxldd.h b/display/qxldd.h
index d63aa9d..51ace78 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -187,6 +187,7 @@ typedef struct DevRes {
     HSEMAPHORE cmd_sem;
     HSEMAPHORE cursor_sem; /* Protects cursor_ring */
     HSEMAPHORE surface_sem; /* Protects surfaces allocation */
+    HSEMAPHORE image_cache_sem; /* Protects image cache */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index a20cb36..4488340 100644
--- a/display/res.c
+++ b/display/res.c
@@ -407,6 +407,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->surface_sem);
                     res->surface_sem = NULL;
                 }
+                if (res->image_cache_sem) {
+                    EngDeleteSemaphore(res->image_cache_sem);
+                    res->image_cache_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -472,6 +476,10 @@ static void InitRes(PDev *pdev)
     if (!pdev->Res->print_sem) {
         PANIC(pdev, "Res print sem creation failed\n");
     }
+    pdev->Res->image_cache_sem = EngCreateSemaphore();
+    if (!pdev->Res->image_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);
@@ -1304,29 +1312,35 @@ typedef struct InternalImage {
 
 static void ImageKeyPut(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 key)
 {
-    ImageKey *image_key = &pdev->Res->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)];
+    ImageKey *image_key;
 
     if (!unique) {
         return;
     }
+    EngAcquireSemaphore(pdev->Res->image_cache_sem);
+    image_key = &pdev->Res->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)];
     image_key->hsurf = hsurf;
     image_key->unique = unique;
     image_key->key = key;
+    EngReleaseSemaphore(pdev->Res->image_cache_sem);
 }
 
 static BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key)
 {
     ImageKey *image_key;
+    BOOL res = FALSE;
 
     if (!unique) {
         return FALSE;
     }
+    EngAcquireSemaphore(pdev->Res->image_cache_sem);
     image_key = &pdev->Res->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)];
     if (image_key->hsurf == hsurf && image_key->unique == unique) {
         *key = image_key->key;
-        return TRUE;
+        res = TRUE;
     }
-    return FALSE;
+    EngReleaseSemaphore(pdev->Res->image_cache_sem);
+    return res;
 }
 
 #define IMAGE_HASH_VAL(hsurf) (HSURF_HASH_VAL(hsurf) & IMAGE_HASH_MASK)
@@ -1334,26 +1348,35 @@ static BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key)
 static CacheImage *ImageCacheGetByKey(PDev *pdev, UINT32 key, BOOL check_rest,
                                       UINT8 format, UINT32 width, UINT32 height)
 {
-    CacheImage *cache_image = pdev->Res->image_cache[IMAGE_HASH_VAL(key)];
+    CacheImage *cache_image;
 
+    EngAcquireSemaphore(pdev->Res->image_cache_sem);
+    cache_image = pdev->Res->image_cache[IMAGE_HASH_VAL(key)];
     while (cache_image) {
         if (cache_image->key == key && (!check_rest || (cache_image->format == format &&
             cache_image->width == width && cache_image->height == height))) {
-            return cache_image;
+            break;
         }
         cache_image = cache_image->next;
     }
-    return NULL;
+    EngReleaseSemaphore(pdev->Res->image_cache_sem);
+    return cache_image;
 }
 
+/* Called with image_cache_sem held */
 static void ImageCacheAdd(PDev *pdev, CacheImage *cache_image)
 {
-    int key = IMAGE_HASH_VAL(cache_image->key);
+    int key;
+
+    EngAcquireSemaphore(pdev->Res->image_cache_sem);
+    key = IMAGE_HASH_VAL(cache_image->key);
     cache_image->next = pdev->Res->image_cache[key];
     cache_image->hits = 1;
     pdev->Res->image_cache[key] = cache_image;
+    EngReleaseSemaphore(pdev->Res->image_cache_sem);
 }
 
+/* Called with image_cache_sem held */
 static void ImageCacheRemove(PDev *pdev, CacheImage *cache_image)
 {
     CacheImage **cache_img;
@@ -1365,12 +1388,13 @@ static void ImageCacheRemove(PDev *pdev, CacheImage *cache_image)
     while (*cache_img) {
         if ((*cache_img)->key == cache_image->key) {
             *cache_img = cache_image->next;
-            return;
+            break;
         }
         cache_img = &(*cache_img)->next;
     }
 }
 
+/* Called with image_cache_sem held */
 static CacheImage *AllocCacheImage(PDev* pdev)
 {
     RingItem *item;
@@ -1539,8 +1563,10 @@ static void FreeQuicImage(PDev *pdev, Resource *res) // todo: defer
 
     internal = (InternalImage *)res->res;
     if (internal->cache) {
+        EngAcquireSemaphore(pdev->Res->image_cache_sem);
         RingAdd(pdev, &pdev->Res->cache_image_lru, &internal->cache->lru_link);
         internal->cache->image = NULL;
+        EngReleaseSemaphore(pdev->Res->image_cache_sem);
     }
 
     chunk_phys = ((QXLDataChunk *)internal->image.quic.data)->next_chunk;
@@ -1702,8 +1728,10 @@ static void FreeBitmapImage(PDev *pdev, Resource *res) // todo: defer
 
     internal = (InternalImage *)res->res;
     if (internal->cache) {
+        EngAcquireSemaphore(pdev->Res->image_cache_sem);
         RingAdd(pdev, &pdev->Res->cache_image_lru, &internal->cache->lru_link);
         internal->cache->image = NULL;
+        EngReleaseSemaphore(pdev->Res->image_cache_sem);
     }
 
     if (internal->image.bitmap.palette) {
@@ -2020,7 +2048,9 @@ static CacheImage *GetCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_tran
     }
 
     if (CacheSizeTest(pdev, surf)) {
-        CacheImage *cache_image = AllocCacheImage(pdev);
+        CacheImage *cache_image;
+        EngAcquireSemaphore(pdev->Res->image_cache_sem);
+        cache_image = AllocCacheImage(pdev);
         ImageCacheRemove(pdev, cache_image);
         cache_image->key = key;
         cache_image->image = NULL;
@@ -2029,6 +2059,7 @@ static CacheImage *GetCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_tran
         cache_image->height = surf->sizlBitmap.cy;
         ImageCacheAdd(pdev, cache_image);
         RingAdd(pdev, &pdev->Res->cache_image_lru, &cache_image->lru_link);
+        EngReleaseSemaphore(pdev->Res->image_cache_sem);
         DEBUG_PRINT((pdev, 11, "%s: ImageCacheAdd %u\n", __FUNCTION__, key));
     }
     return NULL;
@@ -2318,7 +2349,9 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy
             return TRUE;
         }
     } else if (CacheSizeTest(pdev, surf)) {
-        CacheImage *cache_image = AllocCacheImage(pdev);
+        CacheImage *cache_image;
+        EngAcquireSemaphore(pdev->Res->image_cache_sem);
+        cache_image = AllocCacheImage(pdev);
         ImageCacheRemove(pdev, cache_image);
         cache_image->key = key;
         cache_image->image = NULL;
@@ -2327,6 +2360,7 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy
         cache_image->height = surf->sizlBitmap.cy;
         ImageCacheAdd(pdev, cache_image);
         RingAdd(pdev, &pdev->Res->cache_image_lru, &cache_image->lru_link);
+        EngReleaseSemaphore(pdev->Res->image_cache_sem);
         DEBUG_PRINT((pdev, 11, "%s: ImageCacheAdd %u\n", __FUNCTION__, key));
     }
 
commit ecf1ac5b5e8187e1951a448cffeaa0f9741edd30
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 15:42:47 2010 +0200

    Fix typos Chach -> Cache

diff --git a/display/res.c b/display/res.c
index ce7f564..a20cb36 100644
--- a/display/res.c
+++ b/display/res.c
@@ -1909,7 +1909,7 @@ static _inline UINT32 GetFormatLineSize(INT32 width, ULONG bitmap_format, UINT8
     }
 }
 
-static BOOL ChachSizeTest(PDev *pdev, SURFOBJ *surf)
+static BOOL CacheSizeTest(PDev *pdev, SURFOBJ *surf)
 {
     BOOL ret = (UINT32)surf->sizlBitmap.cx * surf->sizlBitmap.cy <= pdev->max_bitmap_size;
     if (!ret) {
@@ -1982,7 +1982,7 @@ BOOL QXLCheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans)
     return FALSE;
 }
 
-static CacheImage *GetChachImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans, int high_bits_set, UINT32 *hash_key)
+static CacheImage *GetCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans, int high_bits_set, UINT32 *hash_key)
 {
     CacheImage *cache_image;
     UINT64 gdi_unique;
@@ -2019,7 +2019,7 @@ static CacheImage *GetChachImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_tran
         return cache_image;
     }
 
-    if (ChachSizeTest(pdev, surf)) {
+    if (CacheSizeTest(pdev, surf)) {
         CacheImage *cache_image = AllocCacheImage(pdev);
         ImageCacheRemove(pdev, cache_image);
         cache_image->key = key;
@@ -2147,7 +2147,7 @@ BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SU
                  surf->iBitmapFormat));
 
     if (use_cache) {
-        cache_image = GetChachImage(pdev, surf, color_trans, high_bits_set, hash_key);
+        cache_image = GetCacheImage(pdev, surf, color_trans, high_bits_set, hash_key);
         if (cache_image && cache_image->image) {
             DEBUG_PRINT((pdev, 11, "%s: cached image found %u\n", __FUNCTION__, cache_image->key));
             internal = cache_image->image;
@@ -2287,7 +2287,7 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy
 
     ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP && surf->iType == STYPE_BITMAP);
 
-    //todo: use GetChachImage
+    //todo: use GetCacheImage
 
     // NOTE: Same BMF_DONTCACHE issue as in QXLGetBitmap
     if (!surf->iUniq || (surf->fjBitmap & BMF_DONTCACHE)) {
@@ -2317,7 +2317,7 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy
             DrawableAddRes(pdev, drawable, image_res);
             return TRUE;
         }
-    } else if (ChachSizeTest(pdev, surf)) {
+    } else if (CacheSizeTest(pdev, surf)) {
         CacheImage *cache_image = AllocCacheImage(pdev);
         ImageCacheRemove(pdev, cache_image);
         cache_image->key = key;
commit e753b6d614f737492815b25ff4ccfd0d5210b489
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 15:37:00 2010 +0200

    Prepend QXL to public function CheckIfCacheImage

diff --git a/display/res.c b/display/res.c
index c053a2f..ce7f564 100644
--- a/display/res.c
+++ b/display/res.c
@@ -1939,7 +1939,7 @@ static _inline UINT64 get_unique(SURFOBJ *surf, XLATEOBJ *color_trans)
     }
 }
 
-BOOL CheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans)
+BOOL QXLCheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans)
 {
     CacheImage *cache_image;
     UINT64 gdi_unique;
diff --git a/display/res.h b/display/res.h
index 6b4882e..3417c02 100644
--- a/display/res.h
+++ b/display/res.h
@@ -47,7 +47,7 @@ BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SU
 BOOL QXLGetBitsFromCache(PDev *pdev, QXLDrawable *drawable, UINT32 hash_key, QXLPHYSICAL *image_phys);
 BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SURFOBJ *surf,
                        QXLRect *area, INT32 *surface_dest);
-BOOL CheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans);
+BOOL QXLCheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans);
 UINT8 *QXLGetBuf(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *buf_phys, UINT32 size);
 BOOL QXLGetStr(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *str_phys, FONTOBJ *font, STROBJ *str);
 
diff --git a/display/rop.c b/display/rop.c
index 6e2a5d9..dce6e44 100644
--- a/display/rop.c
+++ b/display/rop.c
@@ -679,7 +679,7 @@ static BOOL DoCopy(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SU
     }
 
     if (use_cache && TestSplitClips(pdev, src, src_rect, clip, mask) &&
-        !CheckIfCacheImage(pdev, src, color_trans)) {
+        !QXLCheckIfCacheImage(pdev, src, color_trans)) {
         if (clip->iDComplexity == DC_RECT) {
             if (!DoPartialCopy(pdev, surface_id, src, src_rect, area, &clip->rclBounds, color_trans,
                                scale_mode, rop_descriptor)) {
commit 67906d3a092206f161ebca3a5a1123bb528e1d68
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 15:35:46 2010 +0200

    Make internal functions static

diff --git a/display/res.c b/display/res.c
index 07f8991..c053a2f 100644
--- a/display/res.c
+++ b/display/res.c
@@ -1302,7 +1302,7 @@ typedef struct InternalImage {
 
 #define IMAGE_KEY_HASH_VAL(hsurf) (HSURF_HASH_VAL(hsurf) & IMAGE_KEY_HASH_MASK)
 
-void ImageKeyPut(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 key)
+static void ImageKeyPut(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 key)
 {
     ImageKey *image_key = &pdev->Res->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)];
 
@@ -1314,7 +1314,7 @@ void ImageKeyPut(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 key)
     image_key->key = key;
 }
 
-BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key)
+static BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key)
 {
     ImageKey *image_key;
 
commit 578b1e53e623b0d5d69ee6066bae30ddccacac42
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 15:12:15 2010 +0200

    Add semaphore to protect quic_data from concurrent access

diff --git a/display/qxldd.h b/display/qxldd.h
index 26528df..d63aa9d 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -253,6 +253,7 @@ typedef struct PDev {
     UINT8 *surf_base;
 
     QuicData *quic_data;
+    HSEMAPHORE quic_data_sem;
 
     QXLCommandRing *cmd_ring;
     QXLCursorRing *cursor_ring;
diff --git a/display/res.c b/display/res.c
index 353c85b..07f8991 100644
--- a/display/res.c
+++ b/display/res.c
@@ -1645,6 +1645,8 @@ static _inline Resource *GetQuicImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color
         return NULL;
     }
 
+    EngAcquireSemaphore(pdev->quic_data_sem);
+
     quic_data = pdev->quic_data;
 
     alloc_size = MIN(QUIC_ALLOC_BASE + (height * line_size >> 4), QUIC_ALLOC_BASE + QUIC_BUF_MAX);
@@ -1676,13 +1678,18 @@ static _inline Resource *GetQuicImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color
     if (data_size == QUIC_ERROR) {
         FreeQuicImage(pdev, image_res);
         DEBUG_PRINT((pdev, 13, "%s: error\n", __FUNCTION__));
-        return NULL;
+        image_res = NULL;
+        goto out;
     }
 
     quic_data->chunk->data_size = (data_size - quic_data->prev_chunks_io_words) << 2;
     internal->image.quic.data_size = data_size << 2;
     DEBUG_PRINT((pdev, 13, "%s: done. row size %u quic size %u \n", __FUNCTION__,
                  line_size * height, data_size << 2));
+
+ out:
+    EngReleaseSemaphore(pdev->quic_data_sem);
+
     return image_res;
 }
 
@@ -3211,6 +3218,8 @@ BOOL ResInit(PDev *pdev)
         return FALSE;
     }
     pdev->quic_data = usr_data;
+    pdev->quic_data_sem = EngCreateSemaphore();
+
     return TRUE;
 }
 
@@ -3218,6 +3227,7 @@ void ResDestroy(PDev *pdev)
 {
     QuicData *usr_data = pdev->quic_data;
     quic_destroy(usr_data->quic);
+    EngDeleteSemaphore(pdev->quic_data_sem);
     EngFreeMem(usr_data);
 }
 
commit 638c5ff7c62a814afc3e0b8929ad85981df02ae9
Author: Alexander Larsson <alexl at redhat.com>
Date:   Tue Sep 14 15:11:49 2010 +0200

    Remove unused structure member

diff --git a/display/qxldd.h b/display/qxldd.h
index 1cd6fc7..26528df 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -319,8 +319,6 @@ typedef struct PDev {
 
     UINT32 n_surfaces;
     SurfaceInfo surface0_info;
-
-    VIDEOMEMORY *pvmList;
 } PDev;
 
 
commit 590559c13788e63dabce7bc825bb2aad756ccda2
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 20:20:21 2010 +0200

    Save FPU on stack, not in pdev
    
    We can't use the global pdev FPUSave, because multiple processes
    could be calling the sse2 using code in parallel.

diff --git a/display/qxldd.h b/display/qxldd.h
index 956f152..1cd6fc7 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -317,8 +317,6 @@ typedef struct PDev {
     Ring update_trace;
     UpdateTrace update_trace_items[NUM_UPDATE_TRACE_ITEMS];
 
-    UINT8 FPUSave[16 * 4 + 15];
-
     UINT32 n_surfaces;
     SurfaceInfo surface0_info;
 
diff --git a/display/res.c b/display/res.c
index 33abd31..353c85b 100644
--- a/display/res.c
+++ b/display/res.c
@@ -1719,9 +1719,9 @@ static void FreeBitmapImage(PDev *pdev, Resource *res) // todo: defer
     DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__));
 }
 
-static _inline void RestoreFPU(PDev *pdev)
+static _inline void RestoreFPU(PDev *pdev, UINT8 FPUSave[])
 {
-    void *align_addr =  (void *)ALIGN((size_t)(&pdev->FPUSave), SSE_ALIGN);
+    void *align_addr =  (void *)ALIGN((size_t)(FPUSave), SSE_ALIGN);
 
     _asm
     {
@@ -1734,9 +1734,9 @@ static _inline void RestoreFPU(PDev *pdev)
     }
 }
 
-static _inline void SaveFPU(PDev *pdev)
+static _inline void SaveFPU(PDev *pdev, UINT8 FPUSave[])
 {
-    void *align_addr =  (void *)ALIGN((size_t)(&pdev->FPUSave), SSE_ALIGN);
+    void *align_addr =  (void *)ALIGN((size_t)(FPUSave), SSE_ALIGN);
 
     _asm
     {
@@ -1771,7 +1771,6 @@ static _inline Resource *GetBitmapImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *col
     UINT8 *src_end;
     UINT8 *dest;
     UINT8 *dest_end;
-    BOOL use_sse = FALSE;
 
     DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__));
     ASSERT(pdev, width > 0 && height > 0);
@@ -1805,17 +1804,21 @@ static _inline Resource *GetBitmapImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *col
     alloc_size = height * line_size;
 
     if (have_sse2 && alloc_size >= 1024) {
-        use_sse = TRUE;
-        SaveFPU(pdev);
-    }
+        UINT8 FPUSave[16 * 4 + 15];
 
-    for (; src != src_end; src -= surf->lDelta, alloc_size -= line_size) {
-        PutBytesAlign(pdev, &chunk, &dest, &dest_end, src, line_size,
-                      &pdev->Res->num_bits_pages, alloc_size, line_size, TRUE);
-    }
+        SaveFPU(pdev, FPUSave);
+
+	for (; src != src_end; src -= surf->lDelta, alloc_size -= line_size) {
+	  PutBytesAlign(pdev, &chunk, &dest, &dest_end, src, line_size,
+			&pdev->Res->num_bits_pages, alloc_size, line_size, TRUE);
+	}
 
-    if (use_sse) {
-        RestoreFPU(pdev);
+        RestoreFPU(pdev, FPUSave);
+    } else {
+        for (; src != src_end; src -= surf->lDelta, alloc_size -= line_size) {
+            PutBytesAlign(pdev, &chunk, &dest, &dest_end, src, line_size,
+                          &pdev->Res->num_bits_pages, alloc_size, line_size, FALSE);
+        }
     }
 
     GetPallette(pdev, &internal->image.bitmap, color_trans);
commit b12ee84241ee004fd540b3146f50ad786abf36a9
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 20:11:37 2010 +0200

    Add protection for cursor_ring

diff --git a/display/qxldd.h b/display/qxldd.h
index 1a9bfe6..956f152 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -185,6 +185,7 @@ typedef struct DevRes {
 
     HSEMAPHORE print_sem;
     HSEMAPHORE cmd_sem;
+    HSEMAPHORE cursor_sem; /* Protects cursor_ring */
     HSEMAPHORE surface_sem; /* Protects surfaces allocation */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
diff --git a/display/res.c b/display/res.c
index 379ba86..33abd31 100644
--- a/display/res.c
+++ b/display/res.c
@@ -158,6 +158,7 @@ static _inline void CursorCmdAddRes(PDev *pdev, QXLCursorCmd *cmd, Resource *res
     AddRes(pdev, output, res);
 }
 
+/* Called with cursor_sem held */
 static void WaitForCursorRing(PDev* pdev)
 {
     int wait;
@@ -394,6 +395,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->cmd_sem);
                     res->cmd_sem = NULL;
                 }
+                if (res->cursor_sem) {
+                    EngDeleteSemaphore(res->cursor_sem);
+                    res->cursor_sem = NULL;
+                }
                 if (res->print_sem) {
                     EngDeleteSemaphore(res->print_sem);
                     res->print_sem = NULL;
@@ -459,6 +464,10 @@ static void InitRes(PDev *pdev)
     if (!pdev->Res->cmd_sem) {
         PANIC(pdev, "Res cmd sem creation failed\n");
     }
+    pdev->Res->cursor_sem = EngCreateSemaphore();
+    if (!pdev->Res->cursor_sem) {
+        PANIC(pdev, "Res cursor sem creation failed\n");
+    }
     pdev->Res->print_sem = EngCreateSemaphore();
     if (!pdev->Res->print_sem) {
         PANIC(pdev, "Res print sem creation failed\n");
@@ -2695,11 +2704,13 @@ void PushCursorCmd(PDev *pdev, QXLCursorCmd *cursor_cmd)
     QXLCommand *cmd;
 
     DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
+    EngAcquireSemaphore(pdev->Res->cursor_sem);
     WaitForCursorRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cursor_ring);
     cmd->type = QXL_CMD_CURSOR;
     cmd->data = PA(pdev, cursor_cmd, pdev->main_mem_slot);
     PUSH_CURSOR_CMD(pdev);
+    EngReleaseSemaphore(pdev->Res->cursor_sem);
     DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__));
 }
 
commit f599cd2226ecebe925db4c88c448c1dcda926748
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 20:09:32 2010 +0200

    Fixed up cmd_sem use

diff --git a/display/res.c b/display/res.c
index 8b276bb..379ba86 100644
--- a/display/res.c
+++ b/display/res.c
@@ -588,13 +588,13 @@ void PushDrawable(PDev *pdev, QXLDrawable *drawable)
 {
     QXLCommand *cmd;
 
-    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
+    EngAcquireSemaphore(pdev->Res->cmd_sem);
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_DRAW;
     cmd->data = PA(pdev, drawable, pdev->main_mem_slot);
     PUSH_CMD(pdev);
-    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
+    EngReleaseSemaphore(pdev->Res->cmd_sem);
 }
 
 static QXLSurfaceCmd *GetSurfaceCmd(PDev *pdev)
@@ -627,13 +627,13 @@ void PushSurfaceCmd(PDev *pdev, QXLSurfaceCmd *surface_cmd)
 {
     QXLCommand *cmd;
 
-    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
+    EngAcquireSemaphore(pdev->Res->cmd_sem);
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_SURFACE;
     cmd->data = PA(pdev, surface_cmd, pdev->main_mem_slot);
     PUSH_CMD(pdev);
-    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
+    EngReleaseSemaphore(pdev->Res->cmd_sem);
 }
 
 
@@ -2437,13 +2437,13 @@ void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id)
     updat_cmd->update_id = ++pdev->Res->update_id;
     updat_cmd->surface_id = surface_id;
 
-    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
+    EngAcquireSemaphore(pdev->Res->cmd_sem);
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_UPDATE;
     cmd->data = PA(pdev, updat_cmd, pdev->main_mem_slot);
     PUSH_CMD(pdev);
-    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
+    EngReleaseSemaphore(pdev->Res->cmd_sem);
     do {
 #ifdef DBG
         {
commit c42f48817779b4483d1ce6b2dea37b751a165d22
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 20:03:59 2010 +0200

    Only look for streams on primary surface
    
    We currently only support streams there anyway, and the code doesn't
    work for offscreen surfaces as is since its only looking at the
    destination rect.

diff --git a/display/rop.c b/display/rop.c
index 66fc4de..6e2a5d9 100644
--- a/display/rop.c
+++ b/display/rop.c
@@ -500,14 +500,16 @@ static BOOL DoOpaque(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip,
     return TRUE;
 }
 
-static BOOL StreamTest(PDev *pdev, SURFOBJ *src_surf, XLATEOBJ *color_trans, RECTL *src_rect,
-                       RECTL *dest)
+static BOOL StreamTest(PDev *pdev, UINT32 surface_id, SURFOBJ *src_surf, 
+		       XLATEOBJ *color_trans, RECTL *src_rect, RECTL *dest)
 {
     Ring *ring = &pdev->update_trace;
     UpdateTrace *trace = (UpdateTrace *)ring->next;
     LONG src_pixmap_pixels = src_surf->sizlBitmap.cx * src_surf->sizlBitmap.cy;
 
-    if (src_pixmap_pixels <= 128 * 128) {
+    if (src_pixmap_pixels <= 128 * 128 || 
+	/* Only handle streams on primary surface */
+	surface_id != 0) {
         return TRUE;
     }
 
@@ -673,7 +675,7 @@ static BOOL DoCopy(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SU
     if (mask) {
         use_cache = TRUE;
     } else {
-        use_cache = StreamTest(pdev, src, color_trans, src_rect, area);
+        use_cache = StreamTest(pdev, surface_id, src, color_trans, src_rect, area);
     }
 
     if (use_cache && TestSplitClips(pdev, src, src_rect, clip, mask) &&
commit 08a4554b7ad1083393e2f136c45fdc5e51c0a62c
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 17:04:46 2010 +0200

    Protect surface id allocation with semaphore

diff --git a/display/qxldd.h b/display/qxldd.h
index 206b994..1a9bfe6 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -185,6 +185,7 @@ typedef struct DevRes {
 
     HSEMAPHORE print_sem;
     HSEMAPHORE cmd_sem;
+    HSEMAPHORE surface_sem; /* Protects surfaces allocation */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index a31832d..8b276bb 100644
--- a/display/res.c
+++ b/display/res.c
@@ -398,6 +398,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->print_sem);
                     res->print_sem = NULL;
                 }
+                if (res->surface_sem) {
+                    EngDeleteSemaphore(res->surface_sem);
+                    res->surface_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -431,9 +435,13 @@ static void InitRes(PDev *pdev)
 {
     UINT32 i;
 
-   pdev->Res->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
-							 sizeof(SurfaceInfo) * pdev->n_surfaces, 
-							 ALLOC_TAG);
+    pdev->Res->surface_sem = EngCreateSemaphore();
+    if (!pdev->Res->surface_sem) {
+        PANIC(pdev, "Res surface sem creation failed\n");
+    }
+    pdev->Res->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
+							  sizeof(SurfaceInfo) * pdev->n_surfaces, 
+							  ALLOC_TAG);
     if (!pdev->Res->surfaces_info) {
         PANIC(pdev, "Res surfaces_info allocation failed\n");
     }
diff --git a/display/surface.h b/display/surface.h
index a25cbd9..028f97e 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -37,26 +37,37 @@ static _inline void FreeSurface(PDev *pdev, UINT32 surface_id)
     if (surface_id == 0) {
         return;
     }
+
+    EngAcquireSemaphore(pdev->Res->surface_sem);
+
     surface = &pdev->Res->surfaces_info[surface_id];
     surface->draw_area.base_mem = NULL; /* Mark as not used */
     surface->u.next_free = pdev->Res->free_surfaces;
     pdev->Res->free_surfaces = surface;
+
+    EngReleaseSemaphore(pdev->Res->surface_sem);
 }
 
 
 static UINT32 GetFreeSurface(PDev *pdev)
 {
-    UINT32 x;
+    UINT32 x, id;
     SurfaceInfo *surface;
 
+    EngAcquireSemaphore(pdev->Res->surface_sem);
+
     surface = pdev->Res->free_surfaces;
     if (surface == NULL) {
-        return 0;
+        id = 0;
+    } else {
+      pdev->Res->free_surfaces = surface->u.next_free;
+
+      id = surface - pdev->Res->surfaces_info;
     }
 
-    pdev->Res->free_surfaces = surface->u.next_free;
+    EngReleaseSemaphore(pdev->Res->surface_sem);
 
-    return surface - pdev->Res->surfaces_info;
+    return id;
 }
 
 enum {
commit 404251dd0f5001c68f2c0b3d7b84530f3e1b5a40
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 16:59:04 2010 +0200

    Protect all references to cmd_ring with cmd_sem

diff --git a/display/res.c b/display/res.c
index 5dc72c5..a31832d 100644
--- a/display/res.c
+++ b/display/res.c
@@ -78,12 +78,10 @@ static BOOL SetClip(PDev *pdev, CLIPOBJ *clip, QXLDrawable *drawable);
 
 #define PUSH_CMD(pdev) do {                             \
     int notify;                                         \
-    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
     SPICE_RING_PUSH(pdev->cmd_ring, notify);            \
     if (notify) {                                       \
         WRITE_PORT_UCHAR(pdev->notify_cmd_port, 0);     \
     }                                                   \
-    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
 } while (0);
 
 #define PUSH_CURSOR_CMD(pdev) do {                      \
@@ -196,6 +194,7 @@ static void WaitForCursorRing(PDev* pdev)
     }
 }
 
+/* Called with cmd_sem held */
 static void WaitForCmdRing(PDev* pdev)
 {
     int wait;
@@ -581,11 +580,13 @@ void PushDrawable(PDev *pdev, QXLDrawable *drawable)
 {
     QXLCommand *cmd;
 
+    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_DRAW;
     cmd->data = PA(pdev, drawable, pdev->main_mem_slot);
     PUSH_CMD(pdev);
+    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
 }
 
 static QXLSurfaceCmd *GetSurfaceCmd(PDev *pdev)
@@ -618,11 +619,13 @@ void PushSurfaceCmd(PDev *pdev, QXLSurfaceCmd *surface_cmd)
 {
     QXLCommand *cmd;
 
+    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_SURFACE;
     cmd->data = PA(pdev, surface_cmd, pdev->main_mem_slot);
     PUSH_CMD(pdev);
+    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
 }
 
 
@@ -2426,11 +2429,13 @@ void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id)
     updat_cmd->update_id = ++pdev->Res->update_id;
     updat_cmd->surface_id = surface_id;
 
+    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
     WaitForCmdRing(pdev);
     cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring);
     cmd->type = QXL_CMD_UPDATE;
     cmd->data = PA(pdev, updat_cmd, pdev->main_mem_slot);
     PUSH_CMD(pdev);
+    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
     do {
 #ifdef DBG
         {
commit 587f9f9ebc6ce1ffac626bd5ce5841fd8038969a
Author: Alexander Larsson <alexl at redhat.com>
Date:   Mon Sep 13 16:47:23 2010 +0200

    Move cmd_sem and print_sem to global device info
    
    The cmd and print semaphores protect hardware instances that exist
    one per device, so we can't really use per-pdev locks to protect them.

diff --git a/display/driver.c b/display/driver.c
index 1ff8925..1d5576f 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -108,12 +108,12 @@ static CallCounterInfo counters_info[NUM_CALL_COUNTERS] = {
 void DebugPrintV(PDev *pdev, const char *message, va_list ap)
 {
     if (pdev && pdev->log_buf) {
-        EngAcquireSemaphore(pdev->print_sem);
+        EngAcquireSemaphore(pdev->Res->print_sem);
         _snprintf(pdev->log_buf, QXL_LOG_BUF_SIZE, QXLDD_DEBUG_PREFIX);
         _vsnprintf(pdev->log_buf + strlen(QXLDD_DEBUG_PREFIX),
                    QXL_LOG_BUF_SIZE - strlen(QXLDD_DEBUG_PREFIX), message, ap);
         WRITE_PORT_UCHAR(pdev->log_port, 0);
-        EngReleaseSemaphore(pdev->print_sem);
+        EngReleaseSemaphore(pdev->Res->print_sem);
     } else {
         EngDebugPrint(QXLDD_DEBUG_PREFIX, (PCHAR)message, ap);
     }
@@ -509,19 +509,9 @@ DHPDEV DrvEnablePDEV(DEVMODEW *dev_mode, PWSTR ignore1, ULONG ignore2, HSURF *ig
         goto err1;
     }
 
-    if (!(pdev->print_sem = EngCreateSemaphore())) {
-        DEBUG_PRINT((NULL, 0, "%s: create print sem failed\n", __FUNCTION__));
-        goto err2;
-    }
-
-    if (!(pdev->cmd_sem = EngCreateSemaphore())) {
-        DEBUG_PRINT((NULL, 0, "%s: create cmd sem failed\n", __FUNCTION__));
-        goto err3;
-    }
-
     if (!ResInit(pdev)) {
         DEBUG_PRINT((NULL, 0, "%s: init res failed\n", __FUNCTION__));
-        goto err4;
+        goto err2;
     }
 
     RtlCopyMemory(dev_caps, &gdi_info, dev_caps_size);
@@ -530,10 +520,6 @@ DHPDEV DrvEnablePDEV(DEVMODEW *dev_mode, PWSTR ignore1, ULONG ignore2, HSURF *ig
     DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev));
     return(DHPDEV)pdev;
 
-err4:
-    EngDeleteSemaphore(pdev->cmd_sem);
-err3:
-    EngDeleteSemaphore(pdev->print_sem);
 err2:
     DestroyPalette(pdev);
 
@@ -550,8 +536,6 @@ VOID DrvDisablePDEV(DHPDEV in_pdev)
     DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev));
     ResDestroy(pdev);
     DestroyPalette(pdev);
-    EngDeleteSemaphore(pdev->cmd_sem);
-    EngDeleteSemaphore(pdev->print_sem);
     EngFreeMem(pdev);
     DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev));
 }
diff --git a/display/qxldd.h b/display/qxldd.h
index 5588170..206b994 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -183,6 +183,9 @@ typedef struct DevRes {
     UINT64 free_outputs;
     UINT32 update_id;
 
+    HSEMAPHORE print_sem;
+    HSEMAPHORE cmd_sem;
+
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
     Ring cursors_lru;
@@ -263,9 +266,6 @@ typedef struct PDev {
     UINT8 *log_buf;
     UINT32 *log_level;
 
-    HSEMAPHORE print_sem;
-    HSEMAPHORE cmd_sem;
-
     PMemSlot *mem_slots;
     UINT8 num_mem_slot;
     UINT8 main_mem_slot;
diff --git a/display/res.c b/display/res.c
index 7515424..5dc72c5 100644
--- a/display/res.c
+++ b/display/res.c
@@ -78,12 +78,12 @@ static BOOL SetClip(PDev *pdev, CLIPOBJ *clip, QXLDrawable *drawable);
 
 #define PUSH_CMD(pdev) do {                             \
     int notify;                                         \
-    EngAcquireSemaphore(pdev->cmd_sem);                 \
+    EngAcquireSemaphore(pdev->Res->cmd_sem);            \
     SPICE_RING_PUSH(pdev->cmd_ring, notify);            \
     if (notify) {                                       \
         WRITE_PORT_UCHAR(pdev->notify_cmd_port, 0);     \
     }                                                   \
-    EngReleaseSemaphore(pdev->cmd_sem);                 \
+    EngReleaseSemaphore(pdev->Res->cmd_sem);            \
 } while (0);
 
 #define PUSH_CURSOR_CMD(pdev) do {                      \
@@ -391,6 +391,14 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->malloc_sem);
                     res->malloc_sem = NULL;
                 }
+                if (res->cmd_sem) {
+                    EngDeleteSemaphore(res->cmd_sem);
+                    res->cmd_sem = NULL;
+                }
+                if (res->print_sem) {
+                    EngDeleteSemaphore(res->print_sem);
+                    res->print_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -440,6 +448,14 @@ static void InitRes(PDev *pdev)
     if (!pdev->Res->malloc_sem) {
         PANIC(pdev, "Res malloc sem creation failed\n");
     }
+    pdev->Res->cmd_sem = EngCreateSemaphore();
+    if (!pdev->Res->cmd_sem) {
+        PANIC(pdev, "Res cmd sem creation failed\n");
+    }
+    pdev->Res->print_sem = EngCreateSemaphore();
+    if (!pdev->Res->print_sem) {
+        PANIC(pdev, "Res print 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);


More information about the Spice-commits mailing list