rpmsg: glink: Use threaded interrupts

On newer chipsets there is an increase in traffic generated from the
remote for new usecases, this is resulting in the glink interrupt
handler running for an extended amount of time. In combination with the
IPCC architecture, this can starve out other users of IPCC including
other GLINKs.

Change the interrupt to a threaded interrupt to prevent the glink ISR
from starving the CPU with interrupts disabled. In order to make sure
performance for latency sensitive clients is preserved, handle up to
10 packets in hard irq context. Defer the remaining work to the
threaded interrupt if required.

Change-Id: I2f1b085c38c02d231f9a3da2fcce32b129be2012
Signed-off-by: Chris Lew <clew@codeaurora.org>
This commit is contained in:
Chris Lew 2021-08-13 12:19:16 -07:00 committed by Chris Lew
parent 4837e4e0f4
commit 7daf95ce98

View File

@ -1112,15 +1112,15 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
return 0;
}
static irqreturn_t qcom_glink_native_intr(int irq, void *data)
static int qcom_glink_native_rx(struct qcom_glink *glink, int iterations)
{
struct qcom_glink *glink = data;
struct glink_msg msg;
unsigned int param1;
unsigned int param2;
unsigned int avail;
unsigned int cmd;
int ret = 0;
int i;
if (should_wake) {
pr_info("%s: wakeup %s\n", __func__, glink->irqname);
@ -1131,7 +1131,7 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
/* To wakeup any blocking writers */
wake_up_all(&glink->tx_avail_notify);
for (;;) {
for (i = 0; i < iterations || !iterations; i++) {
avail = qcom_glink_rx_avail(glink);
if (avail < sizeof(msg))
break;
@ -1192,6 +1192,25 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
break;
}
return qcom_glink_rx_avail(glink);
}
static irqreturn_t qcom_glink_native_intr(int irq, void *data)
{
struct qcom_glink *glink = data;
int ret;
ret = qcom_glink_native_rx(glink, 10);
return (ret) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
}
static irqreturn_t qcom_glink_native_thread_intr(int irq, void *data)
{
struct qcom_glink *glink = data;
qcom_glink_native_rx(glink, 0);
return IRQ_HANDLED;
}
@ -1966,10 +1985,11 @@ int qcom_glink_native_start(struct qcom_glink *glink)
int ret;
irq = of_irq_get(dev->of_node, 0);
ret = devm_request_irq(dev, irq,
qcom_glink_native_intr,
IRQF_NO_SUSPEND | IRQF_SHARED,
glink->irqname, glink);
ret = devm_request_threaded_irq(dev, irq,
qcom_glink_native_intr,
qcom_glink_native_thread_intr,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
glink->irqname, glink);
if (ret) {
dev_err(dev, "failed to request IRQ\n");
return ret;