rpmsg: glink: Send READ_NOTIFY command in FIFO full case
[ Upstream commit b16a37e1846c9573a847a56fa2f31ba833dae45a ] The current design sleeps unconditionally in TX FIFO full case and wakeup only after sleep timer expires which adds random delays in clients TX path. Avoid sleep and use READ_NOTIFY command so that writer can be woken up when remote notifies about read completion by sending IRQ. Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org> Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> Link: https://lore.kernel.org/r/1596086296-28529-7-git-send-email-deesin@codeaurora.org Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
69b457abeb
commit
a8f4f1e226
1 changed files with 35 additions and 1 deletions
|
@ -92,6 +92,8 @@ struct glink_core_rx_intent {
|
|||
* @rcids: idr of all channels with a known remote channel id
|
||||
* @features: remote features
|
||||
* @intentless: flag to indicate that there is no intent
|
||||
* @tx_avail_notify: Waitqueue for pending tx tasks
|
||||
* @sent_read_notify: flag to check cmd sent or not
|
||||
*/
|
||||
struct qcom_glink {
|
||||
struct device *dev;
|
||||
|
@ -118,6 +120,8 @@ struct qcom_glink {
|
|||
unsigned long features;
|
||||
|
||||
bool intentless;
|
||||
wait_queue_head_t tx_avail_notify;
|
||||
bool sent_read_notify;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -305,6 +309,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink,
|
|||
glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen);
|
||||
}
|
||||
|
||||
static void qcom_glink_send_read_notify(struct qcom_glink *glink)
|
||||
{
|
||||
struct glink_msg msg;
|
||||
|
||||
msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF);
|
||||
msg.param1 = 0;
|
||||
msg.param2 = 0;
|
||||
|
||||
qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0);
|
||||
|
||||
mbox_send_message(glink->mbox_chan, NULL);
|
||||
mbox_client_txdone(glink->mbox_chan, 0);
|
||||
}
|
||||
|
||||
static int qcom_glink_tx(struct qcom_glink *glink,
|
||||
const void *hdr, size_t hlen,
|
||||
const void *data, size_t dlen, bool wait)
|
||||
|
@ -325,12 +343,21 @@ static int qcom_glink_tx(struct qcom_glink *glink,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!glink->sent_read_notify) {
|
||||
glink->sent_read_notify = true;
|
||||
qcom_glink_send_read_notify(glink);
|
||||
}
|
||||
|
||||
/* Wait without holding the tx_lock */
|
||||
spin_unlock_irqrestore(&glink->tx_lock, flags);
|
||||
|
||||
usleep_range(10000, 15000);
|
||||
wait_event_timeout(glink->tx_avail_notify,
|
||||
qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
|
||||
|
||||
spin_lock_irqsave(&glink->tx_lock, flags);
|
||||
|
||||
if (qcom_glink_tx_avail(glink) >= tlen)
|
||||
glink->sent_read_notify = false;
|
||||
}
|
||||
|
||||
qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
|
||||
|
@ -991,6 +1018,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
|
|||
unsigned int cmd;
|
||||
int ret = 0;
|
||||
|
||||
/* To wakeup any blocking writers */
|
||||
wake_up_all(&glink->tx_avail_notify);
|
||||
|
||||
for (;;) {
|
||||
avail = qcom_glink_rx_avail(glink);
|
||||
if (avail < sizeof(msg))
|
||||
|
@ -1530,6 +1560,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
|
|||
struct glink_channel *channel;
|
||||
unsigned long flags;
|
||||
|
||||
/* To wakeup any blocking writers */
|
||||
wake_up_all(&glink->tx_avail_notify);
|
||||
|
||||
spin_lock_irqsave(&glink->idr_lock, flags);
|
||||
channel = idr_find(&glink->lcids, lcid);
|
||||
if (WARN(!channel, "close ack on unknown channel\n")) {
|
||||
|
@ -1691,6 +1724,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
|
|||
spin_lock_init(&glink->rx_lock);
|
||||
INIT_LIST_HEAD(&glink->rx_queue);
|
||||
INIT_WORK(&glink->rx_work, qcom_glink_work);
|
||||
init_waitqueue_head(&glink->tx_avail_notify);
|
||||
|
||||
spin_lock_init(&glink->idr_lock);
|
||||
idr_init(&glink->lcids);
|
||||
|
|
Loading…
Add table
Reference in a new issue