s390/qdio: simplify ACK tracking
authorJulian Wiedmann <jwi@linux.ibm.com>
Mon, 25 Nov 2019 13:18:29 +0000 (14:18 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 10 Feb 2020 11:49:35 +0000 (12:49 +0100)
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: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c

index 4b07984..ff74eb5 100644 (file)
@@ -182,11 +182,9 @@ enum qdio_queue_irq_states {
 };
 
 struct qdio_input_q {
-       /* input buffer acknowledgement flag */
-       int polling;
        /* first ACK'ed buffer */
        int ack_start;
-       /* how much sbals are acknowledged with qebsm */
+       /* how many SBALs are acknowledged */
        int ack_count;
        /* last time of noticing incoming data */
        u64 timestamp;
index 35410e6..9c0370b 100644 (file)
@@ -124,9 +124,8 @@ static int qstat_show(struct seq_file *m, void *v)
        seq_printf(m, "nr_used: %d  ftc: %d\n",
                   atomic_read(&q->nr_buf_used), q->first_to_check);
        if (q->is_input_q) {
-               seq_printf(m, "polling: %d  ack start: %d  ack count: %d\n",
-                          q->u.in.polling, q->u.in.ack_start,
-                          q->u.in.ack_count);
+               seq_printf(m, "ack start: %d  ack count: %d\n",
+                          q->u.in.ack_start, q->u.in.ack_count);
                seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
                           *(u8 *)q->irq_ptr->dsci,
                           test_bit(QDIO_QUEUE_IRQS_DISABLED,
index f8b897b..3475317 100644 (file)
@@ -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)
 {
-       if (!q->u.in.polling)
+       if (!q->u.in.ack_count)
                return;
 
-       q->u.in.polling = 0;
        qperf_inc(q, stop_polling);
 
        /* 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,
-                              q->u.in.ack_count);
-               q->u.in.ack_count = 0;
-       } else
-               set_buf_state(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 = 0;
 }
 
 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,
 
        /* for QEBSM the ACK was already set by EQBS */
        if (is_qebsm(q)) {
-               if (!q->u.in.polling) {
-                       q->u.in.polling = 1;
+               if (!q->u.in.ack_count) {
                        q->u.in.ack_count = count;
                        q->u.in.ack_start = start;
                        return;
@@ -471,12 +466,12 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start,
         * or by the next inbound run.
         */
        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 */
                set_buf_state(q, new, SLSB_P_INPUT_ACK);
                set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
        } else {
-               q->u.in.polling = 1;
+               q->u.in.ack_count = 1;
                set_buf_state(q, new, SLSB_P_INPUT_ACK);
        }
 
@@ -1479,13 +1474,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
 
        qperf_inc(q, inbound_call);
 
-       if (!q->u.in.polling)
+       if (!q->u.in.ack_count)
                goto set;
 
        /* protect against stop polling setting an ACK for an emptied slsb */
        if (count == QDIO_MAX_BUFFERS_PER_Q) {
                /* overwriting everything, just delete polling status */
-               q->u.in.polling = 0;
                q->u.in.ack_count = 0;
                goto set;
        } 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,
                        diff = sub_buf(diff, q->u.in.ack_start);
                        q->u.in.ack_count -= diff;
                        if (q->u.in.ack_count <= 0) {
-                               q->u.in.polling = 0;
                                q->u.in.ack_count = 0;
                                goto set;
                        }
                        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: