mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-07 06:52:07 +00:00
s390/qdio: add IRQ reduction for error SBALs
SBALs in PRIMED or ERROR state represent new work on the Input Queue. But while inbound_primed() does all sorts of ACK management for new PRIMED work, the same handling is currently missing for ERROR work. In particular the path for ERROR work doesn't clear up _old_ ACKs. Treat ERROR work the same as PRIMED work, but consider that the QEBSM auto-ACK feature doesn't apply here. So we need to set the ACK manually, as if it was a non-QEBSM device. Note that this doesn't aspire to actually improve performance, the main goal is to just unify the code paths and have consistent behaviour. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
1db85d0e73
commit
c70d82e966
1 changed files with 11 additions and 12 deletions
|
@ -438,15 +438,12 @@ static void process_buffer_error(struct qdio_q *q, unsigned int start,
|
||||||
q->sbal[start]->element[15].sflags);
|
q->sbal[start]->element[15].sflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void inbound_primed(struct qdio_q *q, unsigned int start,
|
static inline void inbound_handle_work(struct qdio_q *q, unsigned int start,
|
||||||
int count)
|
int count, bool auto_ack)
|
||||||
{
|
{
|
||||||
int new;
|
int new;
|
||||||
|
|
||||||
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr, count);
|
if (auto_ack) {
|
||||||
|
|
||||||
/* for QEBSM the ACK was already set by EQBS */
|
|
||||||
if (is_qebsm(q)) {
|
|
||||||
if (!q->u.in.ack_count) {
|
if (!q->u.in.ack_count) {
|
||||||
q->u.in.ack_count = count;
|
q->u.in.ack_count = count;
|
||||||
q->u.in.ack_start = start;
|
q->u.in.ack_start = start;
|
||||||
|
@ -507,19 +504,21 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SLSB_P_INPUT_PRIMED:
|
case SLSB_P_INPUT_PRIMED:
|
||||||
inbound_primed(q, start, count);
|
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr,
|
||||||
|
count);
|
||||||
|
|
||||||
|
inbound_handle_work(q, start, count, is_qebsm(q));
|
||||||
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
|
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
|
||||||
qperf_inc(q, inbound_queue_full);
|
qperf_inc(q, inbound_queue_full);
|
||||||
if (q->irq_ptr->perf_stat_enabled)
|
if (q->irq_ptr->perf_stat_enabled)
|
||||||
account_sbals(q, count);
|
account_sbals(q, count);
|
||||||
return count;
|
return count;
|
||||||
case SLSB_P_INPUT_ERROR:
|
case SLSB_P_INPUT_ERROR:
|
||||||
|
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in err:%1d %02x", q->nr,
|
||||||
|
count);
|
||||||
|
|
||||||
process_buffer_error(q, start, count);
|
process_buffer_error(q, start, count);
|
||||||
/*
|
inbound_handle_work(q, start, count, false);
|
||||||
* Interrupts may be avoided as long as the error is present
|
|
||||||
* so change the buffer state immediately to avoid starvation.
|
|
||||||
*/
|
|
||||||
set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
|
|
||||||
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
|
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
|
||||||
qperf_inc(q, inbound_queue_full);
|
qperf_inc(q, inbound_queue_full);
|
||||||
if (q->irq_ptr->perf_stat_enabled)
|
if (q->irq_ptr->perf_stat_enabled)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue