Hi,

        Please see my comments below.

Regards,
Fernando.

>-----Original Message-----
>From: Ameya Palande [mailto:[email protected]]
>Sent: Monday, August 10, 2009 8:22 PM
>To: [email protected]
>Cc: [email protected]; Ramirez Luna, Omar; Guzman Lugo, Fernando;
>Moogi, Suyog; [email protected]; Ramos Falcon, Ernesto
>Subject: [PATCH 07/13] DSPBRIDGE: Support multiple processor objects per
>process context
>
>Signed-off-by: Ameya Palande <[email protected]>
>---
> arch/arm/plat-omap/include/dspbridge/drv.h  |    5 +-
> arch/arm/plat-omap/include/dspbridge/proc.h |   23 ++++++++++
> drivers/dsp/bridge/rmgr/drv.c               |   23 ++++++++--
> drivers/dsp/bridge/rmgr/drv_interface.c     |   13 +++++-
> drivers/dsp/bridge/rmgr/proc.c              |   61 ++++++++++-------------
>---
> 5 files changed, 79 insertions(+), 46 deletions(-)
>
>diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-
>omap/include/dspbridge/drv.h
>index c468461..efc3a92 100644
>--- a/arch/arm/plat-omap/include/dspbridge/drv.h
>+++ b/arch/arm/plat-omap/include/dspbridge/drv.h
>@@ -180,8 +180,9 @@ struct PROCESS_CONTEXT{
>       * (To maintain a linked list of process contexts) */
>       struct PROCESS_CONTEXT *next;
>
>-      /* Processor info to which the process is related */
>-      DSP_HPROCESSOR hProcessor;
>+      /* List of Processors */
>+      struct list_head processor_list;
>+      spinlock_t proc_list_lock;
>
>       /* DSP Node resources */
>       struct NODE_RES_OBJECT *pNodeList;
>diff --git a/arch/arm/plat-omap/include/dspbridge/proc.h b/arch/arm/plat-
>omap/include/dspbridge/proc.h
>index f5b0c50..1936a4e 100644
>--- a/arch/arm/plat-omap/include/dspbridge/proc.h
>+++ b/arch/arm/plat-omap/include/dspbridge/proc.h
>@@ -66,6 +66,29 @@
> #include <dspbridge/devdefs.h>
> #include <dspbridge/drv.h>
>
>+/* The PROC_OBJECT structure.   */
>+struct PROC_OBJECT {
>+      struct LST_ELEM link;           /* Link to next PROC_OBJECT */
>+      u32 dwSignature;                /* Used for object validation */
>+      struct DEV_OBJECT *hDevObject;  /* Device this PROC represents */
>+      u32 hProcess;                   /* Process owning this Processor */
>+      struct MGR_OBJECT *hMgrObject;  /* Manager Object Handle */
>+      u32 uAttachCount;               /* Processor attach count */
>+      u32 uProcessor;                 /* Processor number */
>+      u32 uTimeout;                   /* Time out count */
>+      enum DSP_PROCSTATE sState;      /* Processor state */
>+      u32 ulUnit;                     /* DDSP unit number */
>+      bool bIsAlreadyAttached;        /*
>+                                       * True if the Device below has
>+                                       * GPP Client attached
>+                                       */
>+      struct NTFY_OBJECT *hNtfy;      /* Manages  notifications */
>+      struct WMD_DEV_CONTEXT *hWmdContext;    /* WMD Context Handle */
>+      struct WMD_DRV_INTERFACE *pIntfFxns;    /* Function interface to
>WMD */
>+      char *g_pszLastCoff;
>+      struct list_head proc_object;
>+};
>+
> /*
>  *  ======== PROC_Attach ========
>  *  Purpose:
>diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c
>index 4a4ebfa..e64b997 100644
>--- a/drivers/dsp/bridge/rmgr/drv.c
>+++ b/drivers/dsp/bridge/rmgr/drv.c
>@@ -278,9 +278,19 @@ DSP_STATUS DRV_InsertProcContext(struct DRV_OBJECT
>*hDrVObject, HANDLE hPCtxt)
>       struct DRV_OBJECT            *hDRVObject;
>
>       GT_0trace(curTrace, GT_ENTER, "\n In DRV_InsertProcContext\n");
>+
>       status = CFG_GetObject((u32 *)&hDRVObject, REG_DRV_OBJECT);
>       DBC_Assert(hDRVObject != NULL);
>+
>       *pCtxt = MEM_Calloc(1 * sizeof(struct PROCESS_CONTEXT), MEM_PAGED);
>+      if (!*pCtxt) {
>+              pr_err("DSP: MEM_Calloc failed in DRV_InsertProcContext\n");
>+              return DSP_EMEMORY;
>+      }
>+
>+      spin_lock_init(&(*pCtxt)->proc_list_lock);
>+      INIT_LIST_HEAD(&(*pCtxt)->processor_list);
>+
>       GT_0trace(curTrace, GT_ENTER,
>                "\n In DRV_InsertProcContext Calling "
>                "DRV_GetProcCtxtList\n");
>@@ -1005,6 +1015,7 @@ static DSP_STATUS PrintProcessInformation(void)
>       struct DMM_RES_OBJECT *pDMMRes = NULL;
>       struct STRM_RES_OBJECT *pSTRMRes = NULL;
>       struct DSPHEAP_RES_OBJECT *pDSPHEAPRes = NULL;
>+      struct PROC_OBJECT *proc_obj_ptr;
>       DSP_STATUS status = DSP_SOK;
>       u32 tempCount;
>       u32  procID;
>@@ -1031,11 +1042,11 @@ static DSP_STATUS PrintProcessInformation(void)
>                       GT_0trace(curTrace, GT_4CLASS, "\nThe Process"
>                                       " is in DeAllocated state\n");
>               }
>-              GT_1trace(curTrace, GT_4CLASS, "\nThe  hProcessor"
>-                              " handle is: 0X%x\n",
>-                              (u32)pCtxtList->hProcessor);
>-              if (pCtxtList->hProcessor != NULL) {
>-                      PROC_GetProcessorId(pCtxtList->hProcessor, &procID);
>+
>+              spin_lock(&pCtxtList->proc_list_lock);
>+              list_for_each_entry(proc_obj_ptr, &pCtxtList->processor_list,
>+                              proc_object) {
>+                      PROC_GetProcessorId(proc_obj_ptr, &procID);
>                       if (procID == DSP_UNIT) {
>                               GT_0trace(curTrace, GT_4CLASS,
>                                       "\nProcess connected to"
>@@ -1049,6 +1060,8 @@ static DSP_STATUS PrintProcessInformation(void)
>                                       "\n***ERROR:Invalid Processor Id***\n");
>                       }
>               }
>+              spin_unlock(&pCtxtList->proc_list_lock);
>+
>               pNodeRes = pCtxtList->pNodeList;
>               tempCount = 1;
>               while (pNodeRes != NULL) {
>diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c
>b/drivers/dsp/bridge/rmgr/drv_interface.c
>index 7d4a6ea..1cb3d74 100644
>--- a/drivers/dsp/bridge/rmgr/drv_interface.c
>+++ b/drivers/dsp/bridge/rmgr/drv_interface.c
>@@ -452,6 +452,7 @@ static int __devexit omap34xx_bridge_remove(struct
>platform_device *pdev)
>       HANDLE       hDrvObject = NULL;
>       struct PROCESS_CONTEXT  *pTmp = NULL;
>       struct PROCESS_CONTEXT    *pCtxtclosed = NULL;
>+      struct PROC_OBJECT *proc_obj_ptr, *temp;
>
>       GT_0trace(driverTrace, GT_ENTER, "-> driver_exit\n");
>
>@@ -474,7 +475,10 @@ static int __devexit omap34xx_bridge_remove(struct
>platform_device *pdev)
>               GT_1trace(driverTrace, GT_5CLASS, "***Cleanup of "
>                        "process***%d\n", pCtxtclosed->pid);
>               DRV_RemoveAllResources(pCtxtclosed);
>-              PROC_Detach(pCtxtclosed->hProcessor, pCtxtclosed);
>+              list_for_each_entry_safe(proc_obj_ptr, temp,
>+                              &pCtxtclosed->processor_list, proc_object) {
>+                      PROC_Detach(proc_obj_ptr, pCtxtclosed);
>+              }
>               pTmp = pCtxtclosed->next;
>               DRV_RemoveProcContext((struct DRV_OBJECT *)hDrvObject,
>                                    pCtxtclosed, (void *)pCtxtclosed->pid);

I don't think that a resource cleanup be needed in omap34xx_bridge_remove, 
because there is not way that omap34xx_bridge_remove be called before all the 
handles to DSPBridge were released and then all process context have been 
freed. I think also we can delete the process context list at all because each 
process is in charge of his our resource cleanup. Please let me know your 
comments.


>@@ -608,6 +612,7 @@ static int bridge_release(struct inode *ip, struct file
>*filp)
>       DSP_STATUS dsp_status;
>       HANDLE hDrvObject;
>       struct PROCESS_CONTEXT *pr_ctxt;
>+      struct PROC_OBJECT *proc_obj_ptr, *temp;
>
>       GT_0trace(driverTrace, GT_ENTER, "-> bridge_release\n");
>
>@@ -619,7 +624,11 @@ static int bridge_release(struct inode *ip, struct
>file *filp)
>               if (DSP_SUCCEEDED(dsp_status)) {
>                       flush_signals(current);
>                       DRV_RemoveAllResources(pr_ctxt);
>-                      PROC_Detach(pr_ctxt->hProcessor, pr_ctxt);
>+                      list_for_each_entry_safe(proc_obj_ptr, temp,
>+                                      &pr_ctxt->processor_list,
>+                                      proc_object) {
>+                              PROC_Detach(proc_obj_ptr, pr_ctxt);
>+                      }
>                       DRV_RemoveProcContext((struct DRV_OBJECT *)hDrvObject,
>                                       pr_ctxt, (void *)pr_ctxt->pid);
>               } else {
>diff --git a/drivers/dsp/bridge/rmgr/proc.c
>b/drivers/dsp/bridge/rmgr/proc.c
>index 323054f..4a76f24 100644
>--- a/drivers/dsp/bridge/rmgr/proc.c
>+++ b/drivers/dsp/bridge/rmgr/proc.c
>@@ -160,27 +160,6 @@
> #define EXTEND              "_EXT_END"        /* Extmem end addr in DSP 
> binary */
>
> extern char *iva_img;
>-/* The PROC_OBJECT structure.   */
>-struct PROC_OBJECT {
>-      struct LST_ELEM link;           /* Link to next PROC_OBJECT */
>-      u32 dwSignature;        /* Used for object validation */
>-      struct DEV_OBJECT *hDevObject;  /* Device this PROC represents */
>-      u32 hProcess;   /* Process owning this Processor */
>-      struct MGR_OBJECT *hMgrObject;  /* Manager Object Handle */
>-      u32 uAttachCount;       /* Processor attach count */
>-      u32 uProcessor; /* Processor number */
>-      u32 uTimeout;           /* Time out count */
>-      enum DSP_PROCSTATE sState;      /* Processor state */
>-      u32 ulUnit;             /* DDSP unit number */
>-      bool bIsAlreadyAttached;        /*
>-                                       * True if the Device below has
>-                                       * GPP Client attached
>-                                       */
>-      struct NTFY_OBJECT *hNtfy;      /* Manages  notifications */
>-      struct WMD_DEV_CONTEXT *hWmdContext;    /* WMD Context Handle */
>-      struct WMD_DRV_INTERFACE *pIntfFxns;    /* Function interface to
>WMD */
>-      char *g_pszLastCoff;
>-} ;
>
> /*  ----------------------------------- Globals */
> #if GT_TRACE
>@@ -207,24 +186,32 @@ static char **PrependEnvp(char **newEnvp, char
>**envp, s32 cEnvp, s32 cNewEnvp,
> DSP_STATUS PROC_CleanupAllResources(void)
> {
>       DSP_STATUS dsp_status = DSP_SOK;
>-      HANDLE       hDrvObject = NULL;
>-      struct PROCESS_CONTEXT    *pCtxtclosed = NULL;
>+      HANDLE hDrvObject = NULL;
>+      struct PROCESS_CONTEXT *pCtxtclosed = NULL;
>+      struct PROC_OBJECT *proc_obj_ptr, *temp;
>+
>       GT_0trace(PROC_DebugMask, GT_ENTER, "PROC_CleanupAllResources\n");
>+
>       dsp_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
>       if (DSP_FAILED(dsp_status))
>               goto func_end;
>+
>       DRV_GetProcCtxtList(&pCtxtclosed, (struct DRV_OBJECT *)hDrvObject);
>+
>       while (pCtxtclosed != NULL) {
>               if (current->tgid != pCtxtclosed->pid) {
>                       GT_1trace(PROC_DebugMask, GT_5CLASS,
>                                "***Cleanup of "
>                                "process***%d\n", pCtxtclosed->pid);
>-                      if (pCtxtclosed->hProcessor)
>-                              PROC_Detach(pCtxtclosed->hProcessor,
>-                                              pCtxtclosed);
>+                      list_for_each_entry_safe(proc_obj_ptr, temp,
>+                                      &pCtxtclosed->processor_list,
>+                                      proc_object) {
>+                              PROC_Detach(proc_obj_ptr, pCtxtclosed);
>+                      }
>               }
>               pCtxtclosed = pCtxtclosed->next;
>       }

PROC_CleanupAllResources is not needed anymore with the changes to 
bridge_realse we can delete that and process context list too.


>+
>       WMD_DEH_ReleaseDummyMem();
> func_end:
>       return dsp_status;
>@@ -254,12 +241,6 @@ PROC_Attach(u32 uProcessor, OPTIONAL CONST struct
>DSP_PROCESSORATTRIN *pAttrIn,
>                "uProcessor:  0x%x\n\tpAttrIn:  0x%x\n\tphProcessor:"
>                "0x%x\n", uProcessor, pAttrIn, phProcessor);
>
>-      if (pr_ctxt->hProcessor) {
>-              pr_err("DSP: PROC_Attach() on same file handle is "
>-                              "not supported!\n");
>-              goto func_end;
>-      }
>-
>       /* Get the Driver and Manager Object Handles */
>       status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
>       if (DSP_SUCCEEDED(status)) {
>@@ -308,10 +289,11 @@ PROC_Attach(u32 uProcessor, OPTIONAL CONST struct
>DSP_PROCESSORATTRIN *pAttrIn,
>       pProcObject->hDevObject = hDevObject;
>       pProcObject->hMgrObject = hMgrObject;
>       pProcObject->uProcessor = devType;
>-      /* Get Caller Process and store it */
>-      /* Return TGID instead of process handle */
>+      /* Store TGID of Caller Process */
>       pProcObject->hProcess = current->tgid;
>
>+      INIT_LIST_HEAD(&pProcObject->proc_object);
>+
>       if (pAttrIn)
>               pProcObject->uTimeout = pAttrIn->uTimeout;
>       else
>@@ -382,7 +364,9 @@ PROC_Attach(u32 uProcessor, OPTIONAL CONST struct
>DSP_PROCESSORATTRIN *pAttrIn,
>               MEM_FreeObject(pProcObject);
>       }
> #ifndef RES_CLEANUP_DISABLE
>-      pr_ctxt->hProcessor = pProcObject;
>+      spin_lock(&pr_ctxt->proc_list_lock);
>+      list_add(&pProcObject->proc_object, &pr_ctxt->processor_list);
>+      spin_unlock(&pr_ctxt->proc_list_lock);
> #endif
> func_end:
>       DBC_Ensure((status == DSP_EFAIL && *phProcessor == NULL) ||
>@@ -616,8 +600,11 @@ DSP_STATUS PROC_Detach(DSP_HPROCESSOR hProcessor,
>
>       if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) {
> #ifndef RES_CLEANUP_DISABLE
>-              if (pr_ctxt != NULL)
>-                      pr_ctxt->hProcessor = NULL;
>+              if (pr_ctxt) {
>+                      spin_lock(&pr_ctxt->proc_list_lock);
>+                      list_del(&pProcObject->proc_object);
>+                      spin_unlock(&pr_ctxt->proc_list_lock);
>+              }
> #endif
>               /* Notify the Client */
>               NTFY_Notify(pProcObject->hNtfy, DSP_PROCESSORDETACH);
>--
>1.6.2.4
>

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to