Skip to content

Commit

Permalink
s390/qdio: fine-tune the queue sync
Browse files Browse the repository at this point in the history
Push the sync check from qdio_inspect_queue() down into the two
get_*_buffer_frontier() code paths, where we actually need the sync to
look at the current queue state. This lets us avoid the check when we
know that there is no work on the queue (ie. when q->nr_buf_used is 0).

While at it introduce the qdio_sync_*_queue() helpers, so that we can
avoid the branch on q->is_input_q when we already know the queue type.

Signed-off-by: Julian Wiedmann <[email protected]>
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Vasily Gorbik <[email protected]>
  • Loading branch information
julianwiedmann authored and Vasily Gorbik committed Aug 18, 2021
1 parent 10376b5 commit 87e225b
Showing 1 changed file with 20 additions and 11 deletions.
31 changes: 20 additions & 11 deletions drivers/s390/cio/qdio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,22 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
return (cc) ? -EIO : 0;
}

static inline int qdio_sync_input_queue(struct qdio_q *q)
{
return qdio_siga_sync(q, 0, q->mask);
}

static inline int qdio_sync_output_queue(struct qdio_q *q)
{
return qdio_siga_sync(q, q->mask, 0);
}

static inline int qdio_siga_sync_q(struct qdio_q *q)
{
if (q->is_input_q)
return qdio_siga_sync(q, 0, q->mask);
return qdio_sync_input_queue(q);
else
return qdio_siga_sync(q, q->mask, 0);
return qdio_sync_output_queue(q);
}

static int qdio_siga_output(struct qdio_q *q, unsigned int count,
Expand Down Expand Up @@ -442,10 +452,9 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start,
if (!count)
return 0;

/*
* No siga sync here, as a PCI or we after a thin interrupt
* already sync'ed the queues.
*/
if (qdio_need_siga_sync(q->irq_ptr))
qdio_sync_input_queue(q);

count = get_buf_states(q, start, &state, count, 1);
if (!count)
return 0;
Expand Down Expand Up @@ -498,7 +507,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q, unsigned int start)
return 1;

if (qdio_need_siga_sync(q->irq_ptr))
qdio_siga_sync_q(q);
qdio_sync_input_queue(q);
get_buf_state(q, start, &state, 0);

if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
Expand All @@ -520,6 +529,9 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
if (!count)
return 0;

if (qdio_need_siga_sync(q->irq_ptr))
qdio_sync_output_queue(q);

count = get_buf_states(q, start, &state, count, 0);
if (!count)
return 0;
Expand Down Expand Up @@ -1160,7 +1172,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int bufnr, unsigned int co
WARN_ON_ONCE(!IS_ALIGNED(phys_aob, 256));
rc = qdio_kick_outbound_q(q, count, phys_aob);
} else if (qdio_need_siga_sync(q->irq_ptr)) {
rc = qdio_siga_sync_q(q);
rc = qdio_sync_output_queue(q);
} else if (count < QDIO_MAX_BUFFERS_PER_Q &&
get_buf_state(q, prev_buf(bufnr), &state, 0) > 0 &&
state == SLSB_CU_OUTPUT_PRIMED) {
Expand Down Expand Up @@ -1283,9 +1295,6 @@ int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr, bool is_input,
return -ENODEV;
q = is_input ? irq_ptr->input_qs[nr] : irq_ptr->output_qs[nr];

if (qdio_need_siga_sync(irq_ptr))
qdio_siga_sync_q(q);

return __qdio_inspect_queue(q, bufnr, error);
}
EXPORT_SYMBOL_GPL(qdio_inspect_queue);
Expand Down

0 comments on commit 87e225b

Please sign in to comment.