aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2010-05-17 04:00:15 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-05-17 04:00:17 -0400
commitf3eb20fafdc10aea0fb13b113ac3b9a3dc9a5dc6 (patch)
tree1025617dba903e0276efbfcd8e439ed0d475580c /drivers/s390/cio/qdio_main.c
parent09a308f384c4ad2fb45959f5da9918e812207c50 (diff)
[S390] qdio: prevent starvation on PCI devices
If adapter interrupts are not available and traditional IO interrupts are used for qdio the inbound tasklet continued to run if new data arrived. That could possibly block other tasklets scheduled on the same CPU. If new data arrives schedule the tasklet again instead of directly processing the new data. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r--drivers/s390/cio/qdio_main.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 1fc81268330e..f4fd6cd4dc08 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -606,7 +606,7 @@ static void qdio_kick_handler(struct qdio_q *q)
606static void __qdio_inbound_processing(struct qdio_q *q) 606static void __qdio_inbound_processing(struct qdio_q *q)
607{ 607{
608 qperf_inc(q, tasklet_inbound); 608 qperf_inc(q, tasklet_inbound);
609again: 609
610 if (!qdio_inbound_q_moved(q)) 610 if (!qdio_inbound_q_moved(q))
611 return; 611 return;
612 612
@@ -615,7 +615,10 @@ again:
615 if (!qdio_inbound_q_done(q)) { 615 if (!qdio_inbound_q_done(q)) {
616 /* means poll time is not yet over */ 616 /* means poll time is not yet over */
617 qperf_inc(q, tasklet_inbound_resched); 617 qperf_inc(q, tasklet_inbound_resched);
618 goto again; 618 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) {
619 tasklet_schedule(&q->tasklet);
620 return;
621 }
619 } 622 }
620 623
621 qdio_stop_polling(q); 624 qdio_stop_polling(q);
@@ -625,7 +628,8 @@ again:
625 */ 628 */
626 if (!qdio_inbound_q_done(q)) { 629 if (!qdio_inbound_q_done(q)) {
627 qperf_inc(q, tasklet_inbound_resched2); 630 qperf_inc(q, tasklet_inbound_resched2);
628 goto again; 631 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
632 tasklet_schedule(&q->tasklet);
629 } 633 }
630} 634}
631 635