From f2bcf9dd3ecf7c9340025fc0736416e1203b5e35 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 23 Sep 2020 10:36:59 +0200 Subject: [PATCH] s390/qeth: consolidate teardown code Clarify which discipline-specific steps are needed to roll back after error in qeth_l?_set_online(), and which are common to roll back from qeth_hardsetup_card(). Some steps (cancelling the RX modeset, draining the TX queues) are only necessary if the netdev was potentially UP before, so move them to the common qeth_set_offline(). Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 4 ---- drivers/s390/net/qeth_core_main.c | 24 ++++++++++++------- drivers/s390/net/qeth_l2_main.c | 50 ++++++++++++++------------------------- drivers/s390/net/qeth_l3_main.c | 46 +++++++++++++---------------------- 4 files changed, 50 insertions(+), 74 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 242558bdb5ac..f321eabefbe4 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -1062,11 +1062,7 @@ void qeth_notify_cmd(struct qeth_cmd_buffer *iob, int reason); void qeth_put_cmd(struct qeth_cmd_buffer *iob); int qeth_schedule_recovery(struct qeth_card *card); -void qeth_flush_local_addrs(struct qeth_card *card); int qeth_poll(struct napi_struct *napi, int budget); -int qeth_qdio_clear_card(struct qeth_card *, int); -void qeth_clear_working_pool_list(struct qeth_card *); -void qeth_drain_output_queues(struct qeth_card *card); void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable); int qeth_setadpparms_change_macaddr(struct qeth_card *); void qeth_tx_timeout(struct net_device *, unsigned int txqueue); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 5a132241b4dd..fc2c3db9259f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -201,7 +201,7 @@ int qeth_threads_running(struct qeth_card *card, unsigned long threads) } EXPORT_SYMBOL_GPL(qeth_threads_running); -void qeth_clear_working_pool_list(struct qeth_card *card) +static void qeth_clear_working_pool_list(struct qeth_card *card) { struct qeth_buffer_pool_entry *pool_entry, *tmp; struct qeth_qdio_q *queue = card->qdio.in_q; @@ -216,7 +216,6 @@ void qeth_clear_working_pool_list(struct qeth_card *card) for (i = 0; i < ARRAY_SIZE(queue->bufs); i++) queue->bufs[i].pool_entry = NULL; } -EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list); static void qeth_free_pool_entry(struct qeth_buffer_pool_entry *entry) { @@ -658,12 +657,11 @@ static void qeth_flush_local_addrs6(struct qeth_card *card) spin_unlock_irq(&card->local_addrs6_lock); } -void qeth_flush_local_addrs(struct qeth_card *card) +static void qeth_flush_local_addrs(struct qeth_card *card) { qeth_flush_local_addrs4(card); qeth_flush_local_addrs6(card); } -EXPORT_SYMBOL_GPL(qeth_flush_local_addrs); static void qeth_add_local_addrs4(struct qeth_card *card, struct qeth_ipacmd_local_addrs4 *cmd) @@ -1501,7 +1499,7 @@ static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free) } } -void qeth_drain_output_queues(struct qeth_card *card) +static void qeth_drain_output_queues(struct qeth_card *card) { int i; @@ -1512,7 +1510,6 @@ void qeth_drain_output_queues(struct qeth_card *card) qeth_drain_output_queue(card->qdio.out_qs[i], false); } } -EXPORT_SYMBOL_GPL(qeth_drain_output_queues); static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) { @@ -1840,7 +1837,7 @@ static int qeth_clear_halt_card(struct qeth_card *card, int halt) return qeth_clear_channels(card); } -int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) +static int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) { int rc = 0; @@ -1868,7 +1865,6 @@ int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) QETH_CARD_TEXT_(card, 3, "2err%d", rc); return rc; } -EXPORT_SYMBOL_GPL(qeth_qdio_clear_card); static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card) { @@ -5333,6 +5329,10 @@ static int qeth_set_online(struct qeth_card *card) err_online: err_hardsetup: + qeth_qdio_clear_card(card, 0); + qeth_clear_working_pool_list(card); + qeth_flush_local_addrs(card); + qeth_stop_channel(&card->data); qeth_stop_channel(&card->write); qeth_stop_channel(&card->read); @@ -5366,8 +5366,16 @@ int qeth_set_offline(struct qeth_card *card, bool resetting) netif_carrier_off(card->dev); rtnl_unlock(); + cancel_work_sync(&card->rx_mode_work); + card->discipline->set_offline(card); + qeth_qdio_clear_card(card, 0); + qeth_drain_output_queues(card); + qeth_clear_working_pool_list(card); + qeth_flush_local_addrs(card); + card->info.promisc_mode = 0; + rc = qeth_stop_channel(&card->data); rc2 = qeth_stop_channel(&card->write); rc3 = qeth_stop_channel(&card->read); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 6e8d5113d435..fd6891494c69 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -304,34 +304,6 @@ static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card) card->dev, &info.info, NULL); } -static void qeth_l2_stop_card(struct qeth_card *card) -{ - struct qeth_priv *priv = netdev_priv(card->dev); - - QETH_CARD_TEXT(card, 2, "stopcard"); - - qeth_set_allowed_threads(card, 0, 1); - - cancel_work_sync(&card->rx_mode_work); - qeth_l2_drain_rx_mode_cache(card); - - if (card->state == CARD_STATE_SOFTSETUP) - card->state = CARD_STATE_DOWN; - - qeth_qdio_clear_card(card, 0); - qeth_drain_output_queues(card); - qeth_clear_working_pool_list(card); - qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE); - qeth_flush_local_addrs(card); - card->info.promisc_mode = 0; - - if (priv->brport_features & BR_LEARNING_SYNC) { - rtnl_lock(); - qeth_l2_dev2br_fdb_flush(card); - rtnl_unlock(); - } -} - static int qeth_l2_request_initial_mac(struct qeth_card *card) { int rc = 0; @@ -1172,7 +1144,7 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) if (dev->reg_state != NETREG_REGISTERED) { rc = qeth_l2_setup_netdev(card); if (rc) - goto out_remove; + goto err_setup; if (carrier_ok) netif_carrier_on(dev); @@ -1195,14 +1167,28 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) } return 0; -out_remove: - qeth_l2_stop_card(card); +err_setup: + qeth_set_allowed_threads(card, 0, 1); + card->state = CARD_STATE_DOWN; return rc; } static void qeth_l2_set_offline(struct qeth_card *card) { - qeth_l2_stop_card(card); + struct qeth_priv *priv = netdev_priv(card->dev); + + qeth_set_allowed_threads(card, 0, 1); + qeth_l2_drain_rx_mode_cache(card); + + if (card->state == CARD_STATE_SOFTSETUP) + card->state = CARD_STATE_DOWN; + + qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE); + if (priv->brport_features & BR_LEARNING_SYNC) { + rtnl_lock(); + qeth_l2_dev2br_fdb_flush(card); + rtnl_unlock(); + } } static int __init qeth_l2_init(void) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 08285af6a5ff..a6f8878b55c6 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1142,32 +1142,6 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev, return 0; } -static void qeth_l3_stop_card(struct qeth_card *card) -{ - QETH_CARD_TEXT(card, 2, "stopcard"); - - qeth_set_allowed_threads(card, 0, 1); - - cancel_work_sync(&card->rx_mode_work); - qeth_l3_drain_rx_mode_cache(card); - - if (card->options.sniffer && - (card->info.promisc_mode == SET_PROMISC_MODE_ON)) - qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE); - - if (card->state == CARD_STATE_SOFTSETUP) { - card->state = CARD_STATE_DOWN; - qeth_l3_clear_ip_htable(card, 1); - } - - qeth_qdio_clear_card(card, 0); - qeth_drain_output_queues(card); - qeth_clear_working_pool_list(card); - flush_workqueue(card->event_wq); - qeth_flush_local_addrs(card); - card->info.promisc_mode = 0; -} - static void qeth_l3_set_promisc_mode(struct qeth_card *card) { bool enable = card->dev->flags & IFF_PROMISC; @@ -2042,7 +2016,7 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok) if (dev->reg_state != NETREG_REGISTERED) { rc = qeth_l3_setup_netdev(card); if (rc) - goto out_remove; + goto err_setup; if (carrier_ok) netif_carrier_on(dev); @@ -2064,14 +2038,26 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok) } return 0; -out_remove: - qeth_l3_stop_card(card); +err_setup: + qeth_set_allowed_threads(card, 0, 1); + card->state = CARD_STATE_DOWN; + qeth_l3_clear_ip_htable(card, 1); return rc; } static void qeth_l3_set_offline(struct qeth_card *card) { - qeth_l3_stop_card(card); + qeth_set_allowed_threads(card, 0, 1); + qeth_l3_drain_rx_mode_cache(card); + + if (card->options.sniffer && + (card->info.promisc_mode == SET_PROMISC_MODE_ON)) + qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE); + + if (card->state == CARD_STATE_SOFTSETUP) { + card->state = CARD_STATE_DOWN; + qeth_l3_clear_ip_htable(card, 1); + } } /* Returns zero if the command is successfully "consumed" */ -- 2.11.0