4848#include <linux/spinlock.h>
4949#include <linux/slab.h>
5050#include <linux/atomic.h>
51+ #include <linux/hashtable.h>
5152#include "ttm_object.h"
5253#include "vmwgfx_drv.h"
5354
55+ #define VMW_TTM_OBJECT_REF_HT_ORDER 10
56+
5457/**
5558 * struct ttm_object_file
5659 *
@@ -71,7 +74,7 @@ struct ttm_object_file {
7174 struct ttm_object_device * tdev ;
7275 spinlock_t lock ;
7376 struct list_head ref_list ;
74- struct vmwgfx_open_hash ref_hash ;
77+ DECLARE_HASHTABLE ( ref_hash , VMW_TTM_OBJECT_REF_HT_ORDER ) ;
7578 struct kref refcount ;
7679};
7780
@@ -135,6 +138,36 @@ ttm_object_file_ref(struct ttm_object_file *tfile)
135138 return tfile ;
136139}
137140
141+ static int ttm_tfile_find_ref_rcu (struct ttm_object_file * tfile ,
142+ uint64_t key ,
143+ struct vmwgfx_hash_item * * p_hash )
144+ {
145+ struct vmwgfx_hash_item * hash ;
146+
147+ hash_for_each_possible_rcu (tfile -> ref_hash , hash , head , key ) {
148+ if (hash -> key == key ) {
149+ * p_hash = hash ;
150+ return 0 ;
151+ }
152+ }
153+ return - EINVAL ;
154+ }
155+
156+ static int ttm_tfile_find_ref (struct ttm_object_file * tfile ,
157+ uint64_t key ,
158+ struct vmwgfx_hash_item * * p_hash )
159+ {
160+ struct vmwgfx_hash_item * hash ;
161+
162+ hash_for_each_possible (tfile -> ref_hash , hash , head , key ) {
163+ if (hash -> key == key ) {
164+ * p_hash = hash ;
165+ return 0 ;
166+ }
167+ }
168+ return - EINVAL ;
169+ }
170+
138171static void ttm_object_file_destroy (struct kref * kref )
139172{
140173 struct ttm_object_file * tfile =
@@ -237,14 +270,13 @@ void ttm_base_object_unref(struct ttm_base_object **p_base)
237270 * Return: A pointer to the object if successful or NULL otherwise.
238271 */
239272struct ttm_base_object *
240- ttm_base_object_noref_lookup (struct ttm_object_file * tfile , uint32_t key )
273+ ttm_base_object_noref_lookup (struct ttm_object_file * tfile , uint64_t key )
241274{
242275 struct vmwgfx_hash_item * hash ;
243- struct vmwgfx_open_hash * ht = & tfile -> ref_hash ;
244276 int ret ;
245277
246278 rcu_read_lock ();
247- ret = vmwgfx_ht_find_item_rcu ( ht , key , & hash );
279+ ret = ttm_tfile_find_ref_rcu ( tfile , key , & hash );
248280 if (ret ) {
249281 rcu_read_unlock ();
250282 return NULL ;
@@ -256,15 +288,14 @@ ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key)
256288EXPORT_SYMBOL (ttm_base_object_noref_lookup );
257289
258290struct ttm_base_object * ttm_base_object_lookup (struct ttm_object_file * tfile ,
259- uint32_t key )
291+ uint64_t key )
260292{
261293 struct ttm_base_object * base = NULL ;
262294 struct vmwgfx_hash_item * hash ;
263- struct vmwgfx_open_hash * ht = & tfile -> ref_hash ;
264295 int ret ;
265296
266297 rcu_read_lock ();
267- ret = vmwgfx_ht_find_item_rcu ( ht , key , & hash );
298+ ret = ttm_tfile_find_ref_rcu ( tfile , key , & hash );
268299
269300 if (likely (ret == 0 )) {
270301 base = drm_hash_entry (hash , struct ttm_ref_object , hash )-> obj ;
@@ -277,7 +308,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
277308}
278309
279310struct ttm_base_object *
280- ttm_base_object_lookup_for_ref (struct ttm_object_device * tdev , uint32_t key )
311+ ttm_base_object_lookup_for_ref (struct ttm_object_device * tdev , uint64_t key )
281312{
282313 struct ttm_base_object * base ;
283314
@@ -296,7 +327,6 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
296327 bool * existed ,
297328 bool require_existed )
298329{
299- struct vmwgfx_open_hash * ht = & tfile -> ref_hash ;
300330 struct ttm_ref_object * ref ;
301331 struct vmwgfx_hash_item * hash ;
302332 int ret = - EINVAL ;
@@ -309,7 +339,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
309339
310340 while (ret == - EINVAL ) {
311341 rcu_read_lock ();
312- ret = vmwgfx_ht_find_item_rcu ( ht , base -> handle , & hash );
342+ ret = ttm_tfile_find_ref_rcu ( tfile , base -> handle , & hash );
313343
314344 if (ret == 0 ) {
315345 ref = drm_hash_entry (hash , struct ttm_ref_object , hash );
@@ -334,21 +364,14 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
334364 kref_init (& ref -> kref );
335365
336366 spin_lock (& tfile -> lock );
337- ret = vmwgfx_ht_insert_item_rcu (ht , & ref -> hash );
338-
339- if (likely (ret == 0 )) {
340- list_add_tail (& ref -> head , & tfile -> ref_list );
341- kref_get (& base -> refcount );
342- spin_unlock (& tfile -> lock );
343- if (existed != NULL )
344- * existed = false;
345- break ;
346- }
367+ hash_add_rcu (tfile -> ref_hash , & ref -> hash .head , ref -> hash .key );
368+ ret = 0 ;
347369
370+ list_add_tail (& ref -> head , & tfile -> ref_list );
371+ kref_get (& base -> refcount );
348372 spin_unlock (& tfile -> lock );
349- BUG_ON (ret != - EINVAL );
350-
351- kfree (ref );
373+ if (existed != NULL )
374+ * existed = false;
352375 }
353376
354377 return ret ;
@@ -360,10 +383,8 @@ ttm_ref_object_release(struct kref *kref)
360383 struct ttm_ref_object * ref =
361384 container_of (kref , struct ttm_ref_object , kref );
362385 struct ttm_object_file * tfile = ref -> tfile ;
363- struct vmwgfx_open_hash * ht ;
364386
365- ht = & tfile -> ref_hash ;
366- (void )vmwgfx_ht_remove_item_rcu (ht , & ref -> hash );
387+ hash_del_rcu (& ref -> hash .head );
367388 list_del (& ref -> head );
368389 spin_unlock (& tfile -> lock );
369390
@@ -375,13 +396,12 @@ ttm_ref_object_release(struct kref *kref)
375396int ttm_ref_object_base_unref (struct ttm_object_file * tfile ,
376397 unsigned long key )
377398{
378- struct vmwgfx_open_hash * ht = & tfile -> ref_hash ;
379399 struct ttm_ref_object * ref ;
380400 struct vmwgfx_hash_item * hash ;
381401 int ret ;
382402
383403 spin_lock (& tfile -> lock );
384- ret = vmwgfx_ht_find_item ( ht , key , & hash );
404+ ret = ttm_tfile_find_ref ( tfile , key , & hash );
385405 if (unlikely (ret != 0 )) {
386406 spin_unlock (& tfile -> lock );
387407 return - EINVAL ;
@@ -413,16 +433,13 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile)
413433 }
414434
415435 spin_unlock (& tfile -> lock );
416- vmwgfx_ht_remove (& tfile -> ref_hash );
417436
418437 ttm_object_file_unref (& tfile );
419438}
420439
421- struct ttm_object_file * ttm_object_file_init (struct ttm_object_device * tdev ,
422- unsigned int hash_order )
440+ struct ttm_object_file * ttm_object_file_init (struct ttm_object_device * tdev )
423441{
424442 struct ttm_object_file * tfile = kmalloc (sizeof (* tfile ), GFP_KERNEL );
425- int ret ;
426443
427444 if (unlikely (tfile == NULL ))
428445 return NULL ;
@@ -432,17 +449,9 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
432449 kref_init (& tfile -> refcount );
433450 INIT_LIST_HEAD (& tfile -> ref_list );
434451
435- ret = vmwgfx_ht_create (& tfile -> ref_hash , hash_order );
436- if (ret )
437- goto out_err ;
452+ hash_init (tfile -> ref_hash );
438453
439454 return tfile ;
440- out_err :
441- vmwgfx_ht_remove (& tfile -> ref_hash );
442-
443- kfree (tfile );
444-
445- return NULL ;
446455}
447456
448457struct ttm_object_device *
0 commit comments