diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index c1a70985abfa..af867731a5f4 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -16,6 +16,14 @@ #define QDIO_BUSY_BIT_GIVE_UP 2000000 /* 2 seconds = eternity */ #define QDIO_INPUT_THRESHOLD 500 /* 500 microseconds */ +/* + * if an asynchronous HiperSockets queue runs full, the 10 seconds timer wait + * till next initiative to give transmitted skbs back to the stack is too long. + * Therefore polling is started in case of multicast queue is filled more + * than 50 percent. + */ +#define QDIO_IQDIO_POLL_LVL 65 /* HS multicast queue */ + enum qdio_irq_states { QDIO_IRQ_STATE_INACTIVE, QDIO_IRQ_STATE_ESTABLISHED, diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index e6eabc853422..9307512132fe 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -851,6 +851,12 @@ static void __qdio_outbound_processing(struct qdio_q *q) if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) return; + if ((queue_type(q) == QDIO_IQDIO_QFMT) && + (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) { + tasklet_schedule(&q->tasklet); + return; + } + if (q->u.out.pci_out_enabled) return;