]> Git Repo - J-linux.git/commitdiff
s390/qdio: remove 'merge_pending' mechanism
authorJulian Wiedmann <[email protected]>
Sat, 30 Jan 2021 12:22:56 +0000 (13:22 +0100)
committerVasily Gorbik <[email protected]>
Sat, 13 Feb 2021 16:17:55 +0000 (17:17 +0100)
For non-QEBSM devices, get_buf_states() merges PENDING and EMPTY buffers
into a single group of finished buffers. To allow the upper-layer driver
to differentiate between the two states, qdio_check_pending() looks at
each buffer's state again and sets the sbal_state flag to
QDIO_OUTBUF_STATE_FLAG_PENDING accordingly.

So effectively we're spending overhead on _every_ Output Queue
inspection, just to avoid some additional TX completion calls in case
a group of buffers has completed with mixed EMPTY / PENDING state.
Given that PENDING buffers should rarely occur, this is a bad trade-off.
In particular so as the additional checks in get_buf_states() affect
_all_ device types (even those that don't use the PENDING state).

Rip it all out, and just report the PENDING completions separately as
we already do for QEBSM devices.

Signed-off-by: Julian Wiedmann <[email protected]>
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Vasily Gorbik <[email protected]>
arch/s390/include/asm/qdio.h
drivers/s390/cio/qdio_main.c
drivers/s390/net/qeth_core_main.c

index c85f75a3d452dbf37364ce22fbaa80e417aaa934..d9215c7106f0d56f29bdbbe98a14704fba97cb20 100644 (file)
@@ -250,17 +250,13 @@ struct slsb {
  * struct qdio_outbuf_state - SBAL related asynchronous operation information
  *   (for communication with upper layer programs)
  *   (only required for use with completion queues)
- * @flags: flags indicating state of buffer
  * @user: pointer to upper layer program's state information related to SBAL
  *        (stored in user1 data of QAOB)
  */
 struct qdio_outbuf_state {
-       u8 flags;
        void *user;
 };
 
-#define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
-
 #define CHSC_AC1_INITIATE_INPUTQ       0x80
 
 
index 0ad5a4c1bb0865139974dc3331d0fa5252e2ace3..03a0116199089d387a339d133535111aba049e3c 100644 (file)
@@ -202,7 +202,7 @@ again:
  */
 static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
                                 unsigned char *state, unsigned int count,
-                                int auto_ack, int merge_pending)
+                                int auto_ack)
 {
        unsigned char __state = 0;
        int i = 1;
@@ -217,18 +217,9 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
        if (__state & SLSB_OWNER_CU)
                goto out;
 
-       if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
-               __state = SLSB_P_OUTPUT_EMPTY;
-
        for (; i < count; i++) {
                bufnr = next_buf(bufnr);
 
-               /* merge PENDING into EMPTY: */
-               if (merge_pending &&
-                   q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING &&
-                   __state == SLSB_P_OUTPUT_EMPTY)
-                       continue;
-
                /* stop if next state differs from initial state: */
                if (q->slsb.val[bufnr] != __state)
                        break;
@@ -242,7 +233,7 @@ out:
 static inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
                                unsigned char *state, int auto_ack)
 {
-       return get_buf_states(q, bufnr, state, 1, auto_ack, 0);
+       return get_buf_states(q, bufnr, state, 1, auto_ack);
 }
 
 /* wrap-around safe setting of slsb states, returns number of changed buffers */
@@ -464,7 +455,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start,
         * No siga sync here, as a PCI or we after a thin interrupt
         * already sync'ed the queues.
         */
-       count = get_buf_states(q, start, &state, count, 1, 0);
+       count = get_buf_states(q, start, &state, count, 1);
        if (!count)
                return 0;
 
@@ -541,7 +532,6 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
                WARN_ON_ONCE(phys_aob & 0xFF);
        }
 
-       q->sbal_state[bufnr].flags = 0;
        return phys_aob;
 }
 
@@ -554,19 +544,6 @@ static inline int qdio_tasklet_schedule(struct qdio_q *q)
        return -EPERM;
 }
 
-static void qdio_check_pending(struct qdio_q *q, unsigned int index)
-{
-       unsigned char state;
-
-       if (get_buf_state(q, index, &state, 0) > 0 &&
-           state == SLSB_P_OUTPUT_PENDING &&
-           q->u.out.aobs[index]) {
-               q->u.out.sbal_state[index].flags |=
-                       QDIO_OUTBUF_STATE_FLAG_PENDING;
-               q->u.out.aobs[index] = NULL;
-       }
-}
-
 static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
                                        unsigned int *error)
 {
@@ -587,7 +564,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
        if (!count)
                return 0;
 
-       count = get_buf_states(q, start, &state, count, 0, q->u.out.use_cq);
+       count = get_buf_states(q, start, &state, count, 0);
        if (!count)
                return 0;
 
@@ -609,6 +586,9 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
                        account_sbals(q, count);
                return count;
        case SLSB_P_OUTPUT_ERROR:
+               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out error:%1d %02x",
+                             q->nr, count);
+
                *error = QDIO_ERROR_SLSB_STATE;
                process_buffer_error(q, start, count);
                atomic_sub(count, &q->nr_buf_used);
@@ -640,27 +620,6 @@ static inline int qdio_outbound_q_done(struct qdio_q *q)
        return atomic_read(&q->nr_buf_used) == 0;
 }
 
-static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start,
-                                       unsigned int *error)
-{
-       int count;
-
-       count = get_outbound_buffer_frontier(q, start, error);
-
-       if (count) {
-               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
-
-               if (q->u.out.use_cq && *error != QDIO_ERROR_SLSB_PENDING) {
-                       unsigned int i;
-
-                       for (i = 0; i < count; i++)
-                               qdio_check_pending(q, QDIO_BUFNR(start + i));
-               }
-       }
-
-       return count;
-}
-
 static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count,
                                unsigned long aob)
 {
@@ -715,7 +674,7 @@ void qdio_outbound_tasklet(struct tasklet_struct *t)
        qperf_inc(q, tasklet_outbound);
        WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0);
 
-       count = qdio_outbound_q_moved(q, start, &error);
+       count = get_outbound_buffer_frontier(q, start, &error);
        if (count) {
                q->first_to_check = add_buf(start, count);
 
@@ -1482,7 +1441,7 @@ static int __qdio_inspect_queue(struct qdio_q *q, unsigned int *bufnr,
 
        *error = 0;
        count = q->is_input_q ? get_inbound_buffer_frontier(q, start, error) :
-                               qdio_outbound_q_moved(q, start, error);
+                               get_outbound_buffer_frontier(q, start, error);
        if (count == 0)
                return 0;
 
index 13056cc2377bd4de599faa572f7a973da94589a7..068e2d9b1eb8d17066873d06959e14acac386e9d 100644 (file)
@@ -6076,9 +6076,7 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
        struct qeth_card *card = queue->card;
        bool error = !!qdio_error;
 
-       if ((qdio_error == QDIO_ERROR_SLSB_PENDING) ||
-           (queue->bufstates && (queue->bufstates[bidx].flags &
-                                 QDIO_OUTBUF_STATE_FLAG_PENDING))) {
+       if (qdio_error == QDIO_ERROR_SLSB_PENDING) {
                WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
 
                QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
This page took 0.068014 seconds and 4 git commands to generate.