diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-07-30 11:47:47 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-07-30 16:34:28 +1000 |
commit | 78207e8d0bfc7c14d8fa16de2758192828c726a5 (patch) | |
tree | a61d0deb3e5786af003cf3b1c957dcdc710e4c08 /nvkm/subdev/vm/base.c | |
parent | 3e7361211453ba7fbb54686fe7df234e1d8ca863 (diff) | |
download | nouveau-78207e8d0bfc7c14d8fa16de2758192828c726a5.tar.gz |
vm: make vm refcount into a kref
Never used to be required, but a recent change made it necessary.
Reported-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'nvkm/subdev/vm/base.c')
-rw-r--r-- | nvkm/subdev/vm/base.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/nvkm/subdev/vm/base.c b/nvkm/subdev/vm/base.c index 67fcb6c85..ef3133e75 100644 --- a/nvkm/subdev/vm/base.c +++ b/nvkm/subdev/vm/base.c @@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, INIT_LIST_HEAD(&vm->pgd_list); vm->vmm = vmm; - vm->refcount = 1; + kref_init(&vm->refcount); vm->fpde = offset >> (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) } 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; list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { @@ -458,27 +459,19 @@ int nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, struct nouveau_gpuobj *pgd) { - struct nouveau_vm *vm; - int ret; - - vm = ref; - if (vm) { - ret = nouveau_vm_link(vm, pgd); + if (ref) { + int ret = nouveau_vm_link(ref, pgd); if (ret) return ret; - vm->refcount++; + kref_get(&ref->refcount); } - vm = *ptr; - *ptr = ref; - - if (vm) { - nouveau_vm_unlink(vm, pgd); - - if (--vm->refcount == 0) - nouveau_vm_del(vm); + if (*ptr) { + nouveau_vm_unlink(*ptr, pgd); + kref_put(&(*ptr)->refcount, nouveau_vm_del); } + *ptr = ref; return 0; } |