From: Julian Wiedmann <jwi@linux.ibm.com>
Subject: s390/qeth: simplify card look-up on IP notification
Patch-mainline: v4.17-rc1
Git-commit: b9caa98c5135774dae232843ecef3c487c36a7a0
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: simplify card look-up on IP notification
On an IP event, current code tries to determine if the netdev belongs
to a L3 card by walking all qeth cards in the system, and then all of
their VLAN devices too. Short-cut the whole thing by identifying a L3
device through its netdev_ops.
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_core.h | 2 -
drivers/s390/net/qeth_l3_main.c | 77 ++++++----------------------------------
2 files changed, 12 insertions(+), 67 deletions(-)
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -231,8 +231,6 @@ static inline int qeth_is_ipa_enabled(st
#define QETH_IDX_FUNC_LEVEL_OSD 0x0101
#define QETH_IDX_FUNC_LEVEL_IQD 0x4108
-#define QETH_REAL_CARD 1
-#define QETH_VLAN_CARD 2
#define QETH_BUFSIZE 4096
/**
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1594,69 +1594,6 @@ static int qeth_l3_process_inbound_buffe
return work_done;
}
-static int qeth_l3_verify_vlan_dev(struct net_device *dev,
- struct qeth_card *card)
-{
- int rc = 0;
- u16 vid;
-
- for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) {
- struct net_device *netdev;
-
- rcu_read_lock();
- netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q),
- vid);
- rcu_read_unlock();
- if (netdev == dev) {
- rc = QETH_VLAN_CARD;
- break;
- }
- }
-
- if (rc && !(vlan_dev_real_dev(dev)->ml_priv == (void *)card))
- return 0;
-
- return rc;
-}
-
-static int qeth_l3_verify_dev(struct net_device *dev)
-{
- struct qeth_card *card;
- int rc = 0;
- unsigned long flags;
-
- read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
- list_for_each_entry(card, &qeth_core_card_list.list, list) {
- if (card->dev == dev) {
- rc = QETH_REAL_CARD;
- break;
- }
- rc = qeth_l3_verify_vlan_dev(dev, card);
- if (rc)
- break;
- }
- read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
-
- return rc;
-}
-
-static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
-{
- struct qeth_card *card = NULL;
- int rc;
-
- rc = qeth_l3_verify_dev(dev);
- if (rc == QETH_REAL_CARD)
- card = dev->ml_priv;
- else if (rc == QETH_VLAN_CARD)
- card = vlan_dev_real_dev(dev)->ml_priv;
- if (card && card->options.layer2)
- card = NULL;
- if (card)
- QETH_CARD_TEXT_(card, 4, "%d", rc);
- return card ;
-}
-
static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
{
QETH_DBF_TEXT(SETUP, 2, "stopcard");
@@ -3139,12 +3076,22 @@ static int qeth_l3_handle_ip_event(struc
}
}
+static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
+{
+ if (is_vlan_dev(dev))
+ dev = vlan_dev_real_dev(dev);
+ if (dev->netdev_ops == &qeth_l3_osa_netdev_ops ||
+ dev->netdev_ops == &qeth_l3_netdev_ops)
+ return (struct qeth_card *) dev->ml_priv;
+ return NULL;
+}
+
static int qeth_l3_ip_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
- struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
+ struct net_device *dev = ifa->ifa_dev->dev;
struct qeth_ipaddr addr;
struct qeth_card *card;
@@ -3172,7 +3119,7 @@ static int qeth_l3_ip6_event(struct noti
unsigned long event, void *ptr)
{
struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
- struct net_device *dev = (struct net_device *)ifa->idev->dev;
+ struct net_device *dev = ifa->idev->dev;
struct qeth_ipaddr addr;
struct qeth_card *card;