Merge tag 'drm-vc4-fixes-2016-08-29' of https://github.com/anholt/linux into drm-fixes
This pull request brings in fixes for VC4 3D in 4.8, most of which are covered by testcases. * tag 'drm-vc4-fixes-2016-08-29' of https://github.com/anholt/linux: drm/vc4: Fix oops when userspace hands in a bad BO. drm/vc4: Fix overflow mem unreferencing when the binner runs dry. drm/vc4: Free hang state before destroying BO cache. drm/vc4: Fix handling of a pm_runtime_get_sync() success case. drm/vc4: Use drm_malloc_ab to fix large rendering jobs. drm/vc4: Use drm_free_large() on handles to match its allocation.
This commit is contained in:
@@ -57,21 +57,21 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
|
||||
switch (args->param) {
|
||||
case DRM_VC4_PARAM_V3D_IDENT0:
|
||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
args->value = V3D_READ(V3D_IDENT0);
|
||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||
break;
|
||||
case DRM_VC4_PARAM_V3D_IDENT1:
|
||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
args->value = V3D_READ(V3D_IDENT1);
|
||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||
break;
|
||||
case DRM_VC4_PARAM_V3D_IDENT2:
|
||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
args->value = V3D_READ(V3D_IDENT2);
|
||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||
|
||||
@@ -321,6 +321,15 @@ vc4_first_render_job(struct vc4_dev *vc4)
|
||||
struct vc4_exec_info, head);
|
||||
}
|
||||
|
||||
static inline struct vc4_exec_info *
|
||||
vc4_last_render_job(struct vc4_dev *vc4)
|
||||
{
|
||||
if (list_empty(&vc4->render_job_list))
|
||||
return NULL;
|
||||
return list_last_entry(&vc4->render_job_list,
|
||||
struct vc4_exec_info, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct vc4_texture_sample_info - saves the offsets into the UBO for texture
|
||||
* setup parameters.
|
||||
|
||||
@@ -534,8 +534,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *),
|
||||
GFP_KERNEL);
|
||||
exec->bo = drm_calloc_large(exec->bo_count,
|
||||
sizeof(struct drm_gem_cma_object *));
|
||||
if (!exec->bo) {
|
||||
DRM_ERROR("Failed to allocate validated BO pointers\n");
|
||||
return -ENOMEM;
|
||||
@@ -572,8 +572,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
|
||||
fail:
|
||||
kfree(handles);
|
||||
return 0;
|
||||
drm_free_large(handles);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -608,7 +608,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
|
||||
* read the contents back for validation, and I think the
|
||||
* bo->vaddr is uncached access.
|
||||
*/
|
||||
temp = kmalloc(temp_size, GFP_KERNEL);
|
||||
temp = drm_malloc_ab(temp_size, 1);
|
||||
if (!temp) {
|
||||
DRM_ERROR("Failed to allocate storage for copying "
|
||||
"in bin/render CLs.\n");
|
||||
@@ -675,7 +675,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
|
||||
ret = vc4_validate_shader_recs(dev, exec);
|
||||
|
||||
fail:
|
||||
kfree(temp);
|
||||
drm_free_large(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
|
||||
if (exec->bo) {
|
||||
for (i = 0; i < exec->bo_count; i++)
|
||||
drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
|
||||
kfree(exec->bo);
|
||||
drm_free_large(exec->bo);
|
||||
}
|
||||
|
||||
while (!list_empty(&exec->unref_list)) {
|
||||
@@ -942,8 +942,8 @@ vc4_gem_destroy(struct drm_device *dev)
|
||||
vc4->overflow_mem = NULL;
|
||||
}
|
||||
|
||||
vc4_bo_cache_destroy(dev);
|
||||
|
||||
if (vc4->hang_state)
|
||||
vc4_free_hang_state(dev, vc4->hang_state);
|
||||
|
||||
vc4_bo_cache_destroy(dev);
|
||||
}
|
||||
|
||||
@@ -83,8 +83,10 @@ vc4_overflow_mem_work(struct work_struct *work)
|
||||
|
||||
spin_lock_irqsave(&vc4->job_lock, irqflags);
|
||||
current_exec = vc4_first_bin_job(vc4);
|
||||
if (!current_exec)
|
||||
current_exec = vc4_last_render_job(vc4);
|
||||
if (current_exec) {
|
||||
vc4->overflow_mem->seqno = vc4->finished_seqno + 1;
|
||||
vc4->overflow_mem->seqno = current_exec->seqno;
|
||||
list_add_tail(&vc4->overflow_mem->unref_head,
|
||||
¤t_exec->unref_list);
|
||||
vc4->overflow_mem = NULL;
|
||||
|
||||
Reference in New Issue
Block a user