Re: [Intel-gfx] Unexpected behaviour of xrandr and the Intel driver on monitor hotplug
On Mon, 2010-05-17 at 12:13 +0100, Simon Farnsworth wrote: The first bit of misbehaviour I'm seeing is caching of EDID across hotplug events. If I boot my system with no display attached, I correctly see no EDID property. When I connect a monitor via VGA, using cabling that supports DDC, I see EDID. When I unplug the monitor, I continue to see the old EDID. When I then plug in using a cable that doesn't support DDC, I see an extra mode appear in the mode list, but the EDID has not changed. Connecting using the original cable, or disconnecting cables completely removes this extra mode. commit 725398322d05486109375fbb85c3404108881e17 Author: Zhao Yakui yakui.z...@intel.com Date: Thu Mar 4 08:25:55 2010 + drm: remove the EDID blob stored in the EDID property when it is disconnected Now the EDID property will be updated when the corresponding EDID can be obtained from the external display device. But after the external device is plugged-out, the EDID property is not updated. In such case we still get the corresponding EDID property although it is already detected as disconnected. https://bugs.freedesktop.org/show_bug.cgi?id=26743 Signed-off-by: Zhao Yakui yakui.z...@intel.com Signed-off-by: Zhenyu Wang zhen...@linux.intel.com Cc: sta...@kernel.org Signed-off-by: Dave Airlie airl...@redhat.com The second misbehaviour I'm seeing is that the list of modes isn't predictable in the presence of hotplug. If I boot without EDID available, I get one list of modes; if I make EDID available by changing cables, I get a second list of modes. If I then change cables back to the no EDID cable, I get a third list of modes - I was expecting the first list again. Probably a side effect of the above. - 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
Re: [Intel-gfx] [PATCH 1/4] introduce intel_ring_buffer structure
On Tuesday 18 May 2010, Zou, Nanhai nanhai@intel.com wrote: -Original Message- From: Daniel Vetter [mailto:dan...@ffwll.ch] Sent: 2010年5月18日 1:43 Well, that's exactly the problem. You simply can't optimize a kernel interface once it's in use. And if you try to, your users will get the pitchforks and scream bloody murder trying to get you ;) So we need to get these patches right (at least the semantics of the interface) beforehand. Hi, Since VAAPI will be the only client for this multi ring buffer for a period of time. We may not have so much pain to optimize both kernel and user space. This approach touches little user space interface, only 1 new flag is added to IOCTL. We have new kinds of ring buffer to come in SandyBridge and later chips. Since we are still enabling SandyBridge. I can not for cast how those rings would be synchronized to each other. We may use minimum API to work first. Be aware that you cannot expect users to bump both their userspace VAAPI library and their kernel at the same time; there are good reasons for this. If you do tie the VAAPI library version and the kernel version too tightly together, you get into a position where users get upset - if I bump my kernel from 2.6.32 to 2.6.36 to get support for a new WiFi chipset and a new TV capture card, I'm likely to get quite upset if I then have to also respin my userspace. There are also issues around bisection as a tool for isolating regressions - if I have to carefully bump userspace and kernel in lock-step, it's very difficult for me to bisect down until I find the changeset that broke things. As most of the bugs you'll get reported from users like me won't reproduce in your lab, making it harder for me to give you helpful information is not in your interests. In conclusion, as Daniel's been saying, you must get the kernel interface mostly right first time. If it's too slow, a new interface to improve performance isn't hard to add in parallel to the old interface; if the old interface is a DoS vector or worse, you're going to get stuck in a very bad place. -- Simon Farnsworth Software Engineer ONELAN Limited http://www.onelan.com/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] Unexpected behaviour of xrandr and the Intel driver on monitor hotplug
On Tuesday 18 May 2010, Adam Jackson a...@redhat.com wrote: On Mon, 2010-05-17 at 12:13 +0100, Simon Farnsworth wrote: The first bit of misbehaviour I'm seeing is caching of EDID across hotplug events. If I boot my system with no display attached, I correctly see no EDID property. When I connect a monitor via VGA, using cabling that supports DDC, I see EDID. When I unplug the monitor, I continue to see the old EDID. When I then plug in using a cable that doesn't support DDC, I see an extra mode appear in the mode list, but the EDID has not changed. Connecting using the original cable, or disconnecting cables completely removes this extra mode. commit 725398322d05486109375fbb85c3404108881e17 Author: Zhao Yakui yakui.z...@intel.com Date: Thu Mar 4 08:25:55 2010 + Adding that to my kernel build nearly fixed things for me. I still can't explain why the 848x480 mode appears when I connect a DDC-crippled cable to the GMA 945, but I can live with that, I suspect (it looks to be XServer side, anyway, and I'm about to have to generate patches there, as I don't want default modes). -- Simon Farnsworth Software Engineer ONELAN Limited http://www.onelan.com/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] Unexpected behaviour of xrandr and the Intel driver on monitor hotplug
On Tue, 2010-05-18 at 18:07 +0100, Simon Farnsworth wrote: On Tuesday 18 May 2010, Adam Jackson a...@redhat.com wrote: On Mon, 2010-05-17 at 12:13 +0100, Simon Farnsworth wrote: The first bit of misbehaviour I'm seeing is caching of EDID across hotplug events. If I boot my system with no display attached, I correctly see no EDID property. When I connect a monitor via VGA, using cabling that supports DDC, I see EDID. When I unplug the monitor, I continue to see the old EDID. When I then plug in using a cable that doesn't support DDC, I see an extra mode appear in the mode list, but the EDID has not changed. Connecting using the original cable, or disconnecting cables completely removes this extra mode. commit 725398322d05486109375fbb85c3404108881e17 Author: Zhao Yakui yakui.z...@intel.com Date: Thu Mar 4 08:25:55 2010 + Adding that to my kernel build nearly fixed things for me. I still can't explain why the 848x480 mode appears when I connect a DDC-crippled cable to the GMA 945, but I can live with that, I suspect (it looks to be XServer side, anyway, and I'm about to have to generate patches there, as I don't want default modes). 848x480 just barely fits in the default sync ranges, is why. - 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
[Intel-gfx] [PATCH] gpu/drm/i915: Don't disable panel for modesetting if pfit hasn't changed
It seems to be possible to program a new mode without disabling the panel if the panel fitter setup doesn't change. Add support for that. Signed-off-by: Matthew Garrett m...@redhat.com --- drivers/gpu/drm/i915/intel_lvds.c | 22 -- 1 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b66806a..1da0030 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -84,6 +84,16 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev) BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; } +static void intel_lvds_lock_panel(struct drm_device *dev, bool lock) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + if (lock) + I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) 0x3); + else + I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd 16)); +} + /** * Sets the power state for the panel. */ @@ -555,6 +565,8 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) { struct drm_device *dev = encoder-dev; struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_lvds_priv *lvds_priv = intel_encoder-dev_priv; u32 reg; if (HAS_PCH_SPLIT(dev)) @@ -566,7 +578,10 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) dev_priv-backlight_duty_cycle = (dev_priv-saveBLC_PWM_CTL BACKLIGHT_DUTY_CYCLE_MASK); - intel_lvds_set_power(dev, false); + if (lvds_priv-pfit_control == I915_READ(PFIT_CONTROL)) + intel_lvds_lock_panel(dev, false); + else + intel_lvds_set_power(dev, false); } static void intel_lvds_commit( struct drm_encoder *encoder) @@ -578,7 +593,10 @@ static void intel_lvds_commit( struct drm_encoder *encoder) dev_priv-backlight_duty_cycle = intel_lvds_get_max_backlight(dev); - intel_lvds_set_power(dev, true); + if ((I915_READ(PP_CONTROL) (0xabcd 16)) == (0xabcd 16)) + intel_lvds_lock_panel(dev, true); + else + intel_lvds_set_power(dev, true); } static void intel_lvds_mode_set(struct drm_encoder *encoder, -- 1.6.5.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] gpu/drm/i915: Don't disable panel for modesetting if pfit hasn't changed
On Tue, 18 May 2010 13:53:16 -0400 Matthew Garrett m...@redhat.com wrote: It seems to be possible to program a new mode without disabling the panel if the panel fitter setup doesn't change. Add support for that. Signed-off-by: Matthew Garrett m...@redhat.com --- drivers/gpu/drm/i915/intel_lvds.c | 22 -- 1 files changed, 20 insertions(+), 2 deletions(-) Looks good, we should get it upstream early in this cycle to get it some test coverage. If it doesn't work out it's easy to revert. Acked-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, 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 1/9] list.h: add list_for_each_entry_safe_from_reverse
i915 needs this. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- include/linux/list.h | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/include/linux/list.h b/include/linux/list.h index 8392884..21cdd99 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -544,6 +544,21 @@ static inline void list_splice_tail_init(struct list_head *list, pos-member != (head);\ pos = n, n = list_entry(n-member.prev, typeof(*n), member)) +/** + * list_for_each_entry_safe_from_reverse - iterate backwards over list from the current point safe against removal + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member:the name of the list_struct within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_safe_from_reverse(pos, n, head, member) \ + for (n = list_entry(pos-member.prev, typeof(*pos), member);\ +pos-member != (head);\ +pos = n, n = list_entry(n-member.prev, typeof(*n), member)) + /* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/9] drm: kill drm_mm_node-private
Only ever assigned, never used. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c |4 +--- drivers/gpu/drm/ttm/ttm_bo.c |6 -- drivers/gpu/drm/ttm/ttm_bo_util.c |2 -- include/drm/drm_mm.h |1 - 4 files changed, 1 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f69c1b0..952b4b3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2706,10 +2706,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (free_space != NULL) { obj_priv-gtt_space = drm_mm_get_block(free_space, obj-size, alignment); - if (obj_priv-gtt_space != NULL) { - obj_priv-gtt_space-private = obj; + if (obj_priv-gtt_space != NULL) obj_priv-gtt_offset = obj_priv-gtt_space-start; - } } if (obj_priv-gtt_space == NULL) { /* If the gtt is empty and we're still having trouble diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3b5b094..cf8c303 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -476,7 +476,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) ++put_count; } if (bo-mem.mm_node) { - bo-mem.mm_node-private = NULL; drm_mm_put_block(bo-mem.mm_node); bo-mem.mm_node = NULL; } @@ -656,7 +655,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, printk(KERN_ERR TTM_PFX Buffer eviction failed\n); spin_lock(glob-lru_lock); if (evict_mem.mm_node) { - evict_mem.mm_node-private = NULL; drm_mm_put_block(evict_mem.mm_node); evict_mem.mm_node = NULL; } @@ -915,8 +913,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, mem-mm_node = node; mem-mem_type = mem_type; mem-placement = cur_flags; - if (node) - node-private = bo; return 0; } @@ -959,7 +955,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, interruptible, no_wait_reserve, no_wait_gpu); if (ret == 0 mem-mm_node) { mem-placement = cur_flags; - mem-mm_node-private = bo; return 0; } if (ret == -ERESTARTSYS) @@ -1015,7 +1010,6 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, out_unlock: if (ret mem.mm_node) { spin_lock(glob-lru_lock); - mem.mm_node-private = NULL; drm_mm_put_block(mem.mm_node); spin_unlock(glob-lru_lock); } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 13012a1..7cffb3e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -353,8 +353,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, fbo-vm_node = NULL; fbo-sync_obj = driver-sync_obj_ref(bo-sync_obj); - if (fbo-mem.mm_node) - fbo-mem.mm_node-private = (void *)fbo; kref_init(fbo-list_kref); kref_init(fbo-kref); fbo-destroy = ttm_transfered_destroy; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 4c10be3..da94071 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -48,7 +48,6 @@ struct drm_mm_node { unsigned long start; unsigned long size; struct drm_mm *mm; - void *private; }; struct drm_mm { -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/9] drm: kill dead code in drm_mm.c
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- 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 6/9] drm_mm: extract check_free_mm_node
There are already two copies of this logic. And the new scanning stuff will add some more. So extract it into a small helper function. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/drm_mm.c | 71 ++ 1 files changed, 34 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index d2267ff..fd86a6c 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -283,6 +283,27 @@ void drm_mm_put_block(struct drm_mm_node *cur) EXPORT_SYMBOL(drm_mm_put_block); +static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, + unsigned alignment) +{ + unsigned wasted = 0; + + if (entry-size size) + return 0; + + if (alignment) { + register unsigned tmp = entry-start % alignment; + if (tmp) + wasted = alignment - tmp; + } + + if (entry-size = size + wasted) { + return 1; + } + + return 0; +} + struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) @@ -290,30 +311,20 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; list_for_each_entry(entry, mm-free_stack, free_stack) { - wasted = 0; - - if (entry-size size) + if (!check_free_mm_node(entry, size, alignment)) continue; - if (alignment) { - register unsigned tmp = entry-start % alignment; - if (tmp) - wasted += alignment - tmp; - } + if (!best_match) + return entry; - if (entry-size = size + wasted) { - if (!best_match) - return entry; - if (entry-size best_size) { - best = entry; - best_size = entry-size; - } + if (entry-size best_size) { + best = entry; + best_size = entry-size; } } @@ -331,37 +342,23 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; list_for_each_entry(entry, mm-free_stack, free_stack) { - wasted = 0; - - if (entry-size size) + if (entry-start end || (entry-start+entry-size) start) continue; - if (entry-start end || (entry-start+entry-size) start) + if (!check_free_mm_node(entry, size, alignment)) continue; - if (entry-start start) - wasted += start - entry-start; + if (!best_match) + return entry; - if (alignment) { - register unsigned tmp = (entry-start + wasted) % alignment; - if (tmp) - wasted += alignment - tmp; - } - - if (entry-size = size + wasted - (entry-start + wasted + size) = end) { - if (!best_match) - return entry; - if (entry-size best_size) { - best = entry; - best_size = entry-size; - } + if (entry-size best_size) { + best = entry; + best_size = entry-size; } } -- 1.7.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 5/9] drm: sane naming for drm_mm.c
Yeah, I've kinda noticed that fl_entry is the free stack. Still give it (and the memory node list ml_entry) decent names. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/drm_mm.c | 72 ++--- include/drm/drm_mm.h | 11 -- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a5a7a16..d2267ff 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -64,8 +64,8 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) else { child = list_entry(mm-unused_nodes.next, - struct drm_mm_node, fl_entry); - list_del(child-fl_entry); + struct drm_mm_node, free_stack); + list_del(child-free_stack); --mm-num_unused; } spin_unlock(mm-unused_lock); @@ -94,7 +94,7 @@ int drm_mm_pre_get(struct drm_mm *mm) return ret; } ++mm-num_unused; - list_add_tail(node-fl_entry, mm-unused_nodes); + list_add_tail(node-free_stack, mm-unused_nodes); } spin_unlock(mm-unused_lock); return 0; @@ -116,8 +116,8 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, child-start = start; child-mm = mm; - list_add_tail(child-ml_entry, mm-ml_entry); - list_add_tail(child-fl_entry, mm-fl_entry); + list_add_tail(child-node_list, mm-node_list); + list_add_tail(child-free_stack, mm-free_stack); return 0; } @@ -132,15 +132,15 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, if (unlikely(child == NULL)) return NULL; - INIT_LIST_HEAD(child-fl_entry); + INIT_LIST_HEAD(child-free_stack); child-free = 0; child-size = size; child-start = parent-start; child-mm = parent-mm; - list_add_tail(child-ml_entry, parent-ml_entry); - INIT_LIST_HEAD(child-fl_entry); + list_add_tail(child-node_list, parent-node_list); + INIT_LIST_HEAD(child-free_stack); parent-size -= size; parent-start += size; @@ -168,7 +168,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, } if (node-size == size) { - list_del_init(node-fl_entry); + list_del_init(node-free_stack); node-free = 0; } else { node = drm_mm_split_at_start(node, size, atomic); @@ -206,7 +206,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node, } if (node-size == size) { - list_del_init(node-fl_entry); + list_del_init(node-free_stack); node-free = 0; } else { node = drm_mm_split_at_start(node, size, atomic); @@ -228,8 +228,8 @@ void drm_mm_put_block(struct drm_mm_node *cur) { struct drm_mm *mm = cur-mm; - struct list_head *cur_head = cur-ml_entry; - struct list_head *root_head = mm-ml_entry; + struct list_head *cur_head = cur-node_list; + struct list_head *root_head = mm-node_list; struct drm_mm_node *prev_node = NULL; struct drm_mm_node *next_node; @@ -237,7 +237,7 @@ void drm_mm_put_block(struct drm_mm_node *cur) if (cur_head-prev != root_head) { prev_node = - list_entry(cur_head-prev, struct drm_mm_node, ml_entry); + list_entry(cur_head-prev, struct drm_mm_node, node_list); if (prev_node-free) { prev_node-size += cur-size; merged = 1; @@ -245,15 +245,15 @@ void drm_mm_put_block(struct drm_mm_node *cur) } if (cur_head-next != root_head) { next_node = - list_entry(cur_head-next, struct drm_mm_node, ml_entry); + list_entry(cur_head-next, struct drm_mm_node, node_list); if (next_node-free) { if (merged) { prev_node-size += next_node-size; - list_del(next_node-ml_entry); - list_del(next_node-fl_entry); + list_del(next_node-node_list); + list_del(next_node-free_stack); spin_lock(mm-unused_lock); if (mm-num_unused MM_UNUSED_TARGET) { - list_add(next_node-fl_entry, + list_add(next_node-free_stack, mm-unused_nodes);
[Intel-gfx] [PATCH 8/9] drm/i915: prepare for fair lru eviction
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 | 65 +++--- 1 files changed, 39 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 952b4b3..d5a7db7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -50,7 +50,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, @@ -333,7 +334,7 @@ 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, 0); if (ret) return ret; @@ -2114,10 +2115,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; @@ -2131,14 +2134,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 @@ -2203,11 +2223,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; for (;;) { i915_gem_retire_requests(dev); @@ -2215,20 +2235,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); -#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); - } + ret = i915_gem_scan_inactive_list_and_evict(dev, min_size, + alignment, + found); + if (found) +
[Intel-gfx] [PATCH 7/9] drm: implement helper functions for scanning lru list
These helper functions can be used to efficiently scan lru list for eviction. Eviction becomes a three stage process: 1. Scanning through the lru list until a suitable hole has been found. 2. Scan backwards to restore drm_mm consistency and find out which objects fall into the hole. 3. Evict the objects that fall into the hole. These helper functions don't allocate any memory (at the price of not allowing any other concurrent operations). Hence this can also be used for ttm (which does lru scanning under a spinlock). Evicting objects in this fashion should be more fair than the current approach by i915 (scan the lru for a object large enough to contain the new object). It's also more efficient than the current approach used by ttm (uncoditionally evict objects from the lru until there's enough free space). Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/drm_mm.c | 167 - include/drm/drm_mm.h | 15 - 2 files changed, 177 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index fd86a6c..da99edc 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -53,9 +53,9 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) struct drm_mm_node *child; if (atomic) - child = kmalloc(sizeof(*child), GFP_ATOMIC); + child = kzalloc(sizeof(*child), GFP_ATOMIC); else - child = kmalloc(sizeof(*child), GFP_KERNEL); + child = kzalloc(sizeof(*child), GFP_KERNEL); if (unlikely(child == NULL)) { spin_lock(mm-unused_lock); @@ -85,7 +85,7 @@ int drm_mm_pre_get(struct drm_mm *mm) spin_lock(mm-unused_lock); while (mm-num_unused MM_UNUSED_TARGET) { spin_unlock(mm-unused_lock); - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc(sizeof(*node), GFP_KERNEL); spin_lock(mm-unused_lock); if (unlikely(node == NULL)) { @@ -134,7 +134,6 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, INIT_LIST_HEAD(child-free_stack); - child-free = 0; child-size = size; child-start = parent-start; child-mm = parent-mm; @@ -235,6 +234,9 @@ void drm_mm_put_block(struct drm_mm_node *cur) int merged = 0; + BUG_ON(cur-scanned_block || cur-scanned_prev_free + || cur-scanned_next_free); + if (cur_head-prev != root_head) { prev_node = list_entry(cur_head-prev, struct drm_mm_node, node_list); @@ -312,6 +314,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, struct drm_mm_node *best; unsigned long best_size; + BUG_ON(mm-scanned_blocks); + best = NULL; best_size = ~0UL; @@ -343,6 +347,8 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, struct drm_mm_node *best; unsigned long best_size; + BUG_ON(mm-scanned_blocks); + best = NULL; best_size = ~0UL; @@ -366,6 +372,158 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, } EXPORT_SYMBOL(drm_mm_search_free_in_range); +/** + * Initializa lru scanning. + * + * This simply sets up the scanning routines with the parameters for the desired + * hole. + * + * Warning: As long as the scan list is non-empty, no other operations than + * adding/removing nodes to/from the scan list are allowed. + */ +void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, + unsigned alignment) +{ + mm-scan_alignment = alignment; + mm-scan_size = size; + mm-scanned_blocks = 0; + mm-scan_hit_start = 0; + mm-scan_hit_size = 0; +} +EXPORT_SYMBOL(drm_mm_init_scan); + +/** + * Add a node to the scan list that might be freed to make space for the desired + * hole. + * + * Returns non-zero, if a hole has been found, zero otherwise. + */ +int drm_mm_scan_add_block(struct drm_mm_node *node) +{ + struct drm_mm *mm = node-mm; + struct list_head *prev_free, *next_free; + struct drm_mm_node *prev_node, *next_node; + + mm-scanned_blocks++; + + prev_free = next_free = NULL; + + BUG_ON(node-free); + node-scanned_block = 1; + node-free = 1; + + if (node-node_list.prev != mm-node_list) { + prev_node = list_entry(node-node_list.prev, struct drm_mm_node, + node_list); + + if (prev_node-free) { + list_del(prev_node-node_list); + + node-start = prev_node-start; + node-size += prev_node-size; + + prev_node-scanned_prev_free = 1; + + prev_free = prev_node-free_stack; + } + } + +
Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset
From: Clemens Eisserer linuxhippy at gmail.com Subject: Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset. To: intel-gfx intel-gfx at lists.freedesktop.org Date: Saturday, May 15, 2010, 12:56 PM Hi, Why don't you record a video or take a screenshot to make at least clear to us whats going on? - Clemens I do not blame anyone, I know you all want to help. I tried to take a picture and take a video, but unfortunately 30 frame per second can't catch it. Everything looks nice. I will try to explain again. In compare with kernel up to 2.6.27 (because I used Ubuntu, Mandriva), 2.6.33 looks:more brighter, may be more contrast, especially white, it is definitely more brighter although I stated xgamma 0.75. But biggest problem is that colors of the picture are not solid, stable - they are somehow blinking or flickering. Sometime I think may be back lights of LCD panel works different. And after hour or two eyes start notice it, it is looks like colors is not constant, they always changes, little bit but they are playing. It is very noticeable if I log into different TTY (not graphical) and just start mc - it present for eyes. It is impossible to record, sorry. Thanks for help. I have tried OpenSuse 11.2, which is with newer kernel and it shows the same bad like Fedora 12. So I decided to shift on fedora, but unfortunately although Fedora 13 shows screen better - it is still not usable (actually screen picture on Fedora 12 was really awful). I have tried to compare video output on OpenSuse 11.1 and Fedora 13, all of the has the same, except of xdpyinfo: on suse it tells about 3 visuals ( number of visuals:3), but on Fedora 13 - 32 visuals. Fedora 12 got 72. Problems is not with fonts at all, problem with whole screen. Font, because it very contrast, is more noticeable. Also, of course I use freetype for the full hinting. Does it happened to all intel chipset, or to only i915GM, because I of course going to change my laptop, and it looks like I am not going to by a one with intel video. Thanks. Dear All. At last, I found the problem - it is new kernel 33 and 34, I took them from Fedora. I put them to my OpenSuse 11.1 (27 kernel) and boot it up. Picture of the screen became unusable. And it is not Xorg with its drivers, because except of the kernel everything from OpenSuse 11.1 - it is kernel. I do not know how it works with other GPU (intel or nvidia), but mine i915GM shows awful screen. I know what is wrong with picture - colors of the pixels. They are not static, they change. Little bit, but change. It became more noticeable when I just reboot. For example white - it is white, but it changes around white, and as color is brighter it is more annoying. May be I am wrong about all of it, I for sure - I am not going to use 33 and 34 kernel with i915GM. Thanks everyone. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] looking for cOherEnCY
Folks, I understand that the normal method of debugging the GEM driver code is by use of various debug functions conditionally included if/when various WATCH manifests are defined. So I set WATCH_COHERENCY for a port I am doing and that meant that i915_gem_object_check_coherency() got called...but that function gagged on me on an object...and after some looking, it appeared that I was checking the coherency of the frame buffer object. That doesn't appear to be a good idea as fence registers are set up to diddle the tiling setup for the frame buffer. And the kind of coherency check performed by i915_gem_object_check_coherency() is bound to fail for objects which have used the fence registers to set up tiling. The question is: is use of i915_gem_object_check_coherency() a bit too aggressive in the driver code? It seems to me we ask it to check coherency of areas of memory that are not coherent in the manner effectively defined by the tests in i915_gem_object_check_coherency() (for those who don't know, coherence as defined by this function is that a 32-bit read at offset c in CPU VM space (ie. Only through the CPU's MMU and NOT through BAR2) of an object results in the same value as a 32-bit read at the same offset when read through BAR2 of the graphics device...for each page whose coherence is tested, the first quarter of the page is read and compared through both the CPU's MMU and through BAR2). Or am I just plain Missing Something? Thanks. bob ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset
SD wrote on Wednesday, May 19, 2010 8:32 AM: From: Clemens Eisserer linuxhippy at gmail.com Subject: Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset. To: intel-gfx intel-gfx at lists.freedesktop.org Date: Saturday, May 15, 2010, 12:56 PM Hi, Why don't you record a video or take a screenshot to make at least clear to us whats going on? - Clemens I do not blame anyone, I know you all want to help. I tried to take a picture and take a video, but unfortunately 30 frame per second can't catch it. Everything looks nice. I will try to explain again. In compare with kernel up to 2.6.27 (because I used Ubuntu, Mandriva), 2.6.33 looks:more brighter, may be more contrast, especially white, it is definitely more brighter although I stated xgamma 0.75. But biggest problem is that colors of the picture are not solid, stable - they are somehow blinking or flickering. Sometime I think may be back lights of LCD panel works different. And after hour or two eyes start notice it, it is looks like colors is not constant, they always changes, little bit but they are playing. It is very noticeable if I log into different TTY (not graphical) and just start mc - it present for eyes. It is impossible to record, sorry. Thanks for help. I have tried OpenSuse 11.2, which is with newer kernel and it shows the same bad like Fedora 12. So I decided to shift on fedora, but unfortunately although Fedora 13 shows screen better - it is still not usable (actually screen picture on Fedora 12 was really awful). I have tried to compare video output on OpenSuse 11.1 and Fedora 13, all of the has the same, except of xdpyinfo: on suse it tells about 3 visuals ( number of visuals:3), but on Fedora 13 - 32 visuals. Fedora 12 got 72. Problems is not with fonts at all, problem with whole screen. Font, because it very contrast, is more noticeable. Also, of course I use freetype for the full hinting. Does it happened to all intel chipset, or to only i915GM, because I of course going to change my laptop, and it looks like I am not going to by a one with intel video. Thanks. Dear All. At last, I found the problem - it is new kernel 33 and 34, I took them from Fedora. I put them to my OpenSuse 11.1 (27 kernel) and boot it up. Picture of the screen became unusable. And it is not Xorg with its drivers, because except of the kernel everything from OpenSuse 11.1 - it is kernel. I do not know how it works with other GPU (intel or nvidia), but mine i915GM shows awful screen. I know what is wrong with picture - colors of the pixels. They are not static, they change. Little bit, but change. It became more noticeable when I just reboot. For example white - it is white, but it changes around white, and as color is brighter it is more annoying. Flickering? Does booting kernel with i915.powersave=0 work? May be I am wrong about all of it, I for sure - I am not going to use 33 and 34 kernel with i915GM. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 0/9] [RFC] fair-lru eviction
On Tue, 18 May 2010 23:11:42 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: Hi all, This patch series implements the fair-lru eviction Chris Wilson already posted with a twist. It's essentially the same idea algorithm. Differnences versus his patch: - Doesn't do any allocations while scanning. - Implemented in drm_mm.c In other words, this should also be usable by ttm. The idea is simple: Scan through the lru, marking objects as evictable until there is a large area of memory free/free-able. Then walk through all the scanned objects in reverse, checking which ones fall into this hole. Finally evicting them. Comments, ideas highly welcome. As per usual, I couldn't resist and had to clean up the code in drm_mm.c a little. Do you have performance numbers on these patches? pgpGZBf5fIs8Q.pgp Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset
--- On Wed, 5/19/10, Jin, Gordon gordon@intel.com wrote: From: Jin, Gordon gordon@intel.com Subject: RE: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset To: SD sd.dom...@yahoo.com, intel-gfx@lists.freedesktop.org intel-gfx@lists.freedesktop.org Date: Wednesday, May 19, 2010, 6:03 AM SD wrote on Wednesday, May 19, 2010 8:32 AM: From: Clemens Eisserer linuxhippy at gmail.com Subject: Re: [Intel-gfx] Picture quality on laptop LCD with i915GM chipset. To: intel-gfx intel-gfx at lists.freedesktop.org Date: Saturday, May 15, 2010, 12:56 PM Hi, Why don't you record a video or take a screenshot to make at least clear to us whats going on? - Clemens I do not blame anyone, I know you all want to help. I tried to take a picture and take a video, but unfortunately 30 frame per second can't catch it. Everything looks nice. I will try to explain again. In compare with kernel up to 2.6.27 (because I used Ubuntu, Mandriva), 2.6.33 looks:more brighter, may be more contrast, especially white, it is definitely more brighter although I stated xgamma 0.75. But biggest problem is that colors of the picture are not solid, stable - they are somehow blinking or flickering. Sometime I think may be back lights of LCD panel works different. And after hour or two eyes start notice it, it is looks like colors is not constant, they always changes, little bit but they are playing. It is very noticeable if I log into different TTY (not graphical) and just start mc - it present for eyes. It is impossible to record, sorry. Thanks for help. I have tried OpenSuse 11.2, which is with newer kernel and it shows the same bad like Fedora 12. So I decided to shift on fedora, but unfortunately although Fedora 13 shows screen better - it is still not usable (actually screen picture on Fedora 12 was really awful). I have tried to compare video output on OpenSuse 11.1 and Fedora 13, all of the has the same, except of xdpyinfo: on suse it tells about 3 visuals ( number of visuals: 3), but on Fedora 13 - 32 visuals. Fedora 12 got 72. Problems is not with fonts at all, problem with whole screen. Font, because it very contrast, is more noticeable. Also, of course I use freetype for the full hinting. Does it happened to all intel chipset, or to only i915GM, because I of course going to change my laptop, and it looks like I am not going to by a one with intel video. Thanks. Dear All. At last, I found the problem - it is new kernel 33 and 34, I took them from Fedora. I put them to my OpenSuse 11.1 (27 kernel) and boot it up. Picture of the screen became unusable. And it is not Xorg with its drivers, because except of the kernel everything from OpenSuse 11.1 - it is kernel. I do not know how it works with other GPU (intel or nvidia), but mine i915GM shows awful screen. I know what is wrong with picture - colors of the pixels. They are not static, they change. Little bit, but change. It became more noticeable when I just reboot. For example white - it is white, but it changes around white, and as color is brighter it is more annoying. Flickering? Does booting kernel with i915.powersave=0 work? May be I am wrong about all of it, I for sure - I am not going to use 33 and 34 kernel with i915GM. Just checked on Fedora Rawhide 34 kernel. Booted with i915.powersave=0 - there is no difference. I would say that pixel changes brightness. For example, I found a 1 pixel line on fxce panel - white line surrounding by gray aria. And it is possible to notice that pixels on gray line next to white is not constantly gray, they are flickering or changing brightness. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx