summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhoat Harpal <hdhoat@codeaurora.org>2016-12-20 18:22:57 +0530
committerDhoat Harpal <hdhoat@codeaurora.org>2016-12-21 16:51:47 +0530
commit9d8ae4e6989715c720605c1c7a61831f568feb73 (patch)
tree504ef28cdd990a567f96d6001d4023db6245a35a
parent3162449f7d245d45f007d4ea3224576ddf1bcc63 (diff)
soc: qcom: glink_ssr: Add rx done for received packets
Glink ssr client does not send rx done even in success cases. This leads to memory leak in transport layer. Added worker for sending rx_done in deferred context. CRs-Fixed: 1100789 Change-Id: I84a936f834101ba2ad9e354c4d8df6d3c051a2f7 Signed-off-by: Dhoat Harpal <hdhoat@codeaurora.org>
-rw-r--r--drivers/soc/qcom/glink_ssr.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c
index a14d912b7536..4d94e6446505 100644
--- a/drivers/soc/qcom/glink_ssr.c
+++ b/drivers/soc/qcom/glink_ssr.c
@@ -80,6 +80,19 @@ struct configure_and_open_ch_work {
};
/**
+ * struct rx_done_ch_work - Work structure used for sending rx_done on
+ * glink_ssr channels
+ * handle: G-Link channel handle to be used for sending rx_done
+ * ptr: Intent pointer data provided in notify rx function
+ * work: Work structure
+ */
+struct rx_done_ch_work {
+ void *handle;
+ const void *ptr;
+ struct work_struct work;
+};
+
+/**
* struct close_ch_work - Work structure for used for closing glink_ssr channels
* edge: The G-Link edge name for the channel being closed
* handle: G-Link channel handle to be closed
@@ -102,6 +115,15 @@ static LIST_HEAD(subsystem_list);
static atomic_t responses_remaining = ATOMIC_INIT(0);
static wait_queue_head_t waitqueue;
+static void rx_done_cb_worker(struct work_struct *work)
+{
+ struct rx_done_ch_work *rx_done_work =
+ container_of(work, struct rx_done_ch_work, work);
+
+ glink_rx_done(rx_done_work->handle, rx_done_work->ptr, false);
+ kfree(rx_done_work);
+}
+
static void link_state_cb_worker(struct work_struct *work)
{
unsigned long flags;
@@ -196,7 +218,14 @@ void glink_ssr_notify_rx(void *handle, const void *priv, const void *pkt_priv,
{
struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv;
struct cleanup_done_msg *resp = (struct cleanup_done_msg *)ptr;
+ struct rx_done_ch_work *rx_done_work;
+ rx_done_work = kmalloc(sizeof(*rx_done_work), GFP_ATOMIC);
+ if (!rx_done_work) {
+ GLINK_SSR_ERR("<SSR> %s: Could not allocate rx_done_work\n",
+ __func__);
+ return;
+ }
if (unlikely(!cb_data))
goto missing_cb_data;
if (unlikely(!cb_data->do_cleanup_data))
@@ -221,6 +250,10 @@ void glink_ssr_notify_rx(void *handle, const void *priv, const void *pkt_priv,
kfree(cb_data->do_cleanup_data);
cb_data->do_cleanup_data = NULL;
+ rx_done_work->ptr = ptr;
+ rx_done_work->handle = handle;
+ INIT_WORK(&rx_done_work->work, rx_done_cb_worker);
+ queue_work(glink_ssr_wq, &rx_done_work->work);
wake_up(&waitqueue);
return;