Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "Most of the GPU drivers people were at XDC last week, so I didn't get
  much to send, so I let it rollover until this week.

  Also Alex was away for 3 weeks so amdgpu/radeon got a bit more stuff
  than usual in one go.

  I've been trying to figure out some 4.2 issues with i915 still (that
  are fixed in 4.3, but bisecting ends up in a merge commit).  Hopefully
  next week I or i915 people can work that out"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (46 commits)
  drm: Allow also control clients to check the drm version
  drm/vmwgfx: Fix uninitialized return in vmw_kms_helper_dirty()
  drm/vmwgfx: Fix uninitialized return in vmw_cotable_unbind()
  drm/layerscape: fix handling fsl_dcu_drm_plane_index result
  drm/mgag200: Fix driver_load error handling
  drm/mgag200: Fix error handling paths in fbdev driver
  drm/qxl: only report first monitor as connected if we have no state
  drm/radeon: add quirk for MSI R7 370
  drm/amdgpu: Sprinkle drm_modeset_lock_all to appease locking checks
  drm/radeon: Sprinkle drm_modeset_lock_all to appease locking checks
  drm/amdgpu: sync ce and me with SWITCH_BUFFER(2)
  drm/amdgpu: integer overflow in amdgpu_mode_dumb_create()
  drm/amdgpu: info leak in amdgpu_gem_metadata_ioctl()
  drm/amdgpu: integer overflow in amdgpu_info_ioctl()
  drm/amdgpu: unwind properly in amdgpu_cs_parser_init()
  drm/amdgpu: Fix max_vblank_count value for current display engines
  drm/amdgpu: use kmemdup rather than duplicating its implementation
  drm/amdgpu: fix UVD suspend and resume for VI APU
  drm/amdgpu: fix the UVD suspend sequence order
  drm/amdgpu: make UVD handle checking more strict
  ...
  • Loading branch information
torvalds committed Sep 24, 2015
2 parents bfbaa60 + fd03420 commit cc8b8fa
Show file tree
Hide file tree
Showing 63 changed files with 691 additions and 544 deletions.
11 changes: 6 additions & 5 deletions drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ extern int amdgpu_vm_block_size;
extern int amdgpu_enable_scheduler;
extern int amdgpu_sched_jobs;
extern int amdgpu_sched_hw_submission;
extern int amdgpu_enable_semaphores;

#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
Expand Down Expand Up @@ -432,7 +433,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev);
void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);

void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
struct amdgpu_irq_src *irq_src,
unsigned irq_type);
Expand Down Expand Up @@ -890,7 +891,7 @@ struct amdgpu_ring {
struct amdgpu_device *adev;
const struct amdgpu_ring_funcs *funcs;
struct amdgpu_fence_driver fence_drv;
struct amd_gpu_scheduler *scheduler;
struct amd_gpu_scheduler sched;

spinlock_t fence_lock;
struct mutex *ring_lock;
Expand Down Expand Up @@ -1201,8 +1202,6 @@ struct amdgpu_gfx {
struct amdgpu_irq_src priv_inst_irq;
/* gfx status */
uint32_t gfx_current_status;
/* sync signal for const engine */
unsigned ce_sync_offs;
/* ce ram size*/
unsigned ce_ram_size;
};
Expand Down Expand Up @@ -1274,8 +1273,10 @@ struct amdgpu_job {
uint32_t num_ibs;
struct mutex job_lock;
struct amdgpu_user_fence uf;
int (*free_job)(struct amdgpu_job *sched_job);
int (*free_job)(struct amdgpu_job *job);
};
#define to_amdgpu_job(sched_job) \
container_of((sched_job), struct amdgpu_job, base)

static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx)
{
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
return -ENOMEM;

r = amdgpu_bo_create(rdev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, &(*mem)->bo);
AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, &(*mem)->bo);
if (r) {
dev_err(rdev->dev,
"failed to allocate BO for amdkfd (%d)\n", r);
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
int time;

n = AMDGPU_BENCHMARK_ITERATIONS;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL, &sobj);
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL,
NULL, &sobj);
if (r) {
goto out_cleanup;
}
Expand All @@ -91,7 +92,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
if (r) {
goto out_cleanup;
}
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL, &dobj);
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL,
NULL, &dobj);
if (r) {
goto out_cleanup;
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static int amdgpu_cgs_gmap_kmem(void *cgs_device, void *kmem,

struct sg_table *sg = drm_prime_pages_to_sg(&kmem_page, npages);
ret = amdgpu_bo_create(adev, size, PAGE_SIZE, false,
AMDGPU_GEM_DOMAIN_GTT, 0, sg, &bo);
AMDGPU_GEM_DOMAIN_GTT, 0, sg, NULL, &bo);
if (ret)
return ret;
ret = amdgpu_bo_reserve(bo, false);
Expand Down Expand Up @@ -197,7 +197,8 @@ static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,

ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE,
true, domain, flags,
NULL, &placement, &obj);
NULL, &placement, NULL,
&obj);
if (ret) {
DRM_ERROR("(%d) bo create failed\n", ret);
return ret;
Expand Down
137 changes: 80 additions & 57 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,42 +154,41 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
{
union drm_amdgpu_cs *cs = data;
uint64_t *chunk_array_user;
uint64_t *chunk_array = NULL;
uint64_t *chunk_array;
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
unsigned size, i;
int r = 0;
int ret;

if (!cs->in.num_chunks)
goto out;
if (cs->in.num_chunks == 0)
return 0;

chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
if (!chunk_array)
return -ENOMEM;

p->ctx = amdgpu_ctx_get(fpriv, cs->in.ctx_id);
if (!p->ctx) {
r = -EINVAL;
goto out;
ret = -EINVAL;
goto free_chunk;
}

p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);

/* get chunks */
INIT_LIST_HEAD(&p->validated);
chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
if (chunk_array == NULL) {
r = -ENOMEM;
goto out;
}

chunk_array_user = (uint64_t __user *)(cs->in.chunks);
if (copy_from_user(chunk_array, chunk_array_user,
sizeof(uint64_t)*cs->in.num_chunks)) {
r = -EFAULT;
goto out;
ret = -EFAULT;
goto put_bo_list;
}

p->nchunks = cs->in.num_chunks;
p->chunks = kmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),
GFP_KERNEL);
if (p->chunks == NULL) {
r = -ENOMEM;
goto out;
if (!p->chunks) {
ret = -ENOMEM;
goto put_bo_list;
}

for (i = 0; i < p->nchunks; i++) {
Expand All @@ -200,8 +199,9 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
chunk_ptr = (void __user *)chunk_array[i];
if (copy_from_user(&user_chunk, chunk_ptr,
sizeof(struct drm_amdgpu_cs_chunk))) {
r = -EFAULT;
goto out;
ret = -EFAULT;
i--;
goto free_partial_kdata;
}
p->chunks[i].chunk_id = user_chunk.chunk_id;
p->chunks[i].length_dw = user_chunk.length_dw;
Expand All @@ -212,13 +212,14 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)

p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
if (p->chunks[i].kdata == NULL) {
r = -ENOMEM;
goto out;
ret = -ENOMEM;
i--;
goto free_partial_kdata;
}
size *= sizeof(uint32_t);
if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
r = -EFAULT;
goto out;
ret = -EFAULT;
goto free_partial_kdata;
}

switch (p->chunks[i].chunk_id) {
Expand All @@ -238,35 +239,51 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
gobj = drm_gem_object_lookup(p->adev->ddev,
p->filp, handle);
if (gobj == NULL) {
r = -EINVAL;
goto out;
ret = -EINVAL;
goto free_partial_kdata;
}

p->uf.bo = gem_to_amdgpu_bo(gobj);
p->uf.offset = fence_data->offset;
} else {
r = -EINVAL;
goto out;
ret = -EINVAL;
goto free_partial_kdata;
}
break;

case AMDGPU_CHUNK_ID_DEPENDENCIES:
break;

default:
r = -EINVAL;
goto out;
ret = -EINVAL;
goto free_partial_kdata;
}
}


p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL);
if (!p->ibs)
r = -ENOMEM;
if (!p->ibs) {
ret = -ENOMEM;
goto free_all_kdata;
}

out:
kfree(chunk_array);
return r;
return 0;

free_all_kdata:
i = p->nchunks - 1;
free_partial_kdata:
for (; i >= 0; i--)
drm_free_large(p->chunks[i].kdata);
kfree(p->chunks);
put_bo_list:
if (p->bo_list)
amdgpu_bo_list_put(p->bo_list);
amdgpu_ctx_put(p->ctx);
free_chunk:
kfree(chunk_array);

return ret;
}

/* Returns how many bytes TTM can move per IB.
Expand Down Expand Up @@ -321,25 +338,17 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
return max(bytes_moved_threshold, 1024*1024ull);
}

int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p)
int amdgpu_cs_list_validate(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
struct list_head *validated)
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_device *adev = p->adev;
struct amdgpu_bo_list_entry *lobj;
struct list_head duplicates;
struct amdgpu_bo *bo;
u64 bytes_moved = 0, initial_bytes_moved;
u64 bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(adev);
int r;

INIT_LIST_HEAD(&duplicates);
r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates);
if (unlikely(r != 0)) {
return r;
}

list_for_each_entry(lobj, &p->validated, tv.head) {
list_for_each_entry(lobj, validated, tv.head) {
bo = lobj->robj;
if (!bo->pin_count) {
u32 domain = lobj->prefered_domains;
Expand Down Expand Up @@ -373,7 +382,6 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p)
domain = lobj->allowed_domains;
goto retry;
}
ttm_eu_backoff_reservation(&p->ticket, &p->validated);
return r;
}
}
Expand All @@ -386,6 +394,7 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_cs_buckets buckets;
struct list_head duplicates;
bool need_mmap_lock = false;
int i, r;

Expand All @@ -405,8 +414,22 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
if (need_mmap_lock)
down_read(&current->mm->mmap_sem);

r = amdgpu_cs_list_validate(p);
INIT_LIST_HEAD(&duplicates);
r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates);
if (unlikely(r != 0))
goto error_reserve;

r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated);
if (r)
goto error_validate;

r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates);

error_validate:
if (r)
ttm_eu_backoff_reservation(&p->ticket, &p->validated);

error_reserve:
if (need_mmap_lock)
up_read(&current->mm->mmap_sem);

Expand Down Expand Up @@ -772,15 +795,15 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
return 0;
}

static int amdgpu_cs_free_job(struct amdgpu_job *sched_job)
static int amdgpu_cs_free_job(struct amdgpu_job *job)
{
int i;
if (sched_job->ibs)
for (i = 0; i < sched_job->num_ibs; i++)
amdgpu_ib_free(sched_job->adev, &sched_job->ibs[i]);
kfree(sched_job->ibs);
if (sched_job->uf.bo)
drm_gem_object_unreference_unlocked(&sched_job->uf.bo->gem_base);
if (job->ibs)
for (i = 0; i < job->num_ibs; i++)
amdgpu_ib_free(job->adev, &job->ibs[i]);
kfree(job->ibs);
if (job->uf.bo)
drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base);
return 0;
}

Expand All @@ -804,7 +827,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
r = amdgpu_cs_parser_init(parser, data);
if (r) {
DRM_ERROR("Failed to initialize parser !\n");
amdgpu_cs_parser_fini(parser, r, false);
kfree(parser);
up_read(&adev->exclusive_lock);
r = amdgpu_cs_handle_lockup(adev, r);
return r;
Expand Down Expand Up @@ -842,7 +865,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);
if (!job)
return -ENOMEM;
job->base.sched = ring->scheduler;
job->base.sched = &ring->sched;
job->base.s_entity = &parser->ctx->rings[ring->idx].entity;
job->adev = parser->adev;
job->ibs = parser->ibs;
Expand All @@ -857,7 +880,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

job->free_job = amdgpu_cs_free_job;
mutex_lock(&job->job_lock);
r = amd_sched_entity_push_job((struct amd_sched_job *)job);
r = amd_sched_entity_push_job(&job->base);
if (r) {
mutex_unlock(&job->job_lock);
amdgpu_cs_free_job(job);
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
for (i = 0; i < adev->num_rings; i++) {
struct amd_sched_rq *rq;
if (kernel)
rq = &adev->rings[i]->scheduler->kernel_rq;
rq = &adev->rings[i]->sched.kernel_rq;
else
rq = &adev->rings[i]->scheduler->sched_rq;
r = amd_sched_entity_init(adev->rings[i]->scheduler,
rq = &adev->rings[i]->sched.sched_rq;
r = amd_sched_entity_init(&adev->rings[i]->sched,
&ctx->rings[i].entity,
rq, amdgpu_sched_jobs);
if (r)
Expand All @@ -55,7 +55,7 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,

if (i < adev->num_rings) {
for (j = 0; j < i; j++)
amd_sched_entity_fini(adev->rings[j]->scheduler,
amd_sched_entity_fini(&adev->rings[j]->sched,
&ctx->rings[j].entity);
kfree(ctx);
return r;
Expand All @@ -75,7 +75,7 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)

if (amdgpu_enable_scheduler) {
for (i = 0; i < adev->num_rings; i++)
amd_sched_entity_fini(adev->rings[i]->scheduler,
amd_sched_entity_fini(&adev->rings[i]->sched,
&ctx->rings[i].entity);
}
}
Expand Down
Loading

0 comments on commit cc8b8fa

Please sign in to comment.