aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_gem.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-10-02 04:15:17 -0400
committerDave Airlie <airlied@redhat.com>2013-10-09 00:37:55 -0400
commit55fb74adc628b99424360b0123f47ea4484c56fd (patch)
tree3c8b51cc6047af2a59a40989e18c4844afa0a23e /drivers/gpu/drm/nouveau/nouveau_gem.c
parent51bbd276015661a28b69450e104632bc2b633311 (diff)
drm/nouveau: embed gem object in nouveau_bo
There is no reason to keep the gem object separately allocated. nouveau is the last user of gem_obj->driver_private, so if we embed it, we can get rid of 8bytes per gem-object. The implementation follows the radeon driver. bo->gem is only valid, iff the bo was created via the gem helpers _and_ iff the user holds a valid gem reference. That is, as the gem object holds a reference to the nouveau_bo. If you use nouveau_ref() to gain a bo reference, you are not guaranteed to also hold a gem reference. The gem object might get destroyed after the last user drops the gem-ref via drm_gem_object_unreference(). Use drm_gem_object_reference() to gain a gem-reference. For debugging, we can use bo->gem.filp != NULL to test whether a gem-bo is valid. However, this shouldn't be used for real functionality to avoid gem-internal dependencies. Note that the implementation follows the previous style. However, we no longer can check for bo->gem != NULL to test for a valid gem object. This wasn't done before, so we should be safe now. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Reviewed-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_gem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index f32b71238c03..6618318abf50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -43,20 +43,17 @@ nouveau_gem_object_new(struct drm_gem_object *gem)
43void 43void
44nouveau_gem_object_del(struct drm_gem_object *gem) 44nouveau_gem_object_del(struct drm_gem_object *gem)
45{ 45{
46 struct nouveau_bo *nvbo = gem->driver_private; 46 struct nouveau_bo *nvbo = nouveau_gem_object(gem);
47 struct ttm_buffer_object *bo = &nvbo->bo; 47 struct ttm_buffer_object *bo = &nvbo->bo;
48 48
49 if (!nvbo)
50 return;
51 nvbo->gem = NULL;
52
53 if (gem->import_attach) 49 if (gem->import_attach)
54 drm_prime_gem_destroy(gem, nvbo->bo.sg); 50 drm_prime_gem_destroy(gem, nvbo->bo.sg);
55 51
56 ttm_bo_unref(&bo);
57
58 drm_gem_object_release(gem); 52 drm_gem_object_release(gem);
59 kfree(gem); 53
54 /* reset filp so nouveau_bo_del_ttm() can test for it */
55 gem->filp = NULL;
56 ttm_bo_unref(&bo);
60} 57}
61 58
62int 59int
@@ -186,14 +183,15 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
186 if (nv_device(drm->device)->card_type >= NV_50) 183 if (nv_device(drm->device)->card_type >= NV_50)
187 nvbo->valid_domains &= domain; 184 nvbo->valid_domains &= domain;
188 185
189 nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); 186 /* Initialize the embedded gem-object. We return a single gem-reference
190 if (!nvbo->gem) { 187 * to the caller, instead of a normal nouveau_bo ttm reference. */
188 ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size);
189 if (ret) {
191 nouveau_bo_ref(NULL, pnvbo); 190 nouveau_bo_ref(NULL, pnvbo);
192 return -ENOMEM; 191 return -ENOMEM;
193 } 192 }
194 193
195 nvbo->bo.persistent_swap_storage = nvbo->gem->filp; 194 nvbo->bo.persistent_swap_storage = nvbo->gem.filp;
196 nvbo->gem->driver_private = nvbo;
197 return 0; 195 return 0;
198} 196}
199 197
@@ -250,15 +248,15 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
250 if (ret) 248 if (ret)
251 return ret; 249 return ret;
252 250
253 ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); 251 ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle);
254 if (ret == 0) { 252 if (ret == 0) {
255 ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info); 253 ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info);
256 if (ret) 254 if (ret)
257 drm_gem_handle_delete(file_priv, req->info.handle); 255 drm_gem_handle_delete(file_priv, req->info.handle);
258 } 256 }
259 257
260 /* drop reference from allocate - handle holds it now */ 258 /* drop reference from allocate - handle holds it now */
261 drm_gem_object_unreference_unlocked(nvbo->gem); 259 drm_gem_object_unreference_unlocked(&nvbo->gem);
262 return ret; 260 return ret;
263} 261}
264 262
@@ -266,7 +264,7 @@ static int
266nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, 264nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
267 uint32_t write_domains, uint32_t valid_domains) 265 uint32_t write_domains, uint32_t valid_domains)
268{ 266{
269 struct nouveau_bo *nvbo = gem->driver_private; 267 struct nouveau_bo *nvbo = nouveau_gem_object(gem);
270 struct ttm_buffer_object *bo = &nvbo->bo; 268 struct ttm_buffer_object *bo = &nvbo->bo;
271 uint32_t domains = valid_domains & nvbo->valid_domains & 269 uint32_t domains = valid_domains & nvbo->valid_domains &
272 (write_domains ? write_domains : read_domains); 270 (write_domains ? write_domains : read_domains);
@@ -327,7 +325,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
327 list_del(&nvbo->entry); 325 list_del(&nvbo->entry);
328 nvbo->reserved_by = NULL; 326 nvbo->reserved_by = NULL;
329 ttm_bo_unreserve_ticket(&nvbo->bo, ticket); 327 ttm_bo_unreserve_ticket(&nvbo->bo, ticket);
330 drm_gem_object_unreference_unlocked(nvbo->gem); 328 drm_gem_object_unreference_unlocked(&nvbo->gem);
331 } 329 }
332} 330}
333 331
@@ -376,7 +374,7 @@ retry:
376 validate_fini(op, NULL); 374 validate_fini(op, NULL);
377 return -ENOENT; 375 return -ENOENT;
378 } 376 }
379 nvbo = gem->driver_private; 377 nvbo = nouveau_gem_object(gem);
380 if (nvbo == res_bo) { 378 if (nvbo == res_bo) {
381 res_bo = NULL; 379 res_bo = NULL;
382 drm_gem_object_unreference_unlocked(gem); 380 drm_gem_object_unreference_unlocked(gem);
@@ -478,7 +476,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
478 return ret; 476 return ret;
479 } 477 }
480 478
481 ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, 479 ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains,
482 b->write_domains, 480 b->write_domains,
483 b->valid_domains); 481 b->valid_domains);
484 if (unlikely(ret)) { 482 if (unlikely(ret)) {