From 0a51de5410431611bd55602dc3494830e46be32e Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Mon, 21 Feb 2011 13:07:26 +0100 Subject: [PATCH] gpu: pvr: improve per process procfs entry/dir handling When building with full debug, a lot of "Resource Arena" (ra) data is being made available in the rather painful procfs, including per process ra info, kept in process specific subdirectories. Adding and removing process specific entries from procfs took the PID of the currently running process; which sometimes failed during cleanup, when the current process might no longer be anything tracked by the driver. This then resulted in some strange behaviour, where it was impossible to cleanup a process specific procfs directory, resulting in an endless loop. Since process specific procfs entries are only created in the RA code, we now track the pid in the RA struct. When we pass this pid to both the procfs entry creation and removal functions, we now do reliably clean up the procfs entries. Signed-off-by: Luc Verhaegen Signed-off-by: Imre Deak --- pvr/proc.c | 115 ++++++++++++++++++++++++++++++----------------------- pvr/proc.h | 6 +-- pvr/ra.c | 64 +++++++++++++++-------------- 3 files changed, 99 insertions(+), 86 deletions(-) diff --git a/pvr/proc.c b/pvr/proc.c index 613d3de..a8564f0 100644 --- a/pvr/proc.c +++ b/pvr/proc.c @@ -138,59 +138,78 @@ int CreateProcEntry(const char *name, read_proc_t rhandler, return CreateProcEntryInDir(dir, name, rhandler, whandler, data); } -int CreatePerProcessProcEntry(const char *name, read_proc_t rhandler, - write_proc_t whandler, void *data) +static struct proc_dir_entry * +ProcessProcDirCreate(u32 pid) { struct PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; - u32 ui32PID; + char dirname[16]; + int ret; - if (!dir) { - PVR_DPF(PVR_DBG_ERROR, - "CreatePerProcessProcEntries: /proc/%s doesn't exist", - PVRProcDirRoot); + psPerProc = PVRSRVPerProcessPrivateData(pid); + if (!psPerProc) { + pr_err("%s: no per process data for %d\n", __func__, pid); + return NULL; + } - return -ENOMEM; + if (psPerProc->psProcDir) + return psPerProc->psProcDir; + + ret = snprintf(dirname, sizeof(dirname), "%u", pid); + if (ret <= 0 || ret >= sizeof(dirname)) { + pr_err("%s: couldn't generate per process proc dir for %d\n", + __func__, pid); + return NULL; } - ui32PID = OSGetCurrentProcessIDKM(); + psPerProc->psProcDir = proc_mkdir(dirname, dir); + if (!psPerProc->psProcDir) + pr_err("%s: couldn't create /proc/%s/%u\n", + __func__, PVRProcDirRoot, pid); - psPerProc = PVRSRVPerProcessPrivateData(ui32PID); - if (!psPerProc) { - PVR_DPF(PVR_DBG_ERROR, - "CreatePerProcessProcEntries: no per process data"); + return psPerProc->psProcDir; +} - return -ENOMEM; +static struct proc_dir_entry * +ProcessProcDirGet(u32 pid) +{ + struct PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; + + psPerProc = PVRSRVPerProcessPrivateData(pid); + if (!psPerProc) { + pr_err("%s: no per process data for %d\n", __func__, pid); + return NULL; } if (!psPerProc->psProcDir) { - char dirname[16]; - int ret; + pr_err("%s: couldn't retrieve /proc/%s/%u\n", __func__, + PVRProcDirRoot, pid); + return NULL; + } - ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID); + return psPerProc->psProcDir; +} - if (ret <= 0 || ret >= sizeof(dirname)) { - PVR_DPF(PVR_DBG_ERROR, "CreatePerProcessProcEntries: " - "couldn't generate per process proc " - "directory name \"%u\"", - ui32PID); +int CreatePerProcessProcEntry(u32 pid, const char *name, read_proc_t rhandler, + void *data) +{ + if (!dir) { + PVR_DPF(PVR_DBG_ERROR, + "CreatePerProcessProcEntries: /proc/%s doesn't exist", + PVRProcDirRoot); - return -ENOMEM; - } else { - psPerProc->psProcDir = proc_mkdir(dirname, dir); - if (!psPerProc->psProcDir) { - PVR_DPF(PVR_DBG_ERROR, - "CreatePerProcessProcEntries: " - "couldn't create per process proc " - "directory /proc/%s/%u", - PVRProcDirRoot, ui32PID); - - return -ENOMEM; - } - } + return -ENOMEM; } - return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, - whandler, data); + if (pid) { + struct proc_dir_entry *pid_dir = ProcessProcDirCreate(pid); + + if (!pid_dir) + return -ENOMEM; + + return CreateProcEntryInDir(pid_dir, name, rhandler, NULL, + data); + } else + return CreateProcEntryInDir(dir, name, rhandler, NULL, data); } int CreateProcReadEntry(const char *name, @@ -264,24 +283,20 @@ void RemoveProcEntry(const char *name) } } -void RemovePerProcessProcEntry(const char *name) +void RemovePerProcessProcEntry(u32 pid, const char *name) { - struct PVRSRV_ENV_PER_PROCESS_DATA *psPerProc = - PVRSRVFindPerProcessPrivateData(); + if (pid) { + struct proc_dir_entry *pid_dir = ProcessProcDirGet(pid); - if (!psPerProc) { - PVR_DPF(PVR_DBG_ERROR, "CreatePerProcessProcEntries: " - "can't remove %s, no per process data", - name); - return; - } + if (!pid_dir) + return; - if (psPerProc->psProcDir) { - remove_proc_entry(name, psPerProc->psProcDir); + remove_proc_entry(name, pid_dir); PVR_DPF(PVR_DBG_MESSAGE, "Removing proc entry %s from %s", - name, psPerProc->psProcDir->name); - } + name, pid_dir->name); + } else + RemoveProcEntry(name); } void RemovePerProcessProcDir(struct PVRSRV_ENV_PER_PROCESS_DATA *psPerProc) diff --git a/pvr/proc.h b/pvr/proc.h index 942b2ea..c93543c 100644 --- a/pvr/proc.h +++ b/pvr/proc.h @@ -42,12 +42,12 @@ int CreateProcReadEntry(const char *name, int CreateProcEntry(const char *name, read_proc_t rhandler, write_proc_t whandler, void *data); -int CreatePerProcessProcEntry(const char *name, read_proc_t rhandler, - write_proc_t whandler, void *data); +int CreatePerProcessProcEntry(u32 pid, const char *name, read_proc_t rhandler, + void *data); void RemoveProcEntry(const char *name); -void RemovePerProcessProcEntry(const char *name); +void RemovePerProcessProcEntry(u32 pid, const char *name); void RemoveProcEntries(void); diff --git a/pvr/ra.c b/pvr/ra.c index 4c71af1..bcd96b8 100644 --- a/pvr/ra.c +++ b/pvr/ra.c @@ -77,7 +77,7 @@ struct RA_ARENA { #define PROC_NAME_SIZE 32 char szProcInfoName[PROC_NAME_SIZE]; char szProcSegsName[PROC_NAME_SIZE]; - IMG_BOOL bInitProcEntry; + u32 ui32PID; #endif }; @@ -644,41 +644,44 @@ struct RA_ARENA *RA_Create(char *name, u32 base, size_t uSize, #if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_DEBUG_EXTRA) if (strcmp(pArena->name, "") != 0) { int ret; - int (*pfnCreateProcEntry) (const char *, read_proc_t, - write_proc_t, void *); - pArena->bInitProcEntry = - !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); - - pfnCreateProcEntry = pArena->bInitProcEntry ? CreateProcEntry : - CreatePerProcessProcEntry; + if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) + pArena->ui32PID = OSGetCurrentProcessIDKM(); + else + pArena->ui32PID = 0; ret = snprintf(pArena->szProcInfoName, sizeof(pArena->szProcInfoName), "ra_info_%s", pArena->name); - if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) { - (void)pfnCreateProcEntry(ReplaceSpaces - (pArena->szProcInfoName), - RA_DumpInfo, NULL, pArena); - } else { + if ((ret > 0) && (ret < sizeof(pArena->szProcInfoName))) { + ReplaceSpaces(pArena->szProcInfoName); + ret = CreatePerProcessProcEntry(pArena->ui32PID, + pArena->szProcInfoName, + RA_DumpInfo, pArena); + } else + pArena->szProcInfoName[0] = 0; + + if (ret) { pArena->szProcInfoName[0] = 0; - PVR_DPF(PVR_DBG_ERROR, "RA_Create: " - "couldn't create ra_info proc entry for arena %s", - pArena->name); + pr_err("%s: couldn't create ra_info proc entry for " + "arena %s", __func__, pArena->name); } ret = snprintf(pArena->szProcSegsName, sizeof(pArena->szProcSegsName), "ra_segs_%s", pArena->name); - if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) { - (void)pfnCreateProcEntry(ReplaceSpaces - (pArena->szProcSegsName), - RA_DumpSegs, NULL, pArena); - } else { + if ((ret > 0) && (ret < sizeof(pArena->szProcSegsName))) { + ReplaceSpaces(pArena->szProcSegsName); + ret = CreatePerProcessProcEntry(pArena->ui32PID, + pArena->szProcSegsName, + RA_DumpSegs, pArena); + } else + ret = -1; + + if (ret) { pArena->szProcSegsName[0] = 0; - PVR_DPF(PVR_DBG_ERROR, "RA_Create: " - "couldn't create ra_segs proc entry for arena %s", - pArena->name); + pr_err("%s: couldn't create ra_segs proc entry for " + "arena %s", __func__, pArena->name); } } #endif @@ -734,18 +737,13 @@ void RA_Delete(struct RA_ARENA *pArena) } #if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_DEBUG_EXTRA) { - void (*pfnRemoveProcEntry) (const char *); - - pfnRemoveProcEntry = - pArena-> - bInitProcEntry ? RemoveProcEntry : - RemovePerProcessProcEntry; - if (pArena->szProcInfoName[0] != 0) - pfnRemoveProcEntry(pArena->szProcInfoName); + RemovePerProcessProcEntry(pArena->ui32PID, + pArena->szProcInfoName); if (pArena->szProcSegsName[0] != 0) - pfnRemoveProcEntry(pArena->szProcSegsName); + RemovePerProcessProcEntry(pArena->ui32PID, + pArena->szProcSegsName); } #endif HASH_Delete(pArena->pSegmentHash); -- 2.39.5