Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0bacd2f authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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];
+10 −17
Original line number Original line Diff line number Diff line
@@ -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)
}
}


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
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;
}
}