[S390] qdio: prevent starvation on PCI devices
[pandora-kernel.git] / drivers / s390 / cio / qdio_main.c
index 4f8f743..f4fd6cd 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/debug.h>
 #include <asm/qdio.h>
@@ -605,7 +606,7 @@ static void qdio_kick_handler(struct qdio_q *q)
 static void __qdio_inbound_processing(struct qdio_q *q)
 {
        qperf_inc(q, tasklet_inbound);
-again:
+
        if (!qdio_inbound_q_moved(q))
                return;
 
@@ -614,7 +615,10 @@ again:
        if (!qdio_inbound_q_done(q)) {
                /* means poll time is not yet over */
                qperf_inc(q, tasklet_inbound_resched);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) {
+                       tasklet_schedule(&q->tasklet);
+                       return;
+               }
        }
 
        qdio_stop_polling(q);
@@ -624,7 +628,8 @@ again:
         */
        if (!qdio_inbound_q_done(q)) {
                qperf_inc(q, tasklet_inbound_resched2);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+                       tasklet_schedule(&q->tasklet);
        }
 }
 
@@ -954,6 +959,9 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
                return;
        }
 
+       if (irq_ptr->perf_stat_enabled)
+               irq_ptr->perf_stat.qdio_int++;
+
        if (IS_ERR(irb)) {
                switch (PTR_ERR(irb)) {
                case -EIO: