From: Julian Wiedmann <jwi@linux.ibm.com>
Subject: s390/qeth: align L2 and L3 set_rx_mode() implementations
Patch-mainline: v4.16-rc1
Git-commit: 00c163f142edc1c859fc6690afc412215be9ab53
References: FATE#326350, LTC#169511, bsc#1113509
Summary: qeth: performance improvements
Description: This adds recent functional and performance improvements for the
qeth network driver.
Primarily this brings Scatter-Gather support for HiperSockets,
reduced CPU consumption in the L3 IPv4 transmit path for OSA,
improved Promiscuous Mode performance due to IFF_UNICAST_FLT,
support for Scatter-Gather on z/VM virtual NICs, and
support for delayed GRO flushing.
For sanity & stability reasons, this effectively constitutes a
backport of the qeth device driver from 4.19 mainline.
Upstream-Description:
s390/qeth: align L2 and L3 set_rx_mode() implementations
Once all of qeth_l3_set_rx_mode()'s single-use helpers are folded back
in, the two implementations actually look quite similar. So improve the
readability by converting both set_rx_mode() routines to a common
format.
This also allows us to walk ip_mc_htable just once, instead of three
times.
Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
drivers/s390/net/qeth_l2_main.c | 16 ++++--
drivers/s390/net/qeth_l3_main.c | 94 ++++++++++++++--------------------------
2 files changed, 43 insertions(+), 67 deletions(-)
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -639,20 +639,24 @@ static void qeth_l2_set_rx_mode(struct n
qeth_l2_add_mac(card, ha);
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
- if (mac->disp_flag == QETH_DISP_ADDR_DELETE) {
+ switch (mac->disp_flag) {
+ case QETH_DISP_ADDR_DELETE:
qeth_l2_remove_mac(card, mac->mac_addr);
hash_del(&mac->hnode);
kfree(mac);
-
- } else if (mac->disp_flag == QETH_DISP_ADDR_ADD) {
+ break;
+ case QETH_DISP_ADDR_ADD:
rc = qeth_l2_write_mac(card, mac->mac_addr);
if (rc) {
hash_del(&mac->hnode);
kfree(mac);
- } else
- mac->disp_flag = QETH_DISP_ADDR_DELETE;
- } else
+ break;
+ }
+ /* fall through */
+ default:
+ /* for next call to set_rx_mode(): */
mac->disp_flag = QETH_DISP_ADDR_DELETE;
+ }
}
spin_unlock_bh(&card->mclock);
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -36,7 +36,7 @@
static int qeth_l3_set_offline(struct ccwgroup_device *);
static int qeth_l3_stop(struct net_device *);
-static void qeth_l3_set_multicast_list(struct net_device *);
+static void qeth_l3_set_rx_mode(struct net_device *dev);
static int qeth_l3_register_addr_entry(struct qeth_card *,
struct qeth_ipaddr *);
static int qeth_l3_deregister_addr_entry(struct qeth_card *,
@@ -1306,56 +1306,6 @@ qeth_diags_trace(struct qeth_card *card,
return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
}
-static void qeth_l3_mark_all_mc_to_be_deleted(struct qeth_card *card)
-{
- struct qeth_ipaddr *addr;
- int i;
-
- hash_for_each(card->ip_mc_htable, i, addr, hnode)
- addr->disp_flag = QETH_DISP_ADDR_DELETE;
-
-}
-
-static void qeth_l3_add_all_new_mc(struct qeth_card *card)
-{
- struct qeth_ipaddr *addr;
- struct hlist_node *tmp;
- int i;
- int rc;
-
- hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) {
- if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
- rc = qeth_l3_register_addr_entry(card, addr);
- if (!rc || (rc == IPA_RC_LAN_OFFLINE))
- addr->ref_counter = 1;
- else {
- hash_del(&addr->hnode);
- kfree(addr);
- }
- }
- }
-
-}
-
-static void qeth_l3_delete_nonused_mc(struct qeth_card *card)
-{
- struct qeth_ipaddr *addr;
- struct hlist_node *tmp;
- int i;
- int rc;
-
- hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) {
- if (addr->disp_flag == QETH_DISP_ADDR_DELETE) {
- rc = qeth_l3_deregister_addr_entry(card, addr);
- if (!rc || (rc == IPA_RC_MC_ADDR_NOT_FOUND)) {
- hash_del(&addr->hnode);
- kfree(addr);
- }
- }
- }
-
-}
-
static void
qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev)
{
@@ -1636,7 +1586,7 @@ static int qeth_l3_vlan_rx_kill_vid(stru
/* unregister IP addresses of vlan device */
qeth_l3_free_vlan_addresses(card, vid);
clear_bit(vid, card->active_vlans);
- qeth_l3_set_multicast_list(card->dev);
+ qeth_l3_set_rx_mode(dev);
return 0;
}
@@ -1899,24 +1849,46 @@ qeth_l3_handle_promisc_mode(struct qeth_
}
}
-static void qeth_l3_set_multicast_list(struct net_device *dev)
+static void qeth_l3_set_rx_mode(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
+ struct qeth_ipaddr *addr;
+ struct hlist_node *tmp;
+ int i, rc;
QETH_CARD_TEXT(card, 3, "setmulti");
if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
(card->state != CARD_STATE_UP))
return;
if (!card->options.sniffer) {
-
spin_lock_bh(&card->mclock);
- qeth_l3_mark_all_mc_to_be_deleted(card);
-
qeth_l3_add_multicast_ipv4(card);
qeth_l3_add_multicast_ipv6(card);
- qeth_l3_delete_nonused_mc(card);
- qeth_l3_add_all_new_mc(card);
+
+ hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) {
+ switch (addr->disp_flag) {
+ case QETH_DISP_ADDR_DELETE:
+ rc = qeth_l3_deregister_addr_entry(card, addr);
+ if (!rc || rc == IPA_RC_MC_ADDR_NOT_FOUND) {
+ hash_del(&addr->hnode);
+ kfree(addr);
+ }
+ break;
+ case QETH_DISP_ADDR_ADD:
+ rc = qeth_l3_register_addr_entry(card, addr);
+ if (rc && rc != IPA_RC_LAN_OFFLINE) {
+ hash_del(&addr->hnode);
+ kfree(addr);
+ break;
+ }
+ addr->ref_counter = 1;
+ /* fall through */
+ default:
+ /* for next call to set_rx_mode(): */
+ addr->disp_flag = QETH_DISP_ADDR_DELETE;
+ }
+ }
spin_unlock_bh(&card->mclock);
@@ -2877,7 +2849,7 @@ static const struct net_device_ops qeth_
.ndo_get_stats = qeth_get_stats,
.ndo_start_xmit = qeth_l3_hard_start_xmit,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = qeth_l3_set_multicast_list,
+ .ndo_set_rx_mode = qeth_l3_set_rx_mode,
.ndo_do_ioctl = qeth_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
.ndo_fix_features = qeth_fix_features,
@@ -2894,7 +2866,7 @@ static const struct net_device_ops qeth_
.ndo_start_xmit = qeth_l3_hard_start_xmit,
.ndo_features_check = qeth_features_check,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = qeth_l3_set_multicast_list,
+ .ndo_set_rx_mode = qeth_l3_set_rx_mode,
.ndo_do_ioctl = qeth_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
.ndo_fix_features = qeth_fix_features,
@@ -3094,7 +3066,7 @@ static int __qeth_l3_set_online(struct c
__qeth_l3_open(card->dev);
else
dev_open(card->dev);
- qeth_l3_set_multicast_list(card->dev);
+ qeth_l3_set_rx_mode(card->dev);
qeth_recover_features(card->dev);
rtnl_unlock();
}