more fixes for [1965730]. We now free (unmap) both ashmem and pmem regions.

This commit is contained in:
Mathias Agopian
2009-07-07 17:53:43 -07:00
parent 440d4e4741
commit bd80b38f29
3 changed files with 56 additions and 22 deletions

View File

@@ -389,38 +389,36 @@ static int gralloc_free(alloc_device_t* dev,
return -EINVAL; return -EINVAL;
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
{
// free this buffer // free this buffer
private_module_t* m = reinterpret_cast<private_module_t*>( private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module); dev->common.module);
const size_t bufferSize = m->finfo.line_length * m->info.yres; const size_t bufferSize = m->finfo.line_length * m->info.yres;
int index = (hnd->base - m->framebuffer->base) / bufferSize; int index = (hnd->base - m->framebuffer->base) / bufferSize;
m->bufferMask &= ~(1<<index); m->bufferMask &= ~(1<<index);
} } else {
#if HAVE_ANDROID_OS #if HAVE_ANDROID_OS
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
{ if (hnd->fd >= 0) {
if (hnd->fd >= 0) { struct pmem_region sub = { hnd->offset, hnd->size };
struct pmem_region sub = { hnd->offset, hnd->size }; int err = ioctl(hnd->fd, PMEM_UNMAP, &sub);
int err = ioctl(hnd->fd, PMEM_UNMAP, &sub); LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
LOGE_IF(err<0, "PMEM_UNMAP failed (%s), " "fd=%d, sub.offset=%lu, sub.size=%lu",
"fd=%d, sub.offset=%lu, sub.size=%lu", strerror(errno), hnd->fd, hnd->offset, hnd->size);
strerror(errno), hnd->fd, hnd->offset, hnd->size); if (err == 0) {
if (err == 0) { // we can't deallocate the memory in case of UNMAP failure
// we can't deallocate the memory in case of UNMAP failure // because it would give that process access to someone else's
// because it would give that process access to someone else's // surfaces, which would be a security breach.
// surfaces, which would be a security breach. sAllocator.deallocate(hnd->offset);
sAllocator.deallocate(hnd->offset); }
} }
} }
}
#endif // HAVE_ANDROID_OS #endif // HAVE_ANDROID_OS
gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
terminateBuffer(module, const_cast<private_handle_t*>(hnd));
}
gralloc_module_t* m = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
gralloc_unregister_buffer(m, handle);
close(hnd->fd); close(hnd->fd);
delete hnd; delete hnd;
return 0; return 0;

View File

@@ -37,12 +37,14 @@
/*****************************************************************************/ /*****************************************************************************/
struct private_module_t; struct private_module_t;
struct private_handle_t;
inline size_t roundUpToPageSize(size_t x) { inline size_t roundUpToPageSize(size_t x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
} }
int mapFrameBufferLocked(struct private_module_t* module); int mapFrameBufferLocked(struct private_module_t* module);
int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -75,7 +75,14 @@ static int gralloc_unmap(gralloc_module_t const* module,
{ {
private_handle_t* hnd = (private_handle_t*)handle; private_handle_t* hnd = (private_handle_t*)handle;
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
if (munmap((void*)hnd->base, hnd->size) < 0) { void* base = (void*)hnd->base;
size_t size = hnd->size;
#if PMEM_HACK
base = (void*)(intptr_t(base) - hnd->offset);
size += hnd->offset;
#endif
//LOGD("unmapping from %p, size=%d", base, size);
if (munmap(base, size) < 0) {
LOGE("Could not unmap %s", strerror(errno)); LOGE("Could not unmap %s", strerror(errno));
} }
} }
@@ -144,6 +151,33 @@ int gralloc_unregister_buffer(gralloc_module_t const* module,
return 0; return 0;
} }
int terminateBuffer(gralloc_module_t const* module,
private_handle_t* hnd)
{
/*
* If the buffer has been mapped during a lock operation, it's time
* to un-map it. It's an error to be here with a locked buffer.
*/
LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK,
"handle %p still locked (state=%08x)",
hnd, hnd->lockState);
if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) {
// this buffer was mapped, unmap it now
if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) &&
(hnd->pid == getpid())) {
// ... unless it's a "master" pmem buffer, that is a buffer
// mapped in the process it's been allocated.
// (see gralloc_alloc_buffer())
} else {
gralloc_unmap(module, hnd);
}
}
return 0;
}
int gralloc_lock(gralloc_module_t const* module, int gralloc_lock(gralloc_module_t const* module,
buffer_handle_t handle, int usage, buffer_handle_t handle, int usage,
int l, int t, int w, int h, int l, int t, int w, int h,