Skip to content

Commit b58e12a

Browse files
robclarkRob Clark
authored andcommitted
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 <[email protected]> Signed-off-by: Rob Clark <[email protected]> Tested-by: Antonino Maniscalco <[email protected]> Reviewed-by: Antonino Maniscalco <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/661497/
1 parent 6a4d287 commit b58e12a

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

drivers/gpu/drm/msm/msm_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
269269
void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
270270
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
271271
struct dma_buf_attachment *attach, struct sg_table *sg);
272+
struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags);
272273
int msm_gem_prime_pin(struct drm_gem_object *obj);
273274
void msm_gem_prime_unpin(struct drm_gem_object *obj);
274275

drivers/gpu/drm/msm/msm_gem.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,9 @@ static int get_and_pin_iova_range_locked(struct drm_gem_object *obj,
546546

547547
msm_gem_assert_locked(obj);
548548

549+
if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
550+
return -EINVAL;
551+
549552
vma = get_vma_locked(obj, vm, range_start, range_end);
550553
if (IS_ERR(vma))
551554
return PTR_ERR(vma);
@@ -1076,6 +1079,14 @@ static void msm_gem_free_object(struct drm_gem_object *obj)
10761079
put_pages(obj);
10771080
}
10781081

1082+
if (msm_obj->flags & MSM_BO_NO_SHARE) {
1083+
struct drm_gem_object *r_obj =
1084+
container_of(obj->resv, struct drm_gem_object, _resv);
1085+
1086+
/* Drop reference we hold to shared resv obj: */
1087+
drm_gem_object_put(r_obj);
1088+
}
1089+
10791090
drm_gem_object_release(obj);
10801091

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

1122+
if (flags & MSM_BO_NO_SHARE) {
1123+
struct msm_context *ctx = file->driver_priv;
1124+
struct drm_gem_object *r_obj = drm_gpuvm_resv_obj(ctx->vm);
1125+
1126+
drm_gem_object_get(r_obj);
1127+
1128+
obj->resv = r_obj->resv;
1129+
}
1130+
11111131
ret = drm_gem_handle_create(file, obj, handle);
11121132

11131133
/* drop reference from allocate - handle holds it now */
@@ -1140,6 +1160,7 @@ static const struct drm_gem_object_funcs msm_gem_object_funcs = {
11401160
.free = msm_gem_free_object,
11411161
.open = msm_gem_open,
11421162
.close = msm_gem_close,
1163+
.export = msm_gem_prime_export,
11431164
.pin = msm_gem_prime_pin,
11441165
.unpin = msm_gem_prime_unpin,
11451166
.get_sg_table = msm_gem_prime_get_sg_table,

drivers/gpu/drm/msm/msm_gem_prime.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
1616
struct msm_gem_object *msm_obj = to_msm_bo(obj);
1717
int npages = obj->size >> PAGE_SHIFT;
1818

19+
if (msm_obj->flags & MSM_BO_NO_SHARE)
20+
return ERR_PTR(-EINVAL);
21+
1922
if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */
2023
return ERR_PTR(-ENOMEM);
2124

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

51+
52+
struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)
53+
{
54+
if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
55+
return ERR_PTR(-EPERM);
56+
57+
return drm_gem_prime_export(obj, flags);
58+
}
59+
4860
int msm_gem_prime_pin(struct drm_gem_object *obj)
4961
{
5062
struct page **pages;
@@ -53,6 +65,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj)
5365
if (drm_gem_is_imported(obj))
5466
return 0;
5567

68+
if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
69+
return -EINVAL;
70+
5671
pages = msm_gem_pin_pages_locked(obj);
5772
if (IS_ERR(pages))
5873
ret = PTR_ERR(pages);

include/uapi/drm/msm_drm.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,19 @@ struct drm_msm_param {
140140

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

150163
#define MSM_BO_FLAGS (MSM_BO_SCANOUT | \
151164
MSM_BO_GPU_READONLY | \
165+
MSM_BO_NO_SHARE | \
152166
MSM_BO_CACHE_MASK)
153167

154168
struct drm_msm_gem_new {

0 commit comments

Comments
 (0)