drm/sman: rip out owner tracking
In contrast to kms drivers, sis/via _always_ associated a buffer with a drm fd. So by the time we reach lastclose, all open drm fds are gone and with them their associated objects. So when sis/via call drm_sman_cleanup in their lastclose funcs, that will free 0 objects. The owner tracking now serves no purpose at all, hence rip it ou. We can't kill the corresponding fields in struct drm_memblock_item yet because we hijack these in the new driver private owner tracking. But now that drm_sman.c doesn't touch ->owner_list anymore, we need to kill the list_move hack and properly add the item to the file_priv list. Also leave the list_del(&obj->owner_list) in drm_sman_free for the moment, it will move to the drivers when sman disappears completely. v2: Remove the redundant INIT_LIST_HEAD as noted by Chris Wilson Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
aa38e2e015
commit
763240deb4
@ -48,7 +48,6 @@ struct drm_owner_item {
|
||||
void drm_sman_takedown(struct drm_sman * sman)
|
||||
{
|
||||
drm_ht_remove(&sman->user_hash_tab);
|
||||
drm_ht_remove(&sman->owner_hash_tab);
|
||||
kfree(sman->mm);
|
||||
}
|
||||
|
||||
@ -66,16 +65,10 @@ drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
|
||||
goto out;
|
||||
}
|
||||
sman->num_managers = num_managers;
|
||||
INIT_LIST_HEAD(&sman->owner_items);
|
||||
ret = drm_ht_create(&sman->owner_hash_tab, owner_order);
|
||||
if (ret)
|
||||
goto out1;
|
||||
ret = drm_ht_create(&sman->user_hash_tab, user_order);
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
drm_ht_remove(&sman->owner_hash_tab);
|
||||
out1:
|
||||
kfree(sman->mm);
|
||||
out:
|
||||
return ret;
|
||||
@ -161,44 +154,12 @@ drm_sman_set_manager(struct drm_sman * sman, unsigned int manager,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sman_set_manager);
|
||||
|
||||
static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman,
|
||||
unsigned long owner)
|
||||
{
|
||||
int ret;
|
||||
struct drm_hash_item *owner_hash_item;
|
||||
struct drm_owner_item *owner_item;
|
||||
|
||||
ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item);
|
||||
if (!ret) {
|
||||
return drm_hash_entry(owner_hash_item, struct drm_owner_item,
|
||||
owner_hash);
|
||||
}
|
||||
|
||||
owner_item = kzalloc(sizeof(*owner_item), GFP_KERNEL);
|
||||
if (!owner_item)
|
||||
goto out;
|
||||
|
||||
INIT_LIST_HEAD(&owner_item->mem_blocks);
|
||||
owner_item->owner_hash.key = owner;
|
||||
if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash))
|
||||
goto out1;
|
||||
|
||||
list_add_tail(&owner_item->sman_list, &sman->owner_items);
|
||||
return owner_item;
|
||||
|
||||
out1:
|
||||
kfree(owner_item);
|
||||
out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int manager,
|
||||
unsigned long size, unsigned alignment,
|
||||
unsigned long owner)
|
||||
{
|
||||
void *tmp;
|
||||
struct drm_sman_mm *sman_mm;
|
||||
struct drm_owner_item *owner_item;
|
||||
struct drm_memblock_item *memblock;
|
||||
|
||||
BUG_ON(manager >= sman->num_managers);
|
||||
@ -224,16 +185,8 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man
|
||||
(unsigned long)memblock, 32, 0, 0))
|
||||
goto out1;
|
||||
|
||||
owner_item = drm_sman_get_owner_item(sman, owner);
|
||||
if (!owner_item)
|
||||
goto out2;
|
||||
|
||||
list_add_tail(&memblock->owner_list, &owner_item->mem_blocks);
|
||||
|
||||
return memblock;
|
||||
|
||||
out2:
|
||||
drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash);
|
||||
out1:
|
||||
kfree(memblock);
|
||||
out:
|
||||
@ -271,35 +224,11 @@ int drm_sman_free_key(struct drm_sman *sman, unsigned int key)
|
||||
|
||||
EXPORT_SYMBOL(drm_sman_free_key);
|
||||
|
||||
static void drm_sman_remove_owner(struct drm_sman *sman,
|
||||
struct drm_owner_item *owner_item)
|
||||
{
|
||||
list_del(&owner_item->sman_list);
|
||||
drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash);
|
||||
kfree(owner_item);
|
||||
}
|
||||
|
||||
static void drm_sman_do_owner_cleanup(struct drm_sman *sman,
|
||||
struct drm_owner_item *owner_item)
|
||||
{
|
||||
struct drm_memblock_item *entry, *next;
|
||||
|
||||
list_for_each_entry_safe(entry, next, &owner_item->mem_blocks,
|
||||
owner_list) {
|
||||
drm_sman_free(entry);
|
||||
}
|
||||
drm_sman_remove_owner(sman, owner_item);
|
||||
}
|
||||
|
||||
void drm_sman_cleanup(struct drm_sman *sman)
|
||||
{
|
||||
struct drm_owner_item *entry, *next;
|
||||
unsigned int i;
|
||||
struct drm_sman_mm *sman_mm;
|
||||
|
||||
list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) {
|
||||
drm_sman_do_owner_cleanup(sman, entry);
|
||||
}
|
||||
if (sman->mm) {
|
||||
for (i = 0; i < sman->num_managers; ++i) {
|
||||
sman_mm = &sman->mm[i];
|
||||
|
@ -143,7 +143,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
|
||||
item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0);
|
||||
|
||||
if (item) {
|
||||
list_move(&item->owner_list, &file_priv->obj_list);
|
||||
list_add(&item->owner_list, &file_priv->obj_list);
|
||||
mem->offset = ((pool == 0) ?
|
||||
dev_priv->vram_offset : dev_priv->agp_offset) +
|
||||
(item->mm->
|
||||
|
@ -141,7 +141,7 @@ int via_mem_alloc(struct drm_device *dev, void *data,
|
||||
item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0, 0);
|
||||
|
||||
if (item) {
|
||||
list_move(&item->owner_list, &file_priv->obj_list);
|
||||
list_add(&item->owner_list, &file_priv->obj_list);
|
||||
mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
|
||||
dev_priv->vram_offset : dev_priv->agp_offset) +
|
||||
(item->mm->
|
||||
|
@ -87,9 +87,7 @@ struct drm_memblock_item {
|
||||
struct drm_sman {
|
||||
struct drm_sman_mm *mm;
|
||||
int num_managers;
|
||||
struct drm_open_hash owner_hash_tab;
|
||||
struct drm_open_hash user_hash_tab;
|
||||
struct list_head owner_items;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user