Commit b58e12a6 authored by Rob Clark's avatar Rob Clark
Browse files

drm/msm: Add _NO_SHARE flag



Buffers that are not shared between contexts can share a single resv
object.  This way drm_gpuvm will not track them as external objects, and
submit-time validating overhead will be O(1) for all N non-shared BOs,
instead of O(n).

Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Signed-off-by: default avatarRob Clark <robin.clark@oss.qualcomm.com>
Tested-by: default avatarAntonino Maniscalco <antomani103@gmail.com>
Reviewed-by: default avatarAntonino Maniscalco <antomani103@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/661497/
parent 6a4d287a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
		struct dma_buf_attachment *attach, struct sg_table *sg);
struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags);
int msm_gem_prime_pin(struct drm_gem_object *obj);
void msm_gem_prime_unpin(struct drm_gem_object *obj);

+21 −0
Original line number Diff line number Diff line
@@ -546,6 +546,9 @@ static int get_and_pin_iova_range_locked(struct drm_gem_object *obj,

	msm_gem_assert_locked(obj);

	if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
		return -EINVAL;

	vma = get_vma_locked(obj, vm, range_start, range_end);
	if (IS_ERR(vma))
		return PTR_ERR(vma);
@@ -1076,6 +1079,14 @@ static void msm_gem_free_object(struct drm_gem_object *obj)
		put_pages(obj);
	}

	if (msm_obj->flags & MSM_BO_NO_SHARE) {
		struct drm_gem_object *r_obj =
			container_of(obj->resv, struct drm_gem_object, _resv);

		/* Drop reference we hold to shared resv obj: */
		drm_gem_object_put(r_obj);
	}

	drm_gem_object_release(obj);

	kfree(msm_obj->metadata);
@@ -1108,6 +1119,15 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
	if (name)
		msm_gem_object_set_name(obj, "%s", name);

	if (flags & MSM_BO_NO_SHARE) {
		struct msm_context *ctx = file->driver_priv;
		struct drm_gem_object *r_obj = drm_gpuvm_resv_obj(ctx->vm);

		drm_gem_object_get(r_obj);

		obj->resv = r_obj->resv;
	}

	ret = drm_gem_handle_create(file, obj, handle);

	/* drop reference from allocate - handle holds it now */
@@ -1140,6 +1160,7 @@ static const struct drm_gem_object_funcs msm_gem_object_funcs = {
	.free = msm_gem_free_object,
	.open = msm_gem_open,
	.close = msm_gem_close,
	.export = msm_gem_prime_export,
	.pin = msm_gem_prime_pin,
	.unpin = msm_gem_prime_unpin,
	.get_sg_table = msm_gem_prime_get_sg_table,
+15 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
	struct msm_gem_object *msm_obj = to_msm_bo(obj);
	int npages = obj->size >> PAGE_SHIFT;

	if (msm_obj->flags & MSM_BO_NO_SHARE)
		return ERR_PTR(-EINVAL);

	if (WARN_ON(!msm_obj->pages))  /* should have already pinned! */
		return ERR_PTR(-ENOMEM);

@@ -45,6 +48,15 @@ struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
	return msm_gem_import(dev, attach->dmabuf, sg);
}


struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)
{
	if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
		return ERR_PTR(-EPERM);

	return drm_gem_prime_export(obj, flags);
}

int msm_gem_prime_pin(struct drm_gem_object *obj)
{
	struct page **pages;
@@ -53,6 +65,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj)
	if (drm_gem_is_imported(obj))
		return 0;

	if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
		return -EINVAL;

	pages = msm_gem_pin_pages_locked(obj);
	if (IS_ERR(pages))
		ret = PTR_ERR(pages);
+14 −0
Original line number Diff line number Diff line
@@ -140,6 +140,19 @@ struct drm_msm_param {

#define MSM_BO_SCANOUT       0x00000001     /* scanout capable */
#define MSM_BO_GPU_READONLY  0x00000002
/* Private buffers do not need to be explicitly listed in the SUBMIT
 * ioctl, unless referenced by a drm_msm_gem_submit_cmd.  Private
 * buffers may NOT be imported/exported or used for scanout (or any
 * other situation where buffers can be indefinitely pinned, but
 * cases other than scanout are all kernel owned BOs which are not
 * visible to userspace).
 *
 * In exchange for those constraints, all private BOs associated with
 * a single context (drm_file) share a single dma_resv, and if there
 * has been no eviction since the last submit, there are no per-BO
 * bookeeping to do, significantly cutting the SUBMIT overhead.
 */
#define MSM_BO_NO_SHARE      0x00000004
#define MSM_BO_CACHE_MASK    0x000f0000
/* cache modes */
#define MSM_BO_CACHED        0x00010000
@@ -149,6 +162,7 @@ struct drm_msm_param {

#define MSM_BO_FLAGS         (MSM_BO_SCANOUT | \
                              MSM_BO_GPU_READONLY | \
                              MSM_BO_NO_SHARE | \
                              MSM_BO_CACHE_MASK)

struct drm_msm_gem_new {