Skip to content

Commit b16a37e

Browse files
Arun Kumar Neelakantamandersson
authored andcommitted
rpmsg: glink: Send READ_NOTIFY command in FIFO full case
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 <[email protected]> Signed-off-by: Arun Kumar Neelakantam <[email protected]> Signed-off-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 343ba27 commit b16a37e

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

drivers/rpmsg/qcom_glink_native.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ struct glink_core_rx_intent {
9292
* @rcids: idr of all channels with a known remote channel id
9393
* @features: remote features
9494
* @intentless: flag to indicate that there is no intent
95+
* @tx_avail_notify: Waitqueue for pending tx tasks
96+
* @sent_read_notify: flag to check cmd sent or not
9597
*/
9698
struct qcom_glink {
9799
struct device *dev;
@@ -118,6 +120,8 @@ struct qcom_glink {
118120
unsigned long features;
119121

120122
bool intentless;
123+
wait_queue_head_t tx_avail_notify;
124+
bool sent_read_notify;
121125
};
122126

123127
enum {
@@ -301,6 +305,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink,
301305
glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen);
302306
}
303307

308+
static void qcom_glink_send_read_notify(struct qcom_glink *glink)
309+
{
310+
struct glink_msg msg;
311+
312+
msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF);
313+
msg.param1 = 0;
314+
msg.param2 = 0;
315+
316+
qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0);
317+
318+
mbox_send_message(glink->mbox_chan, NULL);
319+
mbox_client_txdone(glink->mbox_chan, 0);
320+
}
321+
304322
static int qcom_glink_tx(struct qcom_glink *glink,
305323
const void *hdr, size_t hlen,
306324
const void *data, size_t dlen, bool wait)
@@ -321,12 +339,21 @@ static int qcom_glink_tx(struct qcom_glink *glink,
321339
goto out;
322340
}
323341

342+
if (!glink->sent_read_notify) {
343+
glink->sent_read_notify = true;
344+
qcom_glink_send_read_notify(glink);
345+
}
346+
324347
/* Wait without holding the tx_lock */
325348
spin_unlock_irqrestore(&glink->tx_lock, flags);
326349

327-
usleep_range(10000, 15000);
350+
wait_event_timeout(glink->tx_avail_notify,
351+
qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
328352

329353
spin_lock_irqsave(&glink->tx_lock, flags);
354+
355+
if (qcom_glink_tx_avail(glink) >= tlen)
356+
glink->sent_read_notify = false;
330357
}
331358

332359
qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
@@ -986,6 +1013,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
9861013
unsigned int cmd;
9871014
int ret = 0;
9881015

1016+
/* To wakeup any blocking writers */
1017+
wake_up_all(&glink->tx_avail_notify);
1018+
9891019
for (;;) {
9901020
avail = qcom_glink_rx_avail(glink);
9911021
if (avail < sizeof(msg))
@@ -1540,6 +1570,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
15401570
struct glink_channel *channel;
15411571
unsigned long flags;
15421572

1573+
/* To wakeup any blocking writers */
1574+
wake_up_all(&glink->tx_avail_notify);
1575+
15431576
spin_lock_irqsave(&glink->idr_lock, flags);
15441577
channel = idr_find(&glink->lcids, lcid);
15451578
if (WARN(!channel, "close ack on unknown channel\n")) {
@@ -1710,6 +1743,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
17101743
spin_lock_init(&glink->rx_lock);
17111744
INIT_LIST_HEAD(&glink->rx_queue);
17121745
INIT_WORK(&glink->rx_work, qcom_glink_work);
1746+
init_waitqueue_head(&glink->tx_avail_notify);
17131747

17141748
spin_lock_init(&glink->idr_lock);
17151749
idr_init(&glink->lcids);

0 commit comments

Comments
 (0)