]>
Commit | Line | Data |
---|---|---|
7748c0ed SL |
1 | From fbfda80ab4457aa001ab1ccd323c1923c5c6e654 Mon Sep 17 00:00:00 2001 |
2 | From: Sudarsana Reddy Kalluru <skalluru@marvell.com> | |
3 | Date: Wed, 6 Feb 2019 14:43:45 -0800 | |
4 | Subject: qede: Fix system crash on configuring channels. | |
5 | ||
6 | [ Upstream commit 0aa4febb420d91df5b56b1864a2465765da85f4b ] | |
7 | ||
8 | Under heavy traffic load, when changing number of channels via | |
9 | ethtool (ethtool -L) which will cause interface to be reloaded, | |
10 | it was observed that some packets gets transmitted on old TX | |
11 | channel/queue id which doesn't really exist after the channel | |
12 | configuration leads to system crash. | |
13 | ||
14 | Add a safeguard in the driver by validating queue id through | |
15 | ndo_select_queue() which is called before the ndo_start_xmit(). | |
16 | ||
17 | Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com> | |
18 | Signed-off-by: Ariel Elior <aelior@marvell.com> | |
19 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
20 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
21 | --- | |
22 | drivers/net/ethernet/qlogic/qede/qede.h | 3 +++ | |
23 | drivers/net/ethernet/qlogic/qede/qede_fp.c | 13 +++++++++++++ | |
24 | drivers/net/ethernet/qlogic/qede/qede_main.c | 3 +++ | |
25 | 3 files changed, 19 insertions(+) | |
26 | ||
27 | diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h | |
28 | index 6a4d266fb8e2..d242a5724069 100644 | |
29 | --- a/drivers/net/ethernet/qlogic/qede/qede.h | |
30 | +++ b/drivers/net/ethernet/qlogic/qede/qede.h | |
31 | @@ -489,6 +489,9 @@ struct qede_reload_args { | |
32 | ||
33 | /* Datapath functions definition */ | |
34 | netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev); | |
35 | +u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, | |
36 | + struct net_device *sb_dev, | |
37 | + select_queue_fallback_t fallback); | |
38 | netdev_features_t qede_features_check(struct sk_buff *skb, | |
39 | struct net_device *dev, | |
40 | netdev_features_t features); | |
41 | diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c | |
42 | index 1a78027de071..a96da16f3404 100644 | |
43 | --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c | |
44 | +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c | |
45 | @@ -1695,6 +1695,19 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |
46 | return NETDEV_TX_OK; | |
47 | } | |
48 | ||
49 | +u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, | |
50 | + struct net_device *sb_dev, | |
51 | + select_queue_fallback_t fallback) | |
52 | +{ | |
53 | + struct qede_dev *edev = netdev_priv(dev); | |
54 | + int total_txq; | |
55 | + | |
56 | + total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc; | |
57 | + | |
58 | + return QEDE_TSS_COUNT(edev) ? | |
59 | + fallback(dev, skb, NULL) % total_txq : 0; | |
60 | +} | |
61 | + | |
62 | /* 8B udp header + 8B base tunnel header + 32B option length */ | |
63 | #define QEDE_MAX_TUN_HDR_LEN 48 | |
64 | ||
65 | diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c | |
66 | index 46d0f2eaa0c0..f3d9c40c4115 100644 | |
67 | --- a/drivers/net/ethernet/qlogic/qede/qede_main.c | |
68 | +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c | |
69 | @@ -631,6 +631,7 @@ static const struct net_device_ops qede_netdev_ops = { | |
70 | .ndo_open = qede_open, | |
71 | .ndo_stop = qede_close, | |
72 | .ndo_start_xmit = qede_start_xmit, | |
73 | + .ndo_select_queue = qede_select_queue, | |
74 | .ndo_set_rx_mode = qede_set_rx_mode, | |
75 | .ndo_set_mac_address = qede_set_mac_addr, | |
76 | .ndo_validate_addr = eth_validate_addr, | |
77 | @@ -666,6 +667,7 @@ static const struct net_device_ops qede_netdev_vf_ops = { | |
78 | .ndo_open = qede_open, | |
79 | .ndo_stop = qede_close, | |
80 | .ndo_start_xmit = qede_start_xmit, | |
81 | + .ndo_select_queue = qede_select_queue, | |
82 | .ndo_set_rx_mode = qede_set_rx_mode, | |
83 | .ndo_set_mac_address = qede_set_mac_addr, | |
84 | .ndo_validate_addr = eth_validate_addr, | |
85 | @@ -684,6 +686,7 @@ static const struct net_device_ops qede_netdev_vf_xdp_ops = { | |
86 | .ndo_open = qede_open, | |
87 | .ndo_stop = qede_close, | |
88 | .ndo_start_xmit = qede_start_xmit, | |
89 | + .ndo_select_queue = qede_select_queue, | |
90 | .ndo_set_rx_mode = qede_set_rx_mode, | |
91 | .ndo_set_mac_address = qede_set_mac_addr, | |
92 | .ndo_validate_addr = eth_validate_addr, | |
93 | -- | |
94 | 2.19.1 | |
95 |