Skip to content

Commit

Permalink
drm/vmwgfx: Copy DRM hash-table code into driver
Browse files Browse the repository at this point in the history
Besides some legacy code, vmwgfx is the only user of DRM's hash-
table implementation. Copy the code into the driver, so that the
core code can be retired.

No functional changes. However, the real solution for vmwgfx is to
use Linux' generic hash-table functions.

v2:
	* add TODO item for updating vmwgfx (Sam)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211129094841.22499-3-tzimmermann@suse.de
  • Loading branch information
Thomas Zimmermann committed Nov 30, 2021
1 parent b93199b commit 2985c96
Show file tree
Hide file tree
Showing 12 changed files with 353 additions and 60 deletions.
11 changes: 11 additions & 0 deletions Documentation/gpu/todo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,17 @@ See drivers/gpu/drm/amd/display/TODO for tasks.

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
==========

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/vmwgfx/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_hashtab.o vmwgfx_kms.o vmwgfx_drv.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_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \
Expand Down
52 changes: 26 additions & 26 deletions drivers/gpu/drm/vmwgfx/ttm_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct ttm_object_file {
struct ttm_object_device *tdev;
spinlock_t lock;
struct list_head ref_list;
struct drm_open_hash ref_hash[TTM_REF_NUM];
struct vmwgfx_open_hash ref_hash[TTM_REF_NUM];
struct kref refcount;
};

Expand All @@ -91,7 +91,7 @@ struct ttm_object_file {

struct ttm_object_device {
spinlock_t object_lock;
struct drm_open_hash object_hash;
struct vmwgfx_open_hash object_hash;
atomic_t object_count;
struct ttm_mem_global *mem_glob;
struct dma_buf_ops ops;
Expand Down Expand Up @@ -123,7 +123,7 @@ struct ttm_object_device {

struct ttm_ref_object {
struct rcu_head rcu_head;
struct drm_hash_item hash;
struct vmwgfx_hash_item hash;
struct list_head head;
struct kref kref;
enum ttm_ref_type ref_type;
Expand Down Expand Up @@ -247,12 +247,12 @@ void ttm_base_object_unref(struct ttm_base_object **p_base)
struct ttm_base_object *
ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key)
{
struct drm_hash_item *hash;
struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
struct vmwgfx_hash_item *hash;
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
int ret;

rcu_read_lock();
ret = drm_ht_find_item_rcu(ht, key, &hash);
ret = vmwgfx_ht_find_item_rcu(ht, key, &hash);
if (ret) {
rcu_read_unlock();
return NULL;
Expand All @@ -267,12 +267,12 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
uint32_t key)
{
struct ttm_base_object *base = NULL;
struct drm_hash_item *hash;
struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
struct vmwgfx_hash_item *hash;
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
int ret;

rcu_read_lock();
ret = drm_ht_find_item_rcu(ht, key, &hash);
ret = vmwgfx_ht_find_item_rcu(ht, key, &hash);

if (likely(ret == 0)) {
base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj;
Expand Down Expand Up @@ -312,12 +312,12 @@ ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key)
bool ttm_ref_object_exists(struct ttm_object_file *tfile,
struct ttm_base_object *base)
{
struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
struct drm_hash_item *hash;
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
struct vmwgfx_hash_item *hash;
struct ttm_ref_object *ref;

rcu_read_lock();
if (unlikely(drm_ht_find_item_rcu(ht, base->handle, &hash) != 0))
if (unlikely(vmwgfx_ht_find_item_rcu(ht, base->handle, &hash) != 0))
goto out_false;

/*
Expand Down Expand Up @@ -349,9 +349,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
enum ttm_ref_type ref_type, bool *existed,
bool require_existed)
{
struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
struct vmwgfx_open_hash *ht = &tfile->ref_hash[ref_type];
struct ttm_ref_object *ref;
struct drm_hash_item *hash;
struct vmwgfx_hash_item *hash;
struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
struct ttm_operation_ctx ctx = {
.interruptible = false,
Expand All @@ -367,7 +367,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,

while (ret == -EINVAL) {
rcu_read_lock();
ret = drm_ht_find_item_rcu(ht, base->handle, &hash);
ret = vmwgfx_ht_find_item_rcu(ht, base->handle, &hash);

if (ret == 0) {
ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
Expand Down Expand Up @@ -398,7 +398,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
kref_init(&ref->kref);

spin_lock(&tfile->lock);
ret = drm_ht_insert_item_rcu(ht, &ref->hash);
ret = vmwgfx_ht_insert_item_rcu(ht, &ref->hash);

if (likely(ret == 0)) {
list_add_tail(&ref->head, &tfile->ref_list);
Expand Down Expand Up @@ -426,11 +426,11 @@ ttm_ref_object_release(struct kref *kref)
container_of(kref, struct ttm_ref_object, kref);
struct ttm_base_object *base = ref->obj;
struct ttm_object_file *tfile = ref->tfile;
struct drm_open_hash *ht;
struct vmwgfx_open_hash *ht;
struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;

ht = &tfile->ref_hash[ref->ref_type];
(void)drm_ht_remove_item_rcu(ht, &ref->hash);
(void)vmwgfx_ht_remove_item_rcu(ht, &ref->hash);
list_del(&ref->head);
spin_unlock(&tfile->lock);

Expand All @@ -446,13 +446,13 @@ ttm_ref_object_release(struct kref *kref)
int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
unsigned long key, enum ttm_ref_type ref_type)
{
struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
struct vmwgfx_open_hash *ht = &tfile->ref_hash[ref_type];
struct ttm_ref_object *ref;
struct drm_hash_item *hash;
struct vmwgfx_hash_item *hash;
int ret;

spin_lock(&tfile->lock);
ret = drm_ht_find_item(ht, key, &hash);
ret = vmwgfx_ht_find_item(ht, key, &hash);
if (unlikely(ret != 0)) {
spin_unlock(&tfile->lock);
return -EINVAL;
Expand Down Expand Up @@ -486,7 +486,7 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile)

spin_unlock(&tfile->lock);
for (i = 0; i < TTM_REF_NUM; ++i)
drm_ht_remove(&tfile->ref_hash[i]);
vmwgfx_ht_remove(&tfile->ref_hash[i]);

ttm_object_file_unref(&tfile);
}
Expand All @@ -508,7 +508,7 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
INIT_LIST_HEAD(&tfile->ref_list);

for (i = 0; i < TTM_REF_NUM; ++i) {
ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
ret = vmwgfx_ht_create(&tfile->ref_hash[i], hash_order);
if (ret) {
j = i;
goto out_err;
Expand All @@ -518,7 +518,7 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
return tfile;
out_err:
for (i = 0; i < j; ++i)
drm_ht_remove(&tfile->ref_hash[i]);
vmwgfx_ht_remove(&tfile->ref_hash[i]);

kfree(tfile);

Expand All @@ -539,7 +539,7 @@ ttm_object_device_init(struct ttm_mem_global *mem_glob,
tdev->mem_glob = mem_glob;
spin_lock_init(&tdev->object_lock);
atomic_set(&tdev->object_count, 0);
ret = drm_ht_create(&tdev->object_hash, hash_order);
ret = vmwgfx_ht_create(&tdev->object_hash, hash_order);
if (ret != 0)
goto out_no_object_hash;

Expand All @@ -564,7 +564,7 @@ void ttm_object_device_release(struct ttm_object_device **p_tdev)

WARN_ON_ONCE(!idr_is_empty(&tdev->idr));
idr_destroy(&tdev->idr);
drm_ht_remove(&tdev->object_hash);
vmwgfx_ht_remove(&tdev->object_hash);

kfree(tdev);
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/vmwgfx/ttm_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@
#include <linux/list.h>
#include <linux/rcupdate.h>

#include <drm/drm_hashtab.h>

#include "ttm_memory.h"
#include "vmwgfx_hashtab.h"

/**
* enum ttm_ref_type
Expand Down
24 changes: 12 additions & 12 deletions drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*/
struct vmw_cmdbuf_res {
struct vmw_resource *res;
struct drm_hash_item hash;
struct vmwgfx_hash_item hash;
struct list_head head;
enum vmw_cmdbuf_res_state state;
struct vmw_cmdbuf_res_manager *man;
Expand All @@ -59,7 +59,7 @@ struct vmw_cmdbuf_res {
* @resources and @list are protected by the cmdbuf mutex for now.
*/
struct vmw_cmdbuf_res_manager {
struct drm_open_hash resources;
struct vmwgfx_open_hash resources;
struct list_head list;
struct vmw_private *dev_priv;
};
Expand All @@ -81,11 +81,11 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man,
enum vmw_cmdbuf_res_type res_type,
u32 user_key)
{
struct drm_hash_item *hash;
struct vmwgfx_hash_item *hash;
int ret;
unsigned long key = user_key | (res_type << 24);

ret = drm_ht_find_item(&man->resources, key, &hash);
ret = vmwgfx_ht_find_item(&man->resources, key, &hash);
if (unlikely(ret != 0))
return ERR_PTR(ret);

Expand All @@ -105,7 +105,7 @@ static void vmw_cmdbuf_res_free(struct vmw_cmdbuf_res_manager *man,
struct vmw_cmdbuf_res *entry)
{
list_del(&entry->head);
WARN_ON(drm_ht_remove_item(&man->resources, &entry->hash));
WARN_ON(vmwgfx_ht_remove_item(&man->resources, &entry->hash));
vmw_resource_unreference(&entry->res);
kfree(entry);
}
Expand Down Expand Up @@ -167,7 +167,7 @@ void vmw_cmdbuf_res_revert(struct list_head *list)
vmw_cmdbuf_res_free(entry->man, entry);
break;
case VMW_CMDBUF_RES_DEL:
ret = drm_ht_insert_item(&entry->man->resources, &entry->hash);
ret = vmwgfx_ht_insert_item(&entry->man->resources, &entry->hash);
BUG_ON(ret);
list_move_tail(&entry->head, &entry->man->list);
entry->state = VMW_CMDBUF_RES_COMMITTED;
Expand Down Expand Up @@ -206,7 +206,7 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man,
return -ENOMEM;

cres->hash.key = user_key | (res_type << 24);
ret = drm_ht_insert_item(&man->resources, &cres->hash);
ret = vmwgfx_ht_insert_item(&man->resources, &cres->hash);
if (unlikely(ret != 0)) {
kfree(cres);
goto out_invalid_key;
Expand Down Expand Up @@ -244,10 +244,10 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
struct vmw_resource **res_p)
{
struct vmw_cmdbuf_res *entry;
struct drm_hash_item *hash;
struct vmwgfx_hash_item *hash;
int ret;

ret = drm_ht_find_item(&man->resources, user_key | (res_type << 24),
ret = vmwgfx_ht_find_item(&man->resources, user_key | (res_type << 24),
&hash);
if (likely(ret != 0))
return -EINVAL;
Expand All @@ -260,7 +260,7 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
*res_p = NULL;
break;
case VMW_CMDBUF_RES_COMMITTED:
(void) drm_ht_remove_item(&man->resources, &entry->hash);
(void) vmwgfx_ht_remove_item(&man->resources, &entry->hash);
list_del(&entry->head);
entry->state = VMW_CMDBUF_RES_DEL;
list_add_tail(&entry->head, list);
Expand Down Expand Up @@ -295,7 +295,7 @@ vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv)

man->dev_priv = dev_priv;
INIT_LIST_HEAD(&man->list);
ret = drm_ht_create(&man->resources, VMW_CMDBUF_RES_MAN_HT_ORDER);
ret = vmwgfx_ht_create(&man->resources, VMW_CMDBUF_RES_MAN_HT_ORDER);
if (ret == 0)
return man;

Expand All @@ -320,7 +320,7 @@ void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man)
list_for_each_entry_safe(entry, next, &man->list, head)
vmw_cmdbuf_res_free(man, entry);

drm_ht_remove(&man->resources);
vmwgfx_ht_remove(&man->resources);
kfree(man);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ static void vmw_driver_unload(struct drm_device *dev)
unregister_pm_notifier(&dev_priv->pm_nb);

if (dev_priv->ctx.res_ht_initialized)
drm_ht_remove(&dev_priv->ctx.res_ht);
vmwgfx_ht_remove(&dev_priv->ctx.res_ht);
vfree(dev_priv->ctx.cmd_bounce);
if (dev_priv->enable_fb) {
vmw_fb_off(dev_priv);
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#include <drm/drm_auth.h>
#include <drm/drm_device.h>
#include <drm/drm_file.h>
#include <drm/drm_hashtab.h>
#include <drm/drm_rect.h>

#include <drm/ttm/ttm_bo_driver.h>
Expand All @@ -43,6 +42,7 @@
#include "ttm_object.h"

#include "vmwgfx_fence.h"
#include "vmwgfx_hashtab.h"
#include "vmwgfx_reg.h"
#include "vmwgfx_validation.h"

Expand Down Expand Up @@ -133,7 +133,7 @@ struct vmw_buffer_object {
*/
struct vmw_validate_buffer {
struct ttm_validate_buffer base;
struct drm_hash_item hash;
struct vmwgfx_hash_item hash;
bool validate_as_mob;
};

Expand Down Expand Up @@ -406,7 +406,7 @@ struct vmw_ctx_validation_info;
* @ctx: The validation context
*/
struct vmw_sw_context{
struct drm_open_hash res_ht;
struct vmwgfx_open_hash res_ht;
bool res_ht_initialized;
bool kernel;
struct vmw_fpriv *fp;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4117,7 +4117,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
vmw_binding_state_reset(sw_context->staged_bindings);

if (!sw_context->res_ht_initialized) {
ret = drm_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER);
ret = vmwgfx_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER);
if (unlikely(ret != 0))
goto out_unlock;

Expand Down
Loading

0 comments on commit 2985c96

Please sign in to comment.