diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h index 2d0db001c..178ef8593 100644 --- a/include/binder/IMemory.h +++ b/include/binder/IMemory.h @@ -36,7 +36,12 @@ public: // flags returned by getFlags() enum { - READ_ONLY = 0x00000001 + READ_ONLY = 0x00000001, +#ifdef USE_MEMORY_HEAP_ION + USE_ION_FD = 0x00008000 +#else + USE_ION_FD = 0x00000008 +#endif }; virtual int getHeapID() const = 0; diff --git a/include/binder/MemoryHeapIon.h b/include/binder/MemoryHeapIon.h new file mode 100644 index 000000000..7e059f4ea --- /dev/null +++ b/include/binder/MemoryHeapIon.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright 2011, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * \file MemoryHeapIon.h + * \brief header file for MemoryHeapIon + * \author MinGu, Jeon(mingu85.jeon) + * \date 2011/11/20 + * + * Revision History: + * - 2011/11/21 : MinGu, Jeon(mingu85.jeon)) \n + * Initial version + * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n + * Change name + */ + +#ifndef ANDROID_MEMORY_HEAP_ION_H +#define ANDROID_MEMORY_HEAP_ION_H + +#include +#include +#include + +#define MHB_ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1) +#define MHB_ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) +#define MHB_ION_HEAP_EXYNOS_MASK (1 << 5) +#define MHB_ION_HEAP_SYSTEM_MASK (1 << 6) + +#define MHB_ION_FLAG_CACHED (1 << 16) +#define MHB_ION_FLAG_CACHED_NEEDS_SYNC (1 << 17) +#define MHB_ION_FLAG_PRESERVE_KMAP (1 << 18) + +#define MHB_ION_EXYNOS_VIDEO_MASK (1 << 21) +#define MHB_ION_EXYNOS_MFC_INPUT_MASK (1 << 25) +#define MHB_ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26) +#define MHB_ION_EXYNOS_GSC_MASK (1 << 27) +#define MHB_ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28) + +namespace android { + +class MemoryHeapIon : public MemoryHeapBase +{ +public: + enum { + USE_ION_FD = IMemoryHeap::USE_ION_FD + }; + MemoryHeapIon(size_t size, uint32_t flags = 0, char const* name = NULL); + MemoryHeapIon(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0); + ~MemoryHeapIon(); +private: + int mIonClient; +}; + +}; +#endif diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index d5860ef6c..b12eda8e9 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -38,11 +38,31 @@ sources := \ Static.cpp \ TextOutput.cpp \ +ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true) +sources += \ + MemoryHeapIon.cpp +endif + LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) + +ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true) +LOCAL_SHARED_LIBRARIES += libion_exynos +LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION + +ifeq ($(TARGET_SLSI_VARIANT),cm) +SLSI_DIR := samsung_slsi-cm +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM) +else +SLSI_DIR := samsung_slsi +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT) +endif +LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include +endif + LOCAL_MODULE := libbinder -LOCAL_SHARED_LIBRARIES := liblog libcutils libutils +LOCAL_SHARED_LIBRARIES += liblog libcutils libutils LOCAL_SRC_FILES := $(sources) ifneq ($(TARGET_USES_64_BIT_BINDER),true) ifneq ($(TARGET_IS_64_BIT),true) @@ -53,9 +73,30 @@ LOCAL_CFLAGS += -Werror include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) + +ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true) +LOCAL_SHARED_LIBRARIES += libion_exynos +LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION + +ifeq ($(TARGET_SLSI_VARIANT),cm) +SLSI_DIR := samsung_slsi-cm +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM) +else +SLSI_DIR := samsung_slsi +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT) +endif +LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include +endif + LOCAL_MODULE := libbinder LOCAL_STATIC_LIBRARIES += libutils LOCAL_SRC_FILES := $(sources) +ifeq ($(BOARD_NEEDS_MEMORYHEAPPMEM),true) +LOCAL_C_INCLUDES += \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include +LOCAL_ADDITIONAL_DEPENDENCIES := \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr +endif ifneq ($(TARGET_USES_64_BIT_BINDER),true) ifneq ($(TARGET_IS_64_BIT),true) LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1 diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp index e9891a830..3f2198abf 100644 --- a/libs/binder/IMemory.cpp +++ b/libs/binder/IMemory.cpp @@ -32,6 +32,10 @@ #include #include +#ifdef USE_MEMORY_HEAP_ION +#include "ion.h" +#endif + #define VERBOSE 0 namespace android { @@ -300,6 +304,14 @@ void BpMemoryHeap::assertReallyMapped() const IInterface::asBinder(this).get(), parcel_fd, size, err, strerror(-err)); +#ifdef USE_MEMORY_HEAP_ION + ion_client ion_client_num = -1; + if (flags & USE_ION_FD) { + ion_client_num = ion_client_create(); + ALOGE_IF(ion_client_num < 0, "BpMemoryHeap : ion client creation error"); + } +#endif + int fd = dup( parcel_fd ); ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)", parcel_fd, size, err, strerror(errno)); @@ -312,7 +324,16 @@ void BpMemoryHeap::assertReallyMapped() const Mutex::Autolock _l(mLock); if (mHeapId == -1) { mRealHeap = true; - mBase = mmap(0, size, access, MAP_SHARED, fd, offset); + +#ifdef USE_MEMORY_HEAP_ION + if (flags & USE_ION_FD) { + if (ion_client_num < 0) + mBase = MAP_FAILED; + else + mBase = ion_map(fd, size, offset); + } else +#endif + mBase = mmap(0, size, access, MAP_SHARED, fd, offset); if (mBase == MAP_FAILED) { ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)", IInterface::asBinder(this).get(), size, fd, strerror(errno)); @@ -324,6 +345,12 @@ void BpMemoryHeap::assertReallyMapped() const android_atomic_write(fd, &mHeapId); } } +#ifdef USE_MEMORY_HEAP_ION + if (ion_client_num < 0) + ion_client_num = -1; + else + ion_client_destroy(ion_client_num); +#endif } } diff --git a/libs/binder/MemoryHeapIon.cpp b/libs/binder/MemoryHeapIon.cpp new file mode 100644 index 000000000..374b72e16 --- /dev/null +++ b/libs/binder/MemoryHeapIon.cpp @@ -0,0 +1,189 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * \file MemoryHeapIon.cpp + * \brief source file for MemoryHeapIon + * \author MinGu, Jeon(mingu85.jeon) + * \date 2011/11/20 + * + * Revision History: + * - 2011/11/20 : MinGu, Jeon(mingu85.jeon)) \n + * Initial version + * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n + * Change name + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ion.h" + +#define HEAP_MASK_FILTER ((1 << 16) - (2)) +#define FLAG_MASK_FILTER (~(HEAP_MASK_FILTER) - (1)) + +namespace android { + +uint32_t ion_HeapMask_valid_check(uint32_t flags) +{ + uint32_t heap_mask, result; + result = 0; + + heap_mask = flags & HEAP_MASK_FILTER; + + switch(heap_mask) { + case MHB_ION_HEAP_SYSTEM_MASK: + return ION_HEAP_SYSTEM_MASK; + case MHB_ION_HEAP_SYSTEM_CONTIG_MASK: + return ION_HEAP_SYSTEM_CONTIG_MASK; + case MHB_ION_HEAP_EXYNOS_CONTIG_MASK: + return ION_HEAP_EXYNOS_CONTIG_MASK; + case MHB_ION_HEAP_EXYNOS_MASK: + return ION_HEAP_EXYNOS_MASK; + default: + ALOGE("MemoryHeapIon : Heap Mask flag is default (flags:%x)", flags); + return 0; + break; + } + ALOGE("MemoryHeapIon : Heap Mask flag is wrong (flags:%x)", flags); + return 0; +} + +uint32_t ion_FlagMask_valid_check(uint32_t flags) +{ + uint32_t flag_mask, result; + result = 0; + + flag_mask = flags & FLAG_MASK_FILTER; + + if (flag_mask & MHB_ION_FLAG_CACHED) + result |= ION_FLAG_CACHED; + if (flag_mask & MHB_ION_FLAG_CACHED_NEEDS_SYNC) + result |= ION_FLAG_CACHED_NEEDS_SYNC; + if (flag_mask & MHB_ION_FLAG_PRESERVE_KMAP) + result |= ION_FLAG_PRESERVE_KMAP; + if (flag_mask & MHB_ION_EXYNOS_VIDEO_MASK) + result |= ION_EXYNOS_VIDEO_MASK; + if (flag_mask & MHB_ION_EXYNOS_MFC_INPUT_MASK) + result |= ION_EXYNOS_MFC_INPUT_MASK; + if (flag_mask & MHB_ION_EXYNOS_MFC_OUTPUT_MASK) + result |= ION_EXYNOS_MFC_OUTPUT_MASK; + if (flag_mask & MHB_ION_EXYNOS_GSC_MASK) + result |= ION_EXYNOS_GSC_MASK; + if (flag_mask & MHB_ION_EXYNOS_FIMD_VIDEO_MASK) + result |= ION_EXYNOS_FIMD_VIDEO_MASK; + + return result; +} + +MemoryHeapIon::MemoryHeapIon(size_t size, uint32_t flags, char const *name):MemoryHeapBase() +{ + void* base = NULL; + int fd = -1; + uint32_t isReadOnly, heapMask, flagMask; + + mIonClient = ion_client_create(); + + if (mIonClient < 0) { + ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno)); + mIonClient = -1; + } else { + isReadOnly = flags & (IMemoryHeap::READ_ONLY); + heapMask = ion_HeapMask_valid_check(flags); + flagMask = ion_FlagMask_valid_check(flags); + + if (heapMask) { + ALOGD("MemoryHeapIon : Allocated with size:%d, heap:0x%X , flag:0x%X", size, heapMask, flagMask); + fd = ion_alloc(mIonClient, size, 0, heapMask, flagMask); + if (fd < 0) { + ALOGE("MemoryHeapIon : ION Reserve memory allocation failed(size[%u]) : %s", size, strerror(errno)); + if (errno == ENOMEM) { // Out of reserve memory. So re-try allocating in system heap + ALOGD("MemoryHeapIon : Re-try Allocating in default heap - SYSTEM heap"); + fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP); + } + } + } else { + fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP); + ALOGD("MemoryHeapIon : Allocated with default heap - SYSTEM heap"); + } + + flags = isReadOnly | heapMask | flagMask; + + if (fd < 0) { + ALOGE("MemoryHeapIon : ION memory allocation failed(size[%u]) : %s", size, strerror(errno)); + } else { + flags |= USE_ION_FD; + base = ion_map(fd, size, 0); + if (base != MAP_FAILED) { + init(fd, base, size, flags, NULL); + } else { + ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]) : %s", size, fd, strerror(errno)); + ion_free(fd); + } + } + } +} + +MemoryHeapIon::MemoryHeapIon(int fd, size_t size, uint32_t flags, uint32_t offset):MemoryHeapBase() +{ + void* base = NULL; + int dup_fd = -1; + + mIonClient = ion_client_create(); + + if (mIonClient < 0) { + ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno)); + mIonClient = -1; + } else { + if (fd >= 0) { + dup_fd = dup(fd); + if (dup_fd == -1) { + ALOGE("MemoryHeapIon : cannot dup fd (size[%u], fd[%d]) : %s", size, fd, strerror(errno)); + } else { + flags |= USE_ION_FD; + base = ion_map(dup_fd, size, 0); + if (base != MAP_FAILED) { + init(dup_fd, base, size, flags, NULL); + } else { + ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]): %s", size, fd, strerror(errno)); + ion_free(dup_fd); + } + } + } else { + ALOGE("MemoryHeapIon : fd parameter error(fd : %d)", fd); + } + } +} + +MemoryHeapIon::~MemoryHeapIon() +{ + if (mIonClient != -1) { + ion_unmap(getBase(), getSize()); + ion_client_destroy(mIonClient); + mIonClient = -1; + } +} + +};