Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 603f2c9f authored by Dave Airlie's avatar Dave Airlie
Browse files

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.
parents 53229425 552416c1
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -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);
+9 −0
Original line number Original line Diff line number Diff line
@@ -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.
+9 −9
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -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,
				      &current_exec->unref_list);
				      &current_exec->unref_list);
			vc4->overflow_mem = NULL;
			vc4->overflow_mem = NULL;