Commit 0b6f4990 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Vasily Gorbik

s390/qdio: simplify ACK tracking

Current code uses a 'polling' flag to keep track of whether an Input
Queue has any ACKed SBALs. QEBSM devices might have multiple ACKed
SBALs, and those are tracked separately with 'ack_count'.

By also setting ack_count for non-QEBSM devices (to a fixed value of 1),
we can use 'ack_count != 0' as replacement for the polling flag.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent fcd98d40
...@@ -182,11 +182,9 @@ enum qdio_queue_irq_states { ...@@ -182,11 +182,9 @@ enum qdio_queue_irq_states {
}; };
struct qdio_input_q { struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
/* first ACK'ed buffer */ /* first ACK'ed buffer */
int ack_start; int ack_start;
/* how much sbals are acknowledged with qebsm */ /* how many SBALs are acknowledged */
int ack_count; int ack_count;
/* last time of noticing incoming data */ /* last time of noticing incoming data */
u64 timestamp; u64 timestamp;
......
...@@ -124,9 +124,8 @@ static int qstat_show(struct seq_file *m, void *v) ...@@ -124,9 +124,8 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "nr_used: %d ftc: %d\n", seq_printf(m, "nr_used: %d ftc: %d\n",
atomic_read(&q->nr_buf_used), q->first_to_check); atomic_read(&q->nr_buf_used), q->first_to_check);
if (q->is_input_q) { if (q->is_input_q) {
seq_printf(m, "polling: %d ack start: %d ack count: %d\n", seq_printf(m, "ack start: %d ack count: %d\n",
q->u.in.polling, q->u.in.ack_start, q->u.in.ack_start, q->u.in.ack_count);
q->u.in.ack_count);
seq_printf(m, "DSCI: %x IRQs disabled: %u\n", seq_printf(m, "DSCI: %x IRQs disabled: %u\n",
*(u8 *)q->irq_ptr->dsci, *(u8 *)q->irq_ptr->dsci,
test_bit(QDIO_QUEUE_IRQS_DISABLED, test_bit(QDIO_QUEUE_IRQS_DISABLED,
......
...@@ -393,19 +393,15 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, ...@@ -393,19 +393,15 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
static inline void qdio_stop_polling(struct qdio_q *q) static inline void qdio_stop_polling(struct qdio_q *q)
{ {
if (!q->u.in.polling) if (!q->u.in.ack_count)
return; return;
q->u.in.polling = 0;
qperf_inc(q, stop_polling); qperf_inc(q, stop_polling);
/* show the card that we are not polling anymore */ /* show the card that we are not polling anymore */
if (is_qebsm(q)) { set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT, q->u.in.ack_count);
q->u.in.ack_count); q->u.in.ack_count = 0;
q->u.in.ack_count = 0;
} else
set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
} }
static inline void account_sbals(struct qdio_q *q, unsigned int count) static inline void account_sbals(struct qdio_q *q, unsigned int count)
...@@ -451,8 +447,7 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start, ...@@ -451,8 +447,7 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start,
/* for QEBSM the ACK was already set by EQBS */ /* for QEBSM the ACK was already set by EQBS */
if (is_qebsm(q)) { if (is_qebsm(q)) {
if (!q->u.in.polling) { if (!q->u.in.ack_count) {
q->u.in.polling = 1;
q->u.in.ack_count = count; q->u.in.ack_count = count;
q->u.in.ack_start = start; q->u.in.ack_start = start;
return; return;
...@@ -471,12 +466,12 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start, ...@@ -471,12 +466,12 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start,
* or by the next inbound run. * or by the next inbound run.
*/ */
new = add_buf(start, count - 1); new = add_buf(start, count - 1);
if (q->u.in.polling) { if (q->u.in.ack_count) {
/* reset the previous ACK but first set the new one */ /* reset the previous ACK but first set the new one */
set_buf_state(q, new, SLSB_P_INPUT_ACK); set_buf_state(q, new, SLSB_P_INPUT_ACK);
set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
} else { } else {
q->u.in.polling = 1; q->u.in.ack_count = 1;
set_buf_state(q, new, SLSB_P_INPUT_ACK); set_buf_state(q, new, SLSB_P_INPUT_ACK);
} }
...@@ -1479,13 +1474,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags, ...@@ -1479,13 +1474,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
qperf_inc(q, inbound_call); qperf_inc(q, inbound_call);
if (!q->u.in.polling) if (!q->u.in.ack_count)
goto set; goto set;
/* protect against stop polling setting an ACK for an emptied slsb */ /* protect against stop polling setting an ACK for an emptied slsb */
if (count == QDIO_MAX_BUFFERS_PER_Q) { if (count == QDIO_MAX_BUFFERS_PER_Q) {
/* overwriting everything, just delete polling status */ /* overwriting everything, just delete polling status */
q->u.in.polling = 0;
q->u.in.ack_count = 0; q->u.in.ack_count = 0;
goto set; goto set;
} else if (buf_in_between(q->u.in.ack_start, bufnr, count)) { } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
...@@ -1495,15 +1489,14 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags, ...@@ -1495,15 +1489,14 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
diff = sub_buf(diff, q->u.in.ack_start); diff = sub_buf(diff, q->u.in.ack_start);
q->u.in.ack_count -= diff; q->u.in.ack_count -= diff;
if (q->u.in.ack_count <= 0) { if (q->u.in.ack_count <= 0) {
q->u.in.polling = 0;
q->u.in.ack_count = 0; q->u.in.ack_count = 0;
goto set; goto set;
} }
q->u.in.ack_start = add_buf(q->u.in.ack_start, diff); q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
} else {
/* the only ACK will be deleted */
q->u.in.ack_count = 0;
} }
else
/* the only ACK will be deleted, so stop polling */
q->u.in.polling = 0;
} }
set: set:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment