mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
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:
parent
4837e4e0f4
commit
7daf95ce98
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user