Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91d814ba authored by Deven Patel's avatar Deven Patel
Browse files

drivers: soc: put APR Tx buffer back into queue in error scenario



When underlying channel fails to send the APR buffer to the remote
end, APR should put the Tx buffer back into queue to avoid memory
leak.

CRs-fixed: 979283
Change-Id: I4f94daa3c9be748a30d532cf9cc8f3aa2284c060
Signed-off-by: default avatarDeven Patel <cdevenp@codeaurora.org>
parent 9492afea
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -92,6 +92,20 @@ static int apr_get_free_buf(int len, void **buf)
	return 0;
}

static void apr_buf_add_tail(void *buf)
{
	struct apr_tx_buf *list;
	unsigned long flags;

	if (!buf)
		return;

	spin_lock_irqsave(&buf_list.lock, flags);
	list = container_of(buf, struct apr_tx_buf, buf);
	list_add_tail(&list->list, &buf_list.list);
	spin_unlock_irqrestore(&buf_list.lock, flags);
}

static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
			   struct apr_pkt_priv *pkt_priv, int len)
{
@@ -137,8 +151,11 @@ int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
		rc = __apr_tal_write(apr_ch, pkt_data, pkt_priv, len);
	} while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES);

	if (rc == -EAGAIN)
		pr_err("%s: TIMEOUT for write\n", __func__);
	if (rc < 0) {
		pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc);
		if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER)
			apr_buf_add_tail(pkt_data);
	}
exit:
	return rc;
}
@@ -177,12 +194,8 @@ void apr_tal_notify_tx_done(void *handle, const void *priv,

	pr_debug("%s: tx_done received\n", __func__);

	if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) {
		spin_lock_irqsave(&buf_list.lock, flags);
		buf = container_of(ptr, struct apr_tx_buf, list);
		list_add_tail(&buf->list, &buf_list.list);
		spin_unlock_irqrestore(&buf_list.lock, flags);
	}
	if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER)
		apr_buf_add_tail(ptr);
}

bool apr_tal_notify_rx_intent_req(void *handle, const void *priv,