From 9c159bbc14ba196d590dc1a2fe7931ccfe73db98 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Fri, 20 Mar 2020 14:00:00 +0100 Subject: s390/qdio: clear DSCI early for polling drivers Polling drivers in a configuration with 1 Input Queue currently keep their DSCI armed all the way through the poll cycle, until qdio_start_irq() clears it. _Any_ intermittent QDIO interrupt delivered to tiqdio_thinint_handler() will thus cause 1) the 'adapter_int' statistic to be incremented, 2) a call to tiqdio_call_inq_handlers() for this device, and then 3) the 'int_discarded' statistics to be incremented. This causes overhead & complexity in the IRQ path, along with ambiguity in the statistics. On the other hand the device should be in IRQ avoidance mode during a poll cycle, so there won't be a lot of DSCI ping-pong that this micro-optimization could prevent. So align the DSCI handling with what we already do for devices with multiple Input Queues: clear it right away while processing the IRQ. For the non-polling path this means that we no longer need to handle the 1-queue case separately. Signed-off-by: Julian Wiedmann Reviewed-by: Benjamin Block Signed-off-by: Vasily Gorbik --- drivers/s390/cio/qdio.h | 1 - drivers/s390/cio/qdio_main.c | 2 -- drivers/s390/cio/qdio_thinint.c | 25 ++----------------------- 3 files changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index b0beafc43d37..b8453b594679 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -374,7 +374,6 @@ int tiqdio_allocate_memory(void); void tiqdio_free_memory(void); int tiqdio_register_thinints(void); void tiqdio_unregister_thinints(void); -void clear_nonshared_ind(struct qdio_irq *); int test_nonshared_ind(struct qdio_irq *); /* prototypes for setup */ diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 9d6e51bcd072..bcc3ab14e72d 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1643,8 +1643,6 @@ int qdio_start_irq(struct ccw_device *cdev) if (!irq_ptr) return -ENODEV; - clear_nonshared_ind(irq_ptr); - for_each_input_queue(irq_ptr, q, i) qdio_stop_polling(q); diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index c78c8dd18a89..ae50373617cd 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -82,32 +82,16 @@ void tiqdio_remove_device(struct qdio_irq *irq_ptr) INIT_LIST_HEAD(&irq_ptr->entry); } -static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr) -{ - return irq_ptr->nr_input_qs > 1; -} - static inline int references_shared_dsci(struct qdio_irq *irq_ptr) { return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; } -void clear_nonshared_ind(struct qdio_irq *irq_ptr) -{ - if (!is_thinint_irq(irq_ptr)) - return; - if (references_shared_dsci(irq_ptr) || - has_multiple_inq_on_dsci(irq_ptr)) - return; - xchg(irq_ptr->dsci, 0); -} - int test_nonshared_ind(struct qdio_irq *irq_ptr) { if (!is_thinint_irq(irq_ptr)) return 0; - if (references_shared_dsci(irq_ptr) || - has_multiple_inq_on_dsci(irq_ptr)) + if (references_shared_dsci(irq_ptr)) return 0; if (*irq_ptr->dsci) return 1; @@ -127,8 +111,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) struct qdio_q *q; int i; - if (!references_shared_dsci(irq) && - has_multiple_inq_on_dsci(irq)) + if (!references_shared_dsci(irq)) xchg(irq->dsci, 0); if (irq->irq_poll) { @@ -140,10 +123,6 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) return; } - if (!references_shared_dsci(irq) && - !has_multiple_inq_on_dsci(irq)) - xchg(irq->dsci, 0); - for_each_input_queue(irq, q, i) { /* * Call inbound processing but not directly -- cgit v1.2.3