mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 10:44:23 +08:00
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 <jwi@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
a8a4ee2740
commit
9c159bbc14
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user