msm: kgsl: Detach memory objects from a process ahead of destroy time

Previously, memory objects assumed that they remained attached to a
process until they are destroyed. In the past this was mostly true,
but worked by luck because a process could technically map the memory
and then close the file descriptor which would eventually explode. Now we
do the process related cleanup (MMU unmap, fixup statistics) when the
object is released from the process so the process can go away without
affecting the other holders of the mem object refcount.
This commit is contained in:
securecrt 2012-07-25 19:47:35 +08:00
parent 93d86da2ee
commit 41513329a1
2 changed files with 20 additions and 5 deletions

View File

@ -199,6 +199,21 @@ void kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
entry->priv = process;
}
/* Detach a memory entry from a process and unmap it from the MMU */
static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
{
if (entry == NULL)
return;
entry->priv->stats[entry->memtype].cur -= entry->memdesc.size;
entry->priv = NULL;
kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc);
kgsl_mem_entry_put(entry);
}
/* Allocate a new context id */
static struct kgsl_context *
@ -597,7 +612,7 @@ kgsl_put_process_private(struct kgsl_device *device,
list_for_each_entry_safe(entry, entry_tmp, &private->mem_list, list) {
list_del(&entry->list);
kgsl_mem_entry_put(entry);
kgsl_mem_entry_detach_process(entry);
}
kgsl_mmu_putpagetable(private->pagetable);
@ -1022,7 +1037,7 @@ static void kgsl_freemem_event_cb(struct kgsl_device *device,
spin_lock(&entry->priv->mem_lock);
list_del(&entry->list);
spin_unlock(&entry->priv->mem_lock);
kgsl_mem_entry_put(entry);
kgsl_mem_entry_detach_process(entry);
}
static long kgsl_ioctl_cmdstream_freememontimestamp(struct kgsl_device_private
@ -1116,7 +1131,7 @@ static long kgsl_ioctl_sharedmem_free(struct kgsl_device_private *dev_priv,
spin_unlock(&private->mem_lock);
if (entry) {
kgsl_mem_entry_put(entry);
kgsl_mem_entry_detach_process(entry);
} else {
KGSL_CORE_ERR("invalid gpuaddr %08x\n", param->gpuaddr);
result = -EINVAL;

View File

@ -1,5 +1,4 @@
/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
* Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -593,6 +592,7 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
memdesc->gpuaddr & KGSL_MMU_ALIGN_MASK,
memdesc->size);
memdesc->gpuaddr = 0;
return 0;
}
EXPORT_SYMBOL(kgsl_mmu_unmap);