Skip to content

Commit 207d0bf

Browse files
committed
Merge branch 's390-qeth-fixes-2020-11-20'
Julian Wiedmann says: ==================== s390/qeth: fixes 2020-11-20 This brings several fixes for qeth's af_iucv-specific code paths. Also one fix by Alexandra for the recently added BR_LEARNING_SYNC support. We want to trust the feature indication bit, so that HW can mask it out if there's any issues on their end. ==================== Link: https://lore.kernel.org/r/20201120090939.101406-1-jwi@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents e10823c + 7ed10e1 commit 207d0bf

File tree

3 files changed

+62
-47
lines changed

3 files changed

+62
-47
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,13 @@ enum qeth_qdio_out_buffer_state {
417417
QETH_QDIO_BUF_EMPTY,
418418
/* Filled by driver; owned by hardware in order to be sent. */
419419
QETH_QDIO_BUF_PRIMED,
420-
/* Identified to be pending in TPQ. */
420+
/* Discovered by the TX completion code: */
421421
QETH_QDIO_BUF_PENDING,
422-
/* Found in completion queue. */
423-
QETH_QDIO_BUF_IN_CQ,
422+
/* Finished by the TX completion code: */
423+
QETH_QDIO_BUF_NEED_QAOB,
424+
/* Received QAOB notification on CQ: */
425+
QETH_QDIO_BUF_QAOB_OK,
426+
QETH_QDIO_BUF_QAOB_ERROR,
424427
/* Handled via transfer pending / completion queue. */
425428
QETH_QDIO_BUF_HANDLED_DELAYED,
426429
};

drivers/s390/net/qeth_core_main.c

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include <net/iucv/af_iucv.h>
3535
#include <net/dsfield.h>
36+
#include <net/sock.h>
3637

3738
#include <asm/ebcdic.h>
3839
#include <asm/chpid.h>
@@ -499,17 +500,12 @@ static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx,
499500

500501
}
501502
}
502-
if (forced_cleanup && (atomic_read(&(q->bufs[bidx]->state)) ==
503-
QETH_QDIO_BUF_HANDLED_DELAYED)) {
504-
/* for recovery situations */
505-
qeth_init_qdio_out_buf(q, bidx);
506-
QETH_CARD_TEXT(q->card, 2, "clprecov");
507-
}
508503
}
509504

510505
static void qeth_qdio_handle_aob(struct qeth_card *card,
511506
unsigned long phys_aob_addr)
512507
{
508+
enum qeth_qdio_out_buffer_state new_state = QETH_QDIO_BUF_QAOB_OK;
513509
struct qaob *aob;
514510
struct qeth_qdio_out_buffer *buffer;
515511
enum iucv_tx_notify notification;
@@ -521,22 +517,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
521517
buffer = (struct qeth_qdio_out_buffer *) aob->user1;
522518
QETH_CARD_TEXT_(card, 5, "%lx", aob->user1);
523519

524-
if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED,
525-
QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) {
526-
notification = TX_NOTIFY_OK;
527-
} else {
528-
WARN_ON_ONCE(atomic_read(&buffer->state) !=
529-
QETH_QDIO_BUF_PENDING);
530-
atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ);
531-
notification = TX_NOTIFY_DELAYED_OK;
532-
}
533-
534-
if (aob->aorc != 0) {
535-
QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc);
536-
notification = qeth_compute_cq_notification(aob->aorc, 1);
537-
}
538-
qeth_notify_skbs(buffer->q, buffer, notification);
539-
540520
/* Free dangling allocations. The attached skbs are handled by
541521
* qeth_cleanup_handled_pending().
542522
*/
@@ -548,7 +528,33 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
548528
if (data && buffer->is_header[i])
549529
kmem_cache_free(qeth_core_header_cache, data);
550530
}
551-
atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
531+
532+
if (aob->aorc) {
533+
QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc);
534+
new_state = QETH_QDIO_BUF_QAOB_ERROR;
535+
}
536+
537+
switch (atomic_xchg(&buffer->state, new_state)) {
538+
case QETH_QDIO_BUF_PRIMED:
539+
/* Faster than TX completion code. */
540+
notification = qeth_compute_cq_notification(aob->aorc, 0);
541+
qeth_notify_skbs(buffer->q, buffer, notification);
542+
atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
543+
break;
544+
case QETH_QDIO_BUF_PENDING:
545+
/* TX completion code is active and will handle the async
546+
* completion for us.
547+
*/
548+
break;
549+
case QETH_QDIO_BUF_NEED_QAOB:
550+
/* TX completion code is already finished. */
551+
notification = qeth_compute_cq_notification(aob->aorc, 1);
552+
qeth_notify_skbs(buffer->q, buffer, notification);
553+
atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
554+
break;
555+
default:
556+
WARN_ON_ONCE(1);
557+
}
552558

553559
qdio_release_aob(aob);
554560
}
@@ -1405,7 +1411,7 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *q,
14051411
skb_queue_walk(&buf->skb_list, skb) {
14061412
QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification);
14071413
QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb);
1408-
if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk)
1414+
if (skb->sk && skb->sk->sk_family == PF_IUCV)
14091415
iucv_sk(skb->sk)->sk_txnotify(skb, notification);
14101416
}
14111417
}
@@ -1416,9 +1422,6 @@ static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error,
14161422
struct qeth_qdio_out_q *queue = buf->q;
14171423
struct sk_buff *skb;
14181424

1419-
/* release may never happen from within CQ tasklet scope */
1420-
WARN_ON_ONCE(atomic_read(&buf->state) == QETH_QDIO_BUF_IN_CQ);
1421-
14221425
if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING)
14231426
qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR);
14241427

@@ -5869,9 +5872,32 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
58695872

58705873
if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED,
58715874
QETH_QDIO_BUF_PENDING) ==
5872-
QETH_QDIO_BUF_PRIMED)
5875+
QETH_QDIO_BUF_PRIMED) {
58735876
qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING);
58745877

5878+
/* Handle race with qeth_qdio_handle_aob(): */
5879+
switch (atomic_xchg(&buffer->state,
5880+
QETH_QDIO_BUF_NEED_QAOB)) {
5881+
case QETH_QDIO_BUF_PENDING:
5882+
/* No concurrent QAOB notification. */
5883+
break;
5884+
case QETH_QDIO_BUF_QAOB_OK:
5885+
qeth_notify_skbs(queue, buffer,
5886+
TX_NOTIFY_DELAYED_OK);
5887+
atomic_set(&buffer->state,
5888+
QETH_QDIO_BUF_HANDLED_DELAYED);
5889+
break;
5890+
case QETH_QDIO_BUF_QAOB_ERROR:
5891+
qeth_notify_skbs(queue, buffer,
5892+
TX_NOTIFY_DELAYED_GENERALERROR);
5893+
atomic_set(&buffer->state,
5894+
QETH_QDIO_BUF_HANDLED_DELAYED);
5895+
break;
5896+
default:
5897+
WARN_ON_ONCE(1);
5898+
}
5899+
}
5900+
58755901
QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
58765902

58775903
/* prepare the queue slot for re-use: */

drivers/s390/net/qeth_l2_main.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -985,32 +985,19 @@ static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
985985
* change notification' and thus can support the learning_sync bridgeport
986986
* attribute
987987
* @card: qeth_card structure pointer
988-
*
989-
* This is a destructive test and must be called before dev2br or
990-
* bridgeport address notification is enabled!
991988
*/
992989
static void qeth_l2_detect_dev2br_support(struct qeth_card *card)
993990
{
994991
struct qeth_priv *priv = netdev_priv(card->dev);
995992
bool dev2br_supported;
996-
int rc;
997993

998994
QETH_CARD_TEXT(card, 2, "d2brsup");
999995
if (!IS_IQD(card))
1000996
return;
1001997

1002998
/* dev2br requires valid cssid,iid,chid */
1003-
if (!card->info.ids_valid) {
1004-
dev2br_supported = false;
1005-
} else if (css_general_characteristics.enarf) {
1006-
dev2br_supported = true;
1007-
} else {
1008-
/* Old machines don't have the feature bit:
1009-
* Probe by testing whether a disable succeeds
1010-
*/
1011-
rc = qeth_l2_pnso(card, PNSO_OC_NET_ADDR_INFO, 0, NULL, NULL);
1012-
dev2br_supported = !rc;
1013-
}
999+
dev2br_supported = card->info.ids_valid &&
1000+
css_general_characteristics.enarf;
10141001
QETH_CARD_TEXT_(card, 2, "D2Bsup%02x", dev2br_supported);
10151002

10161003
if (dev2br_supported)
@@ -2233,7 +2220,6 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok)
22332220
struct net_device *dev = card->dev;
22342221
int rc = 0;
22352222

2236-
/* query before bridgeport_notification may be enabled */
22372223
qeth_l2_detect_dev2br_support(card);
22382224

22392225
mutex_lock(&card->sbp_lock);

0 commit comments

Comments
 (0)