Commit e0bacd2f authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/vm: make vm refcount into a kref

Never used to be required, but a recent change made it necessary.
Reported-by: default avatarMaarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent dc409df9
...@@ -55,7 +55,7 @@ struct nouveau_vma { ...@@ -55,7 +55,7 @@ struct nouveau_vma {
struct nouveau_vm { struct nouveau_vm {
struct nouveau_vmmgr *vmm; struct nouveau_vmmgr *vmm;
struct nouveau_mm mm; struct nouveau_mm mm;
int refcount; struct kref refcount;
struct list_head pgd_list; struct list_head pgd_list;
atomic_t engref[NVDEV_SUBDEV_NR]; atomic_t engref[NVDEV_SUBDEV_NR];
......
...@@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, ...@@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
INIT_LIST_HEAD(&vm->pgd_list); INIT_LIST_HEAD(&vm->pgd_list);
vm->vmm = vmm; vm->vmm = vmm;
vm->refcount = 1; kref_init(&vm->refcount);
vm->fpde = offset >> (vmm->pgt_bits + 12); vm->fpde = offset >> (vmm->pgt_bits + 12);
vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12); vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12);
...@@ -441,8 +441,9 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd) ...@@ -441,8 +441,9 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
} }
static void static void
nouveau_vm_del(struct nouveau_vm *vm) nouveau_vm_del(struct kref *kref)
{ {
struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount);
struct nouveau_vm_pgd *vpgd, *tmp; struct nouveau_vm_pgd *vpgd, *tmp;
list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
...@@ -458,27 +459,19 @@ int ...@@ -458,27 +459,19 @@ int
nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr,
struct nouveau_gpuobj *pgd) struct nouveau_gpuobj *pgd)
{ {
struct nouveau_vm *vm; if (ref) {
int ret; int ret = nouveau_vm_link(ref, pgd);
vm = ref;
if (vm) {
ret = nouveau_vm_link(vm, pgd);
if (ret) if (ret)
return ret; return ret;
vm->refcount++; kref_get(&ref->refcount);
} }
vm = *ptr; if (*ptr) {
*ptr = ref; nouveau_vm_unlink(*ptr, pgd);
kref_put(&(*ptr)->refcount, nouveau_vm_del);
if (vm) {
nouveau_vm_unlink(vm, pgd);
if (--vm->refcount == 0)
nouveau_vm_del(vm);
} }
*ptr = ref;
return 0; return 0;
} }
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