diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2019-03-28 10:43:46 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-04-10 17:47:25 +0200 |
commit | 65e4f776385ac5cab021ad8d992e851375305906 (patch) | |
tree | 566a4e829338583e5b3109bf9670af4f5e472958 /drivers/s390/cio | |
parent | s390/qdio: pass up count of ready-to-process SBALs (diff) | |
download | linux-65e4f776385ac5cab021ad8d992e851375305906.tar.xz linux-65e4f776385ac5cab021ad8d992e851375305906.zip |
s390/qdio: simplify SBAL range calculation
When passing a range of ready-to-process SBALs to the upper-layer
driver, use the available 'count' instead of calculating the distance
between the first_to_check and first_to_kick cursors.
This simplifies the logic of the queue-scan path, and opens up the
possibility of scanning all 128 SBALs in one go (as determining the
reported count no longer requires wrap-around safe arithmetic on the
queue's cursors).
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 195f35256cc5..b6bc02efa0d0 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -636,17 +636,13 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q, return phys_aob; } -static void qdio_kick_handler(struct qdio_q *q) +static void qdio_kick_handler(struct qdio_q *q, unsigned int count) { int start = q->first_to_kick; - int end = q->first_to_check; - int count; if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) return; - count = sub_buf(end, start); - if (q->is_input_q) { qperf_inc(q, inbound_handler); DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); @@ -662,7 +658,7 @@ static void qdio_kick_handler(struct qdio_q *q) q->irq_ptr->int_parm); /* for the next time */ - q->first_to_kick = end; + q->first_to_kick = add_buf(start, count); q->qdio_error = 0; } @@ -685,7 +681,7 @@ static void __qdio_inbound_processing(struct qdio_q *q) if (count == 0) return; - qdio_kick_handler(q); + qdio_kick_handler(q, count); if (!qdio_inbound_q_done(q)) { /* means poll time is not yet over */ @@ -843,7 +839,7 @@ static void __qdio_outbound_processing(struct qdio_q *q) count = qdio_outbound_q_moved(q); if (count) - qdio_kick_handler(q); + qdio_kick_handler(q, count); if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) && !qdio_outbound_q_done(q)) @@ -911,7 +907,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) if (count == 0) return; - qdio_kick_handler(q); + qdio_kick_handler(q, count); if (!qdio_inbound_q_done(q)) { qperf_inc(q, tasklet_inbound_resched); @@ -1674,7 +1670,6 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, int *error) { struct qdio_q *q; - int start, end; struct qdio_irq *irq_ptr = cdev->private->qdio_data; int count; @@ -1699,15 +1694,14 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) return -EIO; - start = q->first_to_kick; - end = q->first_to_check; - *bufnr = start; + *bufnr = q->first_to_kick; *error = q->qdio_error; /* for the next time */ - q->first_to_kick = end; + q->first_to_kick = add_buf(q->first_to_kick, count); q->qdio_error = 0; - return sub_buf(end, start); + + return count; } EXPORT_SYMBOL(qdio_get_next_buffers); |