From patchwork Wed Jul 28 21:04:53 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ramos Falcon, Ernesto" X-Patchwork-Id: 114906 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6SL1BnS013193 for ; Wed, 28 Jul 2010 21:01:11 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756328Ab0G1VAr (ORCPT ); Wed, 28 Jul 2010 17:00:47 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:49163 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756234Ab0G1VAZ (ORCPT ); Wed, 28 Jul 2010 17:00:25 -0400 Received: from dlep36.itg.ti.com ([157.170.170.91]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o6SL0AOr025275 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 28 Jul 2010 16:00:10 -0500 Received: from emcc1.sasken-mty.naucm.ext.ti.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id o6SL09Ek025577; Wed, 28 Jul 2010 16:00:09 -0500 (CDT) Received: from localhost.localdomain (x0076199-desktop.sasken-mty.naucm.ext.ti.com [10.87.230.107]) by emcc1.sasken-mty.naucm.ext.ti.com (8.13.8+Sun/8.13.8) with ESMTP id o6SL06xY017327; Wed, 28 Jul 2010 16:00:09 -0500 (CDT) From: Ernesto Ramos To: gregkh@suse.de Cc: omar.ramirez@ti.com, ohad@wizery.com, ameya.palande@nokia.com, felipe.contreras@nokia.com, fernando.lugo@ti.com, linux-kernel@vger.kernel.org, andy.shevchenko@gmail.com, nm@ti.com, linux-omap@vger.kernel.org, Ernesto Ramos Subject: [PATCH] staging:ti dspbridge: use node id instead of kernel address Date: Wed, 28 Jul 2010 16:04:53 -0500 Message-Id: <1280351097-3346-2-git-send-email-ernesto@ti.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1280351097-3346-1-git-send-email-ernesto@ti.com> References: <1280351097-3346-1-git-send-email-ernesto@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 28 Jul 2010 21:01:11 +0000 (UTC) diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index 28541f7..0b36a11 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -24,6 +24,7 @@ #include #include +#include #define DRV_ASSIGN 1 #define DRV_RELEASE 0 @@ -81,7 +82,7 @@ struct node_res_object { s32 node_allocated; /* Node status */ s32 heap_allocated; /* Heap status */ s32 streams_allocated; /* Streams status */ - struct node_res_object *next; + int id; }; /* used to cache dma mapping information */ @@ -158,8 +159,7 @@ struct process_context { void *hprocessor; /* DSP Node resources */ - struct node_res_object *node_list; - struct mutex node_mutex; + struct idr *node_id; /* DMM mapped memory resources */ struct list_head dmm_map_list; diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 61d2d9b..49ed5c1 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -36,7 +36,7 @@ * pargs: Optional arguments to be passed to the node. * attr_in: Optional pointer to node attributes (priority, * timeout...) - * ph_node: Location to store node handle on output. + * noderes: Location to store node resource info. * Returns: * 0: Success. * -ENOMEM: Insufficient memory on GPP. @@ -50,17 +50,17 @@ * node_init(void) called. * hprocessor != NULL. * node_uuid != NULL. - * ph_node != NULL. + * noderes != NULL. * Ensures: * 0: IsValidNode(*ph_node). - * error: *ph_node == NULL. + * error: *noderes == NULL. */ extern int node_allocate(struct proc_object *hprocessor, const struct dsp_uuid *node_uuid, const struct dsp_cbdata *pargs, const struct dsp_nodeattrin *attr_in, - struct node_object **ph_node, + struct node_res_object **noderes, struct process_context *pr_ctxt); /* @@ -242,7 +242,9 @@ extern int node_create_mgr(struct node_mgr **node_man, * delete function. Loads the node's delete function if necessary. * GPP side resources are freed after node's delete function returns. * Parameters: - * hnode: Node handle returned from node_allocate(). + * noderes: Node resource info handle returned from + * node_allocate(). + * pr_ctxt: Poninter to process context data. * Returns: * 0: Success. * -EFAULT: Invalid hnode. @@ -254,7 +256,7 @@ extern int node_create_mgr(struct node_mgr **node_man, * Ensures: * 0: hnode is invalid. */ -extern int node_delete(struct node_object *hnode, +extern int node_delete(struct node_res_object *noderes, struct process_context *pr_ctxt); /* diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h index 4e1b8a2..d17c7fb 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h +++ b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h @@ -34,17 +34,11 @@ extern int drv_remove_all_resources(void *process_ctxt); extern int drv_remove_proc_context(struct drv_object *driver_obj, void *pr_ctxt); -extern int drv_get_node_res_element(void *hnode, void *node_resource, - void *process_ctx); - extern int drv_insert_node_res_element(void *hnode, void *node_resource, void *process_ctxt); extern void drv_proc_node_update_heap_status(void *node_resource, s32 status); -extern int drv_remove_node_res_element(void *node_resource, - void *process_ctxt); - extern void drv_proc_node_update_status(void *node_resource, s32 status); extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources); diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index da08dfc..6eda7c5 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -1052,6 +1052,20 @@ u32 procwrap_stop(union trapped_args *args, void *pr_ctxt) } /* + * ======== find_handle ========= + */ +inline void find_node_handle(struct node_res_object **noderes, + void *pr_ctxt, void *hnode) +{ + rcu_read_lock(); + *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id, + (int)hnode); + rcu_read_unlock(); + return; +} + + +/* * ======== nodewrap_allocate ======== */ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) @@ -1062,7 +1076,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs; u8 *pargs = NULL; struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; - struct node_object *hnode; + struct node_res_object *node_res; /* Optional argument */ if (psize) { @@ -1095,13 +1109,14 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) if (!status) { status = node_allocate(args->args_node_allocate.hprocessor, &node_uuid, (struct dsp_cbdata *)pargs, - attr_in, &hnode, pr_ctxt); + attr_in, &node_res, pr_ctxt); } if (!status) { - CP_TO_USR(args->args_node_allocate.ph_node, &hnode, status, 1); + CP_TO_USR(args->args_node_allocate.ph_node, &node_res->id, + status, 1); if (status) { status = -EFAULT; - node_delete(hnode, pr_ctxt); + node_delete(node_res, pr_ctxt); } } func_cont: @@ -1119,6 +1134,13 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) struct dsp_bufferattr *pattr = NULL; struct dsp_bufferattr attr; u8 *pbuffer = NULL; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, + args->args_node_allocmsgbuf.hnode); + + if (!node_res) + return -EFAULT; if (!args->args_node_allocmsgbuf.usize) return -EINVAL; @@ -1132,7 +1154,7 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) /* argument */ CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1); if (!status) { - status = node_alloc_msg_buf(args->args_node_allocmsgbuf.hnode, + status = node_alloc_msg_buf(node_res->hnode, args->args_node_allocmsgbuf.usize, pattr, &pbuffer); } @@ -1146,8 +1168,15 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt) { u32 ret; + struct node_res_object *node_res; - ret = node_change_priority(args->args_node_changepriority.hnode, + find_node_handle(&node_res, pr_ctxt, + args->args_node_changepriority.hnode); + + if (!node_res) + return -EFAULT; + + ret = node_change_priority(node_res->hnode, args->args_node_changepriority.prio); return ret; @@ -1164,6 +1193,29 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) u32 cb_data_size; u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param; u8 *pargs = NULL; + struct node_res_object *node_res1, *node_res2; + struct node_object *node1 = NULL, *node2 = NULL; + + if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) { + find_node_handle(&node_res1, pr_ctxt, + args->args_node_connect.hnode); + if (node_res1) + node1 = node_res1->hnode; + } else { + node1 = args->args_node_connect.hnode; + } + + if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) { + find_node_handle(&node_res2, pr_ctxt, + args->args_node_connect.other_node); + if (node_res2) + node2 = node_res2->hnode; + } else { + node2 = args->args_node_connect.other_node; + } + + if (!node1 || !node2) + return -EFAULT; /* Optional argument */ if (psize) { @@ -1191,9 +1243,9 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) } if (!status) { - status = node_connect(args->args_node_connect.hnode, + status = node_connect(node1, args->args_node_connect.stream_id, - args->args_node_connect.other_node, + node2, args->args_node_connect.other_stream, pattrs, (struct dsp_cbdata *)pargs); } @@ -1209,8 +1261,14 @@ func_cont: u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) { u32 ret; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode); - ret = node_create(args->args_node_create.hnode); + if (!node_res) + return -EFAULT; + + ret = node_create(node_res->hnode); return ret; } @@ -1221,8 +1279,14 @@ u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt) { u32 ret; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode); + + if (!node_res) + return -EFAULT; - ret = node_delete(args->args_node_delete.hnode, pr_ctxt); + ret = node_delete(node_res, pr_ctxt); return ret; } @@ -1235,6 +1299,13 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) int status = 0; struct dsp_bufferattr *pattr = NULL; struct dsp_bufferattr attr; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode); + + if (!node_res) + return -EFAULT; + if (args->args_node_freemsgbuf.pattr) { /* Optional argument */ CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1); if (!status) @@ -1246,7 +1317,7 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) return -EFAULT; if (!status) { - status = node_free_msg_buf(args->args_node_freemsgbuf.hnode, + status = node_free_msg_buf(node_res->hnode, args->args_node_freemsgbuf.pbuffer, pattr); } @@ -1261,8 +1332,14 @@ u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt) { int status = 0; struct dsp_nodeattr attr; + struct node_res_object *node_res; - status = node_get_attr(args->args_node_getattr.hnode, &attr, + find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode); + + if (!node_res) + return -EFAULT; + + status = node_get_attr(node_res->hnode, &attr, args->args_node_getattr.attr_size); CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1); @@ -1276,8 +1353,14 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) { int status; struct dsp_msg msg; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode); - status = node_get_message(args->args_node_getmessage.hnode, &msg, + if (!node_res) + return -EFAULT; + + status = node_get_message(node_res->hnode, &msg, args->args_node_getmessage.utimeout); CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); @@ -1291,8 +1374,14 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt) { u32 ret; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode); + + if (!node_res) + return -EFAULT; - ret = node_pause(args->args_node_pause.hnode); + ret = node_pause(node_res->hnode); return ret; } @@ -1304,12 +1393,18 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) { int status = 0; struct dsp_msg msg; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode); + + if (!node_res) + return -EFAULT; CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1); if (!status) { status = - node_put_message(args->args_node_putmessage.hnode, &msg, + node_put_message(node_res->hnode, &msg, args->args_node_putmessage.utimeout); } @@ -1323,6 +1418,13 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) { int status = 0; struct dsp_notification notification; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, + args->args_node_registernotify.hnode); + + if (!node_res) + return -EFAULT; /* Initialize the notification data structure */ notification.ps_name = NULL; @@ -1333,7 +1435,7 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) args->args_proc_register_notify.hnotification, status, 1); - status = node_register_notify(args->args_node_registernotify.hnode, + status = node_register_notify(node_res->hnode, args->args_node_registernotify.event_mask, args->args_node_registernotify. notify_type, ¬ification); @@ -1348,8 +1450,14 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) u32 nodewrap_run(union trapped_args *args, void *pr_ctxt) { u32 ret; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode); + + if (!node_res) + return -EFAULT; - ret = node_run(args->args_node_run.hnode); + ret = node_run(node_res->hnode); return ret; } @@ -1361,8 +1469,14 @@ u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt) { int status; int tempstatus; + struct node_res_object *node_res; - status = node_terminate(args->args_node_terminate.hnode, &tempstatus); + find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode); + + if (!node_res) + return -EFAULT; + + status = node_terminate(node_res->hnode, &tempstatus); CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1); @@ -1548,6 +1662,12 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) struct strm_attr attr; struct strm_object *strm_obj; struct dsp_streamattrin strm_attr_in; + struct node_res_object *node_res; + + find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode); + + if (!node_res) + return -EFAULT; CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1); @@ -1560,7 +1680,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) } } - status = strm_open(args->args_strm_open.hnode, + status = strm_open(node_res->hnode, args->args_strm_open.direction, args->args_strm_open.index, &attr, &strm_obj, pr_ctxt); diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 12c270a..c8d9d25 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -73,7 +73,7 @@ static int request_bridge_resources(struct cfg_hostres *res); /* GPP PROCESS CLEANUP CODE */ -static int drv_proc_free_node_res(void *process_ctxt); +static int drv_proc_free_node_res(int id, void *p, void *data); /* Allocate and add a node resource element * This function is called from .Node_Allocate. */ @@ -84,88 +84,61 @@ int drv_insert_node_res_element(void *hnode, void *node_resource, (struct node_res_object **)node_resource; struct process_context *ctxt = (struct process_context *)process_ctxt; int status = 0; - struct node_res_object *temp_node_res = NULL; + int retval; *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL); - if (*node_res_obj == NULL) - status = -EFAULT; + if (!*node_res_obj) { + status = -ENOMEM; + goto func_end; + } - if (!status) { - if (mutex_lock_interruptible(&ctxt->node_mutex)) { - kfree(*node_res_obj); - return -EPERM; + (*node_res_obj)->hnode = hnode; + retval = idr_get_new(ctxt->node_id, *node_res_obj, + &(*node_res_obj)->id); + if (retval == -EAGAIN) { + if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) { + pr_err("%s: OUT OF MEMORY\n", __func__); + status = -ENOMEM; + goto func_end; } - (*node_res_obj)->hnode = hnode; - if (ctxt->node_list != NULL) { - temp_node_res = ctxt->node_list; - while (temp_node_res->next != NULL) - temp_node_res = temp_node_res->next; - temp_node_res->next = *node_res_obj; - } else { - ctxt->node_list = *node_res_obj; - } - mutex_unlock(&ctxt->node_mutex); + retval = idr_get_new(ctxt->node_id, *node_res_obj, + &(*node_res_obj)->id); + } + if (retval) { + pr_err("%s: FAILED, IDR is FULL\n", __func__); + status = -EFAULT; } +func_end: + if (status) + kfree(*node_res_obj); return status; } /* Release all Node resources and its context -* This is called from .Node_Delete. */ -int drv_remove_node_res_element(void *node_resource, void *process_ctxt) + * Actual Node De-Allocation */ +static int drv_proc_free_node_res(int id, void *p, void *data) { - struct node_res_object *node_res_obj = - (struct node_res_object *)node_resource; - struct process_context *ctxt = (struct process_context *)process_ctxt; - struct node_res_object *temp_node; - int status = 0; - - if (mutex_lock_interruptible(&ctxt->node_mutex)) - return -EPERM; - temp_node = ctxt->node_list; - if (temp_node == node_res_obj) { - ctxt->node_list = node_res_obj->next; - } else { - while (temp_node && temp_node->next != node_res_obj) - temp_node = temp_node->next; - if (!temp_node) - status = -ENOENT; - else - temp_node->next = node_res_obj->next; - } - mutex_unlock(&ctxt->node_mutex); - kfree(node_res_obj); - return status; -} - -/* Actual Node De-Allocation */ -static int drv_proc_free_node_res(void *process_ctxt) -{ - struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; - struct node_res_object *node_list = NULL; - struct node_res_object *node_res_obj = NULL; + struct process_context *ctxt = data; + int status; + struct node_res_object *node_res_obj = p; u32 node_state; - node_list = ctxt->node_list; - while (node_list != NULL) { - node_res_obj = node_list; - node_list = node_list->next; - if (node_res_obj->node_allocated) { - node_state = node_get_state(node_res_obj->hnode); - if (node_state <= NODE_DELETING) { - if ((node_state == NODE_RUNNING) || - (node_state == NODE_PAUSED) || - (node_state == NODE_TERMINATING)) - status = node_terminate - (node_res_obj->hnode, &status); - - status = node_delete(node_res_obj->hnode, ctxt); - } + if (node_res_obj->node_allocated) { + node_state = node_get_state(node_res_obj->hnode); + if (node_state <= NODE_DELETING) { + if ((node_state == NODE_RUNNING) || + (node_state == NODE_PAUSED) || + (node_state == NODE_TERMINATING)) + node_terminate + (node_res_obj->hnode, &status); + + node_delete(node_res_obj, ctxt); } } - return status; + + return 0; } /* Release all Mapped and Reserved DMM resources */ @@ -220,50 +193,12 @@ void drv_proc_node_update_heap_status(void *node_resource, s32 status) */ int drv_remove_all_node_res_elements(void *process_ctxt) { - struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; - struct node_res_object *temp_node2 = NULL; - struct node_res_object *temp_node = NULL; - - drv_proc_free_node_res(ctxt); - temp_node = ctxt->node_list; - while (temp_node != NULL) { - temp_node2 = temp_node; - temp_node = temp_node->next; - kfree(temp_node2); - } - ctxt->node_list = NULL; - return status; -} + struct process_context *ctxt = process_ctxt; -/* Getting the node resource element */ -int drv_get_node_res_element(void *hnode, void *node_resource, - void *process_ctxt) -{ - struct node_res_object **node_res = - (struct node_res_object **)node_resource; - struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; - struct node_res_object *temp_node2 = NULL; - struct node_res_object *temp_node = NULL; - - if (mutex_lock_interruptible(&ctxt->node_mutex)) - return -EPERM; - - temp_node = ctxt->node_list; - while ((temp_node != NULL) && (temp_node->hnode != hnode)) { - temp_node2 = temp_node; - temp_node = temp_node->next; - } + idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt); + idr_destroy(ctxt->node_id); - mutex_unlock(&ctxt->node_mutex); - - if (temp_node != NULL) - *node_res = temp_node; - else - status = -ENOENT; - - return status; + return 0; } /* Allocate the STRM resource element diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index aec7cf7..900cdd3 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -511,8 +511,13 @@ static int bridge_open(struct inode *ip, struct file *filp) INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); spin_lock_init(&pr_ctxt->dmm_rsv_lock); INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); - mutex_init(&pr_ctxt->node_mutex); mutex_init(&pr_ctxt->strm_mutex); + + pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); + if (pr_ctxt->node_id) + idr_init(pr_ctxt->node_id); + else + status = -ENOMEM; } else { status = -ENOMEM; } diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index e2d02c4..6e9441e 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -291,11 +291,11 @@ enum node_state node_get_state(void *hnode) * Allocate GPP resources to manage a node on the DSP. */ int node_allocate(struct proc_object *hprocessor, - const struct dsp_uuid *node_uuid, - const struct dsp_cbdata *pargs, - const struct dsp_nodeattrin *attr_in, - struct node_object **ph_node, - struct process_context *pr_ctxt) + const struct dsp_uuid *node_uuid, + const struct dsp_cbdata *pargs, + const struct dsp_nodeattrin *attr_in, + struct node_res_object **noderes, + struct process_context *pr_ctxt) { struct node_mgr *hnode_mgr; struct dev_object *hdev_obj; @@ -327,10 +327,10 @@ int node_allocate(struct proc_object *hprocessor, DBC_REQUIRE(refs > 0); DBC_REQUIRE(hprocessor != NULL); - DBC_REQUIRE(ph_node != NULL); + DBC_REQUIRE(noderes != NULL); DBC_REQUIRE(node_uuid != NULL); - *ph_node = NULL; + *noderes = NULL; status = proc_get_processor_id(hprocessor, &proc_id); @@ -653,9 +653,6 @@ func_cont: * (for overlay and dll) */ pnode->phase_split = true; - if (!status) - *ph_node = pnode; - /* Notify all clients registered for DSP_NODESTATECHANGE. */ proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE); } else { @@ -666,16 +663,21 @@ func_cont: } if (!status) { - drv_insert_node_res_element(*ph_node, &node_res, pr_ctxt); + status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt); + if (status) { + delete_node(pnode, pr_ctxt); + goto func_end; + } + + *noderes = (struct node_res_object *)node_res; drv_proc_node_update_heap_status(node_res, true); drv_proc_node_update_status(node_res, true); } - DBC_ENSURE((status && (*ph_node == NULL)) || - (!status && *ph_node)); + DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes)); func_end: - dev_dbg(bridge, "%s: hprocessor: %p node_uuid: %p pargs: %p attr_in:" - " %p ph_node: %p status: 0x%x\n", __func__, hprocessor, - node_uuid, pargs, attr_in, ph_node, status); + dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p " + "node_res: %p status: 0x%x\n", __func__, hprocessor, + node_uuid, pargs, attr_in, noderes, status); return status; } @@ -1433,10 +1435,10 @@ int node_create_mgr(struct node_mgr **node_man, * Loads the node's delete function if necessary. Free GPP side resources * after node's delete function returns. */ -int node_delete(struct node_object *hnode, +int node_delete(struct node_res_object *noderes, struct process_context *pr_ctxt) { - struct node_object *pnode = (struct node_object *)hnode; + struct node_object *pnode = noderes->hnode; struct node_mgr *hnode_mgr; struct proc_object *hprocessor; struct disp_object *disp_obj; @@ -1449,32 +1451,32 @@ int node_delete(struct node_object *hnode, u32 proc_id; struct bridge_drv_interface *intf_fxns; - void *node_res; + void *node_res = noderes; struct dsp_processorstate proc_state; DBC_REQUIRE(refs > 0); - if (!hnode) { + if (!pnode) { status = -EFAULT; goto func_end; } /* create struct dsp_cbdata struct for PWR call */ cb_data.cb_data = PWR_TIMEOUT; - hnode_mgr = hnode->hnode_mgr; - hprocessor = hnode->hprocessor; + hnode_mgr = pnode->hnode_mgr; + hprocessor = pnode->hprocessor; disp_obj = hnode_mgr->disp_obj; - node_type = node_get_type(hnode); + node_type = node_get_type(pnode); intf_fxns = hnode_mgr->intf_fxns; /* Enter critical section */ mutex_lock(&hnode_mgr->node_mgr_lock); - state = node_get_state(hnode); + state = node_get_state(pnode); /* Execute delete phase code for non-device node in all cases * except when the node was only allocated. Delete phase must be * executed even if create phase was executed, but failed. * If the node environment pointer is non-NULL, the delete phase * code must be executed. */ - if (!(state == NODE_ALLOCATED && hnode->node_env == (u32) NULL) && + if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) && node_type != NODE_DEVICE) { status = proc_get_processor_id(pnode->hprocessor, &proc_id); if (status) @@ -1487,26 +1489,26 @@ int node_delete(struct node_object *hnode, * is now ok to unload it. If the node is running, we * will unload the execute phase only after deleting * the node. */ - if (state == NODE_PAUSED && hnode->loaded && - hnode->phase_split) { + if (state == NODE_PAUSED && pnode->loaded && + pnode->phase_split) { /* Ok to unload execute code as long as node * is not * running */ status1 = hnode_mgr->nldr_fxns. - pfn_unload(hnode->nldr_node_obj, + pfn_unload(pnode->nldr_node_obj, NLDR_EXECUTE); - hnode->loaded = false; - NODE_SET_STATE(hnode, NODE_DONE); + pnode->loaded = false; + NODE_SET_STATE(pnode, NODE_DONE); } /* Load delete phase code if not loaded or if haven't * * unloaded EXECUTE phase */ - if ((!(hnode->loaded) || (state == NODE_RUNNING)) && - hnode->phase_split) { + if ((!(pnode->loaded) || (state == NODE_RUNNING)) && + pnode->phase_split) { status = hnode_mgr->nldr_fxns. - pfn_load(hnode->nldr_node_obj, NLDR_DELETE); + pfn_load(pnode->nldr_node_obj, NLDR_DELETE); if (!status) - hnode->loaded = true; + pnode->loaded = true; else pr_err("%s: fail - load delete code:" " 0x%x\n", __func__, status); @@ -1515,14 +1517,14 @@ int node_delete(struct node_object *hnode, func_cont1: if (!status) { /* Unblock a thread trying to terminate the node */ - (void)sync_set_event(hnode->sync_done); + (void)sync_set_event(pnode->sync_done); if (proc_id == DSP_UNIT) { /* ul_delete_fxn = address of node's delete * function */ - status = get_fxn_address(hnode, &ul_delete_fxn, + status = get_fxn_address(pnode, &ul_delete_fxn, DELETEPHASE); } else if (proc_id == IVA_UNIT) - ul_delete_fxn = (u32) hnode->node_env; + ul_delete_fxn = (u32) pnode->node_env; if (!status) { status = proc_get_state(hprocessor, &proc_state, @@ -1530,22 +1532,22 @@ func_cont1: dsp_processorstate)); if (proc_state.proc_state != PROC_ERROR) { status = - disp_node_delete(disp_obj, hnode, + disp_node_delete(disp_obj, pnode, hnode_mgr-> ul_fxn_addrs [RMSDELETENODE], ul_delete_fxn, - hnode->node_env); + pnode->node_env); } else - NODE_SET_STATE(hnode, NODE_DONE); + NODE_SET_STATE(pnode, NODE_DONE); /* Unload execute, if not unloaded, and delete * function */ if (state == NODE_RUNNING && - hnode->phase_split) { + pnode->phase_split) { status1 = hnode_mgr->nldr_fxns. - pfn_unload(hnode->nldr_node_obj, + pfn_unload(pnode->nldr_node_obj, NLDR_EXECUTE); } if (status1) @@ -1553,10 +1555,10 @@ func_cont1: " 0x%x\n", __func__, status1); status1 = - hnode_mgr->nldr_fxns.pfn_unload(hnode-> + hnode_mgr->nldr_fxns.pfn_unload(pnode-> nldr_node_obj, NLDR_DELETE); - hnode->loaded = false; + pnode->loaded = false; if (status1) pr_err("%s: fail - unload delete code: " "0x%x\n", __func__, status1); @@ -1565,25 +1567,28 @@ func_cont1: } /* Free host side resources even if a failure occurred */ /* Remove node from hnode_mgr->node_list */ - lst_remove_elem(hnode_mgr->node_list, (struct list_head *)hnode); + lst_remove_elem(hnode_mgr->node_list, (struct list_head *)pnode); hnode_mgr->num_nodes--; /* Decrement count of nodes created on DSP */ if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) && - (hnode->node_env != (u32) NULL))) + (pnode->node_env != (u32) NULL))) hnode_mgr->num_created--; /* Free host-side resources allocated by node_create() * delete_node() fails if SM buffers not freed by client! */ - if (drv_get_node_res_element(hnode, &node_res, pr_ctxt) != - -ENOENT) - drv_proc_node_update_status(node_res, false); - delete_node(hnode, pr_ctxt); + drv_proc_node_update_status(node_res, false); + delete_node(pnode, pr_ctxt); + + /* + * Release all Node resources and its context + */ + idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id); + kfree(node_res); - drv_remove_node_res_element(node_res, pr_ctxt); /* Exit critical section */ mutex_unlock(&hnode_mgr->node_mgr_lock); proc_notify_clients(hprocessor, DSP_NODESTATECHANGE); func_end: - dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status); + dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status); return status; }