diff options
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 31 | ||||
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 15 |
2 files changed, 31 insertions, 15 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4ec368b2555a..d89183f95570 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -49,6 +49,9 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj); * ttm_global_mutex - protecting the global BO state */ DEFINE_MUTEX(ttm_global_mutex); +struct ttm_bo_global ttm_bo_glob = { + .use_count = 0 +}; static struct attribute ttm_bo_count = { .name = "bo_count", @@ -1527,22 +1530,35 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_release(struct ttm_bo_global *glob) +void ttm_bo_global_release(void) { + struct ttm_bo_global *glob = &ttm_bo_glob; + + mutex_lock(&ttm_global_mutex); + if (--glob->use_count > 0) + goto out; + kobject_del(&glob->kobj); kobject_put(&glob->kobj); ttm_mem_global_release(&ttm_mem_glob); +out: + mutex_unlock(&ttm_global_mutex); } EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_init(struct ttm_bo_global *glob) +int ttm_bo_global_init(void) { - int ret; + struct ttm_bo_global *glob = &ttm_bo_glob; + int ret = 0; unsigned i; + mutex_lock(&ttm_global_mutex); + if (++glob->use_count > 1) + goto out; + ret = ttm_mem_global_init(&ttm_mem_glob); if (ret) - return ret; + goto out; spin_lock_init(&glob->lru_lock); glob->mem_glob = &ttm_mem_glob; @@ -1551,7 +1567,7 @@ int ttm_bo_global_init(struct ttm_bo_global *glob) if (unlikely(glob->dummy_read_page == NULL)) { ret = -ENOMEM; - goto out_no_drp; + goto out; } for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) @@ -1563,9 +1579,8 @@ int ttm_bo_global_init(struct ttm_bo_global *glob) &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); if (unlikely(ret != 0)) kobject_put(&glob->kobj); - return ret; -out_no_drp: - kfree(glob); +out: + mutex_unlock(&ttm_global_mutex); return ret; } EXPORT_SYMBOL(ttm_bo_global_init); diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 9cec8835b88f..26be74939f10 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -398,7 +398,7 @@ struct ttm_bo_driver { * @swap_lru: Lru list of buffer objects used for swapping. */ -struct ttm_bo_global { +extern struct ttm_bo_global { /** * Constant after init. @@ -410,8 +410,9 @@ struct ttm_bo_global { spinlock_t lru_lock; /** - * Protected by device_list_mutex. + * Protected by ttm_global_mutex. */ + unsigned int use_count; struct list_head device_list; /** @@ -423,7 +424,7 @@ struct ttm_bo_global { * Internal protection. */ atomic_t bo_count; -}; +} ttm_bo_glob; #define TTM_NUM_MEM_TYPES 8 @@ -568,8 +569,8 @@ void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem); void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem); -void ttm_bo_global_release(struct ttm_bo_global *glob); -int ttm_bo_global_init(struct ttm_bo_global *glob); +void ttm_bo_global_release(void); +int ttm_bo_global_init(void); int ttm_bo_device_release(struct ttm_bo_device *bdev); @@ -906,7 +907,7 @@ struct ttm_bo_global_ref { */ static inline int ttm_bo_global_ref_init(struct drm_global_reference *ref) { - return ttm_bo_global_init(ref->object); + return ttm_bo_global_init(); } /** @@ -920,7 +921,7 @@ static inline int ttm_bo_global_ref_init(struct drm_global_reference *ref) */ static inline void ttm_bo_global_ref_release(struct drm_global_reference *ref) { - ttm_bo_global_release(ref->object); + ttm_bo_global_release(); } #endif |