diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2012-11-20 07:16:51 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-11-28 03:36:15 -0500 |
commit | 5293908afa04b651cc8a7e85ba0938b71f97c2f8 (patch) | |
tree | c20f62bab68206a2fbcf91a71604f3a0dd02e83f /drivers | |
parent | ae8df2ae8aa27bfeb8d1b99e8adaac5810a97fa8 (diff) |
drm/ttm: Use the hashtab _rcu interface for ttm_objects
Also move a kref_init() out of spinlocked region
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_object.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 0e13d9f059ff..58a5f3261c0b 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -157,11 +157,11 @@ int ttm_base_object_init(struct ttm_object_file *tfile, | |||
157 | base->refcount_release = refcount_release; | 157 | base->refcount_release = refcount_release; |
158 | base->ref_obj_release = ref_obj_release; | 158 | base->ref_obj_release = ref_obj_release; |
159 | base->object_type = object_type; | 159 | base->object_type = object_type; |
160 | spin_lock(&tdev->object_lock); | ||
161 | kref_init(&base->refcount); | 160 | kref_init(&base->refcount); |
162 | ret = drm_ht_just_insert_please(&tdev->object_hash, | 161 | spin_lock(&tdev->object_lock); |
163 | &base->hash, | 162 | ret = drm_ht_just_insert_please_rcu(&tdev->object_hash, |
164 | (unsigned long)base, 31, 0, 0); | 163 | &base->hash, |
164 | (unsigned long)base, 31, 0, 0); | ||
165 | spin_unlock(&tdev->object_lock); | 165 | spin_unlock(&tdev->object_lock); |
166 | if (unlikely(ret != 0)) | 166 | if (unlikely(ret != 0)) |
167 | goto out_err0; | 167 | goto out_err0; |
@@ -175,7 +175,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile, | |||
175 | return 0; | 175 | return 0; |
176 | out_err1: | 176 | out_err1: |
177 | spin_lock(&tdev->object_lock); | 177 | spin_lock(&tdev->object_lock); |
178 | (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); | 178 | (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash); |
179 | spin_unlock(&tdev->object_lock); | 179 | spin_unlock(&tdev->object_lock); |
180 | out_err0: | 180 | out_err0: |
181 | return ret; | 181 | return ret; |
@@ -189,8 +189,15 @@ static void ttm_release_base(struct kref *kref) | |||
189 | struct ttm_object_device *tdev = base->tfile->tdev; | 189 | struct ttm_object_device *tdev = base->tfile->tdev; |
190 | 190 | ||
191 | spin_lock(&tdev->object_lock); | 191 | spin_lock(&tdev->object_lock); |
192 | (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); | 192 | (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash); |
193 | spin_unlock(&tdev->object_lock); | 193 | spin_unlock(&tdev->object_lock); |
194 | |||
195 | /* | ||
196 | * Note: We don't use synchronize_rcu() here because it's far | ||
197 | * too slow. It's up to the user to free the object using | ||
198 | * call_rcu() or ttm_base_object_kfree(). | ||
199 | */ | ||
200 | |||
194 | if (base->refcount_release) { | 201 | if (base->refcount_release) { |
195 | ttm_object_file_unref(&base->tfile); | 202 | ttm_object_file_unref(&base->tfile); |
196 | base->refcount_release(&base); | 203 | base->refcount_release(&base); |
@@ -216,7 +223,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, | |||
216 | int ret; | 223 | int ret; |
217 | 224 | ||
218 | rcu_read_lock(); | 225 | rcu_read_lock(); |
219 | ret = drm_ht_find_item(&tdev->object_hash, key, &hash); | 226 | ret = drm_ht_find_item_rcu(&tdev->object_hash, key, &hash); |
220 | 227 | ||
221 | if (likely(ret == 0)) { | 228 | if (likely(ret == 0)) { |
222 | base = drm_hash_entry(hash, struct ttm_base_object, hash); | 229 | base = drm_hash_entry(hash, struct ttm_base_object, hash); |