mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
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: Rob Clark <robdclark@chromium.org> Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com> Tested-by: Antonino Maniscalco <antomani103@gmail.com> Reviewed-by: Antonino Maniscalco <antomani103@gmail.com> Patchwork: https://patchwork.freedesktop.org/patch/661497/
This commit is contained in:
parent
6a4d287a1a
commit
b58e12a66e
@ -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);
|
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 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_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);
|
int msm_gem_prime_pin(struct drm_gem_object *obj);
|
||||||
void msm_gem_prime_unpin(struct drm_gem_object *obj);
|
void msm_gem_prime_unpin(struct drm_gem_object *obj);
|
||||||
|
|
||||||
|
@ -546,6 +546,9 @@ static int get_and_pin_iova_range_locked(struct drm_gem_object *obj,
|
|||||||
|
|
||||||
msm_gem_assert_locked(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);
|
vma = get_vma_locked(obj, vm, range_start, range_end);
|
||||||
if (IS_ERR(vma))
|
if (IS_ERR(vma))
|
||||||
return PTR_ERR(vma);
|
return PTR_ERR(vma);
|
||||||
@ -1076,6 +1079,14 @@ static void msm_gem_free_object(struct drm_gem_object *obj)
|
|||||||
put_pages(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);
|
drm_gem_object_release(obj);
|
||||||
|
|
||||||
kfree(msm_obj->metadata);
|
kfree(msm_obj->metadata);
|
||||||
@ -1108,6 +1119,15 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
|
|||||||
if (name)
|
if (name)
|
||||||
msm_gem_object_set_name(obj, "%s", 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);
|
ret = drm_gem_handle_create(file, obj, handle);
|
||||||
|
|
||||||
/* drop reference from allocate - handle holds it now */
|
/* 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,
|
.free = msm_gem_free_object,
|
||||||
.open = msm_gem_open,
|
.open = msm_gem_open,
|
||||||
.close = msm_gem_close,
|
.close = msm_gem_close,
|
||||||
|
.export = msm_gem_prime_export,
|
||||||
.pin = msm_gem_prime_pin,
|
.pin = msm_gem_prime_pin,
|
||||||
.unpin = msm_gem_prime_unpin,
|
.unpin = msm_gem_prime_unpin,
|
||||||
.get_sg_table = msm_gem_prime_get_sg_table,
|
.get_sg_table = msm_gem_prime_get_sg_table,
|
||||||
|
@ -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);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
int npages = obj->size >> PAGE_SHIFT;
|
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! */
|
if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */
|
||||||
return ERR_PTR(-ENOMEM);
|
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);
|
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)
|
int msm_gem_prime_pin(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
@ -53,6 +65,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj)
|
|||||||
if (drm_gem_is_imported(obj))
|
if (drm_gem_is_imported(obj))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
pages = msm_gem_pin_pages_locked(obj);
|
pages = msm_gem_pin_pages_locked(obj);
|
||||||
if (IS_ERR(pages))
|
if (IS_ERR(pages))
|
||||||
ret = PTR_ERR(pages);
|
ret = PTR_ERR(pages);
|
||||||
|
@ -140,6 +140,19 @@ struct drm_msm_param {
|
|||||||
|
|
||||||
#define MSM_BO_SCANOUT 0x00000001 /* scanout capable */
|
#define MSM_BO_SCANOUT 0x00000001 /* scanout capable */
|
||||||
#define MSM_BO_GPU_READONLY 0x00000002
|
#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
|
#define MSM_BO_CACHE_MASK 0x000f0000
|
||||||
/* cache modes */
|
/* cache modes */
|
||||||
#define MSM_BO_CACHED 0x00010000
|
#define MSM_BO_CACHED 0x00010000
|
||||||
@ -149,6 +162,7 @@ struct drm_msm_param {
|
|||||||
|
|
||||||
#define MSM_BO_FLAGS (MSM_BO_SCANOUT | \
|
#define MSM_BO_FLAGS (MSM_BO_SCANOUT | \
|
||||||
MSM_BO_GPU_READONLY | \
|
MSM_BO_GPU_READONLY | \
|
||||||
|
MSM_BO_NO_SHARE | \
|
||||||
MSM_BO_CACHE_MASK)
|
MSM_BO_CACHE_MASK)
|
||||||
|
|
||||||
struct drm_msm_gem_new {
|
struct drm_msm_gem_new {
|
||||||
|
Loading…
Reference in New Issue
Block a user