summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnand Balagopalakrishnan <anandb@ti.com>2015-12-11 11:29:45 +0300
committerAnand Balagopalakrishnan <anandb@ti.com>2015-12-11 11:29:45 +0300
commitc53a5dfb9f4d5612c372ec8e252cb13a731c9c10 (patch)
tree0347a671a3d405b51a8277f016f175cb08060043
parente06c0a4e11401534b938b9a7b1c3f27a65db871f (diff)
parent03991033fcad439901955d54de24368c216041f2 (diff)
downloadomap5-sgx-ddk-linux-dra7/k4.1.tar.xz
Merge branch 'dra7/k3.14' into dra7/k4.1dra7/k4.1
-rw-r--r--eurasia_km/eurasiacon/build/linux2/config/core.mk3
-rw-r--r--eurasia_km/services4/srvkm/common/devicemem.c14
-rw-r--r--eurasia_km/services4/srvkm/env/linux/mm.c36
-rw-r--r--eurasia_km/services4/srvkm/env/linux/mm.h14
-rw-r--r--eurasia_km/services4/srvkm/env/linux/mmap.c45
-rw-r--r--eurasia_km/services4/srvkm/env/linux/pvr_debug.c2
6 files changed, 89 insertions, 25 deletions
diff --git a/eurasia_km/eurasiacon/build/linux2/config/core.mk b/eurasia_km/eurasiacon/build/linux2/config/core.mk
index 0d7ab16..df13442 100644
--- a/eurasia_km/eurasiacon/build/linux2/config/core.mk
+++ b/eurasia_km/eurasiacon/build/linux2/config/core.mk
@@ -471,9 +471,6 @@ $(eval $(call BothConfigMake,PVR_SYSTEM,$(PVR_SYSTEM)))
# Build-type dependent options
#
$(eval $(call BothConfigMake,BUILD,$(BUILD)))
-$(eval $(call KernelConfigC,DEBUG_LINUX_MMAP_AREAS,))
-$(eval $(call KernelConfigC,DEBUG_LINUX_MEM_AREAS,))
-$(eval $(call KernelConfigC,DEBUG_LINUX_MEMORY_ALLOCATIONS,))
$(eval $(call KernelConfigC,PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS,1))
ifeq ($(BUILD),debug)
diff --git a/eurasia_km/services4/srvkm/common/devicemem.c b/eurasia_km/services4/srvkm/common/devicemem.c
index edcec27..b53d1a6 100644
--- a/eurasia_km/services4/srvkm/common/devicemem.c
+++ b/eurasia_km/services4/srvkm/common/devicemem.c
@@ -1627,15 +1627,8 @@ static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
#if defined(SUPPORT_DRI_DRM_EXTERNAL)
IMG_BOOL bPhysContig = (IMG_BOOL)ui32Param;
- struct drm_gem_object *buf =
- BM_GetGEM(psMemInfo->sMemBlk.hBuffer);
-#endif
- PVRSRV_ERROR err = FreeMemCallBackCommon(psMemInfo, ui32Param,
- PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
-
- PVR_UNREFERENCED_PARAMETER(bDummy);
+ struct drm_gem_object *buf = BM_GetGEM(psMemInfo->sMemBlk.hBuffer);
-#if defined(SUPPORT_DRI_DRM_EXTERNAL)
if (buf) {
if (omap_gem_flags(buf) & OMAP_BO_TILED_MASK) {
omap_gem_put_paddr(buf);
@@ -1649,7 +1642,10 @@ static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
}
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
- return err;
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
}
diff --git a/eurasia_km/services4/srvkm/env/linux/mm.c b/eurasia_km/services4/srvkm/env/linux/mm.c
index 31b1a8a..6f39bea 100644
--- a/eurasia_km/services4/srvkm/env/linux/mm.c
+++ b/eurasia_km/services4/srvkm/env/linux/mm.c
@@ -1766,7 +1766,9 @@ LinuxMemAreaStructAlloc(IMG_VOID)
dump_stack();
return psLinuxMemArea;
#else
- return KMemCacheAllocWrapper(g_PsLinuxMemAreaCache, GFP_KERNEL);
+ LinuxMemArea *psLinuxMemArea = KMemCacheAllocWrapper(g_PsLinuxMemAreaCache, GFP_KERNEL);
+ INIT_LIST_HEAD(&psLinuxMemArea->sHandles);
+ return psLinuxMemArea;
#endif
}
@@ -1778,6 +1780,9 @@ LinuxMemAreaStructAlloc(IMG_VOID)
static IMG_VOID
LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
{
+#if defined(SUPPORT_DRI_DRM_EXTERNAL)
+ LinuxDrmHandle *psDrmHandle, *temp;
+#endif
struct page **pages = NULL;
#if defined(SUPPORT_DRI_DRM_EXTERNAL)
if (psLinuxMemArea->buf){
@@ -1792,6 +1797,35 @@ LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
kfree(pages);
}
+ if(!list_empty(&psLinuxMemArea->sHandles)) {
+
+ /*
+ * Ideally, I should put a WARN_ON here.
+ * reaching this function without a empty list of
+ * handles means that the userspace application has
+ * not cleaned up the EGL context as it is supposed to.
+ * As an example, GLSDK kmscube is one such application.
+ * Having a WARN_ON flags such errors in userspace early.
+ *
+ * But I will be considerate. I will clean the list here.
+ * But steps should also be taken to clean up EGL stack
+ * properly in userspace.
+ */
+#if 0
+ WARN_ON(true));
+#endif
+
+ /*
+ * This cleanup is necessary to free the memory
+ * associated with the list.
+ * The GEM handles are already deleted by drm core.
+ */
+ list_for_each_entry_safe(psDrmHandle, temp, &psLinuxMemArea->sHandles, sNode) {
+ list_del(&psDrmHandle->sNode);
+ kfree(psDrmHandle);
+ }
+ }
+
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
KMemCacheFreeWrapper(g_PsLinuxMemAreaCache, psLinuxMemArea);
/* debug */
diff --git a/eurasia_km/services4/srvkm/env/linux/mm.h b/eurasia_km/services4/srvkm/env/linux/mm.h
index 5551077..9b0544b 100644
--- a/eurasia_km/services4/srvkm/env/linux/mm.h
+++ b/eurasia_km/services4/srvkm/env/linux/mm.h
@@ -111,6 +111,18 @@ typedef enum {
typedef struct _LinuxMemArea LinuxMemArea;
+#if defined(SUPPORT_DRI_DRM_EXTERNAL)
+
+struct _LinuxDrmHandle {
+ IMG_UINT32 uiHandle;
+ struct drm_file *psFile;
+ struct list_head sNode;
+};
+
+typedef struct _LinuxDrmHandle LinuxDrmHandle;
+
+#endif
+
/* FIXME - describe this structure. */
struct _LinuxMemArea {
LINUX_MEM_AREA_TYPE eAreaType;
@@ -198,7 +210,7 @@ struct _LinuxMemArea {
#if defined(SUPPORT_DRI_DRM_EXTERNAL)
IMG_HANDLE buf; /* external buffer handle, like a GEM or ION buffer */
- IMG_UINT32 uiHandle; /* GEM handle */
+ struct list_head sHandles;
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
};
diff --git a/eurasia_km/services4/srvkm/env/linux/mmap.c b/eurasia_km/services4/srvkm/env/linux/mmap.c
index d0b369b..ebf624b 100644
--- a/eurasia_km/services4/srvkm/env/linux/mmap.c
+++ b/eurasia_km/services4/srvkm/env/linux/mmap.c
@@ -527,7 +527,8 @@ PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc =
(PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
struct drm_gem_object *buf = NULL;
- IMG_UINT32 *puiHandle;
+ LinuxDrmHandle *psDrmHandle;
+ IMG_UINT32 uiHandle;
IMG_UINT32 ret;
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
@@ -548,7 +549,6 @@ PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
}
psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
- puiHandle = &psLinuxMemArea->uiHandle;
/* Sparse mappings have to ask the BM for the virtual size */
if (psLinuxMemArea->hBMHandle)
@@ -575,29 +575,49 @@ PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
buf = create_gem_wrapper(psEnvPerProc->dev,
psLinuxMemArea, 0, *pui32RealByteSize);
if(buf){
- ret = drm_gem_handle_create(psEnvPerProc->file, (struct drm_gem_object *)buf, puiHandle);
+ ret = drm_gem_handle_create(psEnvPerProc->file, (struct drm_gem_object *)buf, &uiHandle);
if(ret) {
/*This means we are royaly screwed up. Go home. */
/*Please don't worry about not freeing the GEM. */
/*DRM core will take care of it, eventually. */
- buf = NULL;
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exit_unlock;
+ }
+ psDrmHandle = kmalloc(sizeof(*psDrmHandle), GFP_KERNEL);
+ if(!psDrmHandle) {
+ drm_gem_handle_delete (psEnvPerProc->file, uiHandle);
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exit_unlock;
}
+ psDrmHandle->uiHandle = uiHandle;
+ psDrmHandle->psFile = psEnvPerProc->file;
+ list_add_tail(&psDrmHandle->sNode, &psLinuxMemArea->sHandles);
}
if (!buf)
{
- PVR_DPF((PVR_DBG_ERROR, "%s: Screw you guys, I'm going home..", __FUNCTION__));
+ PVR_DPF((PVR_DBG_ERROR, "%s: A Drm GEM could not be created ..", __FUNCTION__));
eError = PVRSRV_ERROR_OUT_OF_MEMORY;
goto exit_unlock;
}
psLinuxMemArea->buf = buf;
} else {
- ret = drm_gem_handle_create(psEnvPerProc->file, (struct drm_gem_object *)buf, puiHandle);
+ ret = drm_gem_handle_create(psEnvPerProc->file, (struct drm_gem_object *)buf, &uiHandle);
if(ret) {
- PVR_DPF((PVR_DBG_ERROR, "%s: Screw you guys, I'm going home..", __FUNCTION__));
+ PVR_DPF((PVR_DBG_ERROR, "%s: A Drm GEM handle could not be created ..", __FUNCTION__));
eError = PVRSRV_ERROR_OUT_OF_MEMORY;
goto exit_unlock;
}
+
+ psDrmHandle = kmalloc(sizeof(*psDrmHandle), GFP_KERNEL);
+ if(!psDrmHandle) {
+ drm_gem_handle_delete (psEnvPerProc->file, uiHandle);
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exit_unlock;
+ }
+ psDrmHandle->uiHandle = uiHandle;
+ psDrmHandle->psFile = psEnvPerProc->file;
+ list_add_tail(&psDrmHandle->sNode, &psLinuxMemArea->sHandles);
}
}
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
@@ -726,6 +746,7 @@ PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
PVRSRV_ERROR eError;
IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
#if defined(SUPPORT_DRI_DRM_EXTERNAL)
+ LinuxDrmHandle *psDrmHandle, *temp;
PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc =
(PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
#endif /* SUPPORT_DRI_DRM_EXTERNAL */
@@ -749,9 +770,13 @@ PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
#if defined(SUPPORT_DRI_DRM_EXTERNAL)
- if (psLinuxMemArea->uiHandle) {
- drm_gem_handle_delete(psEnvPerProc->file, psLinuxMemArea->uiHandle);
- psLinuxMemArea->uiHandle = 0;
+ list_for_each_entry_safe(psDrmHandle, temp, &psLinuxMemArea->sHandles, sNode) {
+ if(psDrmHandle->psFile == psEnvPerProc->file) {
+ list_del(&psDrmHandle->sNode);
+ drm_gem_handle_delete(psDrmHandle->psFile, psDrmHandle->uiHandle);
+ kfree(psDrmHandle);
+ break;
+ }
}
#endif
diff --git a/eurasia_km/services4/srvkm/env/linux/pvr_debug.c b/eurasia_km/services4/srvkm/env/linux/pvr_debug.c
index 04e42ad..517dcab 100644
--- a/eurasia_km/services4/srvkm/env/linux/pvr_debug.c
+++ b/eurasia_km/services4/srvkm/env/linux/pvr_debug.c
@@ -128,7 +128,7 @@ static inline void GetBufferLock(unsigned long *pulLockFlags)
#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
else
{
- LinuxLockMutex(&gsDebugMutexNonIRQ);
+ LinuxLockMutexNested(&gsDebugMutexNonIRQ, PVRSRV_LOCK_CLASS_MM_DEBUG);
}
#endif
}