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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

