[Intel-gfx] [PATCH] drm/i915: Explosion following OOM in do_execbuffer.
Oops, when merging the extra details following an OOM, I missed that driver_private is now NULL and the correct way to convert from the drm_gem_object into the drm_i915_gem_object is to use to_intel_bo(). BUG: unable to handle kernel NULL pointer dereference at 0069 IP: [c11a4a02] i915_gem_do_execbuffer+0x71f/0xbb6 *pde = Oops: [#1] SMP last sysfs file: /sys/devices/virtual/vc/vcsa3/uevent Pid: 10993, comm: X Not tainted 2.6.35-rc2+ #67 / EIP: 0060:[c11a4a02] EFLAGS: 00213202 CPU: 0 EIP is at i915_gem_do_execbuffer+0x71f/0xbb6 EAX: f647e8a8 EBX: ECX: 0003 EDX: ESI: 00424000 EDI: EBP: f6508e48 ESP: f6508dd4 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process X (pid: 10993, ti=f6508000 task=f6432880 task.ti=f6508000) Stack: f6508de0 f713 0001 f647e8a8 f64f8480 0 f7974414 0006 f6578000 0008 0006 0 f6797880 0040 ffe4 f7974400 00d0 00d0 01c0 Call Trace: [c11a4f3a] ? i915_gem_execbuffer2+0xa1/0xe7 [c118ab96] ? drm_ioctl+0x22c/0x2fa [c11a4e99] ? i915_gem_execbuffer2+0x0/0xe7 [c107e88c] ? do_sync_read+0x8f/0xca [c1088cbd] ? vfs_ioctl+0x2c/0x96 [c118a96a] ? drm_ioctl+0x0/0x2fa [c10891f4] ? do_vfs_ioctl+0x429/0x45a [c107e5c9] ? fsnotify_access+0x54/0x5f [c107ee1c] ? vfs_read+0x9a/0xae [c1089258] ? sys_ioctl+0x33/0x4d [c1002610] ? sysenter_do_call+0x12/0x26 Code: d0 89 4d c4 31 c9 89 45 d8 eb 44 8b 45 cc 8b 14 88 8b 42 50 89 45 bc 8b 45 a0 8b 52 38 89 55 d0 31 d2 f6 40 20 01 74 0d 8b 55 bc f6 42 69 30 0f 95 c2 0f b6 d2 8b 45 d0 c7 45 d4 00 00 00 00 89 EIP: [c11a4a02] i915_gem_do_execbuffer+0x71f/0xbb6 SS:ESP 0068:f6508dd4 CR2: 0069 ---[ end trace 3f1d514b34d39381 ]--- Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0cf9584..781bd09 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3665,6 +3665,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, return ret; } + int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv, @@ -3812,7 +3813,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, unsigned long long total_size = 0; int num_fences = 0; for (i = 0; i args-buffer_count; i++) { - obj_priv = object_list[i]-driver_private; + obj_priv = to_intel_bo(object_list[i]); total_size += object_list[i]-size; num_fences += -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] Destroy screen pixmap on screen close.
On Thu, 1 Jul 2010 09:56:40 -0400, Keith Packard kei...@keithp.com wrote: This avoids a memory leak on server reset. Signed-off-by: Keith Packard kei...@keithp.com --- uxa/uxa.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/uxa/uxa.c b/uxa/uxa.c index a9a705c..dcfaaa9 100644 --- a/uxa/uxa.c +++ b/uxa/uxa.c @@ -1,7 +1,7 @@ /* - * Copyright © 2001 Keith Packard + * Copyright © 2001 Keith Packard * - * Partly based on code that is Copyright © The XFree86 Project Inc. + * Partly based on code that is Copyright © The XFree86 Project Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -381,6 +381,8 @@ static Bool uxa_close_screen(int i, ScreenPtr pScreen) uxa_glyphs_fini(pScreen); + (void) (*pScreen-DestroyPixmap) (pScreen-devPrivate); + pScreen-devPrivate = NULL; This looks like the responsibility of miCloseScreen(). Are we failing to chain up properly? Currently we have uxa_close_screen - PictureCloseScreen - fbCloseScreen and fbCloseScreen supersedes miCloseScreen. So should it not be fbCloseScreen that calls miCloseScreen, since fb has taken over the management of the mi interface? -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/11] drm: use list_for_each_entry in drm_mm.c
From: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Acked-by: Thomas Hellstrom thellst...@vmwgfx.com --- drivers/gpu/drm/drm_mm.c |8 ++-- 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2ac074c..b75eb55 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -332,7 +332,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) { - struct list_head *list; const struct list_head *free_stack = mm-fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -342,8 +341,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry-size size) @@ -376,7 +374,6 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, unsigned long end, int best_match) { - struct list_head *list; const struct list_head *free_stack = mm-fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -386,8 +383,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry-size size) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/11] drm: kill dead code in drm_mm.c
From: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Acked-by: Thomas Hellstrom thellst...@vmwgfx.com Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/drm_mm.c | 45 - 1 files changed, 0 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index b75eb55..a5a7a16 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -48,36 +48,6 @@ #define MM_UNUSED_TARGET 4 -unsigned long drm_mm_tail_space(struct drm_mm *mm) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) - return 0; - - return entry-size; -} - -int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) - return -ENOMEM; - - if (entry-size = size) - return -ENOMEM; - - entry-size -= size; - return 0; -} - static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; @@ -152,21 +122,6 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, return 0; } -int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm-ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry-free) { - return drm_mm_create_tail_node(mm, entry-start + entry-size, - size, atomic); - } - entry-size += size; - return 0; -} - static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, unsigned long size, int atomic) -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/11] drm/i915: prepare for fair lru eviction
From: Daniel Vetter daniel.vet...@ffwll.ch This does two little changes: - Add an alignment parameter for evict_something. It's not really great to whack a carefully sized hole into the gtt with the wrong alignment. Especially since the fallback path is a full evict. - With the inactive scan stuff we need to evict more that one object, so move the unbind call into the helper function that scans for the object to be evicted, too. And adjust its name. No functional changes in this patch, just preparation. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c | 67 --- 1 files changed, 41 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bfc7269..d4bcf71 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,6 +35,7 @@ #include linux/swap.h #include linux/pci.h +static uint32_t i915_gem_get_fence_alignment(struct drm_gem_object *obj); static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); @@ -48,7 +49,8 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); -static int i915_gem_evict_something(struct drm_device *dev, int min_size); +static int i915_gem_evict_something(struct drm_device *dev, int min_size, + unsigned alignment); static int i915_gem_evict_from_inactive_list(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -313,7 +315,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) if (ret == -ENOMEM) { struct drm_device *dev = obj-dev; - ret = i915_gem_evict_something(dev, obj-size); + ret = i915_gem_evict_something(dev, obj-size, + i915_gem_get_fence_alignment(obj)); if (ret) return ret; @@ -1988,10 +1991,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return 0; } -static struct drm_gem_object * -i915_gem_find_inactive_object(struct drm_device *dev, int min_size) +static int +i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size, + unsigned alignment, int *found) { drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *best = NULL; struct drm_gem_object *first = NULL; @@ -2005,14 +2010,31 @@ i915_gem_find_inactive_object(struct drm_device *dev, int min_size) (!best || obj-size best-size)) { best = obj; if (best-size == min_size) - return best; + break; } if (!first) first = obj; } } - return best ? best : first; + obj = best ? best : first; + + if (!obj) { + *found = 0; + return 0; + } + + *found = 1; + +#if WATCH_LRU + DRM_INFO(%s: evicting %p\n, __func__, obj); +#endif + obj_priv = to_intel_bo(obj); + BUG_ON(obj_priv-pin_count != 0); + BUG_ON(obj_priv-active); + + /* Wait on the rendering and unbind the buffer. */ + return i915_gem_object_unbind(obj); } static int @@ -2098,11 +2120,11 @@ i915_gem_evict_everything(struct drm_device *dev) } static int -i915_gem_evict_something(struct drm_device *dev, int min_size) +i915_gem_evict_something(struct drm_device *dev, +int min_size, unsigned alignment) { drm_i915_private_t *dev_priv = dev-dev_private; - struct drm_gem_object *obj; - int ret; + int ret, found; struct intel_ring_buffer *render_ring = dev_priv-render_ring; struct intel_ring_buffer *bsd_ring = dev_priv-bsd_ring; @@ -2115,20 +2137,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) /* If there's an inactive buffer available now, grab it * and be done. */ - obj = i915_gem_find_inactive_object(dev, min_size); - if (obj) { - struct drm_i915_gem_object *obj_priv; - -#if WATCH_LRU - DRM_INFO(%s: evicting %p\n, __func__, obj);
[Intel-gfx] [PATCH 09/11] drm/i915: Move the eviction logic to its own file.
The eviction code is the gnarly underbelly of memory management, and is clearer if kept separated from the normal domain management in GEM. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile |1 + drivers/gpu/drm/i915/i915_drv.h |6 + drivers/gpu/drm/i915/i915_gem.c | 234 +- drivers/gpu/drm/i915/i915_gem_evict.c | 263 + 4 files changed, 272 insertions(+), 232 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_evict.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c..384fd45 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ i915_suspend.o \ i915_gem.o \ i915_gem_debug.o \ + i915_gem_evict.o \ i915_gem_tiling.o \ i915_trace_points.o \ intel_display.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65cf336..b6a0bd0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -964,6 +964,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); +int i915_gpu_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev); uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, @@ -989,6 +990,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); +/* i915_gem_evict.c */ +int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); +int i915_gem_evict_everything(struct drm_device *dev); +int i915_gem_evict_inactive(struct drm_device *dev); + /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1b867c4..bb7d6a9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -49,9 +49,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); -static int i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment); -static int i915_gem_evict_from_inactive_list(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv); @@ -1869,19 +1866,6 @@ i915_gem_flush(struct drm_device *dev, flush_domains); } -static void -i915_gem_flush_ring(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains, - struct intel_ring_buffer *ring) -{ - if (flush_domains I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); - ring-flush(dev, ring, - invalidate_domains, - flush_domains); -} - /** * Ensures that all rendering to the object has completed and the object is * safe to unbind from the GTT or access from the CPU. @@ -1991,53 +1975,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return 0; } -static int -i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size, - unsigned alignment, int *found) -{ - drm_i915_private_t *dev_priv = dev-dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - struct drm_gem_object *best = NULL; - struct drm_gem_object *first = NULL; - - /* Try to find the smallest clean object */ - list_for_each_entry(obj_priv, dev_priv-mm.inactive_list, list) { - struct drm_gem_object *obj = obj_priv-base; - if (obj-size = min_size) { - if ((!obj_priv-dirty || -i915_gem_object_is_purgeable(obj_priv)) - (!best || obj-size best-size)) { - best = obj; - if (best-size == min_size) - break; - } - if (!first) - first = obj; - } - } - - obj = best ? best : first; - - if (!obj) { - *found = 0; - return
[Intel-gfx] [PATCH 11/11] drm/i915: Maintain LRU order of inactive objects upon access by CPU
In order to reduce the penalty of fallbacks under memory pressure and to avoid a potential immediate ping-pong of evicting a mmaped buffer, we move the object to the tail of the inactive list when a page is freshly faulted or the object is moved into the CPU domain. We choose not to protect the CPU objects from casual eviction, preferring to keep the GPU active for as long as possible. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bb7d6a9..26d0345 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1036,6 +1036,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); } + /* Maintain LRU order of inactive objects */ + if (ret == 0 obj_priv-gtt_space !obj_priv-active) + list_move_tail(obj_priv-list, dev_priv-mm.inactive_list); + drm_gem_object_unreference(obj); mutex_unlock(dev-struct_mutex); return ret; @@ -1169,6 +1173,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unlock; } + if (!obj_priv-active) + list_move_tail(obj_priv-list, dev_priv-mm.inactive_list); + pfn = ((dev-agp-base + obj_priv-gtt_offset) PAGE_SHIFT) + page_offset; -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] Destroy screen pixmap on screen close.
On Fri, 02 Jul 2010 09:24:07 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: This looks like the responsibility of miCloseScreen(). Are we failing to chain up properly? I don't think miCloseScreen (or fbCloseScreen) can do this -- before we're called, rendering may not have been finished, after we're called, the acceleration code is shut down and pixmaps cannot be freed. -- keith.pack...@intel.com pgpD1SJAXrNIk.pgp Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] Destroy screen pixmap on screen close.
On Fri, 02 Jul 2010 11:54:44 -0400, Keith Packard kei...@keithp.com wrote: On Fri, 02 Jul 2010 09:24:07 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: This looks like the responsibility of miCloseScreen(). Are we failing to chain up properly? I don't think miCloseScreen (or fbCloseScreen) can do this -- before we're called, rendering may not have been finished, after we're called, the acceleration code is shut down and pixmaps cannot be freed. That sounds true, and deserves a comment in the code. It doesn't explain why fbCloseScreen() calls free(screen-devPrivate) instead of miCloseScreen() and causing the leak in the first place... :) -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Make G4X-style PLL search more permissive
On Fri, 2010-07-02 at 16:43 -0400, Adam Jackson wrote: Worst dotclock for Ironlake DAC refclk is 35kHz (error 0.00571) Worst dotclock for Ironlake SL-LVDS refclk is 102321kHz (error 0.00524) Worst dotclock for Ironlake DL-LVDS refclk is 219642kHz (error 0.00488) Worst dotclock for Ironlake SL-LVDS SSC refclk is 84374kHz (error 0.00529) Worst dotclock for Ironlake DL-LVDS SSC refclk is 183035kHz (error 0.00488) Worst dotclock for G4X SDVO refclk is 5kHz (error 0.17332) Worst dotclock for G4X HDMI refclk is 334400kHz (error 0.00478) Worst dotclock for G4X SL-LVDS refclk is 95571kHz (error 0.00449) Worst dotclock for G4X DL-LVDS refclk is 224000kHz (error 0.00510) The SDVO number looks a bit suspicious, which I haven't tracked down yet. But it's clear that the old threshold is too tight. Well, that was easy. We turn on 2x or 4x pixel multiplication below 100MHz. Once I account for that I get: Worst dotclock for G4X SDVO refclk is 267600kHz (error 0.00448) - ajax signature.asc Description: This is a digitally signed message part ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx