[PATCH] drm/amdgpu: Fix blocking in RCU critical section(v2)
In RCU read-side critical sections, blocking or sleeping is prohibited. v2: Unlock RCU for the code path where result==NULL. (David Zhou) Update subject Tested-by and reported by: Dave Airlie <airl...@redhat.com> [ 141.965723] = [ 141.965724] WARNING: suspicious RCU usage [ 141.965726] 4.12.0-rc7 #221 Not tainted [ 141.965727] - [ 141.965728] /home/airlied/devel/kernel/linux-2.6/include/linux/rcupdate.h:531 Illegal context switch in RCU read-side critical section! [ 141.965730] other info that might help us debug this: [ 141.965731] rcu_scheduler_active = 2, debug_locks = 0 [ 141.965732] 1 lock held by amdgpu_cs:0/1332: [ 141.965733] #0: (rcu_read_lock){..}, at: [] amdgpu_bo_list_get+0x0/0x109 [amdgpu] [ 141.965774] stack backtrace: [ 141.965776] CPU: 6 PID: 1332 Comm: amdgpu_cs:0 Not tainted 4.12.0-rc7 #221 [ 141.965777] Hardware name: To be filled by O.E.M. To be filled by O.E.M./M5A97 R2.0, BIOS 2603 06/26/2015 [ 141.965778] Call Trace: [ 141.965782] dump_stack+0x68/0x92 [ 141.965785] lockdep_rcu_suspicious+0xf7/0x100 [ 141.965788] ___might_sleep+0x56/0x1fc [ 141.965790] __might_sleep+0x68/0x6f [ 141.965793] __mutex_lock+0x4e/0x7b5 [ 141.965817] ? amdgpu_bo_list_get+0xa4/0x109 [amdgpu] [ 141.965820] ? lock_acquire+0x125/0x1b9 [ 141.965844] ? amdgpu_bo_list_set+0x464/0x464 [amdgpu] [ 141.965846] mutex_lock_nested+0x16/0x18 [ 141.965848] ? mutex_lock_nested+0x16/0x18 [ 141.965872] amdgpu_bo_list_get+0xa4/0x109 [amdgpu] [ 141.965895] amdgpu_cs_ioctl+0x4a0/0x17dd [amdgpu] [ 141.965898] ? radix_tree_node_alloc.constprop.11+0x77/0xab [ 141.965916] drm_ioctl+0x264/0x393 [drm] [ 141.965939] ? amdgpu_cs_find_mapping+0x83/0x83 [amdgpu] [ 141.965942] ? trace_hardirqs_on_caller+0x16a/0x186 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index dc87962..e5d61fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -198,12 +198,18 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) result = idr_find(>bo_list_handles, id); if (result) { - if (kref_get_unless_zero(>refcount)) + if (kref_get_unless_zero(>refcount)) { + rcu_read_unlock(); mutex_lock(>lock); - else + } + else { + rcu_read_unlock(); result = NULL; + } + } + else { + rcu_read_unlock(); } - rcu_read_unlock(); return result; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Free resources of bo_list when idr_alloc fails
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index efa6903..dc87962 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -83,7 +83,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev, r = idr_alloc(>bo_list_handles, list, 1, 0, GFP_KERNEL); mutex_unlock(>bo_list_lock); if (r < 0) { - kfree(list); + amdgpu_bo_list_free(list); return r; } *id = r; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: optimize out a spin lock (v2)
Use atomic instead of spin lock. v2: Adjust commit message Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 110 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 - 3 files changed, 76 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 7caf514..21d318b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1588,9 +1588,8 @@ struct amdgpu_device { /* data for buffer migration throttling */ struct { - spinlock_t lock; - s64 last_update_us; - s64 accum_us; /* accumulated microseconds */ + atomic64_t last_update_us; + atomic64_t accum_us; /* accumulated microseconds */ u32 log2_max_MBps; } mm_stats; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 82131d7..7b6f42e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -225,6 +225,9 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) s64 time_us, increment_us; u64 max_bytes; u64 free_vram, total_vram, used_vram; + s64 old_update_us, head_time_us; + s64 accum_us; + s64 old_accum_us, head_accum_us; /* Allow a maximum of 200 accumulated ms. This is basically per-IB * throttling. @@ -242,47 +245,83 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) used_vram = atomic64_read(>vram_usage); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; - spin_lock(>mm_stats.lock); - /* Increase the amount of accumulated us. */ - time_us = ktime_to_us(ktime_get()); - increment_us = time_us - adev->mm_stats.last_update_us; - adev->mm_stats.last_update_us = time_us; - adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us, - us_upper_bound); - - /* This prevents the short period of low performance when the VRAM -* usage is low and the driver is in debt or doesn't have enough -* accumulated us to fill VRAM quickly. -* -* The situation can occur in these cases: -* - a lot of VRAM is freed by userspace -* - the presence of a big buffer causes a lot of evictions -* (solution: split buffers into smaller ones) -* -* If 128 MB or 1/8th of VRAM is free, start filling it now by setting -* accum_us to a positive number. -*/ - if (free_vram >= 128 * 1024 * 1024 || free_vram >= total_vram / 8) { - s64 min_us; - - /* Be more aggresive on dGPUs. Try to fill a portion of free -* VRAM now. -*/ - if (!(adev->flags & AMD_IS_APU)) - min_us = bytes_to_us(adev, free_vram / 4); + old_update_us = atomic64_read(>mm_stats.last_update_us); + for (;;) { + time_us = ktime_to_us(ktime_get()); + head_time_us = atomic64_cmpxchg(>mm_stats.last_update_us, + old_update_us, time_us); + + if (likely(head_time_us == old_update_us)) + /* +* No other task modified adev->mm_stats.last_update_us. +* Update was successful. +*/ + break; else - min_us = 0; /* Reset accum_us on APUs. */ + /* Another task modified the value after we read it. +* A rare contention happens, let us retry. +* In most case, one retry can do the job. +* See function atomic64_add_unless as a similar idea. +*/ + old_update_us = head_time_us; + } + increment_us = time_us - old_update_us; + + old_accum_us = atomic64_read(>mm_stats.accum_us); + + for (;;) { + accum_us = min(old_accum_us + increment_us, us_upper_bound); + + /* This prevents the short period of low performance when the +* VRAM usage is low and the driver is in debt or doesn't have +* enough accumulated us to fill VRAM quickly. +* +* The situation can occur in these cases: +* - a lot of VRAM is freed by userspace +* - the presence of a big buffer causes a lot of evictions +* (solution: split buffers into smaller ones) +
[PATCH 2/3] drm/amdgpu: change a function to static function
The function is called only once inside the .c file. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6b7d2a1..7caf514 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1929,7 +1929,6 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev); bool amdgpu_need_post(struct amdgpu_device *adev); void amdgpu_update_display_priority(struct amdgpu_device *adev); -int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data); void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes); void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain); bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 94c27fc..82131d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -63,7 +63,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, return 0; } -int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) +static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = >vm; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/3] drm/amdgpu: optimize out a spin lock Use atomic instead of spin lock.
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 110 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 - 3 files changed, 76 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 7caf514..21d318b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1588,9 +1588,8 @@ struct amdgpu_device { /* data for buffer migration throttling */ struct { - spinlock_t lock; - s64 last_update_us; - s64 accum_us; /* accumulated microseconds */ + atomic64_t last_update_us; + atomic64_t accum_us; /* accumulated microseconds */ u32 log2_max_MBps; } mm_stats; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 82131d7..7b6f42e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -225,6 +225,9 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) s64 time_us, increment_us; u64 max_bytes; u64 free_vram, total_vram, used_vram; + s64 old_update_us, head_time_us; + s64 accum_us; + s64 old_accum_us, head_accum_us; /* Allow a maximum of 200 accumulated ms. This is basically per-IB * throttling. @@ -242,47 +245,83 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) used_vram = atomic64_read(>vram_usage); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; - spin_lock(>mm_stats.lock); - /* Increase the amount of accumulated us. */ - time_us = ktime_to_us(ktime_get()); - increment_us = time_us - adev->mm_stats.last_update_us; - adev->mm_stats.last_update_us = time_us; - adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us, - us_upper_bound); - - /* This prevents the short period of low performance when the VRAM -* usage is low and the driver is in debt or doesn't have enough -* accumulated us to fill VRAM quickly. -* -* The situation can occur in these cases: -* - a lot of VRAM is freed by userspace -* - the presence of a big buffer causes a lot of evictions -* (solution: split buffers into smaller ones) -* -* If 128 MB or 1/8th of VRAM is free, start filling it now by setting -* accum_us to a positive number. -*/ - if (free_vram >= 128 * 1024 * 1024 || free_vram >= total_vram / 8) { - s64 min_us; - - /* Be more aggresive on dGPUs. Try to fill a portion of free -* VRAM now. -*/ - if (!(adev->flags & AMD_IS_APU)) - min_us = bytes_to_us(adev, free_vram / 4); + old_update_us = atomic64_read(>mm_stats.last_update_us); + for (;;) { + time_us = ktime_to_us(ktime_get()); + head_time_us = atomic64_cmpxchg(>mm_stats.last_update_us, + old_update_us, time_us); + + if (likely(head_time_us == old_update_us)) + /* +* No other task modified adev->mm_stats.last_update_us. +* Update was successful. +*/ + break; else - min_us = 0; /* Reset accum_us on APUs. */ + /* Another task modified the value after we read it. +* A rare contention happens, let us retry. +* In most case, one retry can do the job. +* See function atomic64_add_unless as a similar idea. +*/ + old_update_us = head_time_us; + } + increment_us = time_us - old_update_us; + + old_accum_us = atomic64_read(>mm_stats.accum_us); + + for (;;) { + accum_us = min(old_accum_us + increment_us, us_upper_bound); + + /* This prevents the short period of low performance when the +* VRAM usage is low and the driver is in debt or doesn't have +* enough accumulated us to fill VRAM quickly. +* +* The situation can occur in these cases: +* - a lot of VRAM is freed by userspace +* - the presence of a big buffer causes a lot of evictions +* (solution: split buffers into smaller ones) +* +* If 1
[PATCH 1/3] drm/amdgpu: fix a typo
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 7635f38..94c27fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -494,7 +494,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, >user_invalidated) && e->user_pages) { /* We acquired a page array, but somebody -* invalidated it. Free it an try again +* invalidated it. Free it and try again */ release_pages(e->user_pages, e->robj->tbo.ttm->num_pages, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Optimize mutex usage (v3)
In original function amdgpu_bo_list_get, the waiting for result->lock can be quite long while mutex bo_list_lock was holding. It can make other tasks waiting for bo_list_lock for long period. Secondly, this patch allows several tasks(readers of idr) to proceed at the same time. v2: use rcu and kref (Dave Airlie and Christian König) v3: update v1 commit message (Michel Dänzer) Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 40 - 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 063fc73..e9b3981 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -871,6 +871,8 @@ struct amdgpu_fpriv { struct amdgpu_bo_list { struct mutex lock; + struct rcu_head rhead; + struct kref refcount; struct amdgpu_bo *gds_obj; struct amdgpu_bo *gws_obj; struct amdgpu_bo *oa_obj; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 5af956f..efa6903 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -41,6 +41,20 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, struct drm_amdgpu_bo_list_entry *info, unsigned num_entries); +static void amdgpu_bo_list_release_rcu(struct kref *ref) +{ + unsigned i; + struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list, + refcount); + + for (i = 0; i < list->num_entries; ++i) + amdgpu_bo_unref(>array[i].robj); + + mutex_destroy(>lock); + drm_free_large(list->array); + kfree_rcu(list, rhead); +} + static int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, @@ -57,7 +71,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev, /* initialize bo list*/ mutex_init(>lock); - + kref_init(>refcount); r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); if (r) { kfree(list); @@ -83,14 +97,9 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) mutex_lock(>bo_list_lock); list = idr_remove(>bo_list_handles, id); - if (list) { - /* Another user may have a reference to this list still */ - mutex_lock(>lock); - mutex_unlock(>lock); - amdgpu_bo_list_free(list); - } - mutex_unlock(>bo_list_lock); + if (list) + kref_put(>refcount, amdgpu_bo_list_release_rcu); } static int amdgpu_bo_list_set(struct amdgpu_device *adev, @@ -185,11 +194,17 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) { struct amdgpu_bo_list *result; - mutex_lock(>bo_list_lock); + rcu_read_lock(); result = idr_find(>bo_list_handles, id); - if (result) - mutex_lock(>lock); - mutex_unlock(>bo_list_lock); + + if (result) { + if (kref_get_unless_zero(>refcount)) + mutex_lock(>lock); + else + result = NULL; + } + rcu_read_unlock(); + return result; } @@ -227,6 +242,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, void amdgpu_bo_list_put(struct amdgpu_bo_list *list) { mutex_unlock(>lock); + kref_put(>refcount, amdgpu_bo_list_release_rcu); } void amdgpu_bo_list_free(struct amdgpu_bo_list *list) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/amdgpu: Optimization of AMDGPU_BO_LIST_OP_CREATE (v2)
v2: Remove duplication of zeroing of bo list (Christian König) Move idr_alloc function to end of ioctl (Christian König) Call kfree bo_list when amdgpu_bo_list_set return error. Combine the previous two patches into this patch. Add amdgpu_bo_list_set function prototype. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 53 - 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index a664987..5af956f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -35,33 +35,45 @@ #define AMDGPU_BO_LIST_MAX_PRIORITY32u #define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) -static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, -struct amdgpu_bo_list **result, +static int amdgpu_bo_list_set(struct amdgpu_device *adev, +struct drm_file *filp, +struct amdgpu_bo_list *list, +struct drm_amdgpu_bo_list_entry *info, +unsigned num_entries); + +static int amdgpu_bo_list_create(struct amdgpu_device *adev, +struct drm_file *filp, +struct drm_amdgpu_bo_list_entry *info, +unsigned num_entries, int *id) { int r; + struct amdgpu_fpriv *fpriv = filp->driver_priv; + struct amdgpu_bo_list *list; - *result = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); - if (!*result) + list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); + if (!list) return -ENOMEM; + /* initialize bo list*/ + mutex_init(>lock); + + r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); + if (r) { + kfree(list); + return r; + } + + /* idr alloc should be called only after initialization of bo list. */ mutex_lock(>bo_list_lock); - r = idr_alloc(>bo_list_handles, *result, - 1, 0, GFP_KERNEL); + r = idr_alloc(>bo_list_handles, list, 1, 0, GFP_KERNEL); + mutex_unlock(>bo_list_lock); if (r < 0) { - mutex_unlock(>bo_list_lock); - kfree(*result); + kfree(list); return r; } *id = r; - mutex_init(&(*result)->lock); - (*result)->num_entries = 0; - (*result)->array = NULL; - - mutex_lock(&(*result)->lock); - mutex_unlock(>bo_list_lock); - return 0; } @@ -77,6 +89,7 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) mutex_unlock(>lock); amdgpu_bo_list_free(list); } + mutex_unlock(>bo_list_lock); } @@ -273,16 +286,10 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, switch (args->in.operation) { case AMDGPU_BO_LIST_OP_CREATE: - r = amdgpu_bo_list_create(fpriv, , ); + r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number, + ); if (r) goto error_free; - - r = amdgpu_bo_list_set(adev, filp, list, info, - args->in.bo_number); - amdgpu_bo_list_put(list); - if (r) - goto error_free; - break; case AMDGPU_BO_LIST_OP_DESTROY: -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu: Optimize mutex usage (v2)
Use rw_semaphore instead of mutex for bo_lists. In original function amdgpu_bo_list_get, the waiting for result->lock can be quite long while mutex bo_list_lock was holding. It can make other tasks waiting for bo_list_lock for long period too. Change bo_list_lock to rw_semaphore can avoid most of such long waiting. Secondly, this patch allows several tasks(readers of idr) to proceed at the same time. v2: use rcu and kref (Dave Airlie and Christian König) Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 40 - 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 063fc73..e9b3981 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -871,6 +871,8 @@ struct amdgpu_fpriv { struct amdgpu_bo_list { struct mutex lock; + struct rcu_head rhead; + struct kref refcount; struct amdgpu_bo *gds_obj; struct amdgpu_bo *gws_obj; struct amdgpu_bo *oa_obj; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 5af956f..efa6903 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -41,6 +41,20 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, struct drm_amdgpu_bo_list_entry *info, unsigned num_entries); +static void amdgpu_bo_list_release_rcu(struct kref *ref) +{ + unsigned i; + struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list, + refcount); + + for (i = 0; i < list->num_entries; ++i) + amdgpu_bo_unref(>array[i].robj); + + mutex_destroy(>lock); + drm_free_large(list->array); + kfree_rcu(list, rhead); +} + static int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, @@ -57,7 +71,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev, /* initialize bo list*/ mutex_init(>lock); - + kref_init(>refcount); r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); if (r) { kfree(list); @@ -83,14 +97,9 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) mutex_lock(>bo_list_lock); list = idr_remove(>bo_list_handles, id); - if (list) { - /* Another user may have a reference to this list still */ - mutex_lock(>lock); - mutex_unlock(>lock); - amdgpu_bo_list_free(list); - } - mutex_unlock(>bo_list_lock); + if (list) + kref_put(>refcount, amdgpu_bo_list_release_rcu); } static int amdgpu_bo_list_set(struct amdgpu_device *adev, @@ -185,11 +194,17 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) { struct amdgpu_bo_list *result; - mutex_lock(>bo_list_lock); + rcu_read_lock(); result = idr_find(>bo_list_handles, id); - if (result) - mutex_lock(>lock); - mutex_unlock(>bo_list_lock); + + if (result) { + if (kref_get_unless_zero(>refcount)) + mutex_lock(>lock); + else + result = NULL; + } + rcu_read_unlock(); + return result; } @@ -227,6 +242,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, void amdgpu_bo_list_put(struct amdgpu_bo_list *list) { mutex_unlock(>lock); + kref_put(>refcount, amdgpu_bo_list_release_rcu); } void amdgpu_bo_list_free(struct amdgpu_bo_list *list) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 4/4] drm/amdgpu: Optimize mutex usage
Use rw_semaphore instead of mutex for bo_lists. In original function amdgpu_bo_list_get, the waiting for result->lock can be quite long while mutex bo_list_lock was holding. It can make other tasks waiting for bo_list_lock for long period too. Change bo_list_lock to rw_semaphore can avoid most of such long waiting. Secondly, this patch allows several tasks(readers of idr) to proceed at the same time. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 14 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 3 +-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 063fc73..bfc40d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -859,7 +860,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); struct amdgpu_fpriv { struct amdgpu_vmvm; struct amdgpu_bo_va *prt_va; - struct mutexbo_list_lock; + struct rw_semaphore bo_list_lock; struct idr bo_list_handles; struct amdgpu_ctx_mgr ctx_mgr; u32 vram_lost_counter; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 4363f28..bfe736e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -45,10 +45,10 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, if (!*result) return -ENOMEM; - mutex_lock(>bo_list_lock); + down_read(>bo_list_lock); r = idr_alloc(>bo_list_handles, *result, 1, 0, GFP_KERNEL); - mutex_unlock(>bo_list_lock); + up_read(>bo_list_lock); if (r < 0) { kfree(*result); @@ -67,17 +67,17 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) { struct amdgpu_bo_list *list; - mutex_lock(>bo_list_lock); + down_write(>bo_list_lock); list = idr_remove(>bo_list_handles, id); if (list) { /* Another user may have a reference to this list still */ mutex_lock(>lock); mutex_unlock(>lock); - mutex_unlock(>bo_list_lock); + up_write(>bo_list_lock); amdgpu_bo_list_free(list); } else { - mutex_unlock(>bo_list_lock); + up_write(>bo_list_lock); } } @@ -173,11 +173,11 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) { struct amdgpu_bo_list *result; - mutex_lock(>bo_list_lock); + down_read(>bo_list_lock); result = idr_find(>bo_list_handles, id); if (result) mutex_lock(>lock); - mutex_unlock(>bo_list_lock); + up_read(>bo_list_lock); return result; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index f68ced6..c4cba81 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -841,7 +841,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) goto out_suspend; } - mutex_init(>bo_list_lock); + init_rwsem(>bo_list_lock); idr_init(>bo_list_handles); amdgpu_ctx_mgr_init(>ctx_mgr); @@ -900,7 +900,6 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, amdgpu_bo_list_free(list); idr_destroy(>bo_list_handles); - mutex_destroy(>bo_list_lock); kfree(fpriv); file_priv->driver_priv = NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/4] drm/amdgpu: Optimization of mutex usage
There is no need to lock the bo_list mutex, because there is no other task can access the newly created BO list yet. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index c994a04..4363f28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -60,8 +60,6 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, (*result)->num_entries = 0; (*result)->array = NULL; - mutex_lock(&(*result)->lock); - return 0; } @@ -282,7 +280,6 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, r = amdgpu_bo_list_set(adev, filp, list, info, args->in.bo_number); - amdgpu_bo_list_put(list); if (r) goto error_free; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/4] drm/amdgpu: Optimization of critical section
Make the critical section smaller. There is no need to protect the bo_list, because there is no other task can access the newly created BO list yet. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 02c138f..c994a04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -48,8 +48,9 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, mutex_lock(>bo_list_lock); r = idr_alloc(>bo_list_handles, *result, 1, 0, GFP_KERNEL); + mutex_unlock(>bo_list_lock); + if (r < 0) { - mutex_unlock(>bo_list_lock); kfree(*result); return r; } @@ -60,7 +61,6 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, (*result)->array = NULL; mutex_lock(&(*result)->lock); - mutex_unlock(>bo_list_lock); return 0; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/4] drm/amdgpu: Optimization of critical section
This patch is to move a loop of unref BOs and several memory free function calls out of critical sections. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index a664987..02c138f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -75,9 +75,12 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) /* Another user may have a reference to this list still */ mutex_lock(>lock); mutex_unlock(>lock); + mutex_unlock(>bo_list_lock); amdgpu_bo_list_free(list); } - mutex_unlock(>bo_list_lock); + else { + mutex_unlock(>bo_list_lock); + } } static int amdgpu_bo_list_set(struct amdgpu_device *adev, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/3] drm/amdgpu: move comment to the right place
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f3e7885..a7d6804 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2099,8 +2099,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, amdgpu_check_arguments(adev); - /* Registers mapping */ - /* TODO: block userspace mapping of io register */ spin_lock_init(>mmio_idx_lock); spin_lock_init(>smc_idx_lock); spin_lock_init(>pcie_idx_lock); @@ -2121,6 +2119,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_DELAYED_WORK(>late_init_work, amdgpu_late_init_func_handler); + /* Registers mapping */ + /* TODO: block userspace mapping of io register */ if (adev->asic_type >= CHIP_BONAIRE) { adev->rmmio_base = pci_resource_start(adev->pdev, 5); adev->rmmio_size = pci_resource_len(adev->pdev, 5); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/3] drm/amdgpu: remove duplicate function prototypes
There are two identical function prototypes in same headere file Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 766c79d..7f64765 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1688,7 +1688,6 @@ static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev) return container_of(bdev, struct amdgpu_device, mman.bdev); } -bool amdgpu_device_is_px(struct drm_device *dev); int amdgpu_device_init(struct amdgpu_device *adev, struct drm_device *ddev, struct pci_dev *pdev, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/3] drm/amdgpu: fix a typo in comment
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index b17635c..7a70a2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -525,7 +525,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, goto error_free_pages; } - /* Fill the page arrays for all useptrs. */ + /* Fill the page arrays for all userptrs. */ list_for_each_entry(e, _pages, tv.head) { struct ttm_tt *ttm = e->robj->tbo.ttm; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Move compute vm bug logic to amdgpu_vm.c
In review, Christian would like to keep the logic inside amdgpu_vm.c with a cost of slightly slower. The loop is still optimized out with this patch. v2: remove the if statement. Now it is not slower. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 32 - drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 5 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 38 -- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 + 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 89bc34a..2f1a4e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2227,6 +2227,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->accel_working = true; + amdgpu_vm_check_compute_bug(adev); + /* Initialize the buffer migration limit. */ if (amdgpu_moverate >= 0) max_MBps = amdgpu_moverate; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 7d95435..31aa51d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -153,36 +153,6 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) } /** - * amdgpu_ring_check_compute_vm_bug - check whether this ring has compute vm bug - * - * @adev: amdgpu_device pointer - * @ring: amdgpu_ring structure holding ring information - */ -static void amdgpu_ring_check_compute_vm_bug(struct amdgpu_device *adev, - struct amdgpu_ring *ring) -{ - const struct amdgpu_ip_block *ip_block; - - ring->has_compute_vm_bug = false; - - if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) - /* only compute rings */ - return; - - ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); - if (!ip_block) - return; - - /* Compute ring has a VM bug for GFX version < 7. - And compute ring has a VM bug for GFX 8 MEC firmware version < 673.*/ - if (ip_block->version->major <= 7) { - ring->has_compute_vm_bug = true; - } else if (ip_block->version->major == 8) - if (adev->gfx.mec_fw_version < 673) - ring->has_compute_vm_bug = true; -} - -/** * amdgpu_ring_init - init driver ring struct. * * @adev: amdgpu_device pointer @@ -288,8 +258,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, DRM_ERROR("Failed to register debugfs file for rings !\n"); } - amdgpu_ring_check_compute_vm_bug(adev, ring); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 334307e..ad399c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -208,9 +208,4 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) } -static inline bool amdgpu_ring_has_compute_vm_bug(struct amdgpu_ring *ring) -{ - return ring->has_compute_vm_bug; -} - #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index d4d05a8..6e32748 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -656,6 +656,41 @@ static int amdgpu_vm_alloc_reserved_vmid(struct amdgpu_device *adev, return r; } +/** + * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug + * + * @adev: amdgpu_device pointer + */ +void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev) +{ + const struct amdgpu_ip_block *ip_block; + bool has_compute_vm_bug; + struct amdgpu_ring *ring; + int i; + + has_compute_vm_bug = false; + + ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); + if (ip_block) { + /* Compute has a VM bug for GFX version < 7. + Compute has a VM bug for GFX 8 MEC firmware version < 673.*/ + if (ip_block->version->major <= 7) + has_compute_vm_bug = true; + else if (ip_block->version->major == 8) + if (adev->gfx.mec_fw_version < 673) + has_compute_vm_bug = true; + } + + for (i = 0; i < adev->num_rings; i++) { + ring = adev->rings[i]; + if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) + /* only compute rings */ + ring->has_compute_vm_bug = has_compute_vm_bug; + else + ring->has_compute_vm_bug = false; + } +}
[PATCH] drm/amdgpu: Move compute vm bug logic to amdgpu_vm.c
In review, Christian would like to keep the logic inside amdgpu_vm.c with a cost of slightly slower. The loop is still optimized out with this patch. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 32 --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 6 - drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 35 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 3 +++ 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 89bc34a..2f1a4e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2227,6 +2227,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->accel_working = true; + amdgpu_vm_check_compute_bug(adev); + /* Initialize the buffer migration limit. */ if (amdgpu_moverate >= 0) max_MBps = amdgpu_moverate; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 7d95435..31aa51d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -153,36 +153,6 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) } /** - * amdgpu_ring_check_compute_vm_bug - check whether this ring has compute vm bug - * - * @adev: amdgpu_device pointer - * @ring: amdgpu_ring structure holding ring information - */ -static void amdgpu_ring_check_compute_vm_bug(struct amdgpu_device *adev, - struct amdgpu_ring *ring) -{ - const struct amdgpu_ip_block *ip_block; - - ring->has_compute_vm_bug = false; - - if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) - /* only compute rings */ - return; - - ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); - if (!ip_block) - return; - - /* Compute ring has a VM bug for GFX version < 7. - And compute ring has a VM bug for GFX 8 MEC firmware version < 673.*/ - if (ip_block->version->major <= 7) { - ring->has_compute_vm_bug = true; - } else if (ip_block->version->major == 8) - if (adev->gfx.mec_fw_version < 673) - ring->has_compute_vm_bug = true; -} - -/** * amdgpu_ring_init - init driver ring struct. * * @adev: amdgpu_device pointer @@ -288,8 +258,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, DRM_ERROR("Failed to register debugfs file for rings !\n"); } - amdgpu_ring_check_compute_vm_bug(adev, ring); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 334307e..a9223a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -185,7 +185,6 @@ struct amdgpu_ring { u64 cond_exe_gpu_addr; volatile u32*cond_exe_cpu_addr; unsignedvm_inv_eng; - boolhas_compute_vm_bug; #if defined(CONFIG_DEBUG_FS) struct dentry *ent; #endif @@ -208,9 +207,4 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) } -static inline bool amdgpu_ring_has_compute_vm_bug(struct amdgpu_ring *ring) -{ - return ring->has_compute_vm_bug; -} - #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 90392a1..f8af695 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -656,6 +656,39 @@ static int amdgpu_vm_alloc_reserved_vmid(struct amdgpu_device *adev, return r; } +static bool amdgpu_vm_ring_has_compute_vm_bug(struct amdgpu_ring *ring) +{ + if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) + /* only compute rings */ + return ring->adev->vm_manager.has_compute_vm_bug; + else + return false; +} + +/** + * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug + * + * @adev: amdgpu_device pointer + */ +void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev) +{ + const struct amdgpu_ip_block *ip_block; + + adev->vm_manager.has_compute_vm_bug = false; + + ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); + if (!ip_block) + return; + + /* Compute ring has a VM bug for GFX version < 7. + And compute ring has a VM bug for GFX 8 MEC firmware version < 673.*/ + if (ip_block->version->major <= 7) { + adev->vm_manager.has_compute_vm_bug = true; + } else if (ip_block-&g
[PATCH 3/3] drm/amdgpu: clean up code to make it easier to understand
The original code convert pointer from amdgpu_crtc to drm_crtc then later convert the pointer back. It is difficult to understand why it was written that way. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 4dd83a3..7317fc9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -258,8 +258,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file for (i = 0, found = 0; i < adev->mode_info.num_crtc; i++) { crtc = (struct drm_crtc *)minfo->crtcs[i]; if (crtc && crtc->base.id == info->mode_crtc.id) { - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); - ui32 = amdgpu_crtc->crtc_id; + ui32 = minfo->crtcs[i]->crtc_id; found = 1; break; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/3] drm/amdgpu: Optimize a function called by every IB sheduling
Move several if statements and a loop statment from run time to initialization time. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 33 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 6 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 28 +-- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 6a85db0..7d95435 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -153,6 +153,36 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) } /** + * amdgpu_ring_check_compute_vm_bug - check whether this ring has compute vm bug + * + * @adev: amdgpu_device pointer + * @ring: amdgpu_ring structure holding ring information + */ +static void amdgpu_ring_check_compute_vm_bug(struct amdgpu_device *adev, + struct amdgpu_ring *ring) +{ + const struct amdgpu_ip_block *ip_block; + + ring->has_compute_vm_bug = false; + + if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) + /* only compute rings */ + return; + + ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); + if (!ip_block) + return; + + /* Compute ring has a VM bug for GFX version < 7. + And compute ring has a VM bug for GFX 8 MEC firmware version < 673.*/ + if (ip_block->version->major <= 7) { + ring->has_compute_vm_bug = true; + } else if (ip_block->version->major == 8) + if (adev->gfx.mec_fw_version < 673) + ring->has_compute_vm_bug = true; +} + +/** * amdgpu_ring_init - init driver ring struct. * * @adev: amdgpu_device pointer @@ -257,6 +287,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, if (amdgpu_debugfs_ring_init(adev, ring)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } + + amdgpu_ring_check_compute_vm_bug(adev, ring); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index a9223a8..334307e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -185,6 +185,7 @@ struct amdgpu_ring { u64 cond_exe_gpu_addr; volatile u32*cond_exe_cpu_addr; unsignedvm_inv_eng; + boolhas_compute_vm_bug; #if defined(CONFIG_DEBUG_FS) struct dentry *ent; #endif @@ -207,4 +208,9 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) } +static inline bool amdgpu_ring_has_compute_vm_bug(struct amdgpu_ring *ring) +{ + return ring->has_compute_vm_bug; +} + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b2384b8..7a323f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -656,32 +656,6 @@ static int amdgpu_vm_alloc_reserved_vmid(struct amdgpu_device *adev, return r; } -static bool amdgpu_vm_ring_has_compute_vm_bug(struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - const struct amdgpu_ip_block *ip_block; - - if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) - /* only compute rings */ - return false; - - ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); - if (!ip_block) - return false; - - if (ip_block->version->major <= 7) { - /* gfx7 has no workaround */ - return true; - } else if (ip_block->version->major == 8) { - if (adev->gfx.mec_fw_version >= 673) - /* gfx8 is fixed in MEC firmware 673 */ - return false; - else - return true; - } - return false; -} - bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, struct amdgpu_job *job) { @@ -691,7 +665,7 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, struct amdgpu_vm_id *id; bool gds_switch_needed; bool vm_flush_needed = job->vm_needs_flush || - amdgpu_vm_ring_has_compute_vm_bug(ring); + amdgpu_ring_has_compute_vm_bug(ring); if (job->vm_id == 0) return false; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/3] drm/amdgpu: Remove two ! operations in an if condition
Make the code easier to understand. Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 7a323f9..9fdeb82 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -680,9 +680,11 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, if (amdgpu_vm_had_gpu_reset(adev, id)) return true; - if (!vm_flush_needed && !gds_switch_needed) + + if (vm_flush_needed || gds_switch_needed) + return true; + else return false; - return true; } /** -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: fix errors in comments.
Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 66bb60e..aab3206 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -479,9 +479,8 @@ void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev, /* * amdgpu_wb_*() - * Writeback is the the method by which the the GPU updates special pages - * in memory with the status of certain GPU events (fences, ring pointers, - * etc.). + * Writeback is the method by which GPU updates special pages in memory + * with the status of certain GPU events (fences, ring pointers,etc.). */ /** @@ -507,7 +506,7 @@ static void amdgpu_wb_fini(struct amdgpu_device *adev) * * @adev: amdgpu_device pointer * - * Disables Writeback and frees the Writeback memory (all asics). + * Initialize writeback and allocates writeback memory (all asics). * Used at driver startup. * Returns 0 on success or an -error on failure. */ -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/2] drm/amdgpu: Fix use of interruptible waiting
Hi, I knew this is part of ioctl. And I intended to fix this interruptible waiting in an ioctl. ioctl is one of driver interfaces, where interruptible waiting is good in some scenarios. For example, if ioctl performs IO operations in atomic way, we don't want ioctl to be interrupted by a signal. Interruptible waiting is good when we need to wait for longer time, for example, waiting for an input data for indefinite time. We don't want the process not responding to signals. Interruptible waitings can be good in read/write/ioctl interfaces. For this patch, 1. The wait is short. There is not much benefit by interruptible waiting. The BO is a frame buffer BO. Are there many competitors to lock this BO? If not, the wait is very short. This is my main reason to change. 2. In this function and caller functions, the error handling for such interrupt is complicated and risky. When the waiting is interrupted by a signal, the callers of this function need to handle this interrupt error. I traced the calling stack all the way back to function drm_mode_page_flip_ioctl. I could not find an issue. But I am not sure about even upper layer. Is this IOCTL restartable? How about further higher layer? Since I didn't see benefit in point 1. So I thought it was a good idea to change. Anyway, it is up to you. A change might bring other unseen risk. If you still have concern, I will drop this patch. This IOCTL is used by graphic operation. There may not be a lot of signals to a GUI process which uses this IOCTL. Thanks, Alex Bin On 17-04-26 04:34 AM, Christian König wrote: Am 26.04.2017 um 03:17 schrieb Michel Dänzer: On 26/04/17 06:25 AM, Alex Xie wrote: 1. The wait is short. There is not much benefit by interruptible waiting. 2. In this function and caller functions, the error handling for such interrupt is complicated and risky. Change-Id: I289674ecd3f5ef20c93fe63e33df6d668b3c2edc Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 43082bf..c006cc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -227,7 +227,7 @@ int amdgpu_crtc_prepare_flip( new_abo = gem_to_amdgpu_bo(obj); /* pin the new buffer */ -r = amdgpu_bo_reserve(new_abo, false); +r = amdgpu_bo_reserve(new_abo, true); if (unlikely(r != 0)) { DRM_ERROR("failed to reserve new abo buffer before flip\n"); goto cleanup; I'm afraid we have no choice but to use interruptible here, because this code runs as part of an ioctl (DRM_IOCTL_MODE_PAGE_FLIP). Yes, agree. But the error message is incorrect here and should be removed. Christian. ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/amdgpu: Fix use of interruptible waiting
There is no good mechanism to handle the corresponding error. When signal interrupt happens, unpin is not called. As a result, inside AMDGPU, the statistic of pin size will be wrong. Change-Id: I4a06a227c2757c447cec0058ace4b028553658a2 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 7cf226d..43082bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -172,7 +172,7 @@ void amdgpu_crtc_cleanup_flip_ctx( struct amdgpu_flip_work *work, struct amdgpu_bo *new_abo) { - if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) { + if (unlikely(amdgpu_bo_reserve(new_abo, true) != 0)) { DRM_ERROR("failed to reserve new abo in error path\n"); amdgpu_flip_work_cleanup(work); return; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu: Fix use of interruptible waiting
1. The wait is short. There is not much benefit by interruptible waiting. 2. In this function and caller functions, the error handling for such interrupt is complicated and risky. Change-Id: I289674ecd3f5ef20c93fe63e33df6d668b3c2edc Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 43082bf..c006cc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -227,7 +227,7 @@ int amdgpu_crtc_prepare_flip( new_abo = gem_to_amdgpu_bo(obj); /* pin the new buffer */ - r = amdgpu_bo_reserve(new_abo, false); + r = amdgpu_bo_reserve(new_abo, true); if (unlikely(r != 0)) { DRM_ERROR("failed to reserve new abo buffer before flip\n"); goto cleanup; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Fix use of interruptible waiting
Either in cgs functions or for callers of cgs functions: 1. The signal interrupt can affect the expected behaviour 2. There is no good mechanism to handle the corresponding error 3. There is no chance of deadlock in these single BO waiting 4. There is no clear benefit for interruptible waiting 5. Future caller of these functions might have same issue. Change-Id: Ifc0e0ab862f98cdc6cdaef87cd96f11c91d64f27 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index a1a2d44..31fe4ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -89,7 +89,7 @@ static int amdgpu_cgs_gmap_kmem(struct cgs_device *cgs_device, void *kmem, AMDGPU_GEM_DOMAIN_GTT, 0, sg, NULL, ); if (ret) return ret; - ret = amdgpu_bo_reserve(bo, false); + ret = amdgpu_bo_reserve(bo, true); if (unlikely(ret != 0)) return ret; @@ -107,7 +107,7 @@ static int amdgpu_cgs_gunmap_kmem(struct cgs_device *cgs_device, cgs_handle_t km struct amdgpu_bo *obj = (struct amdgpu_bo *)kmem_handle; if (obj) { - int r = amdgpu_bo_reserve(obj, false); + int r = amdgpu_bo_reserve(obj, true); if (likely(r == 0)) { amdgpu_bo_unpin(obj); amdgpu_bo_unreserve(obj); @@ -215,7 +215,7 @@ static int amdgpu_cgs_free_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; if (obj) { - int r = amdgpu_bo_reserve(obj, false); + int r = amdgpu_bo_reserve(obj, true); if (likely(r == 0)) { amdgpu_bo_kunmap(obj); amdgpu_bo_unpin(obj); @@ -239,7 +239,7 @@ static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h min_offset = obj->placements[0].fpfn << PAGE_SHIFT; max_offset = obj->placements[0].lpfn << PAGE_SHIFT; - r = amdgpu_bo_reserve(obj, false); + r = amdgpu_bo_reserve(obj, true); if (unlikely(r != 0)) return r; r = amdgpu_bo_pin_restricted(obj, obj->prefered_domains, @@ -252,7 +252,7 @@ static int amdgpu_cgs_gunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t { int r; struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; - r = amdgpu_bo_reserve(obj, false); + r = amdgpu_bo_reserve(obj, true); if (unlikely(r != 0)) return r; r = amdgpu_bo_unpin(obj); @@ -265,7 +265,7 @@ static int amdgpu_cgs_kmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h { int r; struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; - r = amdgpu_bo_reserve(obj, false); + r = amdgpu_bo_reserve(obj, true); if (unlikely(r != 0)) return r; r = amdgpu_bo_kmap(obj, map); @@ -277,7 +277,7 @@ static int amdgpu_cgs_kunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t { int r; struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; - r = amdgpu_bo_reserve(obj, false); + r = amdgpu_bo_reserve(obj, true); if (unlikely(r != 0)) return r; amdgpu_bo_kunmap(obj); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/4] drm/amdgpu: Fix use of interruptible waiting 1. The signal interrupt can affect the expected behaviour. 2. There is no mechanism to handle the corresponding error.
Change-Id: I43f3b0b420833a02ad5ece3ddeef04c6512667e9 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 051696d..4d04af9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2181,7 +2181,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) if (amdgpu_crtc->cursor_bo) { struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); - r = amdgpu_bo_reserve(aobj, false); + r = amdgpu_bo_reserve(aobj, true); if (r == 0) { amdgpu_bo_unpin(aobj); amdgpu_bo_unreserve(aobj); @@ -2194,7 +2194,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) robj = gem_to_amdgpu_bo(rfb->obj); /* don't unpin kernel fb objects */ if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { - r = amdgpu_bo_reserve(robj, false); + r = amdgpu_bo_reserve(robj, true); if (r == 0) { amdgpu_bo_unpin(robj); amdgpu_bo_unreserve(robj); @@ -2301,7 +2301,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (amdgpu_crtc->cursor_bo) { struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); - r = amdgpu_bo_reserve(aobj, false); + r = amdgpu_bo_reserve(aobj, true); if (r == 0) { r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/4] drm/amdgpu: Fix use of interruptible waiting 1. The signal interrupt can affect the expected behaviour. 2. There is no good mechanism to handle the corresponding error.
Change-Id: I43f3b0b420833a02ad5ece3ddeef04c6512667e9 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 4d04af9..2ef4759 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2479,7 +2479,7 @@ static int amdgpu_recover_vram_from_shadow(struct amdgpu_device *adev, if (!bo->shadow) return 0; - r = amdgpu_bo_reserve(bo, false); + r = amdgpu_bo_reserve(bo, true); if (r) return r; domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/4] drm/amdgpu: Fix potential issue if reserve function is interrupted If amdgpu_bo_reserve function is interrupted by signal, amdgpu_bo_kunmap function is not called.
Change-Id: Ide2b3be6549b3afb8d6116094b5fff495b18addf Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a09ad3cf..051696d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -350,7 +350,7 @@ static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev) if (adev->vram_scratch.robj == NULL) { return; } - r = amdgpu_bo_reserve(adev->vram_scratch.robj, false); + r = amdgpu_bo_reserve(adev->vram_scratch.robj, true); if (likely(r == 0)) { amdgpu_bo_kunmap(adev->vram_scratch.robj); amdgpu_bo_unpin(adev->vram_scratch.robj); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/amdgpu: Real return value can be over-written when clean up
Change-Id: Ib69f035eeb213a1aec5025e0a9f4515065706118 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c index 3453052..76be2d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c @@ -117,6 +117,11 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, } out_cleanup: + /* Check error value now. The value can be overwritten when clean up.*/ + if (r) { + DRM_ERROR("Error while benchmarking BO move.\n"); + } + if (sobj) { r = amdgpu_bo_reserve(sobj, false); if (likely(r == 0)) { @@ -133,10 +138,6 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, } amdgpu_bo_unref(); } - - if (r) { - DRM_ERROR("Error while benchmarking BO move.\n"); - } } void amdgpu_benchmark(struct amdgpu_device *adev, int test_number) -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu: Fix use of interruptible waiting 1. The signal interrupt can affect the expected behaviour. 2. There is no good mechanism to handle the corresponding error. When signal interru
Change-Id: I6889a4d9dd2703bcf5d448d18f6af51c496a93c9 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c index 76be2d2..75bd76f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c @@ -123,7 +123,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, } if (sobj) { - r = amdgpu_bo_reserve(sobj, false); + r = amdgpu_bo_reserve(sobj, true); if (likely(r == 0)) { amdgpu_bo_unpin(sobj); amdgpu_bo_unreserve(sobj); @@ -131,7 +131,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, amdgpu_bo_unref(); } if (dobj) { - r = amdgpu_bo_reserve(dobj, false); + r = amdgpu_bo_reserve(dobj, true); if (likely(r == 0)) { amdgpu_bo_unpin(dobj); amdgpu_bo_unreserve(dobj); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 4/4] drm/amdgpu: Fix use of interruptible waiting 1. The signal interrupt can affect the expected behaviour. 2. There is no good mechanism to handle the corresponding error.
Change-Id: I504cc9c280c70fa832cb64e6a1e0f8b4a1f3cbfd Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 8f5db2d..e4a6a40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -295,7 +295,7 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, if (*bo == NULL) return; - if (likely(amdgpu_bo_reserve(*bo, false) == 0)) { + if (likely(amdgpu_bo_reserve(*bo, true) == 0)) { if (cpu_addr) amdgpu_bo_kunmap(*bo); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 2/2] drm/amdgpu: print debug message when fails to reserve BO
Change-Id: Ie5a6ba045bde07ccd35b27690709ad1670139447 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 79b5fda..7e43f63 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -356,6 +356,9 @@ static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev) amdgpu_bo_unpin(adev->vram_scratch.robj); amdgpu_bo_unreserve(adev->vram_scratch.robj); amdgpu_bo_unref(>vram_scratch.robj); + } else { + DRM_DEBUG("amdgpu_vram_scratch_fini failed. " + "BO is still referenced.\n"); } } -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 1/2] dmr/amdgpu: Fix wrongly unref of BO
According to comment of amdgpu_bo_reserve, amdgpu_bo_reserve can return with -ERESTARTSYS. When this function was interrupted by a signal, BO should not be unref. Otherwise the BO might be released while is kmapped and pinned, or BO MIGHT be deref multiple times, etc. Change-Id: If76071a768950a0d3ad9d5da7fcae04881807621 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a09ad3cf..79b5fda 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -355,8 +355,8 @@ static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev) amdgpu_bo_kunmap(adev->vram_scratch.robj); amdgpu_bo_unpin(adev->vram_scratch.robj); amdgpu_bo_unreserve(adev->vram_scratch.robj); + amdgpu_bo_unref(>vram_scratch.robj); } - amdgpu_bo_unref(>vram_scratch.robj); } /** -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] dmr/amdgpu: Fix wrongly unref of BO
According to comment of amdgpu_bo_reserve, amdgpu_bo_reserve can return with -ERESTARTSYS. When this function was interrupted by a signal, BO should not be unref. Otherwise the BO might be released while is kmapped and pinned, or BO MIGHT be deref multiple times, etc. Change-Id: If76071a768950a0d3ad9d5da7fcae04881807621 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 53996e3..1dcc2d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -355,8 +355,8 @@ static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev) amdgpu_bo_kunmap(adev->vram_scratch.robj); amdgpu_bo_unpin(adev->vram_scratch.robj); amdgpu_bo_unreserve(adev->vram_scratch.robj); + amdgpu_bo_unref(>vram_scratch.robj); } - amdgpu_bo_unref(>vram_scratch.robj); } /** -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: fix compile warning
warning: comparison of distinct pointer types lacks a cast Change-Id: I317eddd1bd430c98a3c50ec170f592f944081a6e Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 8785420..cf877df 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1204,7 +1204,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, * reserve space for one command every (1 << BLOCK_SIZE) * entries or 2k dwords (whatever is smaller) */ - ncmds = (nptes >> min(adev->vm_manager.block_size, 11)) + 1; + ncmds = (nptes >> min(adev->vm_manager.block_size, 11u)) + 1; /* padding, etc. */ ndw = 64; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/amdgpu: Avoid using signed integer to store pointer value
Change-Id: I861ba3c85c182fdb6b89533029b3272191f331f5 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index c02db01f6..9bdd5d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -237,7 +237,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, struct amdgpu_fpriv *fpriv = filp->driver_priv; union drm_amdgpu_bo_list *args = data; uint32_t handle = args->in.list_handle; - const void __user *uptr = (const void*)(long)args->in.bo_info_ptr; + const void __user *uptr = (const void*)(uintptr_t)args->in.bo_info_ptr; struct drm_amdgpu_bo_list_entry *info; struct amdgpu_bo_list *list; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index e4dc21f..0386015 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -719,7 +719,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, switch (args->op) { case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: { struct drm_amdgpu_gem_create_in info; - void __user *out = (void __user *)(long)args->value; + void __user *out = (void __user *)(uintptr_t)args->value; info.bo_size = robj->gem_base.size; info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index f8d8636..1006d7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -237,7 +237,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file struct amdgpu_device *adev = dev->dev_private; struct drm_amdgpu_info *info = data; struct amdgpu_mode_info *minfo = >mode_info; - void __user *out = (void __user *)(long)info->return_pointer; + void __user *out = (void __user *)(uintptr_t)info->return_pointer; uint32_t size = info->return_size; struct drm_crtc *crtc; uint32_t ui32 = 0; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu: use uintptr_t instead of unsigned long to store pointer
Change-Id: Ic1cb6252482bcf9602c7700c3db075b9edf20e2a Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 3389f1b..a91aa57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -161,7 +161,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } /* get chunks */ - chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks); + chunk_array_user = (uint64_t __user *)(uintptr_t)(cs->in.chunks); if (copy_from_user(chunk_array, chunk_array_user, sizeof(uint64_t)*cs->in.num_chunks)) { ret = -EFAULT; @@ -181,7 +181,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) struct drm_amdgpu_cs_chunk user_chunk; uint32_t __user *cdata; - chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; + chunk_ptr = (void __user *)(uintptr_t)chunk_array[i]; if (copy_from_user(_chunk, chunk_ptr, sizeof(struct drm_amdgpu_cs_chunk))) { ret = -EFAULT; @@ -192,7 +192,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) p->chunks[i].length_dw = user_chunk.length_dw; size = p->chunks[i].length_dw; - cdata = (void __user *)(unsigned long)user_chunk.chunk_data; + cdata = (void __user *)(uintptr_t)user_chunk.chunk_data; p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); if (p->chunks[i].kdata == NULL) { @@ -1339,7 +1339,7 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, if (fences == NULL) return -ENOMEM; - fences_user = (void __user *)(unsigned long)(wait->in.fences); + fences_user = (void __user *)(uintptr_t)(wait->in.fences); if (copy_from_user(fences, fences_user, sizeof(struct drm_amdgpu_fence) * fence_count)) { r = -EFAULT; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Fix compilation warning
Change-Id: Ia251723599024fe258b018a53078d340af01207e Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 30d5c42..8f18d14 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -853,7 +853,7 @@ static int gmc_v6_0_sw_init(void *handle) adev->vm_manager.block_size = amdgpu_vm_block_size; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; - DRM_INFO("vm size is %d GB, block size is %d-bit\n", + DRM_INFO("vm size is %llu GB, block size is %d-bit\n", adev->vm_manager.vm_size, adev->vm_manager.block_size); adev->mc.mc_mask = 0xffULL; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 7113765..b86b454 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1007,7 +1007,7 @@ static int gmc_v7_0_sw_init(void *handle) adev->vm_manager.block_size = amdgpu_vm_block_size; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; - DRM_INFO("vm size is %d GB, block size is %d-bit\n", + DRM_INFO("vm size is %llu GB, block size is %d-bit\n", adev->vm_manager.vm_size, adev->vm_manager.block_size); /* Set the internal MC address mask diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index b3d1f1b..108a20e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1091,7 +1091,7 @@ static int gmc_v8_0_sw_init(void *handle) adev->vm_manager.block_size = amdgpu_vm_block_size; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; - DRM_INFO("vm size is %d GB, block size is %d-bit\n", + DRM_INFO("vm size is %llu GB, block size is %d-bit\n", adev->vm_manager.vm_size, adev->vm_manager.block_size); /* Set the internal MC address mask diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index e1637d5..6329be8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -566,7 +566,7 @@ static int gmc_v9_0_sw_init(void *handle) adev->vm_manager.block_size = 9; } - DRM_INFO("vm size is %d GB, block size is %d-bit\n", + DRM_INFO("vm size is %llu GB, block size is %d-bit\n", adev->vm_manager.vm_size, adev->vm_manager.block_size); /* This interrupt is VMC page fault.*/ -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Move function amdgpu_has_atpx near other similar functions
Change-Id: I1266af0697146369c9fb720b241bfa02280571c9 Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 86fba1a..02ee712 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1905,12 +1905,14 @@ void amdgpu_program_register_sequence(struct amdgpu_device *adev, bool amdgpu_has_atpx_dgpu_power_cntl(void); bool amdgpu_is_atpx_hybrid(void); bool amdgpu_atpx_dgpu_req_power_for_displays(void); +bool amdgpu_has_atpx(void); #else static inline void amdgpu_register_atpx_handler(void) {} static inline void amdgpu_unregister_atpx_handler(void) {} static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } static inline bool amdgpu_is_atpx_hybrid(void) { return false; } static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false; } +static inline bool amdgpu_has_atpx(void) { return false; } #endif /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index a2f2b7f..f8d8636 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -36,12 +36,6 @@ #include #include "amdgpu_amdkfd.h" -#if defined(CONFIG_VGA_SWITCHEROO) -bool amdgpu_has_atpx(void); -#else -static inline bool amdgpu_has_atpx(void) { return false; } -#endif - /** * amdgpu_driver_unload_kms - Main unload function for KMS. * -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Fix 32bit x86 compilation warning
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c:187:2: warning: right shift count >= width of type [enabled by default] drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c:173:2: warning: right shift count >= width of type [enabled by default] drivers/gpu/drm/amd/amdgpu/vega10_ih.c:106:3: warning: right shift count >= width of type [enabled by default] Reported by: kbuild-...@01.org Change-Id: I0c3e52f7fd1026d07ac1042b5e8796fbdf09afff Signed-off-by: Alex Xie <alexbin@amd.com> --- drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index 5604a53..5d4d999 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -172,7 +172,7 @@ int gfxhub_v1_0_gart_enable(struct amdgpu_device *adev) (u32)(adev->dummy_page.addr >> 12)); WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32), - (u32)(adev->dummy_page.addr >> 44)); + (u32)((u64)adev->dummy_page.addr >> 44)); tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmVM_L2_PROTECTION_FAULT_CNTL2)); tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL2, diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 5903bb0..d41e765 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -186,7 +186,7 @@ int mmhub_v1_0_gart_enable(struct amdgpu_device *adev) (u32)(adev->dummy_page.addr >> 12)); WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32), - (u32)(adev->dummy_page.addr >> 44)); + (u32)((u64)adev->dummy_page.addr >> 44)); tmp = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL2)); tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL2, diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 23371e1..041ed0b 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -103,7 +103,7 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev) /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ if (adev->irq.ih.use_bus_addr) { WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE), adev->irq.ih.rb_dma_addr >> 8); - WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI), (adev->irq.ih.rb_dma_addr >> 40) &0xff); + WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI), ((u64)adev->irq.ih.rb_dma_addr >> 40) &0xff); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 1); } else { WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE), adev->irq.ih.gpu_addr >> 8); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH libdrm 3/3] amdgpu: A new option to run tests on render node
Tested: 1. As root, tests passed on primary. 2. As root, tests passed on render node. BO export/import test was skipped 3. As non-privileged user, tests failed on primary as expected. 4. As non-privileged user, tests passed on render node. BO export/import test was skipped Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 13 ++--- tests/amdgpu/amdgpu_test.h | 3 +++ tests/amdgpu/bo_tests.c| 5 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index c01ee54..3fd6820 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -56,6 +56,9 @@ */ int drm_amdgpu[MAX_CARDS_SUPPORTED]; +/** Open render node to test */ +int open_render_node = 0; /* By default run most tests on primary node */ + /** The table of all known test suites to run */ static CU_SuiteInfo suites[] = { { @@ -109,16 +112,17 @@ static void display_test_suites(void) /** Help string for command line parameters */ static const char usage[] = - "Usage: %s [-hlp] [<-s > [-t ]] " + "Usage: %s [-hlpr] [<-s > [-t ]] " "[-b [-d ]]\n" "where:\n" " l - Display all suites and their tests\n" + " r - Run the tests on render node\n" " b - Specify device's PCI bus id to run tests\n" " d - Specify device's PCI device id to run tests (optional)\n" " p - Display information of AMDGPU devices in system\n" " h - Display this help\n"; /** Specified options strings for getopt */ -static const char options[] = "hlps:t:b:d:"; +static const char options[] = "hlrps:t:b:d:"; /* Open AMD devices. * Return the number of AMD device openned. @@ -326,6 +330,9 @@ int main(int argc, char **argv) case 'p': display_devices = 1; break; + case 'r': + open_render_node = 1; + break; case '?': case 'h': fprintf(stderr, usage, argv[0]); @@ -336,7 +343,7 @@ int main(int argc, char **argv) } } - if (amdgpu_open_devices(0) <= 0) { + if (amdgpu_open_devices(open_render_node) <= 0) { perror("Cannot open AMDGPU device"); exit(EXIT_FAILURE); } diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h index fca92ad..e30e231 100644 --- a/tests/amdgpu/amdgpu_test.h +++ b/tests/amdgpu/amdgpu_test.h @@ -35,6 +35,9 @@ /* Forward reference for array to keep "drm" handles */ extern int drm_amdgpu[MAX_CARDS_SUPPORTED]; +/* Global variables */ +extern int open_render_node; + /* Basic test suite / /* diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c index 25df767..74b5e77 100644 --- a/tests/amdgpu/bo_tests.c +++ b/tests/amdgpu/bo_tests.c @@ -152,6 +152,11 @@ static void amdgpu_bo_export_import_do_type(enum amdgpu_bo_handle_type type) static void amdgpu_bo_export_import(void) { + if (open_render_node) { + printf("(DRM render node is used. Skip export/Import test) "); + return; + } + amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_gem_flink_name); amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_dma_buf_fd); } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH libdrm 2/3] amdgpu: A new option to choose which device to run most tests
This can be used to test multiple GPUs v2: Use PCI bus ID and optional PCI device ID to choose device Add an option to display information of AMDGPU devices Tested: ./amdgpu_test -p ./amdgpu_test ./amdgpu_test -b 1 #fail as expected ./amdgpu_test -b 6 #pass ./amdgpu_test -b -d 1 #fail as expected ./amdgpu_test -b -d 0 #pass Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 133 +++-- 1 file changed, 116 insertions(+), 17 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index d2b00d4..c01ee54 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -108,12 +108,17 @@ static void display_test_suites(void) /** Help string for command line parameters */ -static const char usage[] = "Usage: %s [-hl] [<-s > [-t ]]\n" - "where:\n" - " l - Display all suites and their tests\n" - " h - Display this help\n"; +static const char usage[] = + "Usage: %s [-hlp] [<-s > [-t ]] " + "[-b [-d ]]\n" + "where:\n" + " l - Display all suites and their tests\n" + " b - Specify device's PCI bus id to run tests\n" + " d - Specify device's PCI device id to run tests (optional)\n" + " p - Display information of AMDGPU devices in system\n" + " h - Display this help\n"; /** Specified options strings for getopt */ -static const char options[] = "hls:t:"; +static const char options[] = "hlps:t:b:d:"; /* Open AMD devices. * Return the number of AMD device openned. @@ -203,21 +208,79 @@ static void amdgpu_close_devices() static void amdgpu_print_devices() { int i; - for (i = 0; i < MAX_CARDS_SUPPORTED; i++) - if (drm_amdgpu[i] >=0) { - /** Display version of DRM driver */ - drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); + drmDevicePtr device; + + /* Open the first AMD devcie to print driver information. */ + if (drm_amdgpu[0] >=0) { + /* Display AMD driver version information.*/ + drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); + + if (retval == NULL) { + perror("Cannot get version for AMDGPU device"); + return; + } - if (retval == NULL) { - perror("Cannot get version for AMDGPU device"); - exit(EXIT_FAILURE); + printf("Driver name: %s, Date: %s, Description: %s.\n", + retval->name, retval->date, retval->desc); + drmFreeVersion(retval); + } + + /* Display information of AMD devices */ + printf("Devices:\n"); + for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++) + if (drmGetDevice2(drm_amdgpu[i], + DRM_DEVICE_GET_PCI_REVISION, + ) == 0) { + if (device->bustype == DRM_BUS_PCI) { + printf("PCI "); + printf(" domain:%04x", + device->businfo.pci->domain); + printf(" bus:%02x", + device->businfo.pci->bus); + printf(" device:%02x", + device->businfo.pci->dev); + printf(" function:%01x", + device->businfo.pci->func); + printf(" vendor_id:%04x", + device->deviceinfo.pci->vendor_id); + printf(" device_id:%04x", + device->deviceinfo.pci->device_id); + printf(" subvendor_id:%04x", + device->deviceinfo.pci->subvendor_id); + printf(" subdevice_id:%04x", + device->deviceinfo.pci->subdevice_id); + printf(" revision_id:%02x", + device->deviceinfo.pci->revision_id); + printf("\n"); } + drmFreeDevice(); + } +} + +/* Find a match AMD device in PCI bus + * Return the ind
[PATCH libdrm 1/3] amdgpu: verify the tested device
Verify the vender ID and driver name. Open all AMDGPU devices. Provide an option to open render node. Tested as root: PASS Tested as non-privileged user: All tests failed as expected v2: Return value in the ene of function amdgpu_open_devices. Check the return value of amdgpu_open_devices. amdgpu_test is not for USB device for the time being. Get the name of node from function drmGetDevices2. Drop the legacy drmAvailable() from the test. Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 145 +++-- 1 file changed, 115 insertions(+), 30 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index 71f357c..d2b00d4 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -115,6 +115,111 @@ static const char usage[] = "Usage: %s [-hl] [<-s > [-t ]]\n" /** Specified options strings for getopt */ static const char options[] = "hls:t:"; +/* Open AMD devices. + * Return the number of AMD device openned. + */ +static int amdgpu_open_devices(int open_render_node) +{ + drmDevicePtr devices[MAX_CARDS_SUPPORTED]; + int ret; + int i; + int drm_node; + int amd_index = 0; + int drm_count; + int fd; + drmVersionPtr version; + + drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); + + if (drm_count < 0) { + fprintf(stderr, + "drmGetDevices2() returned an error %d\n", + drm_count); + return 0; + } + + for (i = 0; i < drm_count; i++) { + /* If this is not PCI device, skip*/ + if (devices[i]->bustype != DRM_BUS_PCI) + continue; + + /* If this is not AMD GPU vender ID, skip*/ + if (devices[i]->deviceinfo.pci->vendor_id != 0x1002) + continue; + + if (open_render_node) + drm_node = DRM_NODE_RENDER; + else + drm_node = DRM_NODE_PRIMARY; + + fd = -1; + if (devices[i]->available_nodes & 1 << drm_node) + fd = open( + devices[i]->nodes[drm_node], + O_RDWR | O_CLOEXEC); + + /* This node is not available. */ + if (fd < 0) continue; + + version = drmGetVersion(fd); + if (!version) { + fprintf(stderr, + "Warning: Cannot get version for %s." + "Error is %s\n", + devices[i]->nodes[drm_node], + strerror(errno)); + close(fd); + continue; + } + + if (strcmp(version->name, "amdgpu")) { + /* This is not AMDGPU driver, skip.*/ + drmFreeVersion(version); + close(fd); + continue; + } + + drmFreeVersion(version); + + drm_amdgpu[amd_index] = fd; + amd_index++; + } + + drmFreeDevices(devices, drm_count); + return amd_index; +} + +/* Close AMD devices. + */ +static void amdgpu_close_devices() +{ + int i; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) + if (drm_amdgpu[i] >=0) + close(drm_amdgpu[i]); +} + +/* Print AMD devices information */ +static void amdgpu_print_devices() +{ + int i; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) + if (drm_amdgpu[i] >=0) { + /** Display version of DRM driver */ + drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); + + if (retval == NULL) { + perror("Cannot get version for AMDGPU device"); + exit(EXIT_FAILURE); + } + + printf("AMDGPU device #%d: " + "Name: [%s] : Date [%s] : Description [%s]\n", + i, retval->name, retval->date, retval->desc); + drmFreeVersion(retval); + } +} + /* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another * CUnit error code on failure. @@ -128,14 +233,6 @@ int main(int argc, char **argv) CU_pSuite pSuite = NULL; CU_pTest pTest = NULL; - int aval = drmAvailable(); - - if (aval == 0) { - fprintf(stderr, "DRM driver is not available\n"); - e
[PATCH libdrm 3/3] amdgpu: A new option to run tests on render node
Tested: 1. As root, tests passed on primary. 2. As root, BO export/import failed on render node as expected. 3. As non-privileged user, tests failed on primary as expected. 4. As non-privileged user, only BO export/import failed on render node as expected. Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index 2437db4..a6f1dd1 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -109,13 +109,14 @@ static void display_test_suites(void) /** Help string for command line parameters */ static const char usage[] = - "Usage: %s [-hl] [<-s > [-t ]] [-d ]\n" + "Usage: %s [-hlr] [<-s > [-t ]] [-d ]\n" "where:\n" " l - Display all suites and their tests\n" + " r - Run the tests on render node\n" " d - Choose which device to run tests\n" " h - Display this help\n"; /** Specified options strings for getopt */ -static const char options[] = "hls:t:d:"; +static const char options[] = "hlrs:t:d:"; /* Open AMD devices. * Return the number of AMD device openned. @@ -241,6 +242,7 @@ int main(int argc, char **argv) int suite_id = -1; /* By default run everything */ int test_id = -1; /* By default run all tests in the suite */ int device_id = 0; /* By default run most tests on device 0 */ + int render_node = 0;/* By default run most tests on primary node */ CU_pSuite pSuite = NULL; CU_pTest pTest = NULL; @@ -272,6 +274,9 @@ int main(int argc, char **argv) case 'd': device_id = atoi(optarg); break; + case 'r': + render_node = 1; + break; case '?': case 'h': fprintf(stderr, usage, argv[0]); @@ -282,7 +287,7 @@ int main(int argc, char **argv) } } - amdgpu_open_devices(0); + amdgpu_open_devices(render_node); if (drm_amdgpu[0] < 0) { perror("Cannot open AMDGPU device.\n"); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH libdrm 1/3] amdgpu: verify the tested device
Verify the vender ID and driver name. Open all AMDGPU devices. Provide an option to open render node. Tested as root: PASS Tested as non-privileged user: All tests failed as expected Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 144 + 1 file changed, 121 insertions(+), 23 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index 71f357c..e42ef9d 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -115,6 +115,119 @@ static const char usage[] = "Usage: %s [-hl] [<-s > [-t ]]\n" /** Specified options strings for getopt */ static const char options[] = "hls:t:"; +/* Open AMD devices. + * Return the number of AMD device openned. + */ +static int amdgpu_open_devices(int open_render_node) +{ + drmDevicePtr devices[MAX_CARDS_SUPPORTED]; + int ret; + int i; + int j; + int amd_index = 0; + int drm_count; + int fd; + char *device_name; + drmVersionPtr version; + + drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); + + if (drm_count < 0) { + fprintf(stderr, + "drmGetDevices2() returned an error %d\n", + drm_count); + return 0; + } + + for (i = 0; i < drm_count; i++) { + /* If this is not AMD GPU vender ID, skip*/ + if (devices[i]->bustype == DRM_BUS_PCI) + if (devices[i]->deviceinfo.pci->vendor_id != 0x1002) + continue; + + for (j = 0; j < DRM_NODE_MAX; j++) { + if (devices[i]->available_nodes & 1 << j) { + fd = open( + devices[i]->nodes[j], + O_RDONLY | O_CLOEXEC, + 0); + if (fd < 0) continue; + } + + version = drmGetVersion(fd); + if (!version) { + fprintf(stderr, + "Warning: Cannot get version for %s." + "Error is %s\n", + devices[i]->nodes[j], + strerror(errno)); + close(fd); + break; + } + + if (strcmp(version->name, "amdgpu")) { + /* This is not AMDGPU driver, skip.*/ + drmFreeVersion(version); + close(fd); + break; + } + + drmFreeVersion(version); + + if (open_render_node) + device_name = drmGetRenderDeviceNameFromFd(fd); + else + device_name = drmGetPrimaryDeviceNameFromFd(fd); + + close(fd); + + drm_amdgpu[amd_index] = open(device_name, + O_RDWR | O_CLOEXEC); + + if (drm_amdgpu[amd_index] >= 0) + amd_index++; + + free(device_name); + + /* We have open this device. Go to next device.*/ + break; + } + } + + drmFreeDevices(devices, drm_count); +} + +/* Close AMD devices. + */ +static void amdgpu_close_devices() +{ + int i; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) + if (drm_amdgpu[i] >=0) + close(drm_amdgpu[i]); +} + +/* Print AMD devices information */ +static void amdgpu_print_devices() +{ + int i; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) + if (drm_amdgpu[i] >=0) { + /** Display version of DRM driver */ + drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); + + if (retval == NULL) { + perror("Cannot get version for AMDGPU device"); + exit(EXIT_FAILURE); + } + + printf("AMDGPU device #%d: " + "Name: [%s] : Date [%s] : Description [%s]\n", + i, retval->name, retval->date, retval->desc); + drmFreeVersion(retval); + } +} + /* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another * CUnit error code on failure. @@ -163
[PATCH libdrm 2/3] amdgpu: A new option to choose which device to run most tests
This can be used to test multiple GPUs Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/amdgpu_test.c | 25 - 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index e42ef9d..2437db4 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -108,12 +108,14 @@ static void display_test_suites(void) /** Help string for command line parameters */ -static const char usage[] = "Usage: %s [-hl] [<-s > [-t ]]\n" - "where:\n" - " l - Display all suites and their tests\n" - " h - Display this help\n"; +static const char usage[] = + "Usage: %s [-hl] [<-s > [-t ]] [-d ]\n" + "where:\n" + " l - Display all suites and their tests\n" + " d - Choose which device to run tests\n" + " h - Display this help\n"; /** Specified options strings for getopt */ -static const char options[] = "hls:t:"; +static const char options[] = "hls:t:d:"; /* Open AMD devices. * Return the number of AMD device openned. @@ -238,6 +240,7 @@ int main(int argc, char **argv) int i = 0; int suite_id = -1; /* By default run everything */ int test_id = -1; /* By default run all tests in the suite */ + int device_id = 0; /* By default run most tests on device 0 */ CU_pSuite pSuite = NULL; CU_pTest pTest = NULL; @@ -266,6 +269,9 @@ int main(int argc, char **argv) case 't': test_id = atoi(optarg); break; + case 'd': + device_id = atoi(optarg); + break; case '?': case 'h': fprintf(stderr, usage, argv[0]); @@ -283,6 +289,15 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + if (device_id) { + /* Most tests run on device 0. +* Swap the chosen device to device 0. +*/ + i = drm_amdgpu[0]; + drm_amdgpu[0] = drm_amdgpu[device_id]; + drm_amdgpu[device_id] = i; + } + amdgpu_print_devices(); /* Initialize test suites to run */ -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH libdrm] amdgpu: Provide more specific error message if non-privileged user runs amdgpu_test
Before this change, the error message is: "WARNING - Suite initialization failed..." People might think this is a driver problem. Tested with non-privileged user. Now the error message is like: ... Error:Permission denied. Hint:Try to run this test program as root. WARNING - Suite initialization failed for 'Basic Tests'. ... Tested as root with no regression. amdgpu_test uses CUnit. CUnit outputs warning message to stdout. To be consistent, this commit outputs error message to stdout. v2: Use strerror instead of %m. %m is a GNU C Library extension. v3: Limit code and commit message within 80 characters per line. Update commit message. Remove a space before starting parenthesis in function call. Change-Id: Ib891c40ec812053f49ce5a99909455ac3137e32c Signed-off-by: Alex Xie <alexbin@amd.com> --- tests/amdgpu/basic_tests.c | 7 ++- tests/amdgpu/bo_tests.c| 8 +++- tests/amdgpu/cs_tests.c| 8 +++- tests/amdgpu/vce_tests.c | 8 +++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c index 11f6a63..bfda21b 100644 --- a/tests/amdgpu/basic_tests.c +++ b/tests/amdgpu/basic_tests.c @@ -206,8 +206,13 @@ int suite_basic_tests_init(void) if (r == 0) return CUE_SUCCESS; - else + else { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); return CUE_SINIT_FAILED; + } } int suite_basic_tests_clean(void) diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c index 993895d..25df767 100644 --- a/tests/amdgpu/bo_tests.c +++ b/tests/amdgpu/bo_tests.c @@ -65,8 +65,14 @@ int suite_bo_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], _version, _version, _handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } req.alloc_size = BUFFER_SIZE; req.phys_alignment = BUFFER_ALIGN; diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c index a01ee48..82c55aa 100644 --- a/tests/amdgpu/cs_tests.c +++ b/tests/amdgpu/cs_tests.c @@ -76,8 +76,14 @@ int suite_cs_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], _version, _version, _handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } family_id = device_handle->info.family_id; /* VI asic POLARIS10/11 have specific external_rev_id */ diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c index 4915170..de63aa1 100644 --- a/tests/amdgpu/vce_tests.c +++ b/tests/amdgpu/vce_tests.c @@ -94,8 +94,14 @@ int suite_vce_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], _version, _version, _handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } family_id = device_handle->info.family_id; vce_harvest_config = device_handle->info.vce_harvest_config; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx