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: