[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-qxl: Changes to 'upstream-experimental'



 README.xspice               |    4 
 configure.ac                |   15 +-
 src/Makefile.am             |    3 
 src/compat-api.h            |   99 ++++++++++++++++++
 src/mspace.c                |   44 ++++++--
 src/mspace.h                |   10 +
 src/qxl.h                   |   26 +++-
 src/qxl_cursor.c            |    3 
 src/qxl_driver.c            |  237 +++++++++++++++++++++++++++++---------------
 src/qxl_image.c             |    4 
 src/qxl_mem.c               |   59 ++++++++++
 src/qxl_option_helpers.c    |    4 
 src/qxl_ring.c              |    4 
 src/qxl_surface.c           |  123 ++++++++++++++++++----
 src/spiceqxl_display.c      |    7 -
 src/spiceqxl_driver.c       |    3 
 src/spiceqxl_inputs.c       |    3 
 src/spiceqxl_io_port.c      |   11 +-
 src/spiceqxl_main_loop.c    |   20 +++
 src/spiceqxl_spice_server.c |    3 
 src/uxa/uxa-accel.c         |    2 
 src/uxa/uxa-damage.c        |    1 
 src/uxa/uxa-glyphs.c        |   12 +-
 src/uxa/uxa-priv.h          |    3 
 src/uxa/uxa.c               |   18 +--
 25 files changed, 561 insertions(+), 157 deletions(-)

New commits:
commit de66207883efc1f32e96907c3e64f17b2bdf6c3e
Author: Alon Levy <alevy@redhat.com>
Date:   Sun Jul 8 14:05:08 2012 +0300

    qxl_driver/qxl_switch_mode: destroy is not idempotent

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index a6d7636..e4c477a 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -701,10 +701,9 @@ qxl_switch_mode(SWITCH_MODE_ARGS_DECL)
     {
 	qxl_surface_kill (qxl->primary);
 	qxl_surface_cache_sanity_check (qxl->surface_cache);
+        qxl_io_destroy_primary(qxl);
     }
 
-    qxl_io_destroy_primary(qxl);
-
     qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache, m);
     qxl->current_mode = m;
     qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8;

commit 6267b1a56f6104409fcb970eddc4ea9606421331
Author: Alon Levy <alevy@redhat.com>
Date:   Wed Mar 7 14:30:58 2012 +0200

    spiceqxl_display: reformat & rephrase Xspice comment

diff --git a/src/spiceqxl_display.c b/src/spiceqxl_display.c
index ea61430..b1ce557 100644
--- a/src/spiceqxl_display.c
+++ b/src/spiceqxl_display.c
@@ -67,8 +67,8 @@
 
 
 /* XSpice:
- * We only need a single identify slot, no need to change it for the lifetime
- * We actually need no slots, but less changes if we leave one.
+ * We only need a single static identity slot.
+ * We actually need no slots, but less changes if we use one.
  * We currently add it during attache_worker - should not be called more
  * then once during lifetime (but we don't check)
  */

commit e0f301fc0512502542573b3f8dd9452f5a7ea6e1
Author: Jeremy White <jwhite@codeweavers.com>
Date:   Wed Jun 13 17:04:12 2012 -0500

    Compute totalPixmapSize using the same logic as in dix/pixmap.c, rather than hard coding 100.
    
    This was found while building with a modified X server; one with a PixmapRec size of 224, not 64 :-/.

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 54bbd4a..a6d7636 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -1138,8 +1138,6 @@ qxl_screen_init(SCREEN_INIT_ARGS_DECL)
     ErrorF ("allocated %d x %d  %p\n", pScrn->virtualX, pScrn->virtualY, qxl->fb);
 #endif
     
-    pScreen->totalPixmapSize = 100;
-
     pScrn->virtualX = pScrn->currentMode->HDisplay;
     pScrn->virtualY = pScrn->currentMode->VDisplay;
 
@@ -1198,6 +1196,10 @@ qxl_screen_init(SCREEN_INIT_ARGS_DECL)
 
     DamageSetup(pScreen);
     
+    /* We need to set totalPixmapSize after setup_uxa and Damage,
+	as the privatessize is not computed correctly until then */
+    pScreen->totalPixmapSize = BitmapBytePad((sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP) ) * 8);
+
     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
     if (!miCreateDefColormap(pScreen))
       goto out;

commit 6832c0fd917556c52f56f8e82706a83942ed3dc1
Author: Jeremy White <jwhite@codeweavers.com>
Date:   Sun Jun 3 10:28:05 2012 -0500

    Actually process write watches in the wakeup handler
    
    My apologies for the churn; this is, I think, a slightly better patch than
    my previous patch, 'Process watches even when there is no X activity', in that
    it avoids doing an extra polling select when we're idle.

diff --git a/src/spiceqxl_main_loop.c b/src/spiceqxl_main_loop.c
index 1718861..e57fb91 100644
--- a/src/spiceqxl_main_loop.c
+++ b/src/spiceqxl_main_loop.c
@@ -315,9 +315,24 @@ static void select_and_check_watches(void)
     }
 }
 
+static int no_write_watches(Ring *w)
+{
+    SpiceWatch *watch;
+    RingItem *link;
+    RingItem *next;
+
+    RING_FOREACH_SAFE(link, next, w) {
+        watch = (SpiceWatch*)link;
+        if (!watch->remove && (watch->event_mask & SPICE_WATCH_EVENT_WRITE))
+            return 0;
+    }
+
+    return 1;
+}
+
 static void xspice_wakeup_handler(pointer data, int nfds, pointer readmask)
 {
-    if (!nfds) {
+    if (!nfds && no_write_watches(&watches)) {
         return;
     }
     select_and_check_watches();

commit 72a0def8114073c0051f3df880f731d3968cb344
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 30 13:44:40 2012 +0300

    qxl_switch_mode: don't evacuate, just recreate primary surface
    
    In summary, on vt enter we still:
     reset
     recreate memory slots
     clear our mspace allocators
     and then do what switch mode below says
    
    On vt leave we still:
     reset (this is redundant since the first VGA access will trigger a
     reset on the device side)
    
    On switch mode however we only:
     destroy primary surface
     create primary surface (different size)

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 0e34a86..54bbd4a 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -696,19 +696,14 @@ qxl_switch_mode(SWITCH_MODE_ARGS_DECL)
     int mode_index = (int)(unsigned long)mode->Private;
     struct QXLMode *m = qxl->modes + mode_index;
     ScreenPtr pScreen;
-    void *evacuated;
-
-    evacuated = qxl_surface_cache_evacuate_all (qxl->surface_cache);
 
     if (qxl->primary)
     {
 	qxl_surface_kill (qxl->primary);
 	qxl_surface_cache_sanity_check (qxl->surface_cache);
     }
-	
-    qxl_reset_and_create_mem_slots (qxl);
-    
-    ErrorF ("done reset\n");
+
+    qxl_io_destroy_primary(qxl);
 
     qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache, m);
     qxl->current_mode = m;
@@ -725,19 +720,7 @@ qxl_switch_mode(SWITCH_MODE_ARGS_DECL)
 	
 	set_surface (root, qxl->primary);
     }
-    
-    ErrorF ("primary is %p\n", qxl->primary);
-    if (qxl->mem)
-    {
-       qxl_mem_free_all (qxl->mem);
-       qxl_drop_image_cache (qxl);
-    }
-
-    if (qxl->surf_mem)
-	qxl_mem_free_all (qxl->surf_mem);
 
-    qxl_surface_cache_replace_all (qxl->surface_cache, evacuated);
-    
     return TRUE;
 }
 
@@ -1256,8 +1239,20 @@ qxl_enter_vt(VT_FUNC_ARGS_DECL)
     qxl_screen_t *qxl = pScrn->driverPrivate;
 
     qxl_save_state(pScrn);
+
+    qxl_reset_and_create_mem_slots (qxl);
+
     qxl_switch_mode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode));
 
+    if (qxl->mem)
+    {
+       qxl_mem_free_all (qxl->mem);
+       qxl_drop_image_cache (qxl);
+    }
+
+    if (qxl->surf_mem)
+       qxl_mem_free_all (qxl->surf_mem);
+
     if (qxl->vt_surfaces)
     {
 	qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);

commit 8df3eba368e80f60ce815300b85a567a9b02141c
Author: Alon Levy <alevy@redhat.com>
Date:   Thu May 31 13:04:01 2012 +0300

    qxl_surface: don't unlink surface 0
    
    The primary surface, i.e. qxl->primary, the only surface with id==0, is
    allocated in qxl_surface_cache_create_primary with prev==next==NULL.
    Unlinking it was producing a wrong cache->free_surfaces == NULL. This
    was not a problem because unlinking the primary only happened in
    switch_host, which then called surface_cache_init. In a following commit
    switch_host is simplified to destroy-primary+create-primary, so this bug
    needs to be fixed first to avoid leaking surfaces and reaching a no
    surface available situation.

diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index a76db17..113f09b 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -732,10 +732,13 @@ qxl_surface_set_pixmap (qxl_surface_t *surface, PixmapPtr pixmap)
 static void
 unlink_surface (qxl_surface_t *surface)
 {
-    if (surface->prev)
-	surface->prev->next = surface->next;
-    else
-	surface->cache->live_surfaces = surface->next;
+    if (surface->id != 0)
+    {
+        if (surface->prev)
+            surface->prev->next = surface->next;
+        else
+            surface->cache->live_surfaces = surface->next;
+    }
 
     debug_surface_log(surface->cache);
     

commit 22157d4750f9090927d2e3473aa3d3a4f5232792
Author: Alon Levy <alevy@redhat.com>
Date:   Thu May 31 13:03:54 2012 +0300

    qxl_surface: add DEBUG_SURFACE_LIFECYCLE helpers

diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 3b2f9dc..a76db17 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -49,6 +49,12 @@
 
 #include "qxl.h"
 
+#ifdef DEBUG_SURFACE_LIFECYCLE
+#include <stdio.h>
+
+static FILE* surface_log;
+#endif
+
 typedef struct evacuated_surface_t evacuated_surface_t;
 
 struct qxl_surface_t
@@ -122,6 +128,44 @@ struct surface_cache_t
     qxl_surface_t *cached_surfaces[N_CACHED_SURFACES];
 };
 
+#ifdef DEBUG_SURFACE_LIFECYCLE
+static void debug_surface_open(void)
+{
+    if (surface_log)
+        return;
+    surface_log = fopen("/tmp/xf86-video-qxl.surface.log", "w+");
+    if (!surface_log)
+    {
+        fprintf(stderr, "error creating surface log file (DEBUG_SURFACE_LIFECYCLE)\n");
+        exit(-1);
+    }
+}
+
+static int surface_count(qxl_surface_t *surface)
+{
+    int i;
+
+    for (i = 0; surface ;++i, surface = surface->next);
+    return i;
+}
+
+static void debug_surface_log(surface_cache_t *cache)
+{
+    int  live_n, free_n;
+
+    debug_surface_open();
+    live_n = surface_count(cache->live_surfaces);
+    free_n = surface_count(cache->free_surfaces);
+    fprintf(surface_log, "live,free,sum = %d, %d, %d\n", live_n, free_n,
+            live_n + free_n);
+    fflush(surface_log);
+}
+
+#else
+#define debug_surface_log(cache)
+#endif
+
+
 static Bool
 surface_cache_init (surface_cache_t *cache, qxl_screen_t *qxl)
 {
@@ -692,6 +736,8 @@ unlink_surface (qxl_surface_t *surface)
 	surface->prev->next = surface->next;
     else
 	surface->cache->live_surfaces = surface->next;
+
+    debug_surface_log(surface->cache);
     
     if (surface->next)
 	surface->next->prev = surface->prev;

commit 0f817bb4e1b4e33ef50c0399c92f1cc091840ef5
Author: Alon Levy <alevy@redhat.com>
Date:   Tue May 29 12:25:12 2012 +0300

    io: add qxl_io_destroy_primary

diff --git a/src/qxl.h b/src/qxl.h
index 4a1cc62..1db0581 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -436,6 +436,7 @@ static inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
 void qxl_update_area(qxl_screen_t *qxl);
 void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id);
 void qxl_io_create_primary(qxl_screen_t *qxl);
+void qxl_io_destroy_primary(qxl_screen_t *qxl);
 void qxl_io_notify_oom(qxl_screen_t *qxl);
 void qxl_io_flush_surfaces(qxl_screen_t *qxl);
 void qxl_io_destroy_all_surfaces (qxl_screen_t *qxl);
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 51b28db..0e34a86 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -182,6 +182,23 @@ void qxl_io_create_primary(qxl_screen_t *qxl)
     qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED;
 }
 
+void qxl_io_destroy_primary(qxl_screen_t *qxl)
+{
+#ifndef XSPICE
+    if (qxl->pci->revision >= 3)
+    {
+        ioport_write(qxl, QXL_IO_DESTROY_PRIMARY_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    } else
+    {
+        ioport_write(qxl, QXL_IO_DESTROY_PRIMARY, 0);
+    }
+#else
+    ioport_write(qxl, QXL_IO_DESTROY_PRIMARY, 0);
+#endif
+    qxl->device_primary = QXL_DEVICE_PRIMARY_NONE;
+}
+
 void qxl_io_notify_oom(qxl_screen_t *qxl)
 {
     ioport_write(qxl, QXL_IO_NOTIFY_OOM, 0);

commit 326b80974b4080ed7519801f7d1c96077f5ae0b9
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 20:50:46 2012 +0300

    prefix io with qxl_io, add several

diff --git a/src/qxl.h b/src/qxl.h
index a1e53f3..4a1cc62 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -434,9 +434,11 @@ static inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
  * I/O port commands
  */
 void qxl_update_area(qxl_screen_t *qxl);
-void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id);
-void qxl_create_primary(qxl_screen_t *qxl);
-void qxl_notify_oom(qxl_screen_t *qxl);
+void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id);
+void qxl_io_create_primary(qxl_screen_t *qxl);
+void qxl_io_notify_oom(qxl_screen_t *qxl);
+void qxl_io_flush_surfaces(qxl_screen_t *qxl);
+void qxl_io_destroy_all_surfaces (qxl_screen_t *qxl);
 
 #ifdef XSPICE
 /* device to spice-server, now xspice to spice-server */
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index f6e4428..51b28db 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -153,7 +153,7 @@ void qxl_update_area(qxl_screen_t *qxl)
 #endif
 }
 
-void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id)
+void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id)
 {
 #ifndef XSPICE
     if (qxl->pci->revision >= 3) {
@@ -167,7 +167,7 @@ void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id)
 #endif
 }
 
-void qxl_create_primary(qxl_screen_t *qxl)
+void qxl_io_create_primary(qxl_screen_t *qxl)
 {
 #ifndef XSPICE
     if (qxl->pci->revision >= 3) {
@@ -182,11 +182,21 @@ void qxl_create_primary(qxl_screen_t *qxl)
     qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED;
 }
 
-void qxl_notify_oom(qxl_screen_t *qxl)
+void qxl_io_notify_oom(qxl_screen_t *qxl)
 {
     ioport_write(qxl, QXL_IO_NOTIFY_OOM, 0);
 }
 
+void qxl_io_flush_surfaces(qxl_screen_t *qxl)
+{
+#ifndef XSPICE
+    ioport_write(qxl, QXL_IO_FLUSH_SURFACES_ASYNC, 0);
+    qxl_wait_for_io_command(qxl);
+#else
+    ioport_write(qxl, QXL_IO_FLUSH_SURFACES_ASYNC, 0);
+#endif
+}
+
 int
 qxl_garbage_collect (qxl_screen_t *qxl)
 {
@@ -275,7 +285,7 @@ qxl_usleep (int useconds)
 int
 qxl_handle_oom (qxl_screen_t *qxl)
 {
-    qxl_notify_oom(qxl);
+    qxl_io_notify_oom(qxl);
 
 #if 0
     ErrorF (".");
@@ -533,7 +543,7 @@ setup_slot(qxl_screen_t *qxl, uint8_t slot_index_offset,
     ram_header->mem_slot.mem_start = slot->start_phys_addr;
     ram_header->mem_slot.mem_end = slot->end_phys_addr;
 
-    qxl_memslot_add(qxl, slot_index);
+    qxl_io_memslot_add(qxl, slot_index);
 
     slot->generation = qxl->rom->slot_generation;
     
@@ -586,6 +596,25 @@ qxl_mark_mem_unverifiable(qxl_screen_t *qxl)
     qxl_mem_unverifiable(qxl->surf_mem);
 }
 
+void
+qxl_io_destroy_all_surfaces (qxl_screen_t *qxl)
+{
+#ifndef XSPICE
+    if (qxl->pci->revision >= 3)
+    {
+        ioport_write(qxl, QXL_IO_DESTROY_ALL_SURFACES_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    }
+    else
+    {
+        ioport_write(qxl, QXL_IO_DESTROY_ALL_SURFACES, 0);
+    }
+#else
+    ErrorF("Xspice: error: UNIMPLEMENTED qxl_io_destroy_all_surfaces\n");
+#endif
+    qxl->device_primary = QXL_DEVICE_PRIMARY_NONE;
+}
+
 static Bool
 qxl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index a2810c8..3b2f9dc 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -336,7 +336,7 @@ qxl_surface_cache_create_primary (surface_cache_t	*cache,
     create->type = QXL_SURF_TYPE_PRIMARY;
     create->mem = physical_address (cache->qxl, cache->qxl->ram, cache->qxl->main_mem_slot);
 
-    qxl_create_primary(qxl);
+    qxl_io_create_primary(qxl);
 
     dev_addr = (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1);
 

commit 73981e02c90cc81dd462f9fc2a00b5b11a9eab00
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 20:52:48 2012 +0300

    qxl.h: add device_primary tri state UNDEFINED/NONE/CREATED

diff --git a/src/qxl.h b/src/qxl.h
index 7702da8..a1e53f3 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -127,6 +127,12 @@ enum {
     OPTION_COUNT,
 };
 
+enum {
+    QXL_DEVICE_PRIMARY_UNDEFINED,
+    QXL_DEVICE_PRIMARY_NONE,
+    QXL_DEVICE_PRIMARY_CREATED,
+};
+
 struct _qxl_screen_t
 {
     /* These are the names QXL uses */
@@ -139,6 +145,8 @@ struct _qxl_screen_t
     struct qxl_ring *		command_ring;
     struct qxl_ring *		cursor_ring;
     struct qxl_ring *		release_ring;
+
+    int                         device_primary;
     
     int				num_modes;
     struct QXLMode *		modes;
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index db9e50c..f6e4428 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -179,6 +179,7 @@ void qxl_create_primary(qxl_screen_t *qxl)
 #else
     ioport_write(qxl, QXL_IO_CREATE_PRIMARY, 0);
 #endif
+    qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED;
 }
 
 void qxl_notify_oom(qxl_screen_t *qxl)
@@ -547,6 +548,7 @@ static void
 qxl_reset_and_create_mem_slots (qxl_screen_t *qxl)
 {
     ioport_write(qxl, QXL_IO_RESET, 0);
+    qxl->device_primary = QXL_DEVICE_PRIMARY_NONE;
     /* Mem slots */
     ErrorF ("slots start: %d, slots end: %d\n",
 	    qxl->rom->slots_start,
@@ -1237,6 +1239,7 @@ qxl_leave_vt(VT_FUNC_ARGS_DECL)
     ioport_write(qxl, QXL_IO_RESET, 0);
 
     qxl_restore_state(pScrn);
+    qxl->device_primary = QXL_DEVICE_PRIMARY_NONE;
 }
 
 static Bool
@@ -1450,6 +1453,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
 	pScrn->driverPrivate = xnfcalloc(sizeof(qxl_screen_t), 1);
     qxl = pScrn->driverPrivate;
     memset(qxl, 0, sizeof(qxl));
+    qxl->device_primary = QXL_DEVICE_PRIMARY_UNDEFINED;
 
     qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
     

commit b600edc48270a4a368add11ec02e6d365d5da60d
Author: Alon Levy <alevy@redhat.com>
Date:   Thu May 24 00:08:38 2012 +0300

    qxl_surface: logging: add function name to ErrorF

diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index ee921a2..a2810c8 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -636,7 +636,7 @@ qxl_surface_create (surface_cache_t *    cache,
     
     if ((bpp & 3) != 0)
     {
-	ErrorF ("   Bad bpp: %d (%d)\n", bpp, bpp & 7);
+	ErrorF ("%s: Bad bpp: %d (%d)\n", __FUNCTION__, bpp, bpp & 7);
 	return NULL;
     }
 
@@ -654,13 +654,13 @@ qxl_surface_create (surface_cache_t *    cache,
     
     if (bpp != 8 && bpp != 16 && bpp != 32 && bpp != 24)
     {
-	ErrorF ("   Unknown bpp\n");
+	ErrorF ("%s: Unknown bpp\n", __FUNCTION__);
 	return NULL;
     }
 
     if (width == 0 || height == 0)
     {
-	ErrorF ("   Zero width or height\n");
+	ErrorF ("%s: Zero width or height\n", __FUNCTION__);
 	return NULL;
     }
 

commit 3a87e765d91a26ead2cfc5ddad1ba4f3e7d21922
Author: Alon Levy <alevy@redhat.com>
Date:   Thu May 24 11:00:49 2012 +0300

    qxl_surface: cosmetics

diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 4661c18..ee921a2 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -552,7 +552,7 @@ surface_send_create (surface_cache_t *cache,
     /* the final + stride is to work around a bug where the device apparently 
      * scribbles after the end of the image
      */
-    qxl_garbage_collect (cache->qxl);
+    qxl_garbage_collect (qxl);
 retry2:
     address = qxl_alloc (qxl->surf_mem, stride * height + stride);
 

commit 60478640a6c4d74c44fdf67350be6e180960cf5f
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 21:23:26 2012 +0300

    qxl_pre_init: memset qxl struct

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 2c36a6b..db9e50c 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -1449,6 +1449,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
     if (!pScrn->driverPrivate)
 	pScrn->driverPrivate = xnfcalloc(sizeof(qxl_screen_t), 1);
     qxl = pScrn->driverPrivate;
+    memset(qxl, 0, sizeof(qxl));
 
     qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
     

commit 9d929ae1d1bb2e7f03221fcc4d70e761b6ff9242
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 20:46:34 2012 +0300

    qxl_driver: abort on mspace error, don't spin (default abort function)

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 2e24746..2c36a6b 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -41,6 +41,7 @@
 
 #include <xf86Crtc.h>
 
+#include "mspace.h"
 #include "qxl.h"
 #include "assert.h"
 #include "qxl_option_helpers.h"
@@ -430,6 +431,21 @@ qxl_unmap_memory(qxl_screen_t *qxl)
     qxl->modes = NULL;
 }
 
+static void __attribute__ ((__noreturn__)) qxl_mspace_abort_func(void *user_data)
+{
+    abort();
+}
+
+static void __attribute__((format(gnu_printf, 2, 3)))
+qxl_mspace_print_func(void *user_data, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+    VErrorF(format, args);
+    va_end(args);
+}
+
 static Bool
 qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
 {
@@ -459,6 +475,9 @@ qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
 			       qxl->rom->num_pages * getpagesize() - qxl->surface0_size);
     qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size);
 
+    mspace_set_abort_func(qxl_mspace_abort_func);
+    mspace_set_print_func(qxl_mspace_print_func);
+
     return TRUE;
 }
 

commit 6aa3ceb2d3f25726424b03a68ef949deadf7125a
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 20:44:06 2012 +0300

    mspace: add mspace_malloc_stats_return

diff --git a/src/mspace.c b/src/mspace.c
index 17d976a..822aade 100644
--- a/src/mspace.c
+++ b/src/mspace.c
@@ -1479,7 +1479,8 @@ static struct mallinfo internal_mallinfo(mstate m) {
 }
 #endif /* !NO_MALLINFO */
 
-static void internal_malloc_stats(mstate m) {
+static void internal_malloc_stats(mstate m, size_t *ret_maxfp, size_t *ret_fp,
+                                  size_t *ret_used) {
   if (!PREACTION(m)) {
     size_t maxfp = 0;
     size_t fp = 0;
@@ -1503,9 +1504,21 @@ static void internal_malloc_stats(mstate m) {
       }
     }
 
-    PRINT((m->user_data, "max system bytes = %10lu\n", (unsigned long)(maxfp)));
-    PRINT((m->user_data, "system bytes     = %10lu\n", (unsigned long)(fp)));
-    PRINT((m->user_data, "in use bytes     = %10lu\n", (unsigned long)(used)));
+    if (ret_maxfp || ret_fp || ret_used) {
+        if (ret_maxfp) {
+            *ret_maxfp = maxfp;
+        }
+        if (ret_fp) {
+            *ret_fp = fp;
+        }
+        if (ret_used) {
+            *ret_used = used;
+        }
+    } else {
+        PRINT((m->user_data, "max system bytes = %10lu\n", (unsigned long)(maxfp)));
+        PRINT((m->user_data, "system bytes     = %10lu\n", (unsigned long)(fp)));
+        PRINT((m->user_data, "in use bytes     = %10lu\n", (unsigned long)(used)));
+    }
 
     POSTACTION(m);
   }
@@ -2389,16 +2402,24 @@ void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
   return internal_memalign(ms, alignment, bytes);
 }
 
-void mspace_malloc_stats(mspace msp) {
+void mspace_malloc_stats_return(mspace msp, size_t *ret_maxfp, size_t *ret_fp,
+                                size_t *ret_used)
+{
+
   mstate ms = (mstate)msp;
   if (ok_magic(ms)) {
-    internal_malloc_stats(ms);
+    internal_malloc_stats(ms, ret_maxfp, ret_fp, ret_used);
   }
   else {
     USAGE_ERROR_ACTION(ms,ms);
   }
 }
 
+
+void mspace_malloc_stats(mspace msp) {
+    mspace_malloc_stats_return(msp, NULL, NULL, NULL);
+}
+
 size_t mspace_footprint(mspace msp) {
   size_t result;
   mstate ms = (mstate)msp;
diff --git a/src/mspace.h b/src/mspace.h
index 8f5ba83..46a6a56 100644
--- a/src/mspace.h
+++ b/src/mspace.h
@@ -131,9 +131,12 @@ struct mallinfo mspace_mallinfo(mspace msp);
 
 /*
   mspace_malloc_stats behaves as malloc_stats, but reports
-  properties of the given space.
+  properties of the given space. The return variant returns instead of
+  printing the three quantities, maxfp, fp, and used.
 */
 void mspace_malloc_stats(mspace msp);
+void mspace_malloc_stats_return(mspace msp, size_t *ret_maxfp, size_t *ret_fp,
+                                size_t *ret_used);
 
 /*
   mspace_trim behaves as malloc_trim, but

commit 5e505dc6572ee29d0ebe912a8160a8e09bfb5d3e
Author: Alon Levy <alevy@redhat.com>
Date:   Tue May 29 13:46:34 2012 +0300

    qxl_leave_vt: change outb to ioport_write (easier to grep / breakpoint on a single point)

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 966e641..2e24746 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -1215,7 +1215,7 @@ qxl_leave_vt(VT_FUNC_ARGS_DECL)
 
     qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
 
-    outb(qxl->io_base + QXL_IO_RESET, 0);
+    ioport_write(qxl, QXL_IO_RESET, 0);
 
     qxl_restore_state(pScrn);
 }

commit 67f86dc1e824d00a06bdc51ba4c3e88cfbd82292
Author: Alon Levy <alevy@redhat.com>
Date:   Tue May 29 13:45:29 2012 +0300

    rename qxl_reset to qxl_reset_and_create_mem_slots

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 43d2693..966e641 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -525,7 +525,7 @@ setup_slot(qxl_screen_t *qxl, uint8_t slot_index_offset,
 }
 
 static void
-qxl_reset (qxl_screen_t *qxl)
+qxl_reset_and_create_mem_slots (qxl_screen_t *qxl)
 {
     ioport_write(qxl, QXL_IO_RESET, 0);
     /* Mem slots */
@@ -583,7 +583,7 @@ qxl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 
 #ifndef XSPICE
     if (!xf86IsPrimaryPci (qxl->pci) && qxl->primary)
-       qxl_reset (qxl);
+       qxl_reset_and_create_mem_slots (qxl);
 #endif
     
     if (pScrn->vtSema)
@@ -639,7 +639,7 @@ qxl_switch_mode(SWITCH_MODE_ARGS_DECL)
 	qxl_surface_cache_sanity_check (qxl->surface_cache);
     }
 	
-    qxl_reset (qxl);
+    qxl_reset_and_create_mem_slots (qxl);
     
     ErrorF ("done reset\n");
 
@@ -1120,7 +1120,7 @@ qxl_screen_init(SCREEN_INIT_ARGS_DECL)
     qxl->uxa = uxa_driver_alloc ();
     
     /* Set up resources */
-    qxl_reset (qxl);
+    qxl_reset_and_create_mem_slots (qxl);
     ErrorF ("done reset\n");
 
 #ifndef XSPICE

commit 21c1d576925e561551b91b44b0d286f0bdc689c4
Author: Alon Levy <alevy@redhat.com>
Date:   Wed May 23 20:54:44 2012 +0300

    qxl_mem: add debug flags, simple accounting and valgrind enabled
    
    adds preprocessor definitions DEBUG_QXL_MEM & DEBUG_QXL_MEM_VERBOSE

diff --git a/src/qxl.h b/src/qxl.h
index 46155c9..7702da8 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -416,6 +416,12 @@ void *            qxl_allocnf          (qxl_screen_t           *qxl,
 					unsigned long           size);
 int		   qxl_garbage_collect (qxl_screen_t *qxl);
 
+#ifdef DEBUG_QXL_MEM
+void qxl_mem_unverifiable(struct qxl_mem *mem);
+#else
+static inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
+#endif
+
 /*
  * I/O port commands
  */
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index ab44fa0..43d2693 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -558,6 +558,13 @@ qxl_reset (qxl_screen_t *qxl)
 #endif
 }
 
+static void
+qxl_mark_mem_unverifiable(qxl_screen_t *qxl)
+{
+    qxl_mem_unverifiable(qxl->mem);
+    qxl_mem_unverifiable(qxl->surf_mem);
+}
+
 static Bool
 qxl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
@@ -582,6 +589,7 @@ qxl_close_screen(CLOSE_SCREEN_ARGS_DECL)
     if (pScrn->vtSema)
     {
         qxl_restore_state(pScrn);
+        qxl_mark_mem_unverifiable(qxl);
 	qxl_unmap_memory(qxl);
     }
     pScrn->vtSema = FALSE;
diff --git a/src/qxl_mem.c b/src/qxl_mem.c
index 6e57a94..3d9acfd 100644
--- a/src/qxl_mem.c
+++ b/src/qxl_mem.c
@@ -27,13 +27,30 @@
 #include "qxl.h"
 #include "mspace.h"
 
+#ifdef DEBUG_QXL_MEM
+#include <valgrind/memcheck.h>
+#endif
+
 struct qxl_mem
 {
     mspace	space;
     void *	base;
     unsigned long n_bytes;
+#ifdef DEBUG_QXL_MEM
+    size_t used_initial;
+    int unverifiable;
+    int missing;
+#endif
 };
 
+#ifdef DEBUG_QXL_MEM
+void
+qxl_mem_unverifiable(struct qxl_mem *mem)
+{
+    mem->unverifiable = 1;
+}
+#endif
+
 struct qxl_mem *
 qxl_mem_create       (void                   *base,
 		      unsigned long           n_bytes)
@@ -51,6 +68,17 @@ qxl_mem_create       (void                   *base,
     mem->base = base;
     mem->n_bytes = n_bytes;
 
+#ifdef DEBUG_QXL_MEM
+    {
+        size_t used;
+
+        mspace_malloc_stats_return(mem->space, NULL, NULL, &used);
+        mem->used_initial = used;
+        mem->unverifiable = 0;
+        mem->missing = 0;
+    }
+#endif
+
 out:
     return mem;
 
@@ -69,7 +97,15 @@ void *
 qxl_alloc            (struct qxl_mem         *mem,
 		      unsigned long           n_bytes)
 {
-    return mspace_malloc (mem->space, n_bytes);
+    void *addr = mspace_malloc (mem->space, n_bytes);
+
+#ifdef DEBUG_QXL_MEM
+    VALGRIND_MALLOCLIKE_BLOCK(addr, n_bytes, 0, 0);
+#ifdef DEBUG_QXL_MEM_VERBOSE
+    fprintf(stderr, "alloc %p: %ld\n", addr, n_bytes);
+#endif
+#endif
+    return addr;
 }
 
 void


Reply to: