Re: [Intel-gfx] [PATCH] drm: Remove two unused fields from struct drm_display_mode
Hi Damien, please send this to dri-devel list. FWIW, you can add my Reviewed-by: Jani Nikula jani.nik...@intel.com On Fri, 17 Aug 2012, Damien Lespiau damien.lesp...@gmail.com wrote: From: Damien Lespiau damien.lesp...@intel.com Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- drivers/gpu/drm/drm_modes.c |3 --- include/drm/drm_crtc.h |2 -- 2 files changed, 0 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b7adb4a..28637c1 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -706,9 +706,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) p-crtc_vblank_end = max(p-crtc_vsync_end, p-crtc_vtotal); p-crtc_hblank_start = min(p-crtc_hsync_start, p-crtc_hdisplay); p-crtc_hblank_end = max(p-crtc_hsync_end, p-crtc_htotal); - - p-crtc_hadjusted = false; - p-crtc_vadjusted = false; } EXPORT_SYMBOL(drm_mode_set_crtcinfo); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a1a0386..ced3625 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -166,8 +166,6 @@ struct drm_display_mode { int crtc_vsync_start; int crtc_vsync_end; int crtc_vtotal; - int crtc_hadjusted; - int crtc_vadjusted; /* Driver private mode info */ int private_size; -- 1.7.7.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: move functions around
Prep work to make Chris Wilson's unbound tracking patch a bit easier to read. Alas, I'd have preferred that moving the page allocation retry loop from bind to get_pages would have been a separate patch, too. But that looks like real work ;-) Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c | 116 +++ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0514593..0f70c2a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1340,6 +1340,64 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, return i915_gem_mmap_gtt(file, dev, args-handle, args-offset); } +/* Immediately discard the backing storage */ +static void +i915_gem_object_truncate(struct drm_i915_gem_object *obj) +{ + struct inode *inode; + + /* Our goal here is to return as much of the memory as +* is possible back to the system as we are called from OOM. +* To do this we must instruct the shmfs to drop all of its +* backing pages, *now*. +*/ + inode = obj-base.filp-f_path.dentry-d_inode; + shmem_truncate_range(inode, 0, (loff_t)-1); + + if (obj-base.map_list.map) + drm_gem_free_mmap_offset(obj-base); + + obj-madv = __I915_MADV_PURGED; +} + +static inline int +i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) +{ + return obj-madv == I915_MADV_DONTNEED; +} + +static void +i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) +{ + int page_count = obj-base.size / PAGE_SIZE; + int i; + + if (!obj-pages) + return; + + BUG_ON(obj-madv == __I915_MADV_PURGED); + + if (i915_gem_object_needs_bit17_swizzle(obj)) + i915_gem_object_save_bit_17_swizzle(obj); + + if (obj-madv == I915_MADV_DONTNEED) + obj-dirty = 0; + + for (i = 0; i page_count; i++) { + if (obj-dirty) + set_page_dirty(obj-pages[i]); + + if (obj-madv == I915_MADV_WILLNEED) + mark_page_accessed(obj-pages[i]); + + page_cache_release(obj-pages[i]); + } + obj-dirty = 0; + + drm_free_large(obj-pages); + obj-pages = NULL; +} + int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, gfp_t gfpmask) @@ -1387,38 +1445,6 @@ err_pages: return PTR_ERR(page); } -static void -i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) -{ - int page_count = obj-base.size / PAGE_SIZE; - int i; - - if (!obj-pages) - return; - - BUG_ON(obj-madv == __I915_MADV_PURGED); - - if (i915_gem_object_needs_bit17_swizzle(obj)) - i915_gem_object_save_bit_17_swizzle(obj); - - if (obj-madv == I915_MADV_DONTNEED) - obj-dirty = 0; - - for (i = 0; i page_count; i++) { - if (obj-dirty) - set_page_dirty(obj-pages[i]); - - if (obj-madv == I915_MADV_WILLNEED) - mark_page_accessed(obj-pages[i]); - - page_cache_release(obj-pages[i]); - } - obj-dirty = 0; - - drm_free_large(obj-pages); - obj-pages = NULL; -} - void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, struct intel_ring_buffer *ring, @@ -1486,32 +1512,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) WARN_ON(i915_verify_lists(dev)); } -/* Immediately discard the backing storage */ -static void -i915_gem_object_truncate(struct drm_i915_gem_object *obj) -{ - struct inode *inode; - - /* Our goal here is to return as much of the memory as -* is possible back to the system as we are called from OOM. -* To do this we must instruct the shmfs to drop all of its -* backing pages, *now*. -*/ - inode = obj-base.filp-f_path.dentry-d_inode; - shmem_truncate_range(inode, 0, (loff_t)-1); - - if (obj-base.map_list.map) - drm_gem_free_mmap_offset(obj-base); - - obj-madv = __I915_MADV_PURGED; -} - -static inline int -i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) -{ - return obj-madv == I915_MADV_DONTNEED; -} - static u32 i915_gem_get_seqno(struct drm_device *dev) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Track unbound pages
When dealing with a working set larger than the GATT, or even the mappable aperture when touching through the GTT, we end up with evicting objects only to rebind them at a new offset again later. Moving an object into and out of the GTT requires clflushing the pages, thus causing a double-clflush penalty for rebinding. To avoid having to clflush on rebinding, we can track the pages as they are evicted from the GTT and only relinquish those pages on memory pressure. As usual, if it were not for the handling of out-of-memory condition and having to manually shrink our own bo caches, it would be a net reduction of code. Alas. Note: The patch also contains a few changes to the last-hope evict_everything logic in i916_gem_execbuffer.c - we no longer try to only evict the purgeable stuff in a first try (since that's superflous and only helps in OOM corner-cases, not fragmented-gtt trashing situations). Also, the extraction of the get_pages retry loop from bind_to_gtt (and other callsites) to get_pages should imo have been a separate patch. v2: Ditch the newly added put_pages (for unbound objects only) in i915_gem_reset. A quick irc discussion hasn't revealed any important reason for this, so if we need this, I'd like to have a git blame'able explanation for it. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk [danvet: Split out code movements and rant a bit in the commit message with a few Notes. Done v2] Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c| 14 +- drivers/gpu/drm/i915/i915_drv.h| 13 +- drivers/gpu/drm/i915/i915_gem.c| 292 ++-- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 20 +- drivers/gpu/drm/i915/i915_gem_evict.c | 13 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c |9 +- drivers/gpu/drm/i915/i915_gem_gtt.c|2 +- drivers/gpu/drm/i915/i915_irq.c|4 +- drivers/gpu/drm/i915/i915_trace.h | 10 +- 9 files changed, 186 insertions(+), 191 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a18e936..608d3ae 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -211,7 +211,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) dev_priv-mm.object_memory); size = count = mappable_size = mappable_count = 0; - count_objects(dev_priv-mm.gtt_list, gtt_list); + count_objects(dev_priv-mm.bound_list, gtt_list); seq_printf(m, %u [%u] objects, %zu [%zu] bytes in gtt\n, count, mappable_count, size, mappable_size); @@ -225,8 +225,13 @@ static int i915_gem_object_info(struct seq_file *m, void* data) seq_printf(m, %u [%u] inactive objects, %zu [%zu] bytes\n, count, mappable_count, size, mappable_size); + size = count = 0; + list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list) + size += obj-base.size, ++count; + seq_printf(m, %u unbound objects, %zu bytes\n, count, size); + size = count = mappable_size = mappable_count = 0; - list_for_each_entry(obj, dev_priv-mm.gtt_list, gtt_list) { + list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) { if (obj-fault_mappable) { size += obj-gtt_space-size; ++count; @@ -264,7 +269,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data) return ret; total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj, dev_priv-mm.gtt_list, gtt_list) { + list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) { if (list == PINNED_LIST obj-pin_count == 0) continue; @@ -526,7 +531,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) for (i = 0; i dev_priv-num_fence_regs; i++) { struct drm_i915_gem_object *obj = dev_priv-fence_regs[i].obj; - seq_printf(m, Fenced object[%2d] = , i); + seq_printf(m, Fence %d, pin count = %d, object = , + i, dev_priv-fence_regs[i].pin_count); if (obj == NULL) seq_printf(m, unused); else diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ed3ba70..a2382a1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -685,7 +685,13 @@ typedef struct drm_i915_private { struct drm_mm gtt_space; /** List of all objects in gtt_space. Used to restore gtt * mappings on resume */ - struct list_head gtt_list; + struct list_head bound_list; + /** +* List of objects which are not bound to the GTT (thus +* are idle and not used by the GPU) but
Re: [Intel-gfx] [PATCH 02/29] drm/i915: Show (count, size) of purgeable objects in i915_gem_objects
On Sat, Aug 11, 2012 at 03:41:01PM +0100, Chris Wilson wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a7eb093..16e8701 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -197,8 +197,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data) struct drm_info_node *node = (struct drm_info_node *) m-private; struct drm_device *dev = node-minor-dev; struct drm_i915_private *dev_priv = dev-dev_private; - u32 count, mappable_count; - size_t size, mappable_size; + u32 count, mappable_count, purgeable_count; + size_t size, mappable_size, purgeable_size; struct drm_i915_gem_object *obj; int ret; @@ -225,9 +225,12 @@ static int i915_gem_object_info(struct seq_file *m, void* data) seq_printf(m, %u [%u] inactive objects, %zu [%zu] bytes\n, count, mappable_count, size, mappable_size); - size = count = 0; - list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list) + size = count = purgeable_size = purgeable_count = 0; + list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list) { size += obj-base.size, ++count; + if (obj-madv == I915_MADV_DONTNEED) + purgeable_size += obj-base.size, ++purgeable_count; + } seq_printf(m, %u unbound objects, %zu bytes\n, count, size); size = count = mappable_size = mappable_count = 0; @@ -237,10 +240,16 @@ static int i915_gem_object_info(struct seq_file *m, void* data) ++count; } if (obj-pin_mappable) { - mappable_size += obj-gtt_space-size; + mappable_size += obj-gtt_space-size, That s/;/,/ here looks fishy. Shall I kill it when applying? -Daniel ++mappable_count; } + if (obj-madv == I915_MADV_DONTNEED) { + purgeable_size += obj-base.size; + ++purgeable_count; + } } + seq_printf(m, %u purgeable objects, %zu bytes\n, +purgeable_count, purgeable_size); seq_printf(m, %u pinned mappable objects, %zu bytes\n, mappable_count, mappable_size); seq_printf(m, %u fault mappable objects, %zu bytes\n, -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/29] drm/i915: Show (count, size) of purgeable objects in i915_gem_objects
On Mon, 20 Aug 2012 11:04:52 +0200, Daniel Vetter dan...@ffwll.ch wrote: On Sat, Aug 11, 2012 at 03:41:01PM +0100, Chris Wilson wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk if (obj-pin_mappable) { - mappable_size += obj-gtt_space-size; + mappable_size += obj-gtt_space-size, That s/;/,/ here looks fishy. Shall I kill it when applying? Right that is an inoffensive cut'n'paste. Can be killed with glee. -Chris -- 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] Add some sanity checks to unbound tracking
A pair of universally true checks that just need to be put in the right place depending on where in the patch sequence you go. Note that i915_gem_object_put_pages_gtt() already gains the BUG_ON(obj-gtt_space), but on reflection that needed to migrate to put_pages(). --- drivers/gpu/drm/i915/i915_gem.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0608d95..f90390a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1806,6 +1806,8 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) { const struct drm_i915_gem_object_ops *ops = obj-base.driver_private; + BUG_ON(obj-gtt_space); + if (obj-pages == NULL) return 0; @@ -2530,6 +2532,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) if (obj-pin_count) return -EBUSY; + BUG_ON(obj-pages == NULL); + ret = i915_gem_object_finish_gpu(obj); if (ret) return ret; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: add tons of modeset state checks
... let's see how whether this catches anything earlier and I can track down a few bugs. v2: Add more checks and also add DRM_DEBUG_KMS output so that it's clear which connector/encoder/crtc is being checked atm. Which proved rather useful for debugging ... v3: Add a WARN in the common encoder dpms function, now that also modeset changes properly update the dpms state ... v4: Properly add a short explanation for each WARN, to avoid the need to correlate dmesg lines with source lines accurately. Suggested by Chris Wilson. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 84 +++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 95a9f04..5d592f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3637,7 +3637,7 @@ void intel_connector_dpms(struct drm_connector *connector, int mode) if (encoder-base.crtc) intel_encoder_dpms(encoder, mode); else - encoder-connectors_active = false; + WARN_ON(encoder-connectors_active != false); intel_connector_check_state(to_intel_connector(connector)); } @@ -6823,6 +6823,84 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc) base.head) \ if (mask (1 (intel_crtc)-pipe)) \ +static void +intel_modeset_check_state(struct drm_device *dev) +{ + struct intel_crtc *crtc; + struct intel_encoder *encoder; + struct intel_connector *connector; + + list_for_each_entry(connector, dev-mode_config.connector_list, + base.head) { + /* This also checks the encoder/connector hw state with the +* -get_hw_state callbacks. */ + intel_connector_check_state(connector); + + WARN(connector-new_encoder-base != connector-base.encoder, +connector's staged encoder doesn't match current encoder\n); + } + + list_for_each_entry(encoder, dev-mode_config.encoder_list, + base.head) { + bool enabled = false; + bool active = false; + enum pipe pipe; + + DRM_DEBUG_KMS([ENCODER:%d:%s]\n, + encoder-base.base.id, + drm_get_encoder_name(encoder-base)); + + WARN(encoder-new_crtc-base != encoder-base.crtc, +encoder's stage crtc doesn't match current crtc\n); + WARN(encoder-connectors_active !encoder-base.crtc, +encoder's active_connectors set, but no crtc\n); + + list_for_each_entry(connector, dev-mode_config.connector_list, + base.head) { + if (connector-base.encoder != encoder-base) + continue; + enabled = true; + if (connector-base.dpms == DRM_MODE_DPMS_ON) + active = true; + } + WARN(!!encoder-base.crtc != enabled, +encoder's enabled state mismatch\n); + /* dpms on only implies active. */ + WARN(active !encoder-base.crtc, +active encoder with no crtc\n); + WARN(encoder-get_hw_state(encoder, pipe) + !encoder-base.crtc, +encoder's hw state doesn't match sw tracking\n); + } + + list_for_each_entry(crtc, dev-mode_config.crtc_list, + base.head) { + bool enabled = false; + bool active = false; + + DRM_DEBUG_KMS([CRTC:%d]\n, + crtc-base.base.id); + + WARN(crtc-active !crtc-base.enabled, +active crtc, but not enabled in sw tracking\n); + + list_for_each_entry(encoder, dev-mode_config.encoder_list, + base.head) { + if (encoder-base.crtc != crtc-base) + continue; + enabled = true; + if (encoder-connectors_active) + active = true; + } + WARN(active != crtc-active, +crtc's computed active state doesn't match tracked active state\n); + WARN(enabled != crtc-base.enabled, +crtc's computed enabled state doesn't match tracked enabled state\n); + + assert_pipe(dev-dev_private, crtc-pipe, crtc-active); + } +} + bool intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *fb) @@ -6947,6 +7025,8 @@ done: crtc-mode =
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Track unbound pages
On Mon, 20 Aug 2012 11:00:39 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: int -i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, - gfp_t gfpmask) +i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) { + struct drm_i915_private *dev_priv = obj-base.dev-dev_private; int page_count, i; struct address_space *mapping; - struct inode *inode; struct page *page; + gfp_t gfp; if (obj-pages || obj-sg_table) return 0; + /* Assert that the object is not currently in any GPU domain. As it + * wasn't in the GTT, there shouldn't be any way it could have been in + * a GPU cache + */ + BUG_ON(obj-base.read_domains I915_GEM_GPU_DOMAINS); + BUG_ON(obj-base.write_domain I915_GEM_GPU_DOMAINS); + /* Get the list of pages out of our struct file. They'll be pinned * at this point until we release them. */ page_count = obj-base.size / PAGE_SIZE; - BUG_ON(obj-pages != NULL); - obj-pages = drm_malloc_ab(page_count, sizeof(struct page *)); + obj-pages = kmalloc(page_count*sizeof(struct page *), GFP_KERNEL); This is a silly one (by me). At one point the patch introduced i915_malloc() and replaced drm_malloc_ab() with it and then I reverted that after transitioning to using the sg_table everywhere. It needs to still be drm_malloc_ab() in this and the follow-on patches until it is replaced by sg_alloc_table(). -Chris -- 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 04/29] drm/i915: Try harder to allocate an mmap_offset
On Sat, Aug 11, 2012 at 03:41:03PM +0100, Chris Wilson wrote: Given the persistence of an offset for the lifetime of an object, itis easy to contemplate how the mmap space becomes badly fragmented to the point that further allocations fail with ENOSPC. Our only recourse at this point is to try to purge the objects to release some space and reattempt the allocation. References: https://bugs.freedesktop.org/show_bug.cgi?id=39552 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Ok, I've picked up things up to this patch, with the few changes applied as discussed (plus ditching an unused var that I've forgotten to kill when purging the put_pages from gem_reset). I'll look at the others later today. Thanks for the patches, -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Track unbound pages
On Mon, Aug 20, 2012 at 10:36:09AM +0100, Chris Wilson wrote: On Mon, 20 Aug 2012 11:00:39 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: int -i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, - gfp_t gfpmask) +i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) { + struct drm_i915_private *dev_priv = obj-base.dev-dev_private; int page_count, i; struct address_space *mapping; - struct inode *inode; struct page *page; + gfp_t gfp; if (obj-pages || obj-sg_table) return 0; + /* Assert that the object is not currently in any GPU domain. As it +* wasn't in the GTT, there shouldn't be any way it could have been in +* a GPU cache +*/ + BUG_ON(obj-base.read_domains I915_GEM_GPU_DOMAINS); + BUG_ON(obj-base.write_domain I915_GEM_GPU_DOMAINS); + /* Get the list of pages out of our struct file. They'll be pinned * at this point until we release them. */ page_count = obj-base.size / PAGE_SIZE; - BUG_ON(obj-pages != NULL); - obj-pages = drm_malloc_ab(page_count, sizeof(struct page *)); + obj-pages = kmalloc(page_count*sizeof(struct page *), GFP_KERNEL); This is a silly one (by me). At one point the patch introduced i915_malloc() and replaced drm_malloc_ab() with it and then I reverted that after transitioning to using the sg_table everywhere. It needs to still be drm_malloc_ab() in this and the follow-on patches until it is replaced by sg_alloc_table(). Ok, history fixed. Can you please check whether I haven't fumbled it? Thanks, Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 04/29] drm/i915: Try harder to allocate an mmap_offset
On Mon, 20 Aug 2012 11:37:30 +0200, Daniel Vetter dan...@ffwll.ch wrote: Ok, I've picked up things up to this patch, with the few changes applied as discussed (plus ditching an unused var that I've forgotten to kill when purging the put_pages from gem_reset). I'll look at the others later today. I think that's a good point to hand over to QA for the first round of testing; especially with the swap thrashing tests and sporadic failures afterwards. -Chris -- 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 00/58] modeset-rework, the basic conversion
On Sun, 19 Aug 2012, Daniel Vetter daniel.vet...@ffwll.ch wrote: I'll also plan to put tags for the entire series in the merge commit, so if you have tested this on a few machines, read through and agree with the new designs, please reply with your tested-by/acked-by/reviewed-by tags. Flames, comments and test reports highly welcome. Cheers, Daniel [1] http://cgit.freedesktop.org/~danvet/drm/log/?h=modeset-rework-base Tested-by: Jani Nikula jani.nik...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: add tons of modeset state checks
... let's see how whether this catches anything earlier and I can track down a few bugs. v2: Add more checks and also add DRM_DEBUG_KMS output so that it's clear which connector/encoder/crtc is being checked atm. Which proved rather useful for debugging ... v3: Add a WARN in the common encoder dpms function, now that also modeset changes properly update the dpms state ... v4: Properly add a short explanation for each WARN, to avoid the need to correlate dmesg lines with source lines accurately. Suggested by Chris Wilson. v5: Also dump (expected, found) for state checks (or wherever it's not apparent from the test what exactly mismatches with expectations). Again suggested by Chris Wilson. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 90 +++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 95a9f04..4db7b58 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3637,7 +3637,7 @@ void intel_connector_dpms(struct drm_connector *connector, int mode) if (encoder-base.crtc) intel_encoder_dpms(encoder, mode); else - encoder-connectors_active = false; + WARN_ON(encoder-connectors_active != false); intel_connector_check_state(to_intel_connector(connector)); } @@ -6823,6 +6823,90 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc) base.head) \ if (mask (1 (intel_crtc)-pipe)) \ +static void +intel_modeset_check_state(struct drm_device *dev) +{ + struct intel_crtc *crtc; + struct intel_encoder *encoder; + struct intel_connector *connector; + + list_for_each_entry(connector, dev-mode_config.connector_list, + base.head) { + /* This also checks the encoder/connector hw state with the +* -get_hw_state callbacks. */ + intel_connector_check_state(connector); + + WARN(connector-new_encoder-base != connector-base.encoder, +connector's staged encoder doesn't match current encoder\n); + } + + list_for_each_entry(encoder, dev-mode_config.encoder_list, + base.head) { + bool enabled = false; + bool active = false; + enum pipe pipe; + + DRM_DEBUG_KMS([ENCODER:%d:%s]\n, + encoder-base.base.id, + drm_get_encoder_name(encoder-base)); + + WARN(encoder-new_crtc-base != encoder-base.crtc, +encoder's stage crtc doesn't match current crtc\n); + WARN(encoder-connectors_active !encoder-base.crtc, +encoder's active_connectors set, but no crtc\n); + + list_for_each_entry(connector, dev-mode_config.connector_list, + base.head) { + if (connector-base.encoder != encoder-base) + continue; + enabled = true; + if (connector-base.dpms == DRM_MODE_DPMS_ON) + active = true; + } + WARN(!!encoder-base.crtc != enabled, +encoder's enabled state mismatch +(expected %i, found %i)\n, +!!encoder-base.crtc, enabled); + /* dpms on only implies active. */ + WARN(active !encoder-base.crtc, +active encoder with no crtc\n); + WARN(enabled = encoder-get_hw_state(encoder, pipe) + !encoder-base.crtc, +encoder's hw state doesn't match sw tracking +(expected %i, found %i)\n, +!!encoder-base.crtc, enabled); + } + + list_for_each_entry(crtc, dev-mode_config.crtc_list, + base.head) { + bool enabled = false; + bool active = false; + + DRM_DEBUG_KMS([CRTC:%d]\n, + crtc-base.base.id); + + WARN(crtc-active !crtc-base.enabled, +active crtc, but not enabled in sw tracking\n); + + list_for_each_entry(encoder, dev-mode_config.encoder_list, + base.head) { + if (encoder-base.crtc != crtc-base) + continue; + enabled = true; + if (encoder-connectors_active) + active = true; + } + WARN(active != crtc-active, +crtc's computed active state doesn't match tracked active state +(expected %i, found %i)\n, active, crtc-active); +
[Intel-gfx] [PATCH] Check that the drm fd is i915 before calling i915 ioctls on it
Signed-off-by: Adam Jackson a...@redhat.com --- src/intel_module.c | 14 ++ 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/intel_module.c b/src/intel_module.c index edea48d..be9688a 100644 --- a/src/intel_module.c +++ b/src/intel_module.c @@ -392,11 +392,17 @@ static Bool has_kernel_mode_setting(struct pci_device *dev) ret = FALSE; fd = drmOpen(NULL, id); if (fd != -1) { - struct drm_i915_getparam gp; + drmVersionPtr v; - gp.param = I915_PARAM_HAS_GEM; - gp.value = ret; - (void)drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, gp); + v = drmGetVersion(fd); + if (v !strcmp(v-name, i915)) { + struct drm_i915_getparam gp; + + gp.param = I915_PARAM_HAS_GEM; + gp.value = ret; + (void)drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, gp); + } + drmFreeVersion(v); close(fd); } -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: use hsw rps tuning values everywhere on gen6+
On Wed, Aug 15, 2012 at 10:41:45AM +0200, Daniel Vetter wrote: James Bottomley reported [1] a massive power regression, due to the enabling of semaphores by default in 3.5. A workaround for him is to again disable semaphores. And indeed, his system has a very hard time to entre rc6 with semaphores enabled. Ben Widawsky run around with a kill-a-watt a lot and noticed: - There are indeed a few rare systems that seem to have a hard time entering rc6 when desktop-idle. - One machine, The Indestructible Toshiba regressed in this behaviour between 3.5 and 3.6 in a merge commit! So rc6 behaviour with the current setting seems to be highly timing dependent and not robust at all. - The behaviour James reported wrt semaphores seems to be a freak timing thing that only happens on his specific machine, confirming that enabling semaphores shouldn't reduce rc6 residency. Now furthermore the Google ChromeOS guys reported [2] a while ago that at least on some machines a simply a blinking cursor can keep the gpu turbo at the highest frequency. This is because the current rps limits used on snb/ivb are highly asymmetric. On the theory that gpu turbo and rc6 tuning values are related, we've tried whether the much saner looking (since much less asymmetric) rps tuning values used for hsw would also help entering rc6 more robustly. And it seems to work. Reference[1]: http://lists.freedesktop.org/archives/dri-devel/2012-July/025675.html Reference[2]: http://lists.freedesktop.org/archives/intel-gfx/2012-July/018692.html Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=53393 Tested-by: Ben Widawsky b...@bwidawsk.net Cc: sta...@vger.kernel.org Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Ok, I've merged this one here, making the commit message a bit more cautious. Unfortnately we don't seem to have the understanding (nor the resources to gain it) of the hw to do better than copypaste what we get from the hw team :( -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 08/29] drm/i915: Introduce drm_i915_gem_object_ops
On Sat, Aug 11, 2012 at 03:41:07PM +0100, Chris Wilson wrote: In order to specialise functions depending upon the type of object, we can attach vfuncs to each object via their obj-driver_private pointer, bringing it back to life! For instance, this will be used in future patches to only bind pages from a dma-buf for the duration that the object is used by the GPU - and so prevent them from pinning those pages for the entire of the object. Tbh I'd prefer adding a pointer with the right type over not wasting that untyped pointer ... Otherwise I like this, and I'll follow up with suggestions for other functions we could add when reviewing the other patches ;-) -Daniel Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h| 10 - drivers/gpu/drm/i915/i915_gem.c| 65 ++-- drivers/gpu/drm/i915/i915_gem_dmabuf.c |4 +- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bbc51ef..c42190b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -895,6 +895,11 @@ enum i915_cache_level { I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */ }; +struct drm_i915_gem_object_ops { + int (*get_pages)(struct drm_i915_gem_object *); + void (*put_pages)(struct drm_i915_gem_object *); +}; + struct drm_i915_gem_object { struct drm_gem_object base; @@ -1302,7 +1307,8 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void i915_gem_load(struct drm_device *dev); int i915_gem_init_object(struct drm_gem_object *obj); -void i915_gem_object_init(struct drm_i915_gem_object *obj); +void i915_gem_object_init(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_object_ops *ops); struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); @@ -1315,7 +1321,7 @@ int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); void i915_gem_release_mmap(struct drm_i915_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); -int __must_check i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj); +int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); int i915_gem_object_sync(struct drm_i915_gem_object *obj, struct intel_ring_buffer *to); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9c8787e..ed6a1ec 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1407,15 +1407,12 @@ i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) return obj-madv == I915_MADV_DONTNEED; } -static int +static void i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) { int page_count = obj-base.size / PAGE_SIZE; int ret, i; - if (obj-pages == NULL) - return 0; - BUG_ON(obj-gtt_space); BUG_ON(obj-madv == __I915_MADV_PURGED); @@ -1448,9 +1445,19 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) drm_free_large(obj-pages); obj-pages = NULL; +} - list_del(obj-gtt_list); +static int +i915_gem_object_put_pages(struct drm_i915_gem_object *obj) +{ + const struct drm_i915_gem_object_ops *ops = obj-base.driver_private; + if (obj-sg_table || obj-pages == NULL) + return 0; + + ops-put_pages(obj); + + list_del(obj-gtt_list); if (i915_gem_object_is_purgeable(obj)) i915_gem_object_truncate(obj); @@ -1467,7 +1474,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target) dev_priv-mm.unbound_list, gtt_list) { if (i915_gem_object_is_purgeable(obj) - i915_gem_object_put_pages_gtt(obj) == 0) { + i915_gem_object_put_pages(obj) == 0) { count += obj-base.size PAGE_SHIFT; if (count = target) return count; @@ -1479,7 +1486,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target) mm_list) { if (i915_gem_object_is_purgeable(obj) i915_gem_object_unbind(obj) == 0 - i915_gem_object_put_pages_gtt(obj) == 0) { + i915_gem_object_put_pages(obj) == 0) { count += obj-base.size PAGE_SHIFT; if (count = target) return count; @@ -1497,10 +1504,10 @@ i915_gem_shrink_all(struct
Re: [Intel-gfx] [PATCH 16/29] drm/i915: Fix location of stolen memory register for SandyBridge+
On Sat, Aug 11, 2012 at 03:41:15PM +0100, Chris Wilson wrote: A few of the earlier registers where enlarged and so the Base Data of Stolem Memory Register (BDSM) was pushed to 0xb0. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_stolen.c |9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index a01ff74..a528e4a 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -63,7 +63,11 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) * its value of TOLUD. */ base = 0; - if (INTEL_INFO(dev)-gen 3 || IS_G33(dev)) { + if (INTEL_INFO(dev)-gen = 6) { + /* Read Base Data of Stolen Memory Register (BDSM) directly */ + pci_read_config_dword(pdev, 0xB0, base); Wishlist (i.e. feel free to ignore): Can we have #defines instead of magic numbers here, please? -Daniel + base = ~4095; /* lower bits used for locking register */ + } else if (INTEL_INFO(dev)-gen 3 || IS_G33(dev)) { /* Read Graphics Base of Stolen Memory directly */ pci_read_config_dword(pdev, 0xA4, base); #if 0 @@ -172,6 +176,9 @@ int i915_gem_init_stolen(struct drm_device *dev) if (dev_priv-mm.stolen_base == 0) return 0; + DRM_DEBUG_KMS(found %d bytes of stolen memory at %08lx\n, + dev_priv-mm.gtt-stolen_size, dev_priv-mm.stolen_base); + /* Basic memrange allocator for stolen space */ drm_mm_init(dev_priv-mm.stolen, 0, prealloc_size); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 18/29] drm/i915: Delay allocation of stolen space for FBC
On Sat, Aug 11, 2012 at 03:41:17PM +0100, Chris Wilson wrote: As we may wish to wrap regions preallocated by the BIOS, we need to do that before carving out contiguous chunks of stolen space for FBC. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Some comments inline below. -Daniel --- drivers/gpu/drm/i915/i915_drv.h|1 + drivers/gpu/drm/i915/i915_gem_stolen.c | 114 +--- drivers/gpu/drm/i915/intel_display.c |3 + drivers/gpu/drm/i915/intel_pm.c| 13 ++-- 4 files changed, 70 insertions(+), 61 deletions(-) [snip] +int i915_gem_stolen_setup_compression(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_mm_node *entry; + unsigned long size; + + if (dev_priv-mm.stolen_base == 0) + return 0; + + if (dev_priv-cfb_size) + return dev_priv-cfb_size; + + /* Try to set up FBC with a reasonable compressed buffer size */ + size = 0; + list_for_each_entry(entry, dev_priv-mm.stolen.hole_stack, hole_stack) { + unsigned long hole_start = entry-start + entry-size; + unsigned long hole_end = list_entry(entry-node_list.next, + struct drm_mm_node, + node_list)-start; + unsigned long hole_size = hole_end - hole_start; This feels a bit to much munging around in drm_mm internals. What about a drm_mm_for_each_hole(entry, mm, hole_start, hole_end) #define helper? + if (hole_size size) + size = hole_size; + } + + /* Try to get a 32M buffer... */ + if (size (36*1024*1024)) + size = 32*1024*1024; + else /* fall back to 3/4 of the stolen space */ + size = size * 3 / 4; + + return i915_setup_compression(dev, size); } void intel_modeset_gem_init(struct drm_device *dev) [snap] diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3021c18..6f0f498 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -438,12 +438,6 @@ void intel_update_fbc(struct drm_device *dev) dev_priv-no_fbc_reason = FBC_MODULE_PARAM; goto out_disable; } - if (intel_fb-obj-base.size dev_priv-cfb_size) { - DRM_DEBUG_KMS(framebuffer too large, disabling - compression\n); - dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL; - goto out_disable; - } if ((crtc-mode.flags DRM_MODE_FLAG_INTERLACE) || (crtc-mode.flags DRM_MODE_FLAG_DBLSCAN)) { DRM_DEBUG_KMS(mode incompatible with compression, @@ -477,6 +471,13 @@ void intel_update_fbc(struct drm_device *dev) if (in_dbg_master()) goto out_disable; + if (intel_fb-obj-base.size i915_gem_stolen_setup_compression(dev)) { + DRM_DEBUG_KMS(framebuffer too large, disabling + compression\n); + dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL; + goto out_disable; + } I couldn't figure out why this block here had to move ... please enlighten me. + /* If the scanout has not changed, don't modify the FBC settings. * Note that we make the fundamental assumption that the fb-obj * cannot be unpinned (and have its GTT offset and fence revoked) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 22/29] drm/i915: Handle stolen objects in pwrite
On Sat, Aug 11, 2012 at 03:41:21PM +0100, Chris Wilson wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk What about putting kmap/unmap abstractions into obj-ops (like the dma_buf interface already has)? Since the pwrite/pread code is already rather branch heave I hope we don't see the overhead of the indirect call even in microbenchmarks (haven't checked). And this way we would also neatly wrap up dma_bufs for pwrite (if anyone ever really wants that ...). The kmap(_atomic) for stolen mem backed objects would boil down to doing the pointer arithmetic, kunmap would be just a noop. Cheers, Daniel --- drivers/gpu/drm/i915/i915_gem.c | 169 +-- 1 file changed, 111 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 552f95b..a2fb2aa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -664,19 +664,17 @@ out: * needs_clflush_before is set and flushes out any written cachelines after * writing if needs_clflush is set. */ static int -shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length, +shmem_pwrite_fast(char *vaddr, int shmem_page_offset, int page_length, char __user *user_data, bool page_do_bit17_swizzling, bool needs_clflush_before, bool needs_clflush_after) { - char *vaddr; int ret; if (unlikely(page_do_bit17_swizzling)) return -EINVAL; - vaddr = kmap_atomic(page); if (needs_clflush_before) drm_clflush_virt_range(vaddr + shmem_page_offset, page_length); @@ -686,7 +684,6 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length, if (needs_clflush_after) drm_clflush_virt_range(vaddr + shmem_page_offset, page_length); - kunmap_atomic(vaddr); return ret ? -EFAULT : 0; } @@ -694,16 +691,14 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length, /* Only difference to the fast-path function is that this can handle bit17 * and uses non-atomic copy and kmap functions. */ static int -shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, +shmem_pwrite_slow(char *vaddr, int shmem_page_offset, int page_length, char __user *user_data, bool page_do_bit17_swizzling, bool needs_clflush_before, bool needs_clflush_after) { - char *vaddr; int ret; - vaddr = kmap(page); if (unlikely(needs_clflush_before || page_do_bit17_swizzling)) shmem_clflush_swizzled_range(vaddr + shmem_page_offset, page_length, @@ -720,7 +715,6 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, shmem_clflush_swizzled_range(vaddr + shmem_page_offset, page_length, page_do_bit17_swizzling); - kunmap(page); return ret ? -EFAULT : 0; } @@ -731,6 +725,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_i915_gem_pwrite *args, struct drm_file *file) { + struct drm_i915_private *dev_priv = dev-dev_private; ssize_t remain; loff_t offset; char __user *user_data; @@ -770,74 +765,132 @@ i915_gem_shmem_pwrite(struct drm_device *dev, if (ret) return ret; - i915_gem_object_pin_pages(obj); - offset = args-offset; obj-dirty = 1; - for_each_sg(obj-pages-sgl, sg, obj-pages-nents, i) { - struct page *page; - int partial_cacheline_write; + if (obj-stolen) { + while (remain 0) { + char *vaddr; + int partial_cacheline_write; - if (i offset PAGE_SHIFT) - continue; + /* Operation in this page + * + * shmem_page_offset = offset within page in shmem file + * page_length = bytes to copy for this page + */ + shmem_page_offset = offset_in_page(offset); - if (remain = 0) - break; + page_length = remain; + if ((shmem_page_offset + page_length) PAGE_SIZE) + page_length = PAGE_SIZE - shmem_page_offset; - /* Operation in this page - * - * shmem_page_offset = offset within page in shmem file - * page_length = bytes to copy for this page - */ - shmem_page_offset = offset_in_page(offset); +
Re: [Intel-gfx] [PATCH 27/29] drm/i915: Allocate overlay registers from stolen memory
On Sat, Aug 11, 2012 at 03:41:26PM +0100, Chris Wilson wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Since most of the overlay-supporting hw uses physical mem for the overlay I think this isn't much worth it: The additional frobbery in attach/detach_phys object is likely more work than we'll anything we'll ever gain from using stolen mem here. Especially since we'll use stolen mem already for the rings. -Daniel --- drivers/gpu/drm/i915/intel_overlay.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 7a98459..6982191 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1424,8 +1424,10 @@ void intel_setup_overlay(struct drm_device *dev) overlay-dev = dev; - reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); - if (!reg_bo) + reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE); + if (reg_bo == NULL) + reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); + if (reg_bo == NULL) goto out_free; overlay-reg_bo = reg_bo; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Add ERR_INT to gen7 error state
ERR_INT can generate interrupts. However since most of the conditions seem quite fatal the patch opts to simply report it in error state instead of adding more complexity to the interrupt handler for little gain (the bits are sticky anyway). Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 3 +++ drivers/gpu/drm/i915/i915_reg.h | 1 + 4 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0e8f14d..02405c7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -702,6 +702,9 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, DONE_REG: 0x%08x\n, error-done_reg); } + if (INTEL_INFO(dev)-gen == 7) + seq_printf(m, ERR_INT: 0x%08x\n, error-err_int); + for_each_ring(ring, dev_priv, i) i915_ring_error_state(m, dev, error, i); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 33f19eb..c61fc48 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -196,6 +196,7 @@ struct drm_i915_error_state { u32 cpu_ring_head[I915_NUM_RINGS]; u32 cpu_ring_tail[I915_NUM_RINGS]; u32 error; /* gen6+ */ + u32 err_int; /* gen7 */ u32 instpm[I915_NUM_RINGS]; u32 instps[I915_NUM_RINGS]; u32 instdone1; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0c37101..021207c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1211,6 +1211,9 @@ static void i915_capture_error_state(struct drm_device *dev) error-done_reg = I915_READ(DONE_REG); } + if (INTEL_INFO(dev)-gen == 7) + error-err_int = I915_READ(GEN7_ERR_INT); + i915_gem_record_fences(dev, error); i915_gem_record_rings(dev, error); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2f7b688..d4a7d73 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -507,6 +507,7 @@ #define DMA_FADD_I8XX 0x020d0 #define ERROR_GEN6 0x040a0 +#define GEN7_ERR_INT 0x44040 /* GM45+ chicken bits -- debug workaround bits that may be required * for various sorts of correct behavior. The top 16 bits of each are -- 1.7.11.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Find unclaimed MMIO writes.
ERR_INT on HSW will display unclaimed MMIO accesses. This can be either the result of a driver bug writing to an invalid addresses, or the result of RC6. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.c | 4 drivers/gpu/drm/i915/i915_reg.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 845e390..255087f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1182,6 +1182,10 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ if (unlikely(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \ + if (IS_HASWELL(dev_priv-dev) (I915_READ_NOTRACE(GEN7_ERR_INT) ERR_INT_MMIO_UNCLAIMED)) { \ + DRM_ERROR(Unclaimed write to %x\n, reg); \ + writel(ERR_INT_MMIO_UNCLAIMED, dev_priv-regs + GEN7_ERR_INT); \ + } \ } __i915_write(8, b) __i915_write(16, w) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d4a7d73..bab4762 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -508,6 +508,7 @@ #define ERROR_GEN6 0x040a0 #define GEN7_ERR_INT 0x44040 +#define ERR_INT_MMIO_UNCLAIMED (113) /* GM45+ chicken bits -- debug workaround bits that may be required * for various sorts of correct behavior. The top 16 bits of each are -- 1.7.11.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] glxdemo/glxpixmap doesn't work, please help
We are running mesademo on Ivybridge platform. Glxdemo/glxpixmap doesn't work. If somebody could help us out, that would be great. The followings are the command dump from ring buffer when glxdemo and glxpixmap are runing: Address GPU commands Meaning 0x0 7a03 PIPE_COTROL 0x4 0x12 DWORD 1 0x8 0x21084 DWORD 2 0xc 0x0 DWORD 3 0x100x0 DWORD 4 0x140x0 DWORD 5 0x180x7a03PIPE_COTROL 0x1c0x4000DWORD 1 0x200x21084 DWORD 2 0x240x0 DWORD 3 0x280x0 DWORD 4 0x2c0x0 DWORD 5 0x300x7a03PIPE_CONTROL 0x340x1c1dDWORD 1 0x380x21084 DWORD 2 0x3c0x0 DWORD 3 0x400x0 DWORD 4 0x440x0 DWORD 5 0x480x18800080MI_BATCH_BUFFER_START 0x4c0x768000 BATCH_BUFFER_OFFSET 0x500x7a03PIPE_CONTROL 0x540x12 DWORD 1 0x580x21084 DWORD 2 0x5c0x0 DWORD 3 0x600x0 DWORD 4 0x640x0 DWORD 5 0x680x7a03PIPE_CONTROL 0x6c0x4000DWORD 1 0x700x21084 DWORD 2 0x740x0 DWORD 3 0x780x0 DWORD 4 0x7c0x0 DWORD 5 The batch buffer contains 3D render commands and data from glxdemo (or glxpixmap). The GPU hangs at address 0x64. That means all commands in batch buffer are completed but GPU is waiting for some flushes to finish in the pipe_control command. Could you help me figure out is there any thing wrong in this command sequence from the ring buffer? Thank you so much Ying ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] hello
hi,every body du81692468___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] glxdemo/glxpixmap doesn't work, please help
On Tue, 21 Aug 2012 00:49:17 + Liu, Ying2 ying2@intel.com wrote: We are running mesademo on Ivybridge platform. Glxdemo/glxpixmap doesn't work. If somebody could help us out, that would be great. Please do not send HTML e-mail to the mailing list. The followings are the command dump from ring buffer when glxdemo and glxpixmap are runing: Address GPU commands Meaning 0x0 7a03 PIPE_COTROL 0x4 0x12 DWORD 1 0x8 0x21084 DWORD 2 0xc 0x0 DWORD 3 0x100x0 DWORD 4 0x140x0 DWORD 5 0x180x7a03PIPE_COTROL 0x1c0x4000DWORD 1 0x200x21084 DWORD 2 0x240x0 DWORD 3 0x280x0 DWORD 4 0x2c0x0 DWORD 5 0x300x7a03PIPE_CONTROL 0x340x1c1dDWORD 1 0x380x21084 DWORD 2 0x3c0x0 DWORD 3 0x400x0 DWORD 4 0x440x0 DWORD 5 0x480x18800080MI_BATCH_BUFFER_START 0x4c0x768000 BATCH_BUFFER_OFFSET 0x500x7a03PIPE_CONTROL 0x540x12 DWORD 1 0x580x21084 DWORD 2 0x5c0x0 DWORD 3 0x600x0 DWORD 4 0x640x0 DWORD 5 0x680x7a03PIPE_CONTROL 0x6c0x4000DWORD 1 0x700x21084 DWORD 2 0x740x0 DWORD 3 0x780x0 DWORD 4 0x7c0x0 DWORD 5 The batch buffer contains 3D render commands and data from glxdemo (or glxpixmap). The GPU hangs at address 0x64. That means all commands in batch buffer are completed but GPU is waiting for some flushes to finish in the pipe_control command. Could you help me figure out is there any thing wrong in this command sequence from the ring buffer? Thank you so much Ying First, if you have a hang, there should be associated error state. Can you please submit the error state somewhere. Here are directions for filing bugs: http://intellinuxgraphics.org/how_to_report_bug.html I'm just eyeballing it, so this may be off, but I think you're running an old driver because I don't think you have the new TLB INVALIDATE flags in the right places. I'm not sure if the patches went into -fixes, or -queued. These are pretty recently added and fix some known issues. The following would be answered with the error state, but moving past that too for a moment... you say you hang at 0x64. You need to be more specific than that. How do you know you are hung there? At least the debug registers I am aware of only tell how far the Command Streamer has fetched, and parsed. The GPU does not execute the commands synchronously, and so PIPE_CONTROL is used to make sure the commands are executed and their side effects flushed. As an example of the above, if you invoke a shader in a batch which has an infinite loop, your program would hang at the PIPE_CONTROL. -- Ben Widawsky, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: fix reassignment of variable intel_dp-DP
From 952c95621b5fd95a629c36017c36ac9e6c40e839 Mon Sep 17 00:00:00 2001 From: Anhua Xu anhua...@intel.com Date: Tue, 21 Aug 2012 11:00:57 +0800 Subject: [PATCH] drm/i915: fix reassignment of variable intel_dp-DP This little regression was introduced by: commit 417e822deee1d2bcd8a8a60660c40a0903713f2b Author: Keith Packard kei...@keithp.com Date: Tue Nov 1 19:54:11 2011 -0700 drm/i915: Treat PCH eDP like DP in most places PCH eDP has many of the same needs as regular PCH DP connections, including the DP_CTl bit settings, the TRANS_DP_CTL register. The reachable tag for this commit is: v3.1-5461-g417e822 Signed-off-by: Anhua Xu anhua...@intel.com --- drivers/gpu/drm/i915/intel_dp.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426a..c060231 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -882,7 +882,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, * supposed to be read-only. */ intel_dp-DP = I915_READ(intel_dp-output_reg) DP_DETECTED; - intel_dp-DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; /* Handle DP bits in common between all three register formats */ -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 00/58] modeset-rework, the basic conversion
On Sun, 19 Aug 2012 21:12:17 +0200 Daniel Vetter daniel.vet...@ffwll.ch wrote: Hi all, Changes since last time around: - The prep patches are all merged now. - I've left out the actual DP fixes/cleanups, I think we should merge those in a separte step. - A few bugfixes (thanks to Paulo, Jani and Chris). - I've also applied a few bikesheds for naming that Paulo suggested (but I'm not sure whether I've sent those out already in a previous patchbomb). Essentially this is just the core rework, which addes the new get_hw_state code, refactors all the encoders to use the new functions and finally reworks the modeset logic to disable/enable entire pipes, always (and with a deterministic order). For merging to -next, I plan to pull in everything with a real merge commit. For that reason I've put up a modeset-rework-base branch onto my private fdo repo[1]. That way I can put a short documentation for the new modeset design into the merge commit (stichted together from the previous patchbomb cover letters), documenting my folly assumptions for eternity. I'll also plan to put tags for the entire series in the merge commit, so if you have tested this on a few machines, read through and agree with the new designs, please reply with your tested-by/acked-by/reviewed-by tags. Flames, comments and test reports highly welcome. Cheers, Daniel Tested-by: Ben Widawsky b...@bwidawsk.net (before the rebase) [1] http://cgit.freedesktop.org/~danvet/drm/log/?h=modeset-rework-base Daniel Vetter (58): drm/i915: add crtc-enable/disable vfuncs insted of dpms drm/i915: rip out crtc prepare/commit indirection drm/i915: add direct encoder disable/enable infrastructure drm/i915/hdmi: convert to encoder-disable/enable drm/i915/tv: convert to encoder enable/disable drm/i915/lvds: convert to encoder disable/enable drm/i915/dp: convert to encoder disable/enable drm/i915/crt: convert to encoder disable/enable drm/i915/sdvo: convert to encoder disable/enable drm/i915/dvo: convert to encoder disable/enable drm/i915: convert dpms functions of dvo/sdvo/crt drm/i915: rip out encoder-disable/enable checks drm/i915: clean up encoder_prepare/commit drm/i915: copypaste drm_crtc_helper_set_config drm/i915: call set_base directly drm/i915: inline intel_best_encoder drm/i915: copypaste drm_crtc_helper_set_mode drm/i915: simplify intel_crtc_prepare_encoders drm/i915: rip out encoder-prepare/commit drm/i915: call crtc functions directly drm/i915: WARN when trying to enabled an unused crtc drm/i915: Add interfaces to read out encoder/connector hw state drm/i915/dp: implement get_hw_state drm/i915/hdmi: implement get_hw_state drm/i915/tv: implement get_hw_state drm/i915/lvds: implement get_hw_state drm/i915/crt: implement get_hw_state drm/i915/sdvo: implement get_hw_state drm/i915/dvo: implement get_hw_state drm/i915: read out the modeset hw state at load and resume time drm/i915: check connector hw/sw state drm/i915: rip out intel_crtc-dpms_mode drm/i915: rip out intel_dp-dpms_mode drm/i915: ensure the force pipe A quirk is actually followed drm/i915: introduce struct intel_set_config drm/i915: extract modeset config save/restore code drm/i915: extract intel_set_config_compute_mode_changes drm/i915: extract intel_set_config_update_output_state drm/i915: implement crtc helper semantics relied upon by the fb helper drm/i915: don't update the fb base if there is no fb drm/i915: convert pointless error checks in set_config to BUGs drm/i915: don't save all the encoder/crtc state in set_config drm/i915: stage modeset output changes drm/i915: push crtc-fb update into pipe_set_base drm/i915: remove crtc disabling special case drm/i915: move output commit and crtc disabling into set_mode drm/i915: extract adjusted mode computation drm/i915: use staged outuput config in tv-mode_fixup drm/i915: use staged outuput config in lvds-mode_fixup drm/i915: compute masks of crtcs affected in set_mode drm/i915: implement new set_mode code flow drm/i915: push commit_output_state past crtc disabling drm/i915: s/intel_encoder_disable/intel_encoder_noop drm/i915: WARN if the pipe won't turn off drm/i915: switch the load detect code to the staged modeset config drm/i915: push commit_output_state past the crtc/encoder preparing drm/i915: disable all crtcs at suspend time drm/i915: add tons of modeset state checks drivers/gpu/drm/i915/dvo.h |6 + drivers/gpu/drm/i915/dvo_ch7017.c| 13 + drivers/gpu/drm/i915/dvo_ch7xxx.c| 13 + drivers/gpu/drm/i915/dvo_ivch.c | 15 + drivers/gpu/drm/i915/dvo_ns2501.c| 15 + drivers/gpu/drm/i915/dvo_sil164.c| 16 + drivers/gpu/drm/i915/dvo_tfp410.c| 14 + drivers/gpu/drm/i915/i915_drv.c |4 + drivers/gpu/drm/i915/i915_drv.h |4 +-