Commit 9da30cdd authored by Maaz Mombasawala's avatar Maaz Mombasawala Committed by Zack Rusin

drm/vmwgfx: Remove vmwgfx_hashtab

The vmwgfx driver has migrated from using the hashtable in vmwgfx_hashtab
to the linux/hashtable implementation. Remove the vmwgfx_hashtab from the
driver.
Signed-off-by: default avatarMaaz Mombasawala <mombasawalam@vmware.com>
Reviewed-by: default avatarMartin Krastev <krastevm@vmware.com>
Reviewed-by: default avatarZack Rusin <zackr@vmware.com>
Signed-off-by: default avatarZack Rusin <zackr@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-12-zack@kde.org
parent 76a9e07f
...@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks. ...@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks.
Contact: Harry Wentland, Alex Deucher Contact: Harry Wentland, Alex Deucher
vmwgfx: Replace hashtable with Linux' implementation
----------------------------------------------------
The vmwgfx driver uses its own hashtable implementation. Replace the
code with Linux' implementation and update the callers. It's mostly a
refactoring task, but the interfaces are different.
Contact: Zack Rusin, Thomas Zimmermann <tzimmermann@suse.de>
Level: Intermediate
Bootsplash Bootsplash
========== ==========
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_hashtab.o vmwgfx_kms.o vmwgfx_drv.o \ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_ttm_buffer.o \ vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_ttm_buffer.o \
vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
vmwgfx_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \ vmwgfx_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \
......
...@@ -284,7 +284,7 @@ ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key) ...@@ -284,7 +284,7 @@ ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key)
} }
__release(RCU); __release(RCU);
return drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; return hlist_entry(hash, struct ttm_ref_object, hash)->obj;
} }
EXPORT_SYMBOL(ttm_base_object_noref_lookup); EXPORT_SYMBOL(ttm_base_object_noref_lookup);
...@@ -299,7 +299,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, ...@@ -299,7 +299,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); ret = ttm_tfile_find_ref_rcu(tfile, key, &hash);
if (likely(ret == 0)) { if (likely(ret == 0)) {
base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; base = hlist_entry(hash, struct ttm_ref_object, hash)->obj;
if (!kref_get_unless_zero(&base->refcount)) if (!kref_get_unless_zero(&base->refcount))
base = NULL; base = NULL;
} }
...@@ -343,7 +343,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, ...@@ -343,7 +343,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
ret = ttm_tfile_find_ref_rcu(tfile, base->handle, &hash); ret = ttm_tfile_find_ref_rcu(tfile, base->handle, &hash);
if (ret == 0) { if (ret == 0) {
ref = drm_hash_entry(hash, struct ttm_ref_object, hash); ref = hlist_entry(hash, struct ttm_ref_object, hash);
if (kref_get_unless_zero(&ref->kref)) { if (kref_get_unless_zero(&ref->kref)) {
rcu_read_unlock(); rcu_read_unlock();
break; break;
...@@ -407,7 +407,7 @@ int ttm_ref_object_base_unref(struct ttm_object_file *tfile, ...@@ -407,7 +407,7 @@ int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
spin_unlock(&tfile->lock); spin_unlock(&tfile->lock);
return -EINVAL; return -EINVAL;
} }
ref = drm_hash_entry(hash, struct ttm_ref_object, hash); ref = hlist_entry(hash, struct ttm_ref_object, hash);
kref_put(&ref->kref, ttm_ref_object_release); kref_put(&ref->kref, ttm_ref_object_release);
spin_unlock(&tfile->lock); spin_unlock(&tfile->lock);
return 0; return 0;
......
...@@ -42,8 +42,6 @@ ...@@ -42,8 +42,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include "vmwgfx_hashtab.h"
/** /**
* enum ttm_object_type * enum ttm_object_type
* *
......
...@@ -88,7 +88,7 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man, ...@@ -88,7 +88,7 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man,
hash_for_each_possible_rcu(man->resources, hash, head, key) { hash_for_each_possible_rcu(man->resources, hash, head, key) {
if (hash->key == key) if (hash->key == key)
return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res; return hlist_entry(hash, struct vmw_cmdbuf_res, hash)->res;
} }
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
...@@ -243,7 +243,7 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, ...@@ -243,7 +243,7 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
hash_for_each_possible_rcu(man->resources, hash, head, key) { hash_for_each_possible_rcu(man->resources, hash, head, key) {
if (hash->key == key) { if (hash->key == key) {
entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash); entry = hlist_entry(hash, struct vmw_cmdbuf_res, hash);
break; break;
} }
} }
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include "ttm_object.h" #include "ttm_object.h"
#include "vmwgfx_fence.h" #include "vmwgfx_fence.h"
#include "vmwgfx_hashtab.h"
#include "vmwgfx_reg.h" #include "vmwgfx_reg.h"
#include "vmwgfx_validation.h" #include "vmwgfx_validation.h"
...@@ -104,6 +103,11 @@ struct vmw_fpriv { ...@@ -104,6 +103,11 @@ struct vmw_fpriv {
bool gb_aware; /* user-space is guest-backed aware */ bool gb_aware; /* user-space is guest-backed aware */
}; };
struct vmwgfx_hash_item {
struct hlist_node head;
unsigned long key;
};
/** /**
* struct vmw_buffer_object - TTM buffer object with vmwgfx additions * struct vmw_buffer_object - TTM buffer object with vmwgfx additions
* @base: The TTM buffer object * @base: The TTM buffer object
......
/*
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Simple open hash tab implementation.
*
* Authors:
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include <linux/export.h>
#include <linux/hash.h>
#include <linux/mm.h>
#include <linux/rculist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <drm/drm_print.h>
#include "vmwgfx_hashtab.h"
int vmwgfx_ht_create(struct vmwgfx_open_hash *ht, unsigned int order)
{
unsigned int size = 1 << order;
ht->order = order;
ht->table = NULL;
if (size <= PAGE_SIZE / sizeof(*ht->table))
ht->table = kcalloc(size, sizeof(*ht->table), GFP_KERNEL);
else
ht->table = vzalloc(array_size(size, sizeof(*ht->table)));
if (!ht->table) {
DRM_ERROR("Out of memory for hash table\n");
return -ENOMEM;
}
return 0;
}
void vmwgfx_ht_verbose_list(struct vmwgfx_open_hash *ht, unsigned long key)
{
struct vmwgfx_hash_item *entry;
struct hlist_head *h_list;
unsigned int hashed_key;
int count = 0;
hashed_key = hash_long(key, ht->order);
DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key);
h_list = &ht->table[hashed_key];
hlist_for_each_entry(entry, h_list, head)
DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key);
}
static struct hlist_node *vmwgfx_ht_find_key(struct vmwgfx_open_hash *ht, unsigned long key)
{
struct vmwgfx_hash_item *entry;
struct hlist_head *h_list;
unsigned int hashed_key;
hashed_key = hash_long(key, ht->order);
h_list = &ht->table[hashed_key];
hlist_for_each_entry(entry, h_list, head) {
if (entry->key == key)
return &entry->head;
if (entry->key > key)
break;
}
return NULL;
}
static struct hlist_node *vmwgfx_ht_find_key_rcu(struct vmwgfx_open_hash *ht, unsigned long key)
{
struct vmwgfx_hash_item *entry;
struct hlist_head *h_list;
unsigned int hashed_key;
hashed_key = hash_long(key, ht->order);
h_list = &ht->table[hashed_key];
hlist_for_each_entry_rcu(entry, h_list, head) {
if (entry->key == key)
return &entry->head;
if (entry->key > key)
break;
}
return NULL;
}
int vmwgfx_ht_insert_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item)
{
struct vmwgfx_hash_item *entry;
struct hlist_head *h_list;
struct hlist_node *parent;
unsigned int hashed_key;
unsigned long key = item->key;
hashed_key = hash_long(key, ht->order);
h_list = &ht->table[hashed_key];
parent = NULL;
hlist_for_each_entry(entry, h_list, head) {
if (entry->key == key)
return -EINVAL;
if (entry->key > key)
break;
parent = &entry->head;
}
if (parent)
hlist_add_behind_rcu(&item->head, parent);
else
hlist_add_head_rcu(&item->head, h_list);
return 0;
}
/*
* Just insert an item and return any "bits" bit key that hasn't been
* used before.
*/
int vmwgfx_ht_just_insert_please(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item,
unsigned long seed, int bits, int shift,
unsigned long add)
{
int ret;
unsigned long mask = (1UL << bits) - 1;
unsigned long first, unshifted_key;
unshifted_key = hash_long(seed, bits);
first = unshifted_key;
do {
item->key = (unshifted_key << shift) + add;
ret = vmwgfx_ht_insert_item(ht, item);
if (ret)
unshifted_key = (unshifted_key + 1) & mask;
} while (ret && (unshifted_key != first));
if (ret) {
DRM_ERROR("Available key bit space exhausted\n");
return -EINVAL;
}
return 0;
}
int vmwgfx_ht_find_item(struct vmwgfx_open_hash *ht, unsigned long key,
struct vmwgfx_hash_item **item)
{
struct hlist_node *list;
list = vmwgfx_ht_find_key_rcu(ht, key);
if (!list)
return -EINVAL;
*item = hlist_entry(list, struct vmwgfx_hash_item, head);
return 0;
}
int vmwgfx_ht_remove_key(struct vmwgfx_open_hash *ht, unsigned long key)
{
struct hlist_node *list;
list = vmwgfx_ht_find_key(ht, key);
if (list) {
hlist_del_init_rcu(list);
return 0;
}
return -EINVAL;
}
int vmwgfx_ht_remove_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item)
{
hlist_del_init_rcu(&item->head);
return 0;
}
void vmwgfx_ht_remove(struct vmwgfx_open_hash *ht)
{
if (ht->table) {
kvfree(ht->table);
ht->table = NULL;
}
}
/*
* Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Simple open hash tab implementation.
*
* Authors:
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
/*
* TODO: Replace this hashtable with Linux' generic implementation
* from <linux/hashtable.h>.
*/
#ifndef VMWGFX_HASHTAB_H
#define VMWGFX_HASHTAB_H
#include <linux/list.h>
#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
struct vmwgfx_hash_item {
struct hlist_node head;
unsigned long key;
};
struct vmwgfx_open_hash {
struct hlist_head *table;
u8 order;
};
int vmwgfx_ht_create(struct vmwgfx_open_hash *ht, unsigned int order);
int vmwgfx_ht_insert_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item);
int vmwgfx_ht_just_insert_please(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item,
unsigned long seed, int bits, int shift,
unsigned long add);
int vmwgfx_ht_find_item(struct vmwgfx_open_hash *ht, unsigned long key,
struct vmwgfx_hash_item **item);
void vmwgfx_ht_verbose_list(struct vmwgfx_open_hash *ht, unsigned long key);
int vmwgfx_ht_remove_key(struct vmwgfx_open_hash *ht, unsigned long key);
int vmwgfx_ht_remove_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item);
void vmwgfx_ht_remove(struct vmwgfx_open_hash *ht);
/*
* RCU-safe interface
*
* The user of this API needs to make sure that two or more instances of the
* hash table manipulation functions are never run simultaneously.
* The lookup function vmwgfx_ht_find_item_rcu may, however, run simultaneously
* with any of the manipulation functions as long as it's called from within
* an RCU read-locked section.
*/
#define vmwgfx_ht_insert_item_rcu vmwgfx_ht_insert_item
#define vmwgfx_ht_just_insert_please_rcu vmwgfx_ht_just_insert_please
#define vmwgfx_ht_remove_key_rcu vmwgfx_ht_remove_key
#define vmwgfx_ht_remove_item_rcu vmwgfx_ht_remove_item
#define vmwgfx_ht_find_item_rcu vmwgfx_ht_find_item
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment