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) {
|
switch (args->param) {
|
||||||
case DRM_VC4_PARAM_V3D_IDENT0:
|
case DRM_VC4_PARAM_V3D_IDENT0:
|
||||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
args->value = V3D_READ(V3D_IDENT0);
|
args->value = V3D_READ(V3D_IDENT0);
|
||||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||||
break;
|
break;
|
||||||
case DRM_VC4_PARAM_V3D_IDENT1:
|
case DRM_VC4_PARAM_V3D_IDENT1:
|
||||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
args->value = V3D_READ(V3D_IDENT1);
|
args->value = V3D_READ(V3D_IDENT1);
|
||||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||||
break;
|
break;
|
||||||
case DRM_VC4_PARAM_V3D_IDENT2:
|
case DRM_VC4_PARAM_V3D_IDENT2:
|
||||||
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
args->value = V3D_READ(V3D_IDENT2);
|
args->value = V3D_READ(V3D_IDENT2);
|
||||||
pm_runtime_put(&vc4->v3d->pdev->dev);
|
pm_runtime_put(&vc4->v3d->pdev->dev);
|
||||||
|
@@ -321,6 +321,15 @@ vc4_first_render_job(struct vc4_dev *vc4)
|
|||||||
struct vc4_exec_info, head);
|
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
|
* struct vc4_texture_sample_info - saves the offsets into the UBO for texture
|
||||||
* setup parameters.
|
* setup parameters.
|
||||||
|
@@ -534,8 +534,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *),
|
exec->bo = drm_calloc_large(exec->bo_count,
|
||||||
GFP_KERNEL);
|
sizeof(struct drm_gem_cma_object *));
|
||||||
if (!exec->bo) {
|
if (!exec->bo) {
|
||||||
DRM_ERROR("Failed to allocate validated BO pointers\n");
|
DRM_ERROR("Failed to allocate validated BO pointers\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -572,8 +572,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
|
|||||||
spin_unlock(&file_priv->table_lock);
|
spin_unlock(&file_priv->table_lock);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
kfree(handles);
|
drm_free_large(handles);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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
|
* read the contents back for validation, and I think the
|
||||||
* bo->vaddr is uncached access.
|
* bo->vaddr is uncached access.
|
||||||
*/
|
*/
|
||||||
temp = kmalloc(temp_size, GFP_KERNEL);
|
temp = drm_malloc_ab(temp_size, 1);
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
DRM_ERROR("Failed to allocate storage for copying "
|
DRM_ERROR("Failed to allocate storage for copying "
|
||||||
"in bin/render CLs.\n");
|
"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);
|
ret = vc4_validate_shader_recs(dev, exec);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
kfree(temp);
|
drm_free_large(temp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +688,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
|
|||||||
if (exec->bo) {
|
if (exec->bo) {
|
||||||
for (i = 0; i < exec->bo_count; i++)
|
for (i = 0; i < exec->bo_count; i++)
|
||||||
drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
|
drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
|
||||||
kfree(exec->bo);
|
drm_free_large(exec->bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!list_empty(&exec->unref_list)) {
|
while (!list_empty(&exec->unref_list)) {
|
||||||
@@ -942,8 +942,8 @@ vc4_gem_destroy(struct drm_device *dev)
|
|||||||
vc4->overflow_mem = NULL;
|
vc4->overflow_mem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vc4_bo_cache_destroy(dev);
|
|
||||||
|
|
||||||
if (vc4->hang_state)
|
if (vc4->hang_state)
|
||||||
vc4_free_hang_state(dev, 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);
|
spin_lock_irqsave(&vc4->job_lock, irqflags);
|
||||||
current_exec = vc4_first_bin_job(vc4);
|
current_exec = vc4_first_bin_job(vc4);
|
||||||
|
if (!current_exec)
|
||||||
|
current_exec = vc4_last_render_job(vc4);
|
||||||
if (current_exec) {
|
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,
|
list_add_tail(&vc4->overflow_mem->unref_head,
|
||||||
¤t_exec->unref_list);
|
¤t_exec->unref_list);
|
||||||
vc4->overflow_mem = NULL;
|
vc4->overflow_mem = NULL;
|
||||||
|
Reference in New Issue
Block a user