mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
Including fixes from bpf and wireless.
Nothing scary here. Feels like the first wave of regressions from v6.5 is addressed - one outstanding fix still to come in TLS for the sendpage rework. Current release - regressions: - udp: fix __ip_append_data()'s handling of MSG_SPLICE_PAGES - dsa: fix older DSA drivers using phylink Previous releases - regressions: - gro: fix misuse of CB in udp socket lookup - mlx5: unregister devlink params in case interface is down - Revert "wifi: ath11k: Enable threaded NAPI" Previous releases - always broken: - sched: cls_u32: fix match key mis-addressing - sched: bind logic fixes for cls_fw, cls_u32 and cls_route - add bound checks to a number of places which hand-parse netlink - bpf: disable preemption in perf_event_output helpers code - qed: fix scheduling in a tasklet while getting stats - avoid using APIs which are not hardirq-safe in couple of drivers, when we may be in a hard IRQ (netconsole) - wifi: cfg80211: fix return value in scan logic, avoid page allocator warning - wifi: mt76: mt7615: do not advertise 5 GHz on first PHY of MT7615D (DBDC) Misc: - drop handful of inactive maintainers, put some new in place Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmTMCRwACgkQMUZtbf5S Irv1tRAArN6rfYrr2ulaTOfMqhWb1Q+kAs00nBCKqC+OdWgT0hqw2QAuqTAVjhje 8HBYlNGyhJ10yp0Q5y4Fp9CsBDHDDNjIp/YGEbr0vC/9mUDOhYD8WV07SmZmzEJu gmt4LeFPTk07yZy7VxMLY5XKuwce6MWGHArehZE7PSa9+07yY2Ov9X02ntr9hSdH ih+VdDI12aTVSj208qb0qNb2JkefFHW9dntVxce4/mtYJE9+47KMR2aXDXtCh0C6 ECgx0LQkdEJ5vNSYfypww0SXIG5aj7sE6HMTdJkjKH7ws4xrW8H+P9co77Hb/DTH TsRBS4SgB20hFNxz3OQwVmAvj+2qfQssL7SeIkRnaEWeTBuVqCwjLdoIzKXJxxq+ cvtUAAM8XUPqec5cPiHPkeAJV6aJhrdUdMjjbCI9uFYU32AWFBQEqvVGP9xdhXHK QIpTLiy26Vw8PwiJdROuGiZJCXePqQRLDuMX1L43ZO1rwIrZcWGHjCNtsR9nXKgQ apbbxb2/rq2FBMB+6obKeHzWDy3JraNCsUspmfleqdjQ2mpbRokd4Vw2564FJgaC 5OznPIX6OuoCY5sftLUcRcpH5ncNj01BvyqjWyCIfJdkCqCUL7HSAgxfm5AUnZip ZIXOzZnZ6uTUQFptXdjey/jNEQ6qpV8RmwY0CMsmJoo88DXI34Y= =HYkl -----END PGP SIGNATURE----- Merge tag 'net-6.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bpf and wireless. Nothing scary here. Feels like the first wave of regressions from v6.5 is addressed - one outstanding fix still to come in TLS for the sendpage rework. Current release - regressions: - udp: fix __ip_append_data()'s handling of MSG_SPLICE_PAGES - dsa: fix older DSA drivers using phylink Previous releases - regressions: - gro: fix misuse of CB in udp socket lookup - mlx5: unregister devlink params in case interface is down - Revert "wifi: ath11k: Enable threaded NAPI" Previous releases - always broken: - sched: cls_u32: fix match key mis-addressing - sched: bind logic fixes for cls_fw, cls_u32 and cls_route - add bound checks to a number of places which hand-parse netlink - bpf: disable preemption in perf_event_output helpers code - qed: fix scheduling in a tasklet while getting stats - avoid using APIs which are not hardirq-safe in couple of drivers, when we may be in a hard IRQ (netconsole) - wifi: cfg80211: fix return value in scan logic, avoid page allocator warning - wifi: mt76: mt7615: do not advertise 5 GHz on first PHY of MT7615D (DBDC) Misc: - drop handful of inactive maintainers, put some new in place" * tag 'net-6.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (98 commits) MAINTAINERS: update TUN/TAP maintainers test/vsock: remove vsock_perf executable on `make clean` tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen tcp_metrics: annotate data-races around tm->tcpm_net tcp_metrics: annotate data-races around tm->tcpm_vals[] tcp_metrics: annotate data-races around tm->tcpm_lock tcp_metrics: annotate data-races around tm->tcpm_stamp tcp_metrics: fix addr_same() helper prestera: fix fallback to previous version on same major version udp: Fix __ip_append_data()'s handling of MSG_SPLICE_PAGES net/mlx5e: Set proper IPsec source port in L4 selector net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio net/mlx5: fs_core: Make find_closest_ft more generic wifi: brcmfmac: Fix field-spanning write in brcmf_scan_params_v2_to_v1() vxlan: Fix nexthop hash size ip6mr: Fix skb_under_panic in ip6mr_cache_report() s390/qeth: Don't call dev_close/dev_open (DOWN/UP) net: tap_open(): set sk_uid from current_fsuid() net: tun_chr_open(): set sk_uid from current_fsuid() net: dcb: choose correct policy to parse DCB_ATTR_BCN ...
This commit is contained in:
commit
999f663186
@ -293,7 +293,7 @@ allOf:
|
||||
patternProperties:
|
||||
"^mac@[0-1]$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- $ref: ethernet-controller.yaml#
|
||||
description:
|
||||
@ -305,14 +305,9 @@ patternProperties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
phy-handle: true
|
||||
|
||||
phy-mode: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- phy-handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -91,12 +91,18 @@ properties:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
tx_delay:
|
||||
description: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as default.
|
||||
description: Delay value for TXD timing.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 0x7F
|
||||
default: 0x30
|
||||
|
||||
rx_delay:
|
||||
description: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as default.
|
||||
description: Delay value for RXD timing.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 0x7F
|
||||
default: 0x10
|
||||
|
||||
phy-supply:
|
||||
description: PHY regulator
|
||||
|
42
MAINTAINERS
42
MAINTAINERS
@ -3262,9 +3262,8 @@ F: Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
|
||||
F: drivers/input/touchscreen/atmel_mxt_ts.c
|
||||
|
||||
ATMEL WIRELESS DRIVER
|
||||
M: Simon Kelley <simon@thekelleys.org.uk>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
W: http://www.thekelleys.org.uk/atmel
|
||||
W: http://atmelwlandriver.sourceforge.net/
|
||||
F: drivers/net/wireless/atmel/atmel*
|
||||
@ -3394,7 +3393,7 @@ F: drivers/media/radio/radio-aztech*
|
||||
B43 WIRELESS DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: b43-dev@lists.infradead.org
|
||||
S: Odd Fixes
|
||||
S: Orphan
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/b43
|
||||
F: drivers/net/wireless/broadcom/b43/
|
||||
|
||||
@ -5462,8 +5461,7 @@ F: Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
|
||||
F: drivers/net/can/ctucanfd/
|
||||
|
||||
CW1200 WLAN driver
|
||||
M: Solomon Peachy <pizza@shaftnet.org>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/st/cw1200/
|
||||
|
||||
CX18 VIDEO4LINUX DRIVER
|
||||
@ -12592,18 +12590,14 @@ F: Documentation/devicetree/bindings/net/marvell,pp2.yaml
|
||||
F: drivers/net/ethernet/marvell/mvpp2/
|
||||
|
||||
MARVELL MWIFIEX WIRELESS DRIVER
|
||||
M: Amitkumar Karwar <amitkarwar@gmail.com>
|
||||
M: Ganapathi Bhat <ganapathi017@gmail.com>
|
||||
M: Sharvari Harisangam <sharvari.harisangam@nxp.com>
|
||||
M: Xinming Hu <huxinming820@gmail.com>
|
||||
M: Brian Norris <briannorris@chromium.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/net/wireless/marvell/mwifiex/
|
||||
|
||||
MARVELL MWL8K WIRELESS DRIVER
|
||||
M: Lennert Buytenhek <buytenh@wantstofly.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/marvell/mwl8k.c
|
||||
|
||||
MARVELL NAND CONTROLLER DRIVER
|
||||
@ -17449,6 +17443,7 @@ F: drivers/media/tuners/qt1010*
|
||||
|
||||
QUALCOMM ATH12K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
M: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
L: ath12k@lists.infradead.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
@ -17456,6 +17451,7 @@ F: drivers/net/wireless/ath/ath12k/
|
||||
|
||||
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
M: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
L: ath10k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
|
||||
@ -17465,6 +17461,7 @@ F: drivers/net/wireless/ath/ath10k/
|
||||
|
||||
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
M: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
L: ath11k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k
|
||||
@ -17985,7 +17982,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g
|
||||
F: drivers/net/wireless/realtek/rtlwifi/
|
||||
|
||||
REALTEK WIRELESS DRIVER (rtw88)
|
||||
M: Yan-Hsuan Chuang <tony0620emma@gmail.com>
|
||||
M: Ping-Ke Shih <pkshih@realtek.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/realtek/rtw88/
|
||||
@ -20404,7 +20401,6 @@ F: drivers/pwm/pwm-stm32*
|
||||
F: include/linux/*/stm32-*tim*
|
||||
|
||||
STMMAC ETHERNET DRIVER
|
||||
M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@foss.st.com>
|
||||
M: Jose Abreu <joabreu@synopsys.com>
|
||||
L: netdev@vger.kernel.org
|
||||
@ -21681,11 +21677,14 @@ S: Orphan
|
||||
F: drivers/net/ethernet/dec/tulip/
|
||||
|
||||
TUN/TAP driver
|
||||
M: Maxim Krasnyansky <maxk@qti.qualcomm.com>
|
||||
M: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
|
||||
M: Jason Wang <jasowang@redhat.com>
|
||||
S: Maintained
|
||||
W: http://vtun.sourceforge.net/tun
|
||||
F: Documentation/networking/tuntap.rst
|
||||
F: arch/um/os-Linux/drivers/
|
||||
F: drivers/net/tap.c
|
||||
F: drivers/net/tun.c
|
||||
|
||||
TURBOCHANNEL SUBSYSTEM
|
||||
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
|
||||
@ -21908,9 +21907,8 @@ S: Maintained
|
||||
F: drivers/usb/misc/apple-mfi-fastcharge.c
|
||||
|
||||
USB AR5523 WIRELESS DRIVER
|
||||
M: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/ath/ar5523/
|
||||
|
||||
USB ATTACHED SCSI
|
||||
@ -22187,9 +22185,8 @@ F: drivers/usb/gadget/legacy/webcam.c
|
||||
F: include/uapi/linux/usb/g_uvc.h
|
||||
|
||||
USB WIRELESS RNDIS DRIVER (rndis_wlan)
|
||||
M: Jussi Kivilinna <jussi.kivilinna@iki.fi>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/legacy/rndis_wlan.c
|
||||
|
||||
USB XHCI DRIVER
|
||||
@ -22964,7 +22961,7 @@ F: drivers/input/misc/wistron_btns.c
|
||||
|
||||
WL3501 WIRELESS PCMCIA CARD DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Odd fixes
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/legacy/wl3501*
|
||||
|
||||
WMI BINARY MOF DRIVER
|
||||
@ -23535,11 +23532,8 @@ S: Maintained
|
||||
F: mm/zbud.c
|
||||
|
||||
ZD1211RW WIRELESS DRIVER
|
||||
M: Ulrich Kunitz <kune@deine-taler.de>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: zd1211-devs@lists.sourceforge.net (subscribers-only)
|
||||
S: Maintained
|
||||
W: http://zd1211.ath.cx/wiki/DriverRewrite
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/zydas/zd1211rw/
|
||||
|
||||
ZD1301 MEDIA DRIVER
|
||||
|
@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
|
||||
*z1t = cpu_to_le16(new_z1); /* now send data */
|
||||
if (bch->tx_idx < bch->tx_skb->len)
|
||||
return;
|
||||
dev_kfree_skb(bch->tx_skb);
|
||||
dev_kfree_skb_any(bch->tx_skb);
|
||||
if (get_next_bframe(bch))
|
||||
goto next_t_frame;
|
||||
return;
|
||||
@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
|
||||
}
|
||||
bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */
|
||||
bz->f1 = new_f1; /* next frame */
|
||||
dev_kfree_skb(bch->tx_skb);
|
||||
dev_kfree_skb_any(bch->tx_skb);
|
||||
get_next_bframe(bch);
|
||||
}
|
||||
|
||||
@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch)
|
||||
if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
|
||||
hfcpci_fill_fifo(bch);
|
||||
else {
|
||||
dev_kfree_skb(bch->tx_skb);
|
||||
dev_kfree_skb_any(bch->tx_skb);
|
||||
if (get_next_bframe(bch))
|
||||
hfcpci_fill_fifo(bch);
|
||||
}
|
||||
@ -2277,7 +2277,7 @@ _hfcpci_softirq(struct device *dev, void *unused)
|
||||
return 0;
|
||||
|
||||
if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
|
||||
spin_lock(&hc->lock);
|
||||
spin_lock_irq(&hc->lock);
|
||||
bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
|
||||
if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
|
||||
main_rec_hfcpci(bch);
|
||||
@ -2288,7 +2288,7 @@ _hfcpci_softirq(struct device *dev, void *unused)
|
||||
main_rec_hfcpci(bch);
|
||||
tx_birq(bch);
|
||||
}
|
||||
spin_unlock(&hc->lock);
|
||||
spin_unlock_irq(&hc->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1436,7 +1436,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv");
|
||||
if (IS_ERR(priv->clk_mdiv)) {
|
||||
@ -1444,7 +1446,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
|
||||
goto out_clk;
|
||||
}
|
||||
|
||||
clk_prepare_enable(priv->clk_mdiv);
|
||||
ret = clk_prepare_enable(priv->clk_mdiv);
|
||||
if (ret)
|
||||
goto out_clk;
|
||||
|
||||
ret = bcm_sf2_sw_rst(priv);
|
||||
if (ret) {
|
||||
|
@ -635,10 +635,9 @@ static const struct regmap_range ksz9477_valid_regs[] = {
|
||||
regmap_reg_range(0x1030, 0x1030),
|
||||
regmap_reg_range(0x1100, 0x1115),
|
||||
regmap_reg_range(0x111a, 0x111f),
|
||||
regmap_reg_range(0x1122, 0x1127),
|
||||
regmap_reg_range(0x112a, 0x112b),
|
||||
regmap_reg_range(0x1136, 0x1139),
|
||||
regmap_reg_range(0x113e, 0x113f),
|
||||
regmap_reg_range(0x1120, 0x112b),
|
||||
regmap_reg_range(0x1134, 0x113b),
|
||||
regmap_reg_range(0x113c, 0x113f),
|
||||
regmap_reg_range(0x1400, 0x1401),
|
||||
regmap_reg_range(0x1403, 0x1403),
|
||||
regmap_reg_range(0x1410, 0x1417),
|
||||
@ -669,10 +668,9 @@ static const struct regmap_range ksz9477_valid_regs[] = {
|
||||
regmap_reg_range(0x2030, 0x2030),
|
||||
regmap_reg_range(0x2100, 0x2115),
|
||||
regmap_reg_range(0x211a, 0x211f),
|
||||
regmap_reg_range(0x2122, 0x2127),
|
||||
regmap_reg_range(0x212a, 0x212b),
|
||||
regmap_reg_range(0x2136, 0x2139),
|
||||
regmap_reg_range(0x213e, 0x213f),
|
||||
regmap_reg_range(0x2120, 0x212b),
|
||||
regmap_reg_range(0x2134, 0x213b),
|
||||
regmap_reg_range(0x213c, 0x213f),
|
||||
regmap_reg_range(0x2400, 0x2401),
|
||||
regmap_reg_range(0x2403, 0x2403),
|
||||
regmap_reg_range(0x2410, 0x2417),
|
||||
@ -703,10 +701,9 @@ static const struct regmap_range ksz9477_valid_regs[] = {
|
||||
regmap_reg_range(0x3030, 0x3030),
|
||||
regmap_reg_range(0x3100, 0x3115),
|
||||
regmap_reg_range(0x311a, 0x311f),
|
||||
regmap_reg_range(0x3122, 0x3127),
|
||||
regmap_reg_range(0x312a, 0x312b),
|
||||
regmap_reg_range(0x3136, 0x3139),
|
||||
regmap_reg_range(0x313e, 0x313f),
|
||||
regmap_reg_range(0x3120, 0x312b),
|
||||
regmap_reg_range(0x3134, 0x313b),
|
||||
regmap_reg_range(0x313c, 0x313f),
|
||||
regmap_reg_range(0x3400, 0x3401),
|
||||
regmap_reg_range(0x3403, 0x3403),
|
||||
regmap_reg_range(0x3410, 0x3417),
|
||||
@ -737,10 +734,9 @@ static const struct regmap_range ksz9477_valid_regs[] = {
|
||||
regmap_reg_range(0x4030, 0x4030),
|
||||
regmap_reg_range(0x4100, 0x4115),
|
||||
regmap_reg_range(0x411a, 0x411f),
|
||||
regmap_reg_range(0x4122, 0x4127),
|
||||
regmap_reg_range(0x412a, 0x412b),
|
||||
regmap_reg_range(0x4136, 0x4139),
|
||||
regmap_reg_range(0x413e, 0x413f),
|
||||
regmap_reg_range(0x4120, 0x412b),
|
||||
regmap_reg_range(0x4134, 0x413b),
|
||||
regmap_reg_range(0x413c, 0x413f),
|
||||
regmap_reg_range(0x4400, 0x4401),
|
||||
regmap_reg_range(0x4403, 0x4403),
|
||||
regmap_reg_range(0x4410, 0x4417),
|
||||
@ -771,10 +767,9 @@ static const struct regmap_range ksz9477_valid_regs[] = {
|
||||
regmap_reg_range(0x5030, 0x5030),
|
||||
regmap_reg_range(0x5100, 0x5115),
|
||||
regmap_reg_range(0x511a, 0x511f),
|
||||
regmap_reg_range(0x5122, 0x5127),
|
||||
regmap_reg_range(0x512a, 0x512b),
|
||||
regmap_reg_range(0x5136, 0x5139),
|
||||
regmap_reg_range(0x513e, 0x513f),
|
||||
regmap_reg_range(0x5120, 0x512b),
|
||||
regmap_reg_range(0x5134, 0x513b),
|
||||
regmap_reg_range(0x513c, 0x513f),
|
||||
regmap_reg_range(0x5400, 0x5401),
|
||||
regmap_reg_range(0x5403, 0x5403),
|
||||
regmap_reg_range(0x5410, 0x5417),
|
||||
|
@ -633,12 +633,13 @@ tx_kick_pending:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
||||
static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
||||
{
|
||||
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
|
||||
struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txr->txq_index);
|
||||
u16 cons = txr->tx_cons;
|
||||
struct pci_dev *pdev = bp->pdev;
|
||||
int nr_pkts = bnapi->tx_pkts;
|
||||
int i;
|
||||
unsigned int tx_bytes = 0;
|
||||
|
||||
@ -688,6 +689,7 @@ next_tx_int:
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
bnapi->tx_pkts = 0;
|
||||
WRITE_ONCE(txr->tx_cons, cons);
|
||||
|
||||
__netif_txq_completed_wake(txq, nr_pkts, tx_bytes,
|
||||
@ -697,17 +699,24 @@ next_tx_int:
|
||||
|
||||
static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping,
|
||||
struct bnxt_rx_ring_info *rxr,
|
||||
unsigned int *offset,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct device *dev = &bp->pdev->dev;
|
||||
struct page *page;
|
||||
|
||||
page = page_pool_dev_alloc_pages(rxr->page_pool);
|
||||
if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) {
|
||||
page = page_pool_dev_alloc_frag(rxr->page_pool, offset,
|
||||
BNXT_RX_PAGE_SIZE);
|
||||
} else {
|
||||
page = page_pool_dev_alloc_pages(rxr->page_pool);
|
||||
*offset = 0;
|
||||
}
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
*mapping = dma_map_page_attrs(dev, page, 0, PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
*mapping = dma_map_page_attrs(dev, page, *offset, BNXT_RX_PAGE_SIZE,
|
||||
bp->rx_dir, DMA_ATTR_WEAK_ORDERING);
|
||||
if (dma_mapping_error(dev, *mapping)) {
|
||||
page_pool_recycle_direct(rxr->page_pool, page);
|
||||
return NULL;
|
||||
@ -747,15 +756,16 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
dma_addr_t mapping;
|
||||
|
||||
if (BNXT_RX_PAGE_MODE(bp)) {
|
||||
unsigned int offset;
|
||||
struct page *page =
|
||||
__bnxt_alloc_rx_page(bp, &mapping, rxr, gfp);
|
||||
__bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp);
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
mapping += bp->rx_dma_offset;
|
||||
rx_buf->data = page;
|
||||
rx_buf->data_ptr = page_address(page) + bp->rx_offset;
|
||||
rx_buf->data_ptr = page_address(page) + offset + bp->rx_offset;
|
||||
} else {
|
||||
u8 *data = __bnxt_alloc_rx_frag(bp, &mapping, gfp);
|
||||
|
||||
@ -815,7 +825,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp,
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (BNXT_RX_PAGE_MODE(bp)) {
|
||||
page = __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp);
|
||||
page = __bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp);
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
@ -962,15 +972,15 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
|
||||
return NULL;
|
||||
}
|
||||
dma_addr -= bp->rx_dma_offset;
|
||||
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
skb = build_skb(page_address(page), PAGE_SIZE);
|
||||
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE,
|
||||
bp->rx_dir, DMA_ATTR_WEAK_ORDERING);
|
||||
skb = build_skb(data_ptr - bp->rx_offset, BNXT_RX_PAGE_SIZE);
|
||||
if (!skb) {
|
||||
page_pool_recycle_direct(rxr->page_pool, page);
|
||||
return NULL;
|
||||
}
|
||||
skb_mark_for_recycle(skb);
|
||||
skb_reserve(skb, bp->rx_dma_offset);
|
||||
skb_reserve(skb, bp->rx_offset);
|
||||
__skb_put(skb, len);
|
||||
|
||||
return skb;
|
||||
@ -996,8 +1006,8 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,
|
||||
return NULL;
|
||||
}
|
||||
dma_addr -= bp->rx_dma_offset;
|
||||
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE,
|
||||
bp->rx_dir, DMA_ATTR_WEAK_ORDERING);
|
||||
|
||||
if (unlikely(!payload))
|
||||
payload = eth_get_headlen(bp->dev, data_ptr, len);
|
||||
@ -1010,7 +1020,7 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,
|
||||
|
||||
skb_mark_for_recycle(skb);
|
||||
off = (void *)data_ptr - page_address(page);
|
||||
skb_add_rx_frag(skb, 0, page, off, len, PAGE_SIZE);
|
||||
skb_add_rx_frag(skb, 0, page, off, len, BNXT_RX_PAGE_SIZE);
|
||||
memcpy(skb->data - NET_IP_ALIGN, data_ptr - NET_IP_ALIGN,
|
||||
payload + NET_IP_ALIGN);
|
||||
|
||||
@ -1141,7 +1151,7 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp,
|
||||
|
||||
skb->data_len += total_frag_len;
|
||||
skb->len += total_frag_len;
|
||||
skb->truesize += PAGE_SIZE * agg_bufs;
|
||||
skb->truesize += BNXT_RX_PAGE_SIZE * agg_bufs;
|
||||
return skb;
|
||||
}
|
||||
|
||||
@ -2569,12 +2579,11 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
|
||||
return rx_pkts;
|
||||
}
|
||||
|
||||
static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi)
|
||||
static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi,
|
||||
int budget)
|
||||
{
|
||||
if (bnapi->tx_pkts) {
|
||||
bnapi->tx_int(bp, bnapi, bnapi->tx_pkts);
|
||||
bnapi->tx_pkts = 0;
|
||||
}
|
||||
if (bnapi->tx_pkts)
|
||||
bnapi->tx_int(bp, bnapi, budget);
|
||||
|
||||
if ((bnapi->events & BNXT_RX_EVENT) && !(bnapi->in_reset)) {
|
||||
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
|
||||
@ -2603,7 +2612,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
|
||||
*/
|
||||
bnxt_db_cq(bp, &cpr->cp_db, cpr->cp_raw_cons);
|
||||
|
||||
__bnxt_poll_work_done(bp, bnapi);
|
||||
__bnxt_poll_work_done(bp, bnapi, budget);
|
||||
return rx_pkts;
|
||||
}
|
||||
|
||||
@ -2734,7 +2743,7 @@ static int __bnxt_poll_cqs(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
||||
}
|
||||
|
||||
static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi,
|
||||
u64 dbr_type)
|
||||
u64 dbr_type, int budget)
|
||||
{
|
||||
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
|
||||
int i;
|
||||
@ -2750,7 +2759,7 @@ static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi,
|
||||
cpr2->had_work_done = 0;
|
||||
}
|
||||
}
|
||||
__bnxt_poll_work_done(bp, bnapi);
|
||||
__bnxt_poll_work_done(bp, bnapi, budget);
|
||||
}
|
||||
|
||||
static int bnxt_poll_p5(struct napi_struct *napi, int budget)
|
||||
@ -2780,7 +2789,8 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)
|
||||
if (cpr->has_more_work)
|
||||
break;
|
||||
|
||||
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ_ARMALL);
|
||||
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ_ARMALL,
|
||||
budget);
|
||||
cpr->cp_raw_cons = raw_cons;
|
||||
if (napi_complete_done(napi, work_done))
|
||||
BNXT_DB_NQ_ARM_P5(&cpr->cp_db,
|
||||
@ -2810,7 +2820,7 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget)
|
||||
}
|
||||
raw_cons = NEXT_RAW_CMP(raw_cons);
|
||||
}
|
||||
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ);
|
||||
__bnxt_poll_cqs_done(bp, bnapi, DBR_TYPE_CQ, budget);
|
||||
if (raw_cons != cpr->cp_raw_cons) {
|
||||
cpr->cp_raw_cons = raw_cons;
|
||||
BNXT_DB_NQ_P5(&cpr->cp_db, raw_cons);
|
||||
@ -2943,8 +2953,8 @@ skip_rx_tpa_free:
|
||||
rx_buf->data = NULL;
|
||||
if (BNXT_RX_PAGE_MODE(bp)) {
|
||||
mapping -= bp->rx_dma_offset;
|
||||
dma_unmap_page_attrs(&pdev->dev, mapping, PAGE_SIZE,
|
||||
bp->rx_dir,
|
||||
dma_unmap_page_attrs(&pdev->dev, mapping,
|
||||
BNXT_RX_PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
page_pool_recycle_direct(rxr->page_pool, data);
|
||||
} else {
|
||||
@ -3213,6 +3223,8 @@ static int bnxt_alloc_rx_page_pool(struct bnxt *bp,
|
||||
pp.napi = &rxr->bnapi->napi;
|
||||
pp.dev = &bp->pdev->dev;
|
||||
pp.dma_dir = DMA_BIDIRECTIONAL;
|
||||
if (PAGE_SIZE > BNXT_RX_PAGE_SIZE)
|
||||
pp.flags |= PP_FLAG_PAGE_FRAG;
|
||||
|
||||
rxr->page_pool = page_pool_create(&pp);
|
||||
if (IS_ERR(rxr->page_pool)) {
|
||||
@ -3989,26 +4001,29 @@ void bnxt_set_ring_params(struct bnxt *bp)
|
||||
*/
|
||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
{
|
||||
struct net_device *dev = bp->dev;
|
||||
|
||||
if (page_mode) {
|
||||
bp->flags &= ~BNXT_FLAG_AGG_RINGS;
|
||||
bp->flags |= BNXT_FLAG_RX_PAGE_MODE;
|
||||
|
||||
if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) {
|
||||
if (bp->xdp_prog->aux->xdp_has_frags)
|
||||
dev->max_mtu = min_t(u16, bp->max_mtu, BNXT_MAX_MTU);
|
||||
else
|
||||
dev->max_mtu =
|
||||
min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU);
|
||||
if (dev->mtu > BNXT_MAX_PAGE_MODE_MTU) {
|
||||
bp->flags |= BNXT_FLAG_JUMBO;
|
||||
bp->rx_skb_func = bnxt_rx_multi_page_skb;
|
||||
bp->dev->max_mtu =
|
||||
min_t(u16, bp->max_mtu, BNXT_MAX_MTU);
|
||||
} else {
|
||||
bp->flags |= BNXT_FLAG_NO_AGG_RINGS;
|
||||
bp->rx_skb_func = bnxt_rx_page_skb;
|
||||
bp->dev->max_mtu =
|
||||
min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU);
|
||||
}
|
||||
bp->rx_dir = DMA_BIDIRECTIONAL;
|
||||
/* Disable LRO or GRO_HW */
|
||||
netdev_update_features(bp->dev);
|
||||
netdev_update_features(dev);
|
||||
} else {
|
||||
bp->dev->max_mtu = bp->max_mtu;
|
||||
dev->max_mtu = bp->max_mtu;
|
||||
bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
|
||||
bp->rx_dir = DMA_FROM_DEVICE;
|
||||
bp->rx_skb_func = bnxt_rx_skb;
|
||||
@ -9429,6 +9444,8 @@ static void bnxt_enable_napi(struct bnxt *bp)
|
||||
cpr->sw_stats.rx.rx_resets++;
|
||||
bnapi->in_reset = false;
|
||||
|
||||
bnapi->tx_pkts = 0;
|
||||
|
||||
if (bnapi->rx_ring) {
|
||||
INIT_WORK(&cpr->dim.work, bnxt_dim_work);
|
||||
cpr->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
|
||||
|
@ -1005,7 +1005,7 @@ struct bnxt_napi {
|
||||
struct bnxt_tx_ring_info *tx_ring;
|
||||
|
||||
void (*tx_int)(struct bnxt *, struct bnxt_napi *,
|
||||
int);
|
||||
int budget);
|
||||
int tx_pkts;
|
||||
u8 events;
|
||||
|
||||
|
@ -125,16 +125,20 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp,
|
||||
dma_unmap_len_set(tx_buf, len, 0);
|
||||
}
|
||||
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
||||
{
|
||||
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
|
||||
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
|
||||
bool rx_doorbell_needed = false;
|
||||
int nr_pkts = bnapi->tx_pkts;
|
||||
struct bnxt_sw_tx_bd *tx_buf;
|
||||
u16 tx_cons = txr->tx_cons;
|
||||
u16 last_tx_cons = tx_cons;
|
||||
int i, j, frags;
|
||||
|
||||
if (!budget)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nr_pkts; i++) {
|
||||
tx_buf = &txr->tx_buf_ring[tx_cons];
|
||||
|
||||
@ -161,6 +165,8 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
||||
}
|
||||
tx_cons = NEXT_TX(tx_cons);
|
||||
}
|
||||
|
||||
bnapi->tx_pkts = 0;
|
||||
WRITE_ONCE(txr->tx_cons, tx_cons);
|
||||
if (rx_doorbell_needed) {
|
||||
tx_buf = &txr->tx_buf_ring[last_tx_cons];
|
||||
@ -180,8 +186,8 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
u16 cons, u8 *data_ptr, unsigned int len,
|
||||
struct xdp_buff *xdp)
|
||||
{
|
||||
u32 buflen = BNXT_RX_PAGE_SIZE;
|
||||
struct bnxt_sw_rx_bd *rx_buf;
|
||||
u32 buflen = PAGE_SIZE;
|
||||
struct pci_dev *pdev;
|
||||
dma_addr_t mapping;
|
||||
u32 offset;
|
||||
@ -297,7 +303,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
rx_buf = &rxr->rx_buf_ring[cons];
|
||||
mapping = rx_buf->mapping - bp->rx_dma_offset;
|
||||
dma_unmap_page_attrs(&pdev->dev, mapping,
|
||||
PAGE_SIZE, bp->rx_dir,
|
||||
BNXT_RX_PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
|
||||
/* if we are unable to allocate a new buffer, abort and reuse */
|
||||
@ -480,7 +486,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
|
||||
}
|
||||
xdp_update_skb_shared_info(skb, num_frags,
|
||||
sinfo->xdp_frags_size,
|
||||
PAGE_SIZE * sinfo->nr_frags,
|
||||
BNXT_RX_PAGE_SIZE * sinfo->nr_frags,
|
||||
xdp_buff_is_frag_pfmemalloc(xdp));
|
||||
return skb;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
|
||||
struct bnxt_tx_ring_info *txr,
|
||||
dma_addr_t mapping, u32 len,
|
||||
struct xdp_buff *xdp);
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget);
|
||||
bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
struct xdp_buff xdp, struct page *page, u8 **data_ptr,
|
||||
unsigned int *len, u8 *event);
|
||||
|
@ -8813,6 +8813,7 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type,
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
struct ice_pf *pf = np->vsi->back;
|
||||
bool locked = false;
|
||||
int err;
|
||||
|
||||
switch (type) {
|
||||
@ -8822,10 +8823,27 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type,
|
||||
ice_setup_tc_block_cb,
|
||||
np, np, true);
|
||||
case TC_SETUP_QDISC_MQPRIO:
|
||||
if (pf->adev) {
|
||||
mutex_lock(&pf->adev_mutex);
|
||||
device_lock(&pf->adev->dev);
|
||||
locked = true;
|
||||
if (pf->adev->dev.driver) {
|
||||
netdev_err(netdev, "Cannot change qdisc when RDMA is active\n");
|
||||
err = -EBUSY;
|
||||
goto adev_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup traffic classifier for receive side */
|
||||
mutex_lock(&pf->tc_mutex);
|
||||
err = ice_setup_tc_mqprio_qdisc(netdev, type_data);
|
||||
mutex_unlock(&pf->tc_mutex);
|
||||
|
||||
adev_unlock:
|
||||
if (locked) {
|
||||
device_unlock(&pf->adev->dev);
|
||||
mutex_unlock(&pf->adev_mutex);
|
||||
}
|
||||
return err;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -1302,11 +1302,10 @@ static int korina_probe(struct platform_device *pdev)
|
||||
else if (of_get_ethdev_address(pdev->dev.of_node, dev) < 0)
|
||||
eth_hw_addr_random(dev);
|
||||
|
||||
clk = devm_clk_get_optional(&pdev->dev, "mdioclk");
|
||||
clk = devm_clk_get_optional_enabled(&pdev->dev, "mdioclk");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
if (clk) {
|
||||
clk_prepare_enable(clk);
|
||||
lp->mii_clock_freq = clk_get_rate(clk);
|
||||
} else {
|
||||
lp->mii_clock_freq = 200000000; /* max possible input clk */
|
||||
|
@ -98,6 +98,9 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
|
||||
writeq(OCTEP_CTRL_MBOX_STATUS_INIT,
|
||||
OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem));
|
||||
|
||||
mutex_init(&mbox->h2fq_lock);
|
||||
mutex_init(&mbox->f2hq_lock);
|
||||
|
||||
mbox->h2fq.sz = readl(OCTEP_CTRL_MBOX_H2FQ_SZ(mbox->barmem));
|
||||
mbox->h2fq.hw_prod = OCTEP_CTRL_MBOX_H2FQ_PROD(mbox->barmem);
|
||||
mbox->h2fq.hw_cons = OCTEP_CTRL_MBOX_H2FQ_CONS(mbox->barmem);
|
||||
|
@ -727,7 +727,8 @@ pick_fw_ver:
|
||||
|
||||
err = request_firmware_direct(&fw->bin, fw_path, fw->dev.dev);
|
||||
if (err) {
|
||||
if (ver_maj == PRESTERA_SUPP_FW_MAJ_VER) {
|
||||
if (ver_maj != PRESTERA_PREV_FW_MAJ_VER ||
|
||||
ver_min != PRESTERA_PREV_FW_MIN_VER) {
|
||||
ver_maj = PRESTERA_PREV_FW_MAJ_VER;
|
||||
ver_min = PRESTERA_PREV_FW_MIN_VER;
|
||||
|
||||
|
@ -1030,9 +1030,6 @@ int mlx5e_tc_tun_encap_dests_set(struct mlx5e_priv *priv,
|
||||
int out_index;
|
||||
int err = 0;
|
||||
|
||||
if (!mlx5e_is_eswitch_flow(flow))
|
||||
return 0;
|
||||
|
||||
parse_attr = attr->parse_attr;
|
||||
esw_attr = attr->esw_attr;
|
||||
*vf_tun = false;
|
||||
|
@ -323,8 +323,11 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_linear(struct mlx5e_rq *rq,
|
||||
net_prefetch(mxbuf->xdp.data);
|
||||
|
||||
prog = rcu_dereference(rq->xdp_prog);
|
||||
if (likely(prog && mlx5e_xdp_handle(rq, prog, mxbuf)))
|
||||
if (likely(prog && mlx5e_xdp_handle(rq, prog, mxbuf))) {
|
||||
if (likely(__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)))
|
||||
wi->flags |= BIT(MLX5E_WQE_FRAG_SKIP_RELEASE);
|
||||
return NULL; /* page/packet was consumed by XDP */
|
||||
}
|
||||
|
||||
/* XDP_PASS: copy the data from the UMEM to a new SKB. The frame reuse
|
||||
* will be handled by mlx5e_free_rx_wqe.
|
||||
|
@ -808,9 +808,9 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp
|
||||
}
|
||||
|
||||
if (upspec->sport) {
|
||||
MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
|
||||
MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_sport,
|
||||
upspec->sport_mask);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_sport, upspec->sport);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x)
|
||||
|
||||
trailer_len = alen + plen + 2;
|
||||
|
||||
pskb_trim(skb, skb->len - trailer_len);
|
||||
ret = pskb_trim(skb, skb->len - trailer_len);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len);
|
||||
ip_send_check(ipv4hdr);
|
||||
|
@ -188,7 +188,6 @@ static void mlx5e_tls_debugfs_init(struct mlx5e_tls *tls,
|
||||
|
||||
int mlx5e_ktls_init(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5_crypto_dek_pool *dek_pool;
|
||||
struct mlx5e_tls *tls;
|
||||
|
||||
if (!mlx5e_is_ktls_device(priv->mdev))
|
||||
@ -199,12 +198,6 @@ int mlx5e_ktls_init(struct mlx5e_priv *priv)
|
||||
return -ENOMEM;
|
||||
tls->mdev = priv->mdev;
|
||||
|
||||
dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY);
|
||||
if (IS_ERR(dek_pool)) {
|
||||
kfree(tls);
|
||||
return PTR_ERR(dek_pool);
|
||||
}
|
||||
tls->dek_pool = dek_pool;
|
||||
priv->tls = tls;
|
||||
|
||||
mlx5e_tls_debugfs_init(tls, priv->dfs_root);
|
||||
@ -222,7 +215,6 @@ void mlx5e_ktls_cleanup(struct mlx5e_priv *priv)
|
||||
debugfs_remove_recursive(tls->debugfs.dfs);
|
||||
tls->debugfs.dfs = NULL;
|
||||
|
||||
mlx5_crypto_dek_pool_destroy(tls->dek_pool);
|
||||
kfree(priv->tls);
|
||||
priv->tls = NULL;
|
||||
}
|
||||
|
@ -908,28 +908,51 @@ static void mlx5e_tls_tx_debugfs_init(struct mlx5e_tls *tls,
|
||||
|
||||
int mlx5e_ktls_init_tx(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5_crypto_dek_pool *dek_pool;
|
||||
struct mlx5e_tls *tls = priv->tls;
|
||||
int err;
|
||||
|
||||
if (!mlx5e_is_ktls_device(priv->mdev))
|
||||
return 0;
|
||||
|
||||
/* DEK pool could be used by either or both of TX and RX. But we have to
|
||||
* put the creation here to avoid syndrome when doing devlink reload.
|
||||
*/
|
||||
dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY);
|
||||
if (IS_ERR(dek_pool))
|
||||
return PTR_ERR(dek_pool);
|
||||
tls->dek_pool = dek_pool;
|
||||
|
||||
if (!mlx5e_is_ktls_tx(priv->mdev))
|
||||
return 0;
|
||||
|
||||
priv->tls->tx_pool = mlx5e_tls_tx_pool_init(priv->mdev, &priv->tls->sw_stats);
|
||||
if (!priv->tls->tx_pool)
|
||||
return -ENOMEM;
|
||||
if (!priv->tls->tx_pool) {
|
||||
err = -ENOMEM;
|
||||
goto err_tx_pool_init;
|
||||
}
|
||||
|
||||
mlx5e_tls_tx_debugfs_init(tls, tls->debugfs.dfs);
|
||||
|
||||
return 0;
|
||||
|
||||
err_tx_pool_init:
|
||||
mlx5_crypto_dek_pool_destroy(dek_pool);
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5e_ktls_cleanup_tx(struct mlx5e_priv *priv)
|
||||
{
|
||||
if (!mlx5e_is_ktls_tx(priv->mdev))
|
||||
return;
|
||||
goto dek_pool_destroy;
|
||||
|
||||
debugfs_remove_recursive(priv->tls->debugfs.dfs_tx);
|
||||
priv->tls->debugfs.dfs_tx = NULL;
|
||||
|
||||
mlx5e_tls_tx_pool_cleanup(priv->tls->tx_pool);
|
||||
priv->tls->tx_pool = NULL;
|
||||
|
||||
dek_pool_destroy:
|
||||
if (mlx5e_is_ktls_device(priv->mdev))
|
||||
mlx5_crypto_dek_pool_destroy(priv->tls->dek_pool);
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ static int macsec_fs_tx_create_crypto_table_groups(struct mlx5e_flow_table *ft)
|
||||
|
||||
if (!in) {
|
||||
kfree(ft->g);
|
||||
ft->g = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -135,6 +135,16 @@ static void arfs_del_rules(struct mlx5e_flow_steering *fs);
|
||||
|
||||
int mlx5e_arfs_disable(struct mlx5e_flow_steering *fs)
|
||||
{
|
||||
/* Moving to switchdev mode, fs->arfs is freed by mlx5e_nic_profile
|
||||
* cleanup_rx callback and it is not recreated when
|
||||
* mlx5e_uplink_rep_profile is loaded as mlx5e_create_flow_steering()
|
||||
* is not called by the uplink_rep profile init_rx callback. Thus, if
|
||||
* ntuple is set, moving to switchdev flow will enter this function
|
||||
* with fs->arfs nullified.
|
||||
*/
|
||||
if (!mlx5e_fs_get_arfs(fs))
|
||||
return 0;
|
||||
|
||||
arfs_del_rules(fs);
|
||||
|
||||
return arfs_disable(fs);
|
||||
|
@ -1036,7 +1036,23 @@ static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_s
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
|
||||
static void mlx5e_flush_rq_cq(struct mlx5e_rq *rq)
|
||||
{
|
||||
struct mlx5_cqwq *cqwq = &rq->cq.wq;
|
||||
struct mlx5_cqe64 *cqe;
|
||||
|
||||
if (test_bit(MLX5E_RQ_STATE_MINI_CQE_ENHANCED, &rq->state)) {
|
||||
while ((cqe = mlx5_cqwq_get_cqe_enahnced_comp(cqwq)))
|
||||
mlx5_cqwq_pop(cqwq);
|
||||
} else {
|
||||
while ((cqe = mlx5_cqwq_get_cqe(cqwq)))
|
||||
mlx5_cqwq_pop(cqwq);
|
||||
}
|
||||
|
||||
mlx5_cqwq_update_db_record(cqwq);
|
||||
}
|
||||
|
||||
int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state)
|
||||
{
|
||||
struct net_device *dev = rq->netdev;
|
||||
int err;
|
||||
@ -1046,6 +1062,10 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
|
||||
netdev_err(dev, "Failed to move rq 0x%x to reset\n", rq->rqn);
|
||||
return err;
|
||||
}
|
||||
|
||||
mlx5e_free_rx_descs(rq);
|
||||
mlx5e_flush_rq_cq(rq);
|
||||
|
||||
err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to move rq 0x%x to ready\n", rq->rqn);
|
||||
@ -1055,13 +1075,6 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state)
|
||||
{
|
||||
mlx5e_free_rx_descs(rq);
|
||||
|
||||
return mlx5e_rq_to_ready(rq, curr_state);
|
||||
}
|
||||
|
||||
static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = rq->mdev;
|
||||
|
@ -1012,7 +1012,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
|
||||
err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
|
||||
if (err) {
|
||||
mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
|
||||
return err;
|
||||
goto err_rx_res_free;
|
||||
}
|
||||
|
||||
err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
|
||||
@ -1046,6 +1046,7 @@ err_destroy_rx_res:
|
||||
mlx5e_rx_res_destroy(priv->rx_res);
|
||||
err_close_drop_rq:
|
||||
mlx5e_close_drop_rq(&priv->drop_rq);
|
||||
err_rx_res_free:
|
||||
mlx5e_rx_res_free(priv->rx_res);
|
||||
priv->rx_res = NULL;
|
||||
err_free_fs:
|
||||
@ -1159,6 +1160,10 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mlx5e_rep_neigh_init(rpriv);
|
||||
if (err)
|
||||
goto err_neigh_init;
|
||||
|
||||
if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
|
||||
err = mlx5e_init_uplink_rep_tx(rpriv);
|
||||
if (err)
|
||||
@ -1175,6 +1180,8 @@ err_ht_init:
|
||||
if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
|
||||
mlx5e_cleanup_uplink_rep_tx(rpriv);
|
||||
err_init_tx:
|
||||
mlx5e_rep_neigh_cleanup(rpriv);
|
||||
err_neigh_init:
|
||||
mlx5e_destroy_tises(priv);
|
||||
return err;
|
||||
}
|
||||
@ -1188,22 +1195,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
|
||||
if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
|
||||
mlx5e_cleanup_uplink_rep_tx(rpriv);
|
||||
|
||||
mlx5e_rep_neigh_cleanup(rpriv);
|
||||
mlx5e_destroy_tises(priv);
|
||||
}
|
||||
|
||||
static void mlx5e_rep_enable(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
|
||||
mlx5e_set_netdev_mtu_boundaries(priv);
|
||||
mlx5e_rep_neigh_init(rpriv);
|
||||
}
|
||||
|
||||
static void mlx5e_rep_disable(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
|
||||
mlx5e_rep_neigh_cleanup(rpriv);
|
||||
}
|
||||
|
||||
static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
|
||||
@ -1253,7 +1255,6 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event
|
||||
|
||||
static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
struct net_device *netdev = priv->netdev;
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
u16 max_mtu;
|
||||
@ -1275,7 +1276,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
|
||||
mlx5_notifier_register(mdev, &priv->events_nb);
|
||||
mlx5e_dcbnl_initialize(priv);
|
||||
mlx5e_dcbnl_init_app(priv);
|
||||
mlx5e_rep_neigh_init(rpriv);
|
||||
mlx5e_rep_bridge_init(priv);
|
||||
|
||||
netdev->wanted_features |= NETIF_F_HW_TC;
|
||||
@ -1290,7 +1290,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
|
||||
|
||||
static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
|
||||
rtnl_lock();
|
||||
@ -1300,7 +1299,6 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
|
||||
rtnl_unlock();
|
||||
|
||||
mlx5e_rep_bridge_cleanup(priv);
|
||||
mlx5e_rep_neigh_cleanup(rpriv);
|
||||
mlx5e_dcbnl_delete_app(priv);
|
||||
mlx5_notifier_unregister(mdev, &priv->events_nb);
|
||||
mlx5e_rep_tc_disable(priv);
|
||||
|
@ -1725,6 +1725,19 @@ verify_attr_actions(u32 actions, struct netlink_ext_ack *extack)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_encap_dests(struct mlx5_flow_attr *attr)
|
||||
{
|
||||
struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr;
|
||||
int out_index;
|
||||
|
||||
for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++)
|
||||
if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
post_process_attr(struct mlx5e_tc_flow *flow,
|
||||
struct mlx5_flow_attr *attr,
|
||||
@ -1737,9 +1750,11 @@ post_process_attr(struct mlx5e_tc_flow *flow,
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun);
|
||||
if (err)
|
||||
goto err_out;
|
||||
if (mlx5e_is_eswitch_flow(flow) && has_encap_dests(attr)) {
|
||||
err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun);
|
||||
if (err)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) {
|
||||
err = mlx5e_tc_attach_mod_hdr(flow->priv, flow, attr);
|
||||
|
@ -64,7 +64,7 @@ void mlx5_esw_bridge_debugfs_init(struct net_device *br_netdev, struct mlx5_esw_
|
||||
|
||||
bridge->debugfs_dir = debugfs_create_dir(br_netdev->name,
|
||||
bridge->br_offloads->debugfs_root);
|
||||
debugfs_create_file("fdb", 0444, bridge->debugfs_dir, bridge,
|
||||
debugfs_create_file("fdb", 0400, bridge->debugfs_dir, bridge,
|
||||
&mlx5_esw_bridge_debugfs_fops);
|
||||
}
|
||||
|
||||
|
@ -1436,7 +1436,6 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb)
|
||||
|
||||
esw_init_chains_offload_flags(esw, &attr.flags);
|
||||
attr.ns = MLX5_FLOW_NAMESPACE_FDB;
|
||||
attr.fs_base_prio = FDB_TC_OFFLOAD;
|
||||
attr.max_grp_num = esw->params.large_group_num;
|
||||
attr.default_ft = miss_fdb;
|
||||
attr.mapping = esw->offloads.reg_c0_obj_pool;
|
||||
@ -2779,9 +2778,9 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
|
||||
struct mlx5_eswitch *peer_esw,
|
||||
bool pair)
|
||||
{
|
||||
u8 peer_idx = mlx5_get_dev_index(peer_esw->dev);
|
||||
u16 peer_vhca_id = MLX5_CAP_GEN(peer_esw->dev, vhca_id);
|
||||
u16 vhca_id = MLX5_CAP_GEN(esw->dev, vhca_id);
|
||||
struct mlx5_flow_root_namespace *peer_ns;
|
||||
u8 idx = mlx5_get_dev_index(esw->dev);
|
||||
struct mlx5_flow_root_namespace *ns;
|
||||
int err;
|
||||
|
||||
@ -2789,18 +2788,18 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
|
||||
ns = esw->dev->priv.steering->fdb_root_ns;
|
||||
|
||||
if (pair) {
|
||||
err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_idx);
|
||||
err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_vhca_id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_flow_namespace_set_peer(peer_ns, ns, idx);
|
||||
err = mlx5_flow_namespace_set_peer(peer_ns, ns, vhca_id);
|
||||
if (err) {
|
||||
mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
|
||||
mlx5_flow_namespace_set_peer(ns, NULL, peer_vhca_id);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
|
||||
mlx5_flow_namespace_set_peer(peer_ns, NULL, idx);
|
||||
mlx5_flow_namespace_set_peer(ns, NULL, peer_vhca_id);
|
||||
mlx5_flow_namespace_set_peer(peer_ns, NULL, vhca_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -4196,7 +4195,7 @@ int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable,
|
||||
}
|
||||
|
||||
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
|
||||
MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, 1);
|
||||
MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, enable);
|
||||
|
||||
err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport->vport,
|
||||
MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2);
|
||||
|
@ -140,7 +140,7 @@ static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace
|
||||
|
||||
static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns,
|
||||
struct mlx5_flow_root_namespace *peer_ns,
|
||||
u8 peer_idx)
|
||||
u16 peer_vhca_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ struct mlx5_flow_cmds {
|
||||
|
||||
int (*set_peer)(struct mlx5_flow_root_namespace *ns,
|
||||
struct mlx5_flow_root_namespace *peer_ns,
|
||||
u8 peer_idx);
|
||||
u16 peer_vhca_id);
|
||||
|
||||
int (*create_ns)(struct mlx5_flow_root_namespace *ns);
|
||||
int (*destroy_ns)(struct mlx5_flow_root_namespace *ns);
|
||||
|
@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
|
||||
struct fs_node *iter = list_entry(start, struct fs_node, list);
|
||||
struct mlx5_flow_table *ft = NULL;
|
||||
|
||||
if (!root || root->type == FS_TYPE_PRIO_CHAINS)
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
list_for_each_advance_continue(iter, &root->children, reverse) {
|
||||
@ -905,20 +905,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
|
||||
return ft;
|
||||
}
|
||||
|
||||
/* If reverse is false then return the first flow table in next priority of
|
||||
* prio in the tree, else return the last flow table in the previous priority
|
||||
* of prio in the tree.
|
||||
*/
|
||||
static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse)
|
||||
static struct fs_node *find_prio_chains_parent(struct fs_node *parent,
|
||||
struct fs_node **child)
|
||||
{
|
||||
struct fs_node *node = NULL;
|
||||
|
||||
while (parent && parent->type != FS_TYPE_PRIO_CHAINS) {
|
||||
node = parent;
|
||||
parent = parent->parent;
|
||||
}
|
||||
|
||||
if (child)
|
||||
*child = node;
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
/* If reverse is false then return the first flow table next to the passed node
|
||||
* in the tree, else return the last flow table before the node in the tree.
|
||||
* If skip is true, skip the flow tables in the same prio_chains prio.
|
||||
*/
|
||||
static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse,
|
||||
bool skip)
|
||||
{
|
||||
struct fs_node *prio_chains_parent = NULL;
|
||||
struct mlx5_flow_table *ft = NULL;
|
||||
struct fs_node *curr_node;
|
||||
struct fs_node *parent;
|
||||
|
||||
parent = prio->node.parent;
|
||||
curr_node = &prio->node;
|
||||
if (skip)
|
||||
prio_chains_parent = find_prio_chains_parent(node, NULL);
|
||||
parent = node->parent;
|
||||
curr_node = node;
|
||||
while (!ft && parent) {
|
||||
ft = find_closest_ft_recursive(parent, &curr_node->list, reverse);
|
||||
if (parent != prio_chains_parent)
|
||||
ft = find_closest_ft_recursive(parent, &curr_node->list,
|
||||
reverse);
|
||||
curr_node = parent;
|
||||
parent = curr_node->parent;
|
||||
}
|
||||
@ -926,15 +948,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers
|
||||
}
|
||||
|
||||
/* Assuming all the tree is locked by mutex chain lock */
|
||||
static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio)
|
||||
static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node)
|
||||
{
|
||||
return find_closest_ft(prio, false);
|
||||
return find_closest_ft(node, false, true);
|
||||
}
|
||||
|
||||
/* Assuming all the tree is locked by mutex chain lock */
|
||||
static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
|
||||
static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node)
|
||||
{
|
||||
return find_closest_ft(prio, true);
|
||||
return find_closest_ft(node, true, true);
|
||||
}
|
||||
|
||||
static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
|
||||
@ -946,7 +968,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
|
||||
next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
|
||||
fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent);
|
||||
|
||||
return find_next_chained_ft(prio);
|
||||
return find_next_chained_ft(&prio->node);
|
||||
}
|
||||
|
||||
static int connect_fts_in_prio(struct mlx5_core_dev *dev,
|
||||
@ -970,21 +992,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node,
|
||||
struct fs_node *parent,
|
||||
struct fs_node **child,
|
||||
bool reverse)
|
||||
{
|
||||
struct mlx5_flow_table *ft;
|
||||
|
||||
ft = find_closest_ft(node, reverse, false);
|
||||
|
||||
if (ft && parent == find_prio_chains_parent(&ft->node, child))
|
||||
return ft;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Connect flow tables from previous priority of prio to ft */
|
||||
static int connect_prev_fts(struct mlx5_core_dev *dev,
|
||||
struct mlx5_flow_table *ft,
|
||||
struct fs_prio *prio)
|
||||
{
|
||||
struct fs_node *prio_parent, *parent = NULL, *child, *node;
|
||||
struct mlx5_flow_table *prev_ft;
|
||||
int err = 0;
|
||||
|
||||
prev_ft = find_prev_chained_ft(prio);
|
||||
if (prev_ft) {
|
||||
prio_parent = find_prio_chains_parent(&prio->node, &child);
|
||||
|
||||
/* return directly if not under the first sub ns of prio_chains prio */
|
||||
if (prio_parent && !list_is_first(&child->list, &prio_parent->children))
|
||||
return 0;
|
||||
|
||||
prev_ft = find_prev_chained_ft(&prio->node);
|
||||
while (prev_ft) {
|
||||
struct fs_prio *prev_prio;
|
||||
|
||||
fs_get_obj(prev_prio, prev_ft->node.parent);
|
||||
return connect_fts_in_prio(dev, prev_prio, ft);
|
||||
err = connect_fts_in_prio(dev, prev_prio, ft);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
if (!parent) {
|
||||
parent = find_prio_chains_parent(&prev_prio->node, &child);
|
||||
if (!parent)
|
||||
break;
|
||||
}
|
||||
|
||||
node = child;
|
||||
prev_ft = find_closet_ft_prio_chains(node, parent, &child, true);
|
||||
}
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
|
||||
@ -1123,7 +1179,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
next_ft = first_ft ? first_ft : find_next_chained_ft(prio);
|
||||
next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node);
|
||||
err = connect_fwd_rules(dev, ft, next_ft);
|
||||
if (err)
|
||||
return err;
|
||||
@ -1198,7 +1254,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
|
||||
|
||||
tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
|
||||
next_ft = unmanaged ? ft_attr->next_ft :
|
||||
find_next_chained_ft(fs_prio);
|
||||
find_next_chained_ft(&fs_prio->node);
|
||||
ft->def_miss_action = ns->def_miss_action;
|
||||
ft->ns = ns;
|
||||
err = root->cmds->create_flow_table(root, ft, ft_attr, next_ft);
|
||||
@ -2195,13 +2251,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);
|
||||
/* Assuming prio->node.children(flow tables) is sorted by level */
|
||||
static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)
|
||||
{
|
||||
struct fs_node *prio_parent, *child;
|
||||
struct fs_prio *prio;
|
||||
|
||||
fs_get_obj(prio, ft->node.parent);
|
||||
|
||||
if (!list_is_last(&ft->node.list, &prio->node.children))
|
||||
return list_next_entry(ft, node.list);
|
||||
return find_next_chained_ft(prio);
|
||||
|
||||
prio_parent = find_prio_chains_parent(&prio->node, &child);
|
||||
|
||||
if (prio_parent && list_is_first(&child->list, &prio_parent->children))
|
||||
return find_closest_ft(&prio->node, false, false);
|
||||
|
||||
return find_next_chained_ft(&prio->node);
|
||||
}
|
||||
|
||||
static int update_root_ft_destroy(struct mlx5_flow_table *ft)
|
||||
@ -3621,7 +3684,7 @@ void mlx5_destroy_match_definer(struct mlx5_core_dev *dev,
|
||||
|
||||
int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
|
||||
struct mlx5_flow_root_namespace *peer_ns,
|
||||
u8 peer_idx)
|
||||
u16 peer_vhca_id)
|
||||
{
|
||||
if (peer_ns && ns->mode != peer_ns->mode) {
|
||||
mlx5_core_err(ns->dev,
|
||||
@ -3629,7 +3692,7 @@ int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ns->cmds->set_peer(ns, peer_ns, peer_idx);
|
||||
return ns->cmds->set_peer(ns, peer_ns, peer_vhca_id);
|
||||
}
|
||||
|
||||
/* This function should be called only at init stage of the namespace.
|
||||
|
@ -303,7 +303,7 @@ const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void);
|
||||
|
||||
int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
|
||||
struct mlx5_flow_root_namespace *peer_ns,
|
||||
u8 peer_idx);
|
||||
u16 peer_vhca_id);
|
||||
|
||||
int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns,
|
||||
enum mlx5_flow_steering_mode mode);
|
||||
|
@ -178,7 +178,7 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains,
|
||||
if (!mlx5_chains_ignore_flow_level_supported(chains) ||
|
||||
(chain == 0 && prio == 1 && level == 0)) {
|
||||
ft_attr.level = chains->fs_base_level;
|
||||
ft_attr.prio = chains->fs_base_prio;
|
||||
ft_attr.prio = chains->fs_base_prio + prio - 1;
|
||||
ns = (chains->ns == MLX5_FLOW_NAMESPACE_FDB) ?
|
||||
mlx5_get_fdb_sub_ns(chains->dev, chain) :
|
||||
mlx5_get_flow_namespace(chains->dev, chains->ns);
|
||||
|
@ -1506,6 +1506,7 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)
|
||||
if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
|
||||
mlx5_core_warn(dev, "%s: interface is down, NOP\n",
|
||||
__func__);
|
||||
mlx5_devlink_params_unregister(priv_to_devlink(dev));
|
||||
mlx5_cleanup_once(dev);
|
||||
goto out;
|
||||
}
|
||||
|
@ -2079,7 +2079,7 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn,
|
||||
|
||||
peer_vport = vhca_id_valid && mlx5_core_is_pf(dmn->mdev) &&
|
||||
(vhca_id != dmn->info.caps.gvmi);
|
||||
vport_dmn = peer_vport ? dmn->peer_dmn[vhca_id] : dmn;
|
||||
vport_dmn = peer_vport ? xa_load(&dmn->peer_dmn_xa, vhca_id) : dmn;
|
||||
if (!vport_dmn) {
|
||||
mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n");
|
||||
return NULL;
|
||||
|
@ -564,11 +564,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
|
||||
|
||||
err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free_in;
|
||||
|
||||
*reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id);
|
||||
kvfree(in);
|
||||
|
||||
err_free_in:
|
||||
kvfree(in);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -475,6 +475,7 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type)
|
||||
mutex_init(&dmn->info.rx.mutex);
|
||||
mutex_init(&dmn->info.tx.mutex);
|
||||
xa_init(&dmn->definers_xa);
|
||||
xa_init(&dmn->peer_dmn_xa);
|
||||
|
||||
if (dr_domain_caps_init(mdev, dmn)) {
|
||||
mlx5dr_err(dmn, "Failed init domain, no caps\n");
|
||||
@ -507,6 +508,7 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type)
|
||||
uninit_caps:
|
||||
dr_domain_caps_uninit(dmn);
|
||||
def_xa_destroy:
|
||||
xa_destroy(&dmn->peer_dmn_xa);
|
||||
xa_destroy(&dmn->definers_xa);
|
||||
kfree(dmn);
|
||||
return NULL;
|
||||
@ -547,6 +549,7 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn)
|
||||
dr_domain_uninit_csum_recalc_fts(dmn);
|
||||
dr_domain_uninit_resources(dmn);
|
||||
dr_domain_caps_uninit(dmn);
|
||||
xa_destroy(&dmn->peer_dmn_xa);
|
||||
xa_destroy(&dmn->definers_xa);
|
||||
mutex_destroy(&dmn->info.tx.mutex);
|
||||
mutex_destroy(&dmn->info.rx.mutex);
|
||||
@ -556,17 +559,21 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn)
|
||||
|
||||
void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
|
||||
struct mlx5dr_domain *peer_dmn,
|
||||
u8 peer_idx)
|
||||
u16 peer_vhca_id)
|
||||
{
|
||||
struct mlx5dr_domain *peer;
|
||||
|
||||
mlx5dr_domain_lock(dmn);
|
||||
|
||||
if (dmn->peer_dmn[peer_idx])
|
||||
refcount_dec(&dmn->peer_dmn[peer_idx]->refcount);
|
||||
peer = xa_load(&dmn->peer_dmn_xa, peer_vhca_id);
|
||||
if (peer)
|
||||
refcount_dec(&peer->refcount);
|
||||
|
||||
dmn->peer_dmn[peer_idx] = peer_dmn;
|
||||
WARN_ON(xa_err(xa_store(&dmn->peer_dmn_xa, peer_vhca_id, peer_dmn, GFP_KERNEL)));
|
||||
|
||||
if (dmn->peer_dmn[peer_idx])
|
||||
refcount_inc(&dmn->peer_dmn[peer_idx]->refcount);
|
||||
peer = xa_load(&dmn->peer_dmn_xa, peer_vhca_id);
|
||||
if (peer)
|
||||
refcount_inc(&peer->refcount);
|
||||
|
||||
mlx5dr_domain_unlock(dmn);
|
||||
}
|
||||
|
@ -1652,17 +1652,18 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
|
||||
struct mlx5dr_domain *dmn = sb->dmn;
|
||||
struct mlx5dr_domain *vport_dmn;
|
||||
u8 *bit_mask = sb->bit_mask;
|
||||
struct mlx5dr_domain *peer;
|
||||
bool source_gvmi_set;
|
||||
|
||||
DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn);
|
||||
|
||||
if (sb->vhca_id_valid) {
|
||||
peer = xa_load(&dmn->peer_dmn_xa, id);
|
||||
/* Find port GVMI based on the eswitch_owner_vhca_id */
|
||||
if (id == dmn->info.caps.gvmi)
|
||||
vport_dmn = dmn;
|
||||
else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
|
||||
(id == dmn->peer_dmn[id]->info.caps.gvmi))
|
||||
vport_dmn = dmn->peer_dmn[id];
|
||||
else if (peer && (id == peer->info.caps.gvmi))
|
||||
vport_dmn = peer;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1984,16 +1984,17 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
|
||||
struct mlx5dr_domain *dmn = sb->dmn;
|
||||
struct mlx5dr_domain *vport_dmn;
|
||||
u8 *bit_mask = sb->bit_mask;
|
||||
struct mlx5dr_domain *peer;
|
||||
|
||||
DR_STE_SET_TAG(src_gvmi_qp_v1, tag, source_qp, misc, source_sqn);
|
||||
|
||||
if (sb->vhca_id_valid) {
|
||||
peer = xa_load(&dmn->peer_dmn_xa, id);
|
||||
/* Find port GVMI based on the eswitch_owner_vhca_id */
|
||||
if (id == dmn->info.caps.gvmi)
|
||||
vport_dmn = dmn;
|
||||
else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
|
||||
(id == dmn->peer_dmn[id]->info.caps.gvmi))
|
||||
vport_dmn = dmn->peer_dmn[id];
|
||||
else if (peer && (id == peer->info.caps.gvmi))
|
||||
vport_dmn = peer;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -935,7 +935,6 @@ struct mlx5dr_domain_info {
|
||||
};
|
||||
|
||||
struct mlx5dr_domain {
|
||||
struct mlx5dr_domain *peer_dmn[MLX5_MAX_PORTS];
|
||||
struct mlx5_core_dev *mdev;
|
||||
u32 pdn;
|
||||
struct mlx5_uars_page *uar;
|
||||
@ -956,6 +955,7 @@ struct mlx5dr_domain {
|
||||
struct list_head dbg_tbl_list;
|
||||
struct mlx5dr_dbg_dump_info dump_info;
|
||||
struct xarray definers_xa;
|
||||
struct xarray peer_dmn_xa;
|
||||
/* memory management statistics */
|
||||
u32 num_buddies[DR_ICM_TYPE_MAX];
|
||||
};
|
||||
|
@ -781,14 +781,14 @@ restore_fte:
|
||||
|
||||
static int mlx5_cmd_dr_set_peer(struct mlx5_flow_root_namespace *ns,
|
||||
struct mlx5_flow_root_namespace *peer_ns,
|
||||
u8 peer_idx)
|
||||
u16 peer_vhca_id)
|
||||
{
|
||||
struct mlx5dr_domain *peer_domain = NULL;
|
||||
|
||||
if (peer_ns)
|
||||
peer_domain = peer_ns->fs_dr_domain.dr_domain;
|
||||
mlx5dr_domain_set_peer(ns->fs_dr_domain.dr_domain,
|
||||
peer_domain, peer_idx);
|
||||
peer_domain, peer_vhca_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ int mlx5dr_domain_sync(struct mlx5dr_domain *domain, u32 flags);
|
||||
|
||||
void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
|
||||
struct mlx5dr_domain *peer_dmn,
|
||||
u8 peer_idx);
|
||||
u16 peer_vhca_id);
|
||||
|
||||
struct mlx5dr_table *
|
||||
mlx5dr_table_create(struct mlx5dr_domain *domain, u32 level, u32 flags,
|
||||
|
@ -193,6 +193,22 @@ void qed_hw_remove(struct qed_dev *cdev);
|
||||
*/
|
||||
struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn);
|
||||
|
||||
/**
|
||||
* qed_ptt_acquire_context(): Allocate a PTT window honoring the context
|
||||
* atomicy.
|
||||
*
|
||||
* @p_hwfn: HW device data.
|
||||
* @is_atomic: Hint from the caller - if the func can sleep or not.
|
||||
*
|
||||
* Context: The function should not sleep in case is_atomic == true.
|
||||
* Return: struct qed_ptt.
|
||||
*
|
||||
* Should be called at the entry point to the driver
|
||||
* (at the beginning of an exported function).
|
||||
*/
|
||||
struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn,
|
||||
bool is_atomic);
|
||||
|
||||
/**
|
||||
* qed_ptt_release(): Release PTT Window.
|
||||
*
|
||||
|
@ -693,13 +693,14 @@ static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn,
|
||||
}
|
||||
|
||||
static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn,
|
||||
struct qed_fcoe_stats *p_stats)
|
||||
struct qed_fcoe_stats *p_stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
struct qed_ptt *p_ptt;
|
||||
|
||||
memset(p_stats, 0, sizeof(*p_stats));
|
||||
|
||||
p_ptt = qed_ptt_acquire(p_hwfn);
|
||||
p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic);
|
||||
|
||||
if (!p_ptt) {
|
||||
DP_ERR(p_hwfn, "Failed to acquire ptt\n");
|
||||
@ -973,19 +974,27 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev,
|
||||
QED_SPQ_MODE_EBLOCK, NULL);
|
||||
}
|
||||
|
||||
static int qed_fcoe_stats_context(struct qed_dev *cdev,
|
||||
struct qed_fcoe_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic);
|
||||
}
|
||||
|
||||
static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats)
|
||||
{
|
||||
return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats);
|
||||
return qed_fcoe_stats_context(cdev, stats, false);
|
||||
}
|
||||
|
||||
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
|
||||
struct qed_mcp_fcoe_stats *stats)
|
||||
struct qed_mcp_fcoe_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
struct qed_fcoe_stats proto_stats;
|
||||
|
||||
/* Retrieve FW statistics */
|
||||
memset(&proto_stats, 0, sizeof(proto_stats));
|
||||
if (qed_fcoe_stats(cdev, &proto_stats)) {
|
||||
if (qed_fcoe_stats_context(cdev, &proto_stats, is_atomic)) {
|
||||
DP_VERBOSE(cdev, QED_MSG_STORAGE,
|
||||
"Failed to collect FCoE statistics\n");
|
||||
return;
|
||||
|
@ -28,8 +28,20 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn);
|
||||
void qed_fcoe_setup(struct qed_hwfn *p_hwfn);
|
||||
|
||||
void qed_fcoe_free(struct qed_hwfn *p_hwfn);
|
||||
/**
|
||||
* qed_get_protocol_stats_fcoe(): Fills provided statistics
|
||||
* struct with statistics.
|
||||
*
|
||||
* @cdev: Qed dev pointer.
|
||||
* @stats: Points to struct that will be filled with statistics.
|
||||
* @is_atomic: Hint from the caller - if the func can sleep or not.
|
||||
*
|
||||
* Context: The function should not sleep in case is_atomic == true.
|
||||
* Return: Void.
|
||||
*/
|
||||
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
|
||||
struct qed_mcp_fcoe_stats *stats);
|
||||
struct qed_mcp_fcoe_stats *stats,
|
||||
bool is_atomic);
|
||||
#else /* CONFIG_QED_FCOE */
|
||||
static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
|
||||
{
|
||||
@ -40,7 +52,8 @@ static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {}
|
||||
static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {}
|
||||
|
||||
static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
|
||||
struct qed_mcp_fcoe_stats *stats)
|
||||
struct qed_mcp_fcoe_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_QED_FCOE */
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "qed_reg_addr.h"
|
||||
#include "qed_sriov.h"
|
||||
|
||||
#define QED_BAR_ACQUIRE_TIMEOUT 1000
|
||||
#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT 1000
|
||||
#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP 1000
|
||||
#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT 100000
|
||||
#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY 10
|
||||
|
||||
/* Invalid values */
|
||||
#define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1))
|
||||
@ -84,12 +87,22 @@ void qed_ptt_pool_free(struct qed_hwfn *p_hwfn)
|
||||
}
|
||||
|
||||
struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn)
|
||||
{
|
||||
return qed_ptt_acquire_context(p_hwfn, false);
|
||||
}
|
||||
|
||||
struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, bool is_atomic)
|
||||
{
|
||||
struct qed_ptt *p_ptt;
|
||||
unsigned int i;
|
||||
unsigned int i, count;
|
||||
|
||||
if (is_atomic)
|
||||
count = QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT;
|
||||
else
|
||||
count = QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT;
|
||||
|
||||
/* Take the free PTT from the list */
|
||||
for (i = 0; i < QED_BAR_ACQUIRE_TIMEOUT; i++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
spin_lock_bh(&p_hwfn->p_ptt_pool->lock);
|
||||
|
||||
if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) {
|
||||
@ -105,7 +118,12 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn)
|
||||
}
|
||||
|
||||
spin_unlock_bh(&p_hwfn->p_ptt_pool->lock);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
if (is_atomic)
|
||||
udelay(QED_BAR_ACQUIRE_TIMEOUT_UDELAY);
|
||||
else
|
||||
usleep_range(QED_BAR_ACQUIRE_TIMEOUT_USLEEP,
|
||||
QED_BAR_ACQUIRE_TIMEOUT_USLEEP * 2);
|
||||
}
|
||||
|
||||
DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n");
|
||||
|
@ -999,13 +999,14 @@ static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn,
|
||||
}
|
||||
|
||||
static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn,
|
||||
struct qed_iscsi_stats *stats)
|
||||
struct qed_iscsi_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
struct qed_ptt *p_ptt;
|
||||
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
p_ptt = qed_ptt_acquire(p_hwfn);
|
||||
p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic);
|
||||
if (!p_ptt) {
|
||||
DP_ERR(p_hwfn, "Failed to acquire ptt\n");
|
||||
return -EAGAIN;
|
||||
@ -1336,9 +1337,16 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev,
|
||||
QED_SPQ_MODE_EBLOCK, NULL);
|
||||
}
|
||||
|
||||
static int qed_iscsi_stats_context(struct qed_dev *cdev,
|
||||
struct qed_iscsi_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic);
|
||||
}
|
||||
|
||||
static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats)
|
||||
{
|
||||
return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats);
|
||||
return qed_iscsi_stats_context(cdev, stats, false);
|
||||
}
|
||||
|
||||
static int qed_iscsi_change_mac(struct qed_dev *cdev,
|
||||
@ -1358,13 +1366,14 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev,
|
||||
}
|
||||
|
||||
void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
|
||||
struct qed_mcp_iscsi_stats *stats)
|
||||
struct qed_mcp_iscsi_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
struct qed_iscsi_stats proto_stats;
|
||||
|
||||
/* Retrieve FW statistics */
|
||||
memset(&proto_stats, 0, sizeof(proto_stats));
|
||||
if (qed_iscsi_stats(cdev, &proto_stats)) {
|
||||
if (qed_iscsi_stats_context(cdev, &proto_stats, is_atomic)) {
|
||||
DP_VERBOSE(cdev, QED_MSG_STORAGE,
|
||||
"Failed to collect ISCSI statistics\n");
|
||||
return;
|
||||
|
@ -39,11 +39,14 @@ void qed_iscsi_free(struct qed_hwfn *p_hwfn);
|
||||
*
|
||||
* @cdev: Qed dev pointer.
|
||||
* @stats: Points to struct that will be filled with statistics.
|
||||
* @is_atomic: Hint from the caller - if the func can sleep or not.
|
||||
*
|
||||
* Context: The function should not sleep in case is_atomic == true.
|
||||
* Return: Void.
|
||||
*/
|
||||
void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
|
||||
struct qed_mcp_iscsi_stats *stats);
|
||||
struct qed_mcp_iscsi_stats *stats,
|
||||
bool is_atomic);
|
||||
#else /* IS_ENABLED(CONFIG_QED_ISCSI) */
|
||||
static inline int qed_iscsi_alloc(struct qed_hwfn *p_hwfn)
|
||||
{
|
||||
@ -56,7 +59,8 @@ static inline void qed_iscsi_free(struct qed_hwfn *p_hwfn) {}
|
||||
|
||||
static inline void
|
||||
qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
|
||||
struct qed_mcp_iscsi_stats *stats) {}
|
||||
struct qed_mcp_iscsi_stats *stats,
|
||||
bool is_atomic) {}
|
||||
#endif /* IS_ENABLED(CONFIG_QED_ISCSI) */
|
||||
|
||||
#endif
|
||||
|
@ -1863,7 +1863,8 @@ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn,
|
||||
}
|
||||
|
||||
static void _qed_get_vport_stats(struct qed_dev *cdev,
|
||||
struct qed_eth_stats *stats)
|
||||
struct qed_eth_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
u8 fw_vport = 0;
|
||||
int i;
|
||||
@ -1872,10 +1873,11 @@ static void _qed_get_vport_stats(struct qed_dev *cdev,
|
||||
|
||||
for_each_hwfn(cdev, i) {
|
||||
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
|
||||
struct qed_ptt *p_ptt = IS_PF(cdev) ? qed_ptt_acquire(p_hwfn)
|
||||
: NULL;
|
||||
struct qed_ptt *p_ptt;
|
||||
bool b_get_port_stats;
|
||||
|
||||
p_ptt = IS_PF(cdev) ? qed_ptt_acquire_context(p_hwfn, is_atomic)
|
||||
: NULL;
|
||||
if (IS_PF(cdev)) {
|
||||
/* The main vport index is relative first */
|
||||
if (qed_fw_vport(p_hwfn, 0, &fw_vport)) {
|
||||
@ -1900,6 +1902,13 @@ out:
|
||||
}
|
||||
|
||||
void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats)
|
||||
{
|
||||
qed_get_vport_stats_context(cdev, stats, false);
|
||||
}
|
||||
|
||||
void qed_get_vport_stats_context(struct qed_dev *cdev,
|
||||
struct qed_eth_stats *stats,
|
||||
bool is_atomic)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
@ -1908,7 +1917,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats)
|
||||
return;
|
||||
}
|
||||
|
||||
_qed_get_vport_stats(cdev, stats);
|
||||
_qed_get_vport_stats(cdev, stats, is_atomic);
|
||||
|
||||
if (!cdev->reset_stats)
|
||||
return;
|
||||
@ -1960,7 +1969,7 @@ void qed_reset_vport_stats(struct qed_dev *cdev)
|
||||
if (!cdev->reset_stats) {
|
||||
DP_INFO(cdev, "Reset stats not allocated\n");
|
||||
} else {
|
||||
_qed_get_vport_stats(cdev, cdev->reset_stats);
|
||||
_qed_get_vport_stats(cdev, cdev->reset_stats, false);
|
||||
cdev->reset_stats->common.link_change_count = 0;
|
||||
}
|
||||
}
|
||||
|
@ -249,8 +249,32 @@ qed_sp_eth_rx_queues_update(struct qed_hwfn *p_hwfn,
|
||||
enum spq_mode comp_mode,
|
||||
struct qed_spq_comp_cb *p_comp_data);
|
||||
|
||||
/**
|
||||
* qed_get_vport_stats(): Fills provided statistics
|
||||
* struct with statistics.
|
||||
*
|
||||
* @cdev: Qed dev pointer.
|
||||
* @stats: Points to struct that will be filled with statistics.
|
||||
*
|
||||
* Return: Void.
|
||||
*/
|
||||
void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats);
|
||||
|
||||
/**
|
||||
* qed_get_vport_stats_context(): Fills provided statistics
|
||||
* struct with statistics.
|
||||
*
|
||||
* @cdev: Qed dev pointer.
|
||||
* @stats: Points to struct that will be filled with statistics.
|
||||
* @is_atomic: Hint from the caller - if the func can sleep or not.
|
||||
*
|
||||
* Context: The function should not sleep in case is_atomic == true.
|
||||
* Return: Void.
|
||||
*/
|
||||
void qed_get_vport_stats_context(struct qed_dev *cdev,
|
||||
struct qed_eth_stats *stats,
|
||||
bool is_atomic);
|
||||
|
||||
void qed_reset_vport_stats(struct qed_dev *cdev);
|
||||
|
||||
/**
|
||||
|
@ -3092,7 +3092,7 @@ void qed_get_protocol_stats(struct qed_dev *cdev,
|
||||
|
||||
switch (type) {
|
||||
case QED_MCP_LAN_STATS:
|
||||
qed_get_vport_stats(cdev, ð_stats);
|
||||
qed_get_vport_stats_context(cdev, ð_stats, true);
|
||||
stats->lan_stats.ucast_rx_pkts =
|
||||
eth_stats.common.rx_ucast_pkts;
|
||||
stats->lan_stats.ucast_tx_pkts =
|
||||
@ -3100,10 +3100,10 @@ void qed_get_protocol_stats(struct qed_dev *cdev,
|
||||
stats->lan_stats.fcs_err = -1;
|
||||
break;
|
||||
case QED_MCP_FCOE_STATS:
|
||||
qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats);
|
||||
qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats, true);
|
||||
break;
|
||||
case QED_MCP_ISCSI_STATS:
|
||||
qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats);
|
||||
qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats, true);
|
||||
break;
|
||||
default:
|
||||
DP_VERBOSE(cdev, QED_MSG_SP,
|
||||
|
@ -40,15 +40,16 @@
|
||||
*/
|
||||
struct ef4_loopback_payload {
|
||||
char pad[2]; /* Ensures ip is 4-byte aligned */
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
struct_group_attr(packet, __packed,
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
);
|
||||
} __packed __aligned(4);
|
||||
#define EF4_LOOPBACK_PAYLOAD_LEN (sizeof(struct ef4_loopback_payload) - \
|
||||
offsetof(struct ef4_loopback_payload, \
|
||||
header))
|
||||
#define EF4_LOOPBACK_PAYLOAD_LEN \
|
||||
sizeof_field(struct ef4_loopback_payload, packet)
|
||||
|
||||
/* Loopback test source MAC address */
|
||||
static const u8 payload_source[ETH_ALEN] __aligned(2) = {
|
||||
@ -299,7 +300,7 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx,
|
||||
|
||||
payload = &state->payload;
|
||||
|
||||
memcpy(&received.header, buf_ptr,
|
||||
memcpy(&received.packet, buf_ptr,
|
||||
min_t(int, pkt_len, EF4_LOOPBACK_PAYLOAD_LEN));
|
||||
received.ip.saddr = payload->ip.saddr;
|
||||
if (state->offload_csum)
|
||||
@ -370,7 +371,7 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx,
|
||||
buf_ptr, pkt_len, 0);
|
||||
netif_err(efx, drv, efx->net_dev, "expected packet:\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
|
||||
&state->payload.header, EF4_LOOPBACK_PAYLOAD_LEN,
|
||||
&state->payload.packet, EF4_LOOPBACK_PAYLOAD_LEN,
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
@ -440,6 +441,8 @@ static int ef4_begin_loopback(struct ef4_tx_queue *tx_queue)
|
||||
payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2));
|
||||
/* Strip off the leading padding */
|
||||
skb_pull(skb, offsetof(struct ef4_loopback_payload, header));
|
||||
/* Strip off the trailing padding */
|
||||
skb_trim(skb, EF4_LOOPBACK_PAYLOAD_LEN);
|
||||
|
||||
/* Ensure everything we've written is visible to the
|
||||
* interrupt handler. */
|
||||
|
@ -43,15 +43,16 @@
|
||||
*/
|
||||
struct efx_loopback_payload {
|
||||
char pad[2]; /* Ensures ip is 4-byte aligned */
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
struct_group_attr(packet, __packed,
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
);
|
||||
} __packed __aligned(4);
|
||||
#define EFX_LOOPBACK_PAYLOAD_LEN (sizeof(struct efx_loopback_payload) - \
|
||||
offsetof(struct efx_loopback_payload, \
|
||||
header))
|
||||
#define EFX_LOOPBACK_PAYLOAD_LEN \
|
||||
sizeof_field(struct efx_loopback_payload, packet)
|
||||
|
||||
/* Loopback test source MAC address */
|
||||
static const u8 payload_source[ETH_ALEN] __aligned(2) = {
|
||||
@ -297,7 +298,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
|
||||
|
||||
payload = &state->payload;
|
||||
|
||||
memcpy(&received.header, buf_ptr,
|
||||
memcpy(&received.packet, buf_ptr,
|
||||
min_t(int, pkt_len, EFX_LOOPBACK_PAYLOAD_LEN));
|
||||
received.ip.saddr = payload->ip.saddr;
|
||||
if (state->offload_csum)
|
||||
@ -368,7 +369,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
|
||||
buf_ptr, pkt_len, 0);
|
||||
netif_err(efx, drv, efx->net_dev, "expected packet:\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
|
||||
&state->payload.header, EFX_LOOPBACK_PAYLOAD_LEN,
|
||||
&state->payload.packet, EFX_LOOPBACK_PAYLOAD_LEN,
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
@ -438,6 +439,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
|
||||
payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2));
|
||||
/* Strip off the leading padding */
|
||||
skb_pull(skb, offsetof(struct efx_loopback_payload, header));
|
||||
/* Strip off the trailing padding */
|
||||
skb_trim(skb, EFX_LOOPBACK_PAYLOAD_LEN);
|
||||
|
||||
/* Ensure everything we've written is visible to the
|
||||
* interrupt handler. */
|
||||
|
@ -43,15 +43,16 @@
|
||||
*/
|
||||
struct efx_loopback_payload {
|
||||
char pad[2]; /* Ensures ip is 4-byte aligned */
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
struct_group_attr(packet, __packed,
|
||||
struct ethhdr header;
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
__be16 iteration;
|
||||
char msg[64];
|
||||
);
|
||||
} __packed __aligned(4);
|
||||
#define EFX_LOOPBACK_PAYLOAD_LEN (sizeof(struct efx_loopback_payload) - \
|
||||
offsetof(struct efx_loopback_payload, \
|
||||
header))
|
||||
#define EFX_LOOPBACK_PAYLOAD_LEN \
|
||||
sizeof_field(struct efx_loopback_payload, packet)
|
||||
|
||||
/* Loopback test source MAC address */
|
||||
static const u8 payload_source[ETH_ALEN] __aligned(2) = {
|
||||
@ -297,7 +298,7 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx,
|
||||
|
||||
payload = &state->payload;
|
||||
|
||||
memcpy(&received.header, buf_ptr,
|
||||
memcpy(&received.packet, buf_ptr,
|
||||
min_t(int, pkt_len, EFX_LOOPBACK_PAYLOAD_LEN));
|
||||
received.ip.saddr = payload->ip.saddr;
|
||||
if (state->offload_csum)
|
||||
@ -368,7 +369,7 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx,
|
||||
buf_ptr, pkt_len, 0);
|
||||
netif_err(efx, drv, efx->net_dev, "expected packet:\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
|
||||
&state->payload.header, EFX_LOOPBACK_PAYLOAD_LEN,
|
||||
&state->payload.packet, EFX_LOOPBACK_PAYLOAD_LEN,
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
@ -438,6 +439,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
|
||||
payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2));
|
||||
/* Strip off the leading padding */
|
||||
skb_pull(skb, offsetof(struct efx_loopback_payload, header));
|
||||
/* Strip off the trailing padding */
|
||||
skb_trim(skb, EFX_LOOPBACK_PAYLOAD_LEN);
|
||||
|
||||
/* Ensure everything we've written is visible to the
|
||||
* interrupt handler. */
|
||||
|
@ -1851,6 +1851,17 @@ static int netsec_of_probe(struct platform_device *pdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* SynQuacer is physically configured with TX and RX delays
|
||||
* but the standard firmware claimed otherwise for a long
|
||||
* time, ignore it.
|
||||
*/
|
||||
if (of_machine_is_compatible("socionext,developer-box") &&
|
||||
priv->phy_interface != PHY_INTERFACE_MODE_RGMII_ID) {
|
||||
dev_warn(&pdev->dev, "Outdated firmware reports incorrect PHY mode, overriding\n");
|
||||
priv->phy_interface = PHY_INTERFACE_MODE_RGMII_ID;
|
||||
}
|
||||
|
||||
priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
|
||||
if (!priv->phy_np) {
|
||||
dev_err(&pdev->dev, "missing required property 'phy-handle'\n");
|
||||
|
@ -234,7 +234,8 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
|
||||
res.addr = mgbe->regs;
|
||||
res.irq = irq;
|
||||
|
||||
mgbe->clks = devm_kzalloc(&pdev->dev, sizeof(*mgbe->clks), GFP_KERNEL);
|
||||
mgbe->clks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(mgbe_clks),
|
||||
sizeof(*mgbe->clks), GFP_KERNEL);
|
||||
if (!mgbe->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1567,12 +1567,16 @@ static int temac_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Error handle returned DMA RX and TX interrupts */
|
||||
if (lp->rx_irq < 0)
|
||||
return dev_err_probe(&pdev->dev, lp->rx_irq,
|
||||
if (lp->rx_irq <= 0) {
|
||||
rc = lp->rx_irq ?: -EINVAL;
|
||||
return dev_err_probe(&pdev->dev, rc,
|
||||
"could not get DMA RX irq\n");
|
||||
if (lp->tx_irq < 0)
|
||||
return dev_err_probe(&pdev->dev, lp->tx_irq,
|
||||
}
|
||||
if (lp->tx_irq <= 0) {
|
||||
rc = lp->tx_irq ?: -EINVAL;
|
||||
return dev_err_probe(&pdev->dev, rc,
|
||||
"could not get DMA TX irq\n");
|
||||
}
|
||||
|
||||
if (temac_np) {
|
||||
/* Retrieve the MAC address */
|
||||
|
@ -534,7 +534,7 @@ static int tap_open(struct inode *inode, struct file *file)
|
||||
q->sock.state = SS_CONNECTED;
|
||||
q->sock.file = file;
|
||||
q->sock.ops = &tap_socket_ops;
|
||||
sock_init_data_uid(&q->sock, &q->sk, inode->i_uid);
|
||||
sock_init_data_uid(&q->sock, &q->sk, current_fsuid());
|
||||
q->sk.sk_write_space = tap_sock_write_space;
|
||||
q->sk.sk_destruct = tap_sock_destruct;
|
||||
q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
|
||||
|
@ -3469,7 +3469,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
|
||||
tfile->socket.file = file;
|
||||
tfile->socket.ops = &tun_socket_ops;
|
||||
|
||||
sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid);
|
||||
sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid());
|
||||
|
||||
tfile->sk.sk_write_space = tun_sock_write_space;
|
||||
tfile->sk.sk_sndbuf = INT_MAX;
|
||||
|
@ -618,9 +618,23 @@ static const struct usb_device_id products[] = {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8005, /* A-300 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8006, /* B-500/SL-5600 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8006, /* B-500/SL-5600 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
@ -628,6 +642,13 @@ static const struct usb_device_id products[] = {
|
||||
.idProduct = 0x8007, /* C-700 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8007, /* C-700 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
|
@ -4224,8 +4224,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
set_bit(EVENT_DEV_DISCONNECT, &dev->flags);
|
||||
|
||||
netif_napi_del(&dev->napi);
|
||||
|
||||
udev = interface_to_usbdev(intf);
|
||||
@ -4233,6 +4231,8 @@ static void lan78xx_disconnect(struct usb_interface *intf)
|
||||
|
||||
unregister_netdev(net);
|
||||
|
||||
timer_shutdown_sync(&dev->stat_monitor);
|
||||
set_bit(EVENT_DEV_DISCONNECT, &dev->flags);
|
||||
cancel_delayed_work_sync(&dev->wq);
|
||||
|
||||
phydev = net->phydev;
|
||||
@ -4247,9 +4247,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)
|
||||
|
||||
usb_scuttle_anchored_urbs(&dev->deferred);
|
||||
|
||||
if (timer_pending(&dev->stat_monitor))
|
||||
del_timer_sync(&dev->stat_monitor);
|
||||
|
||||
lan78xx_unbind(dev, intf);
|
||||
|
||||
lan78xx_free_tx_resources(dev);
|
||||
|
@ -1423,6 +1423,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */
|
||||
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */
|
||||
{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */
|
||||
{QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */
|
||||
{QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
|
||||
|
@ -289,9 +289,23 @@ static const struct usb_device_id products [] = {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8005, /* A-300 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = (unsigned long)&bogus_mdlm_info,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8006, /* B-500/SL-5600 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = ZAURUS_PXA_INFO,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8006, /* B-500/SL-5600 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = (unsigned long)&bogus_mdlm_info,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
@ -299,6 +313,13 @@ static const struct usb_device_id products [] = {
|
||||
.idProduct = 0x8007, /* C-700 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = ZAURUS_PXA_INFO,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x8007, /* C-700 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = (unsigned long)&bogus_mdlm_info,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
|
@ -376,7 +376,6 @@ static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
|
||||
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
|
||||
if (!irq_grp->napi_enabled) {
|
||||
dev_set_threaded(&irq_grp->napi_ndev, true);
|
||||
napi_enable(&irq_grp->napi);
|
||||
irq_grp->napi_enabled = true;
|
||||
}
|
||||
|
@ -466,7 +466,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
|
||||
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
|
||||
if (!irq_grp->napi_enabled) {
|
||||
dev_set_threaded(&irq_grp->napi_ndev, true);
|
||||
napi_enable(&irq_grp->napi);
|
||||
irq_grp->napi_enabled = true;
|
||||
}
|
||||
|
@ -36,11 +36,6 @@ ath6kl_core-y += wmi.o
|
||||
ath6kl_core-y += core.o
|
||||
ath6kl_core-y += recovery.o
|
||||
|
||||
# FIXME: temporarily silence -Wdangling-pointer on non W=1+ builds
|
||||
ifndef KBUILD_EXTRA_WARN
|
||||
CFLAGS_htc_mbox.o += $(call cc-disable-warning, dangling-pointer)
|
||||
endif
|
||||
|
||||
ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o
|
||||
|
||||
|
@ -398,7 +398,12 @@ struct brcmf_scan_params_le {
|
||||
* fixed parameter portion is assumed, otherwise
|
||||
* ssid in the fixed portion is ignored
|
||||
*/
|
||||
__le16 channel_list[1]; /* list of chanspecs */
|
||||
union {
|
||||
__le16 padding; /* Reserve space for at least 1 entry for abort
|
||||
* which uses an on stack brcmf_scan_params_le
|
||||
*/
|
||||
DECLARE_FLEX_ARRAY(__le16, channel_list); /* chanspecs */
|
||||
};
|
||||
};
|
||||
|
||||
struct brcmf_scan_params_v2_le {
|
||||
|
@ -577,7 +577,7 @@ struct tx_msg {
|
||||
struct tib_structure tib;
|
||||
struct phy_header phy;
|
||||
struct mac_header mac;
|
||||
UCHAR var[1];
|
||||
UCHAR var[];
|
||||
};
|
||||
|
||||
/****** ECF Receive Control Structure (RCS) Area at Shared RAM offset 0x0800 */
|
||||
|
@ -128,12 +128,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
|
||||
case MT_EE_5GHZ:
|
||||
dev->mphy.cap.has_5ghz = true;
|
||||
break;
|
||||
case MT_EE_2GHZ:
|
||||
dev->mphy.cap.has_2ghz = true;
|
||||
break;
|
||||
case MT_EE_DBDC:
|
||||
dev->dbdc_support = true;
|
||||
fallthrough;
|
||||
case MT_EE_2GHZ:
|
||||
dev->mphy.cap.has_2ghz = true;
|
||||
break;
|
||||
default:
|
||||
dev->mphy.cap.has_2ghz = true;
|
||||
dev->mphy.cap.has_5ghz = true;
|
||||
|
@ -716,7 +716,6 @@ struct qeth_card_info {
|
||||
u16 chid;
|
||||
u8 ids_valid:1; /* cssid,iid,chid */
|
||||
u8 dev_addr_is_registered:1;
|
||||
u8 open_when_online:1;
|
||||
u8 promisc_mode:1;
|
||||
u8 use_v1_blkt:1;
|
||||
u8 is_vm_nic:1;
|
||||
|
@ -5373,8 +5373,6 @@ int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
|
||||
qeth_clear_ipacmd_list(card);
|
||||
|
||||
rtnl_lock();
|
||||
card->info.open_when_online = card->dev->flags & IFF_UP;
|
||||
dev_close(card->dev);
|
||||
netif_device_detach(card->dev);
|
||||
netif_carrier_off(card->dev);
|
||||
rtnl_unlock();
|
||||
|
@ -2388,9 +2388,12 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok)
|
||||
qeth_enable_hw_features(dev);
|
||||
qeth_l2_enable_brport_features(card);
|
||||
|
||||
if (card->info.open_when_online) {
|
||||
card->info.open_when_online = 0;
|
||||
dev_open(dev, NULL);
|
||||
if (netif_running(dev)) {
|
||||
local_bh_disable();
|
||||
napi_schedule(&card->napi);
|
||||
/* kick-start the NAPI softirq: */
|
||||
local_bh_enable();
|
||||
qeth_l2_set_rx_mode(dev);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
@ -2018,9 +2018,11 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok)
|
||||
netif_device_attach(dev);
|
||||
qeth_enable_hw_features(dev);
|
||||
|
||||
if (card->info.open_when_online) {
|
||||
card->info.open_when_online = 0;
|
||||
dev_open(dev, NULL);
|
||||
if (netif_running(dev)) {
|
||||
local_bh_disable();
|
||||
napi_schedule(&card->napi);
|
||||
/* kick-start the NAPI softirq: */
|
||||
local_bh_enable();
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
@ -452,6 +452,49 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb,
|
||||
gro_normal_list(napi);
|
||||
}
|
||||
|
||||
/* This function is the alternative of 'inet_iif' and 'inet_sdif'
|
||||
* functions in case we can not rely on fields of IPCB.
|
||||
*
|
||||
* The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized.
|
||||
* The caller must hold the RCU read lock.
|
||||
*/
|
||||
static inline void inet_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif)
|
||||
{
|
||||
*iif = inet_iif(skb) ?: skb->dev->ifindex;
|
||||
*sdif = 0;
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
|
||||
if (netif_is_l3_slave(skb->dev)) {
|
||||
struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev);
|
||||
|
||||
*sdif = *iif;
|
||||
*iif = master ? master->ifindex : 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function is the alternative of 'inet6_iif' and 'inet6_sdif'
|
||||
* functions in case we can not rely on fields of IP6CB.
|
||||
*
|
||||
* The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized.
|
||||
* The caller must hold the RCU read lock.
|
||||
*/
|
||||
static inline void inet6_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif)
|
||||
{
|
||||
/* using skb->dev->ifindex because skb_dst(skb) is not initialized */
|
||||
*iif = skb->dev->ifindex;
|
||||
*sdif = 0;
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
|
||||
if (netif_is_l3_slave(skb->dev)) {
|
||||
struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev);
|
||||
|
||||
*sdif = *iif;
|
||||
*iif = master ? master->ifindex : 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern struct list_head offload_base;
|
||||
|
||||
#endif /* _NET_IPV6_GRO_H */
|
||||
|
@ -107,11 +107,12 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
|
||||
|
||||
static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
if (!sk->sk_mark &&
|
||||
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
|
||||
u32 mark = READ_ONCE(sk->sk_mark);
|
||||
|
||||
if (!mark && READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
|
||||
return skb->mark;
|
||||
|
||||
return sk->sk_mark;
|
||||
return mark;
|
||||
}
|
||||
|
||||
static inline int inet_request_bound_dev_if(const struct sock *sk,
|
||||
|
@ -93,7 +93,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
|
||||
{
|
||||
ipcm_init(ipcm);
|
||||
|
||||
ipcm->sockc.mark = inet->sk.sk_mark;
|
||||
ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark);
|
||||
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
|
||||
ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if);
|
||||
ipcm->addr = inet->inet_saddr;
|
||||
|
@ -168,7 +168,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
|
||||
__be16 dport, __be16 sport,
|
||||
__u8 proto, __u8 tos, int oif)
|
||||
{
|
||||
flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
|
||||
flowi4_init_output(fl4, oif, sk ? READ_ONCE(sk->sk_mark) : 0, tos,
|
||||
RT_SCOPE_UNIVERSE, proto,
|
||||
sk ? inet_sk_flowi_flags(sk) : 0,
|
||||
daddr, saddr, dport, sport, sock_net_uid(net, sk));
|
||||
@ -301,7 +301,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst,
|
||||
if (inet_sk(sk)->transparent)
|
||||
flow_flags |= FLOWI_FLAG_ANYSRC;
|
||||
|
||||
flowi4_init_output(fl4, oif, sk->sk_mark, ip_sock_rt_tos(sk),
|
||||
flowi4_init_output(fl4, oif, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk),
|
||||
ip_sock_rt_scope(sk), protocol, flow_flags, dst,
|
||||
src, dport, sport, sk->sk_uid);
|
||||
}
|
||||
|
@ -556,12 +556,12 @@ static inline void vxlan_flag_attr_error(int attrtype,
|
||||
}
|
||||
|
||||
static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh,
|
||||
int hash,
|
||||
u32 hash,
|
||||
struct vxlan_rdst *rdst)
|
||||
{
|
||||
struct fib_nh_common *nhc;
|
||||
|
||||
nhc = nexthop_path_fdb_result(nh, hash);
|
||||
nhc = nexthop_path_fdb_result(nh, hash >> 1);
|
||||
if (unlikely(!nhc))
|
||||
return false;
|
||||
|
||||
|
@ -710,9 +710,11 @@ enum {
|
||||
TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
|
||||
TCA_FLOWER_KEY_CFM_MD_LEVEL,
|
||||
TCA_FLOWER_KEY_CFM_OPCODE,
|
||||
TCA_FLOWER_KEY_CFM_OPT_MAX,
|
||||
__TCA_FLOWER_KEY_CFM_OPT_MAX,
|
||||
};
|
||||
|
||||
#define TCA_FLOWER_KEY_CFM_OPT_MAX (__TCA_FLOWER_KEY_CFM_OPT_MAX - 1)
|
||||
|
||||
#define TCA_FLOWER_MASK_FLAGS_RANGE (1 << 0) /* Range-based match */
|
||||
|
||||
/* Match-all classifier */
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/completion.h>
|
||||
#include <trace/events/xdp.h>
|
||||
#include <linux/btf_ids.h>
|
||||
|
||||
@ -73,6 +74,7 @@ struct bpf_cpu_map_entry {
|
||||
struct rcu_head rcu;
|
||||
|
||||
struct work_struct kthread_stop_wq;
|
||||
struct completion kthread_running;
|
||||
};
|
||||
|
||||
struct bpf_cpu_map {
|
||||
@ -129,11 +131,17 @@ static void __cpu_map_ring_cleanup(struct ptr_ring *ring)
|
||||
* invoked cpu_map_kthread_stop(). Catch any broken behaviour
|
||||
* gracefully and warn once.
|
||||
*/
|
||||
struct xdp_frame *xdpf;
|
||||
void *ptr;
|
||||
|
||||
while ((xdpf = ptr_ring_consume(ring)))
|
||||
if (WARN_ON_ONCE(xdpf))
|
||||
xdp_return_frame(xdpf);
|
||||
while ((ptr = ptr_ring_consume(ring))) {
|
||||
WARN_ON_ONCE(1);
|
||||
if (unlikely(__ptr_test_bit(0, &ptr))) {
|
||||
__ptr_clear_bit(0, &ptr);
|
||||
kfree_skb(ptr);
|
||||
continue;
|
||||
}
|
||||
xdp_return_frame(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
|
||||
@ -153,7 +161,6 @@ static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
|
||||
static void cpu_map_kthread_stop(struct work_struct *work)
|
||||
{
|
||||
struct bpf_cpu_map_entry *rcpu;
|
||||
int err;
|
||||
|
||||
rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq);
|
||||
|
||||
@ -163,14 +170,7 @@ static void cpu_map_kthread_stop(struct work_struct *work)
|
||||
rcu_barrier();
|
||||
|
||||
/* kthread_stop will wake_up_process and wait for it to complete */
|
||||
err = kthread_stop(rcpu->kthread);
|
||||
if (err) {
|
||||
/* kthread_stop may be called before cpu_map_kthread_run
|
||||
* is executed, so we need to release the memory related
|
||||
* to rcpu.
|
||||
*/
|
||||
put_cpu_map_entry(rcpu);
|
||||
}
|
||||
kthread_stop(rcpu->kthread);
|
||||
}
|
||||
|
||||
static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu,
|
||||
@ -298,11 +298,11 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,
|
||||
return nframes;
|
||||
}
|
||||
|
||||
|
||||
static int cpu_map_kthread_run(void *data)
|
||||
{
|
||||
struct bpf_cpu_map_entry *rcpu = data;
|
||||
|
||||
complete(&rcpu->kthread_running);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
/* When kthread gives stop order, then rcpu have been disconnected
|
||||
@ -467,6 +467,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
|
||||
goto free_ptr_ring;
|
||||
|
||||
/* Setup kthread */
|
||||
init_completion(&rcpu->kthread_running);
|
||||
rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,
|
||||
"cpumap/%d/map:%d", cpu,
|
||||
map->id);
|
||||
@ -480,6 +481,12 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
|
||||
kthread_bind(rcpu->kthread, cpu);
|
||||
wake_up_process(rcpu->kthread);
|
||||
|
||||
/* Make sure kthread has been running, so kthread_stop() will not
|
||||
* stop the kthread prematurely and all pending frames or skbs
|
||||
* will be handled by the kthread before kthread_stop() returns.
|
||||
*/
|
||||
wait_for_completion(&rcpu->kthread_running);
|
||||
|
||||
return rcpu;
|
||||
|
||||
free_prog:
|
||||
|
@ -661,8 +661,7 @@ static DEFINE_PER_CPU(int, bpf_trace_nest_level);
|
||||
BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
||||
u64, flags, void *, data, u64, size)
|
||||
{
|
||||
struct bpf_trace_sample_data *sds = this_cpu_ptr(&bpf_trace_sds);
|
||||
int nest_level = this_cpu_inc_return(bpf_trace_nest_level);
|
||||
struct bpf_trace_sample_data *sds;
|
||||
struct perf_raw_record raw = {
|
||||
.frag = {
|
||||
.size = size,
|
||||
@ -670,7 +669,11 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
||||
},
|
||||
};
|
||||
struct perf_sample_data *sd;
|
||||
int err;
|
||||
int nest_level, err;
|
||||
|
||||
preempt_disable();
|
||||
sds = this_cpu_ptr(&bpf_trace_sds);
|
||||
nest_level = this_cpu_inc_return(bpf_trace_nest_level);
|
||||
|
||||
if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(sds->sds))) {
|
||||
err = -EBUSY;
|
||||
@ -688,9 +691,9 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
||||
perf_sample_save_raw_data(sd, &raw);
|
||||
|
||||
err = __bpf_perf_event_output(regs, map, flags, sd);
|
||||
|
||||
out:
|
||||
this_cpu_dec(bpf_trace_nest_level);
|
||||
preempt_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -715,7 +718,6 @@ static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_misc_sds);
|
||||
u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
|
||||
void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
|
||||
{
|
||||
int nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
|
||||
struct perf_raw_frag frag = {
|
||||
.copy = ctx_copy,
|
||||
.size = ctx_size,
|
||||
@ -732,8 +734,12 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
|
||||
};
|
||||
struct perf_sample_data *sd;
|
||||
struct pt_regs *regs;
|
||||
int nest_level;
|
||||
u64 ret;
|
||||
|
||||
preempt_disable();
|
||||
nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
|
||||
|
||||
if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
@ -748,6 +754,7 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
|
||||
ret = __bpf_perf_event_output(regs, map, flags, sd);
|
||||
out:
|
||||
this_cpu_dec(bpf_event_output_nest_level);
|
||||
preempt_enable();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -865,7 +865,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||
|
||||
skb->dev = dev;
|
||||
skb->priority = sk->sk_priority;
|
||||
skb->mark = sk->sk_mark;
|
||||
skb->mark = READ_ONCE(sk->sk_mark);
|
||||
skb->tstamp = sockc.transmit_time;
|
||||
|
||||
skb_setup_tx_timestamp(skb, sockc.tsflags);
|
||||
|
@ -496,8 +496,11 @@ bpf_sk_storage_diag_alloc(const struct nlattr *nla_stgs)
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
nla_for_each_nested(nla, nla_stgs, rem) {
|
||||
if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD)
|
||||
if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD) {
|
||||
if (nla_len(nla) != sizeof(u32))
|
||||
return ERR_PTR(-EINVAL);
|
||||
nr_maps++;
|
||||
}
|
||||
}
|
||||
|
||||
diag = kzalloc(struct_size(diag, maps, nr_maps), GFP_KERNEL);
|
||||
|
@ -5140,13 +5140,17 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
||||
if (br_spec) {
|
||||
nla_for_each_nested(attr, br_spec, rem) {
|
||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) {
|
||||
if (nla_len(attr) < sizeof(flags))
|
||||
return -EINVAL;
|
||||
|
||||
have_flags = true;
|
||||
flags = nla_get_u16(attr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (nla_type(attr) == IFLA_BRIDGE_MODE) {
|
||||
if (nla_len(attr) < sizeof(u16))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,6 +429,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
|
||||
{
|
||||
struct __kernel_sock_timeval tv;
|
||||
int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval);
|
||||
long val;
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
@ -439,7 +440,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
|
||||
if (tv.tv_sec < 0) {
|
||||
static int warned __read_mostly;
|
||||
|
||||
*timeo_p = 0;
|
||||
WRITE_ONCE(*timeo_p, 0);
|
||||
if (warned < 10 && net_ratelimit()) {
|
||||
warned++;
|
||||
pr_info("%s: `%s' (pid %d) tries to set negative timeout\n",
|
||||
@ -447,11 +448,12 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*timeo_p = MAX_SCHEDULE_TIMEOUT;
|
||||
if (tv.tv_sec == 0 && tv.tv_usec == 0)
|
||||
return 0;
|
||||
if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1))
|
||||
*timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, USEC_PER_SEC / HZ);
|
||||
val = MAX_SCHEDULE_TIMEOUT;
|
||||
if ((tv.tv_sec || tv.tv_usec) &&
|
||||
(tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)))
|
||||
val = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec,
|
||||
USEC_PER_SEC / HZ);
|
||||
WRITE_ONCE(*timeo_p, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -804,7 +806,7 @@ EXPORT_SYMBOL(sock_no_linger);
|
||||
void sock_set_priority(struct sock *sk, u32 priority)
|
||||
{
|
||||
lock_sock(sk);
|
||||
sk->sk_priority = priority;
|
||||
WRITE_ONCE(sk->sk_priority, priority);
|
||||
release_sock(sk);
|
||||
}
|
||||
EXPORT_SYMBOL(sock_set_priority);
|
||||
@ -813,9 +815,9 @@ void sock_set_sndtimeo(struct sock *sk, s64 secs)
|
||||
{
|
||||
lock_sock(sk);
|
||||
if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1)
|
||||
sk->sk_sndtimeo = secs * HZ;
|
||||
WRITE_ONCE(sk->sk_sndtimeo, secs * HZ);
|
||||
else
|
||||
sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
|
||||
WRITE_ONCE(sk->sk_sndtimeo, MAX_SCHEDULE_TIMEOUT);
|
||||
release_sock(sk);
|
||||
}
|
||||
EXPORT_SYMBOL(sock_set_sndtimeo);
|
||||
@ -988,7 +990,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf);
|
||||
static void __sock_set_mark(struct sock *sk, u32 val)
|
||||
{
|
||||
if (val != sk->sk_mark) {
|
||||
sk->sk_mark = val;
|
||||
WRITE_ONCE(sk->sk_mark, val);
|
||||
sk_dst_reset(sk);
|
||||
}
|
||||
}
|
||||
@ -1007,7 +1009,7 @@ static void sock_release_reserved_memory(struct sock *sk, int bytes)
|
||||
bytes = round_down(bytes, PAGE_SIZE);
|
||||
|
||||
WARN_ON(bytes > sk->sk_reserved_mem);
|
||||
sk->sk_reserved_mem -= bytes;
|
||||
WRITE_ONCE(sk->sk_reserved_mem, sk->sk_reserved_mem - bytes);
|
||||
sk_mem_reclaim(sk);
|
||||
}
|
||||
|
||||
@ -1044,7 +1046,8 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
|
||||
}
|
||||
sk->sk_forward_alloc += pages << PAGE_SHIFT;
|
||||
|
||||
sk->sk_reserved_mem += pages << PAGE_SHIFT;
|
||||
WRITE_ONCE(sk->sk_reserved_mem,
|
||||
sk->sk_reserved_mem + (pages << PAGE_SHIFT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1213,7 +1216,7 @@ set_sndbuf:
|
||||
if ((val >= 0 && val <= 6) ||
|
||||
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||
|
||||
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
|
||||
sk->sk_priority = val;
|
||||
WRITE_ONCE(sk->sk_priority, val);
|
||||
else
|
||||
ret = -EPERM;
|
||||
break;
|
||||
@ -1438,7 +1441,8 @@ set_sndbuf:
|
||||
cmpxchg(&sk->sk_pacing_status,
|
||||
SK_PACING_NONE,
|
||||
SK_PACING_NEEDED);
|
||||
sk->sk_max_pacing_rate = ulval;
|
||||
/* Pairs with READ_ONCE() from sk_getsockopt() */
|
||||
WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
|
||||
sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
|
||||
break;
|
||||
}
|
||||
@ -1533,7 +1537,9 @@ set_sndbuf:
|
||||
}
|
||||
if ((u8)val == SOCK_TXREHASH_DEFAULT)
|
||||
val = READ_ONCE(sock_net(sk)->core.sysctl_txrehash);
|
||||
/* Paired with READ_ONCE() in tcp_rtx_synack() */
|
||||
/* Paired with READ_ONCE() in tcp_rtx_synack()
|
||||
* and sk_getsockopt().
|
||||
*/
|
||||
WRITE_ONCE(sk->sk_txrehash, (u8)val);
|
||||
break;
|
||||
|
||||
@ -1633,11 +1639,11 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_SNDBUF:
|
||||
v.val = sk->sk_sndbuf;
|
||||
v.val = READ_ONCE(sk->sk_sndbuf);
|
||||
break;
|
||||
|
||||
case SO_RCVBUF:
|
||||
v.val = sk->sk_rcvbuf;
|
||||
v.val = READ_ONCE(sk->sk_rcvbuf);
|
||||
break;
|
||||
|
||||
case SO_REUSEADDR:
|
||||
@ -1679,7 +1685,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_PRIORITY:
|
||||
v.val = sk->sk_priority;
|
||||
v.val = READ_ONCE(sk->sk_priority);
|
||||
break;
|
||||
|
||||
case SO_LINGER:
|
||||
@ -1717,16 +1723,18 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
|
||||
case SO_RCVTIMEO_OLD:
|
||||
case SO_RCVTIMEO_NEW:
|
||||
lv = sock_get_timeout(sk->sk_rcvtimeo, &v, SO_RCVTIMEO_OLD == optname);
|
||||
lv = sock_get_timeout(READ_ONCE(sk->sk_rcvtimeo), &v,
|
||||
SO_RCVTIMEO_OLD == optname);
|
||||
break;
|
||||
|
||||
case SO_SNDTIMEO_OLD:
|
||||
case SO_SNDTIMEO_NEW:
|
||||
lv = sock_get_timeout(sk->sk_sndtimeo, &v, SO_SNDTIMEO_OLD == optname);
|
||||
lv = sock_get_timeout(READ_ONCE(sk->sk_sndtimeo), &v,
|
||||
SO_SNDTIMEO_OLD == optname);
|
||||
break;
|
||||
|
||||
case SO_RCVLOWAT:
|
||||
v.val = sk->sk_rcvlowat;
|
||||
v.val = READ_ONCE(sk->sk_rcvlowat);
|
||||
break;
|
||||
|
||||
case SO_SNDLOWAT:
|
||||
@ -1843,7 +1851,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
optval, optlen, len);
|
||||
|
||||
case SO_MARK:
|
||||
v.val = sk->sk_mark;
|
||||
v.val = READ_ONCE(sk->sk_mark);
|
||||
break;
|
||||
|
||||
case SO_RCVMARK:
|
||||
@ -1862,7 +1870,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
if (!sock->ops->set_peek_off)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
v.val = sk->sk_peek_off;
|
||||
v.val = READ_ONCE(sk->sk_peek_off);
|
||||
break;
|
||||
case SO_NOFCS:
|
||||
v.val = sock_flag(sk, SOCK_NOFCS);
|
||||
@ -1892,7 +1900,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
case SO_BUSY_POLL:
|
||||
v.val = sk->sk_ll_usec;
|
||||
v.val = READ_ONCE(sk->sk_ll_usec);
|
||||
break;
|
||||
case SO_PREFER_BUSY_POLL:
|
||||
v.val = READ_ONCE(sk->sk_prefer_busy_poll);
|
||||
@ -1900,12 +1908,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
#endif
|
||||
|
||||
case SO_MAX_PACING_RATE:
|
||||
/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
|
||||
if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
|
||||
lv = sizeof(v.ulval);
|
||||
v.ulval = sk->sk_max_pacing_rate;
|
||||
v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
|
||||
} else {
|
||||
/* 32bit version */
|
||||
v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
|
||||
v.val = min_t(unsigned long, ~0U,
|
||||
READ_ONCE(sk->sk_max_pacing_rate));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1973,11 +1983,12 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_RESERVE_MEM:
|
||||
v.val = sk->sk_reserved_mem;
|
||||
v.val = READ_ONCE(sk->sk_reserved_mem);
|
||||
break;
|
||||
|
||||
case SO_TXREHASH:
|
||||
v.val = sk->sk_txrehash;
|
||||
/* Paired with WRITE_ONCE() in sk_setsockopt() */
|
||||
v.val = READ_ONCE(sk->sk_txrehash);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3168,7 +3179,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim);
|
||||
|
||||
int sk_set_peek_off(struct sock *sk, int val)
|
||||
{
|
||||
sk->sk_peek_off = val;
|
||||
WRITE_ONCE(sk->sk_peek_off, val);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sk_set_peek_off);
|
||||
|
@ -115,7 +115,6 @@ static void sock_map_sk_acquire(struct sock *sk)
|
||||
__acquires(&sk->sk_lock.slock)
|
||||
{
|
||||
lock_sock(sk);
|
||||
preempt_disable();
|
||||
rcu_read_lock();
|
||||
}
|
||||
|
||||
@ -123,7 +122,6 @@ static void sock_map_sk_release(struct sock *sk)
|
||||
__releases(&sk->sk_lock.slock)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
preempt_enable();
|
||||
release_sock(sk);
|
||||
}
|
||||
|
||||
|
@ -980,7 +980,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested_deprecated(data, DCB_BCN_ATTR_MAX,
|
||||
tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest,
|
||||
tb[DCB_ATTR_BCN], dcbnl_bcn_nest,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -238,8 +238,8 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
|
||||
opt = ireq->ipv6_opt;
|
||||
if (!opt)
|
||||
opt = rcu_dereference(np->opt);
|
||||
err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass,
|
||||
sk->sk_priority);
|
||||
err = ip6_xmit(sk, skb, &fl6, READ_ONCE(sk->sk_mark), opt,
|
||||
np->tclass, sk->sk_priority);
|
||||
rcu_read_unlock();
|
||||
err = net_xmit_eval(err);
|
||||
}
|
||||
|
@ -1727,8 +1727,15 @@ int dsa_port_phylink_create(struct dsa_port *dp)
|
||||
ds->ops->phylink_mac_an_restart)
|
||||
dp->pl_config.legacy_pre_march2020 = true;
|
||||
|
||||
if (ds->ops->phylink_get_caps)
|
||||
if (ds->ops->phylink_get_caps) {
|
||||
ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
|
||||
} else {
|
||||
/* For legacy drivers */
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
dp->pl_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
dp->pl_config.supported_interfaces);
|
||||
}
|
||||
|
||||
pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
mode, &dsa_port_phylink_mac_ops);
|
||||
|
@ -150,7 +150,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
|
||||
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, READ_ONCE(sk->sk_mark)))
|
||||
goto errout;
|
||||
|
||||
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
|
||||
@ -799,7 +799,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
|
||||
entry.ifindex = sk->sk_bound_dev_if;
|
||||
entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0;
|
||||
if (sk_fullsock(sk))
|
||||
entry.mark = sk->sk_mark;
|
||||
entry.mark = READ_ONCE(sk->sk_mark);
|
||||
else if (sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
entry.mark = inet_rsk(inet_reqsk(sk))->ir_mark;
|
||||
else if (sk->sk_state == TCP_TIME_WAIT)
|
||||
|
@ -184,9 +184,9 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
|
||||
ip_options_build(skb, &opt->opt, daddr, rt);
|
||||
}
|
||||
|
||||
skb->priority = sk->sk_priority;
|
||||
skb->priority = READ_ONCE(sk->sk_priority);
|
||||
if (!skb->mark)
|
||||
skb->mark = sk->sk_mark;
|
||||
skb->mark = READ_ONCE(sk->sk_mark);
|
||||
|
||||
/* Send it out. */
|
||||
return ip_local_out(net, skb->sk, skb);
|
||||
@ -528,8 +528,8 @@ packet_routed:
|
||||
skb_shinfo(skb)->gso_segs ?: 1);
|
||||
|
||||
/* TODO : should we use skb->sk here instead of sk ? */
|
||||
skb->priority = sk->sk_priority;
|
||||
skb->mark = sk->sk_mark;
|
||||
skb->priority = READ_ONCE(sk->sk_priority);
|
||||
skb->mark = READ_ONCE(sk->sk_mark);
|
||||
|
||||
res = ip_local_out(net, sk, skb);
|
||||
rcu_read_unlock();
|
||||
@ -1158,10 +1158,15 @@ alloc_new_skb:
|
||||
}
|
||||
|
||||
copy = datalen - transhdrlen - fraggap - pagedlen;
|
||||
/* [!] NOTE: copy will be negative if pagedlen>0
|
||||
* because then the equation reduces to -fraggap.
|
||||
*/
|
||||
if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
|
||||
err = -EFAULT;
|
||||
kfree_skb(skb);
|
||||
goto error;
|
||||
} else if (flags & MSG_SPLICE_PAGES) {
|
||||
copy = 0;
|
||||
}
|
||||
|
||||
offset += copy;
|
||||
@ -1209,6 +1214,10 @@ alloc_new_skb:
|
||||
} else if (flags & MSG_SPLICE_PAGES) {
|
||||
struct msghdr *msg = from;
|
||||
|
||||
err = -EIO;
|
||||
if (WARN_ON_ONCE(copy > msg->msg_iter.count))
|
||||
goto error;
|
||||
|
||||
err = skb_splice_from_iter(skb, &msg->msg_iter, copy,
|
||||
sk->sk_allocation);
|
||||
if (err < 0)
|
||||
|
@ -592,7 +592,7 @@ void __ip_sock_set_tos(struct sock *sk, int val)
|
||||
}
|
||||
if (inet_sk(sk)->tos != val) {
|
||||
inet_sk(sk)->tos = val;
|
||||
sk->sk_priority = rt_tos2priority(val);
|
||||
WRITE_ONCE(sk->sk_priority, rt_tos2priority(val));
|
||||
sk_dst_reset(sk);
|
||||
}
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
|
||||
goto error;
|
||||
skb_reserve(skb, hlen);
|
||||
|
||||
skb->priority = sk->sk_priority;
|
||||
skb->priority = READ_ONCE(sk->sk_priority);
|
||||
skb->mark = sockc->mark;
|
||||
skb->tstamp = sockc->transmit_time;
|
||||
skb_dst_set(skb, &rt->dst);
|
||||
|
@ -518,7 +518,7 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
oif = sk->sk_bound_dev_if;
|
||||
mark = sk->sk_mark;
|
||||
mark = READ_ONCE(sk->sk_mark);
|
||||
tos = ip_sock_rt_tos(sk);
|
||||
scope = ip_sock_rt_scope(sk);
|
||||
prot = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol;
|
||||
@ -552,7 +552,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt && inet_opt->opt.srr)
|
||||
daddr = inet_opt->opt.faddr;
|
||||
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
|
||||
flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark),
|
||||
ip_sock_rt_tos(sk) & IPTOS_RT_MASK,
|
||||
ip_sock_rt_scope(sk),
|
||||
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
|
||||
|
@ -931,9 +931,9 @@ static void tcp_v4_send_ack(const struct sock *sk,
|
||||
ctl_sk = this_cpu_read(ipv4_tcp_sk);
|
||||
sock_net_set(ctl_sk, net);
|
||||
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
|
||||
inet_twsk(sk)->tw_mark : sk->sk_mark;
|
||||
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
|
||||
ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
|
||||
inet_twsk(sk)->tw_priority : sk->sk_priority;
|
||||
inet_twsk(sk)->tw_priority : READ_ONCE(sk->sk_priority);
|
||||
transmit_time = tcp_transmit_time(sk);
|
||||
ip_send_unicast_reply(ctl_sk,
|
||||
skb, &TCP_SKB_CB(skb)->header.h4.opt,
|
||||
|
@ -40,7 +40,7 @@ struct tcp_fastopen_metrics {
|
||||
|
||||
struct tcp_metrics_block {
|
||||
struct tcp_metrics_block __rcu *tcpm_next;
|
||||
possible_net_t tcpm_net;
|
||||
struct net *tcpm_net;
|
||||
struct inetpeer_addr tcpm_saddr;
|
||||
struct inetpeer_addr tcpm_daddr;
|
||||
unsigned long tcpm_stamp;
|
||||
@ -51,34 +51,38 @@ struct tcp_metrics_block {
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
|
||||
static inline struct net *tm_net(struct tcp_metrics_block *tm)
|
||||
static inline struct net *tm_net(const struct tcp_metrics_block *tm)
|
||||
{
|
||||
return read_pnet(&tm->tcpm_net);
|
||||
/* Paired with the WRITE_ONCE() in tcpm_new() */
|
||||
return READ_ONCE(tm->tcpm_net);
|
||||
}
|
||||
|
||||
static bool tcp_metric_locked(struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx)
|
||||
{
|
||||
return tm->tcpm_lock & (1 << idx);
|
||||
/* Paired with WRITE_ONCE() in tcpm_suck_dst() */
|
||||
return READ_ONCE(tm->tcpm_lock) & (1 << idx);
|
||||
}
|
||||
|
||||
static u32 tcp_metric_get(struct tcp_metrics_block *tm,
|
||||
static u32 tcp_metric_get(const struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx)
|
||||
{
|
||||
return tm->tcpm_vals[idx];
|
||||
/* Paired with WRITE_ONCE() in tcp_metric_set() */
|
||||
return READ_ONCE(tm->tcpm_vals[idx]);
|
||||
}
|
||||
|
||||
static void tcp_metric_set(struct tcp_metrics_block *tm,
|
||||
enum tcp_metric_index idx,
|
||||
u32 val)
|
||||
{
|
||||
tm->tcpm_vals[idx] = val;
|
||||
/* Paired with READ_ONCE() in tcp_metric_get() */
|
||||
WRITE_ONCE(tm->tcpm_vals[idx], val);
|
||||
}
|
||||
|
||||
static bool addr_same(const struct inetpeer_addr *a,
|
||||
const struct inetpeer_addr *b)
|
||||
{
|
||||
return inetpeer_addr_cmp(a, b) == 0;
|
||||
return (a->family == b->family) && !inetpeer_addr_cmp(a, b);
|
||||
}
|
||||
|
||||
struct tcpm_hash_bucket {
|
||||
@ -89,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly;
|
||||
static unsigned int tcp_metrics_hash_log __read_mostly;
|
||||
|
||||
static DEFINE_SPINLOCK(tcp_metrics_lock);
|
||||
static DEFINE_SEQLOCK(fastopen_seqlock);
|
||||
|
||||
static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
||||
const struct dst_entry *dst,
|
||||
@ -97,7 +102,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
||||
u32 msval;
|
||||
u32 val;
|
||||
|
||||
tm->tcpm_stamp = jiffies;
|
||||
WRITE_ONCE(tm->tcpm_stamp, jiffies);
|
||||
|
||||
val = 0;
|
||||
if (dst_metric_locked(dst, RTAX_RTT))
|
||||
@ -110,30 +115,42 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,
|
||||
val |= 1 << TCP_METRIC_CWND;
|
||||
if (dst_metric_locked(dst, RTAX_REORDERING))
|
||||
val |= 1 << TCP_METRIC_REORDERING;
|
||||
tm->tcpm_lock = val;
|
||||
/* Paired with READ_ONCE() in tcp_metric_locked() */
|
||||
WRITE_ONCE(tm->tcpm_lock, val);
|
||||
|
||||
msval = dst_metric_raw(dst, RTAX_RTT);
|
||||
tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC;
|
||||
tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC);
|
||||
|
||||
msval = dst_metric_raw(dst, RTAX_RTTVAR);
|
||||
tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC;
|
||||
tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH);
|
||||
tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND);
|
||||
tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING);
|
||||
tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC);
|
||||
tcp_metric_set(tm, TCP_METRIC_SSTHRESH,
|
||||
dst_metric_raw(dst, RTAX_SSTHRESH));
|
||||
tcp_metric_set(tm, TCP_METRIC_CWND,
|
||||
dst_metric_raw(dst, RTAX_CWND));
|
||||
tcp_metric_set(tm, TCP_METRIC_REORDERING,
|
||||
dst_metric_raw(dst, RTAX_REORDERING));
|
||||
if (fastopen_clear) {
|
||||
write_seqlock(&fastopen_seqlock);
|
||||
tm->tcpm_fastopen.mss = 0;
|
||||
tm->tcpm_fastopen.syn_loss = 0;
|
||||
tm->tcpm_fastopen.try_exp = 0;
|
||||
tm->tcpm_fastopen.cookie.exp = false;
|
||||
tm->tcpm_fastopen.cookie.len = 0;
|
||||
write_sequnlock(&fastopen_seqlock);
|
||||
}
|
||||
}
|
||||
|
||||
#define TCP_METRICS_TIMEOUT (60 * 60 * HZ)
|
||||
|
||||
static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
|
||||
static void tcpm_check_stamp(struct tcp_metrics_block *tm,
|
||||
const struct dst_entry *dst)
|
||||
{
|
||||
if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
|
||||
unsigned long limit;
|
||||
|
||||
if (!tm)
|
||||
return;
|
||||
limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT;
|
||||
if (unlikely(time_after(jiffies, limit)))
|
||||
tcpm_suck_dst(tm, dst, false);
|
||||
}
|
||||
|
||||
@ -174,20 +191,23 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
|
||||
oldest = deref_locked(tcp_metrics_hash[hash].chain);
|
||||
for (tm = deref_locked(oldest->tcpm_next); tm;
|
||||
tm = deref_locked(tm->tcpm_next)) {
|
||||
if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp))
|
||||
if (time_before(READ_ONCE(tm->tcpm_stamp),
|
||||
READ_ONCE(oldest->tcpm_stamp)))
|
||||
oldest = tm;
|
||||
}
|
||||
tm = oldest;
|
||||
} else {
|
||||
tm = kmalloc(sizeof(*tm), GFP_ATOMIC);
|
||||
tm = kzalloc(sizeof(*tm), GFP_ATOMIC);
|
||||
if (!tm)
|
||||
goto out_unlock;
|
||||
}
|
||||
write_pnet(&tm->tcpm_net, net);
|
||||
/* Paired with the READ_ONCE() in tm_net() */
|
||||
WRITE_ONCE(tm->tcpm_net, net);
|
||||
|
||||
tm->tcpm_saddr = *saddr;
|
||||
tm->tcpm_daddr = *daddr;
|
||||
|
||||
tcpm_suck_dst(tm, dst, true);
|
||||
tcpm_suck_dst(tm, dst, reclaim);
|
||||
|
||||
if (likely(!reclaim)) {
|
||||
tm->tcpm_next = tcp_metrics_hash[hash].chain;
|
||||
@ -434,7 +454,7 @@ void tcp_update_metrics(struct sock *sk)
|
||||
tp->reordering);
|
||||
}
|
||||
}
|
||||
tm->tcpm_stamp = jiffies;
|
||||
WRITE_ONCE(tm->tcpm_stamp, jiffies);
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@ -539,8 +559,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_SEQLOCK(fastopen_seqlock);
|
||||
|
||||
void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
|
||||
struct tcp_fastopen_cookie *cookie)
|
||||
{
|
||||
@ -647,7 +665,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,
|
||||
}
|
||||
|
||||
if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE,
|
||||
jiffies - tm->tcpm_stamp,
|
||||
jiffies - READ_ONCE(tm->tcpm_stamp),
|
||||
TCP_METRICS_ATTR_PAD) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
@ -658,7 +676,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) {
|
||||
u32 val = tm->tcpm_vals[i];
|
||||
u32 val = tcp_metric_get(tm, i);
|
||||
|
||||
if (!val)
|
||||
continue;
|
||||
|
@ -114,6 +114,7 @@
|
||||
#include <net/sock_reuseport.h>
|
||||
#include <net/addrconf.h>
|
||||
#include <net/udp_tunnel.h>
|
||||
#include <net/gro.h>
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/ipv6_stubs.h>
|
||||
#endif
|
||||
@ -555,10 +556,13 @@ struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct net *net = dev_net(skb->dev);
|
||||
int iif, sdif;
|
||||
|
||||
inet_get_iif_sdif(skb, &iif, &sdif);
|
||||
|
||||
return __udp4_lib_lookup(net, iph->saddr, sport,
|
||||
iph->daddr, dport, inet_iif(skb),
|
||||
inet_sdif(skb), net->ipv4.udp_table, NULL);
|
||||
iph->daddr, dport, iif,
|
||||
sdif, net->ipv4.udp_table, NULL);
|
||||
}
|
||||
|
||||
/* Must be called under rcu_read_lock().
|
||||
|
@ -609,10 +609,13 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
|
||||
{
|
||||
const struct iphdr *iph = skb_gro_network_header(skb);
|
||||
struct net *net = dev_net(skb->dev);
|
||||
int iif, sdif;
|
||||
|
||||
inet_get_iif_sdif(skb, &iif, &sdif);
|
||||
|
||||
return __udp4_lib_lookup(net, iph->saddr, sport,
|
||||
iph->daddr, dport, inet_iif(skb),
|
||||
inet_sdif(skb), net->ipv4.udp_table, NULL);
|
||||
iph->daddr, dport, iif,
|
||||
sdif, net->ipv4.udp_table, NULL);
|
||||
}
|
||||
|
||||
INDIRECT_CALLABLE_SCOPE
|
||||
|
@ -1073,7 +1073,7 @@ static int ip6mr_cache_report(const struct mr_table *mrt, struct sk_buff *pkt,
|
||||
And all this only to mangle msg->im6_msgtype and
|
||||
to set msg->im6_mbz to "mbz" :-)
|
||||
*/
|
||||
skb_push(skb, -skb_network_offset(pkt));
|
||||
__skb_pull(skb, skb_network_offset(pkt));
|
||||
|
||||
skb_push(skb, sizeof(*msg));
|
||||
skb_reset_transport_header(skb);
|
||||
|
@ -120,7 +120,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
|
||||
ipcm6_init_sk(&ipc6, np);
|
||||
ipc6.sockc.tsflags = sk->sk_tsflags;
|
||||
ipc6.sockc.mark = sk->sk_mark;
|
||||
ipc6.sockc.mark = READ_ONCE(sk->sk_mark);
|
||||
|
||||
fl6.flowi6_oif = oif;
|
||||
|
||||
|
@ -614,7 +614,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
|
||||
skb_reserve(skb, hlen);
|
||||
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
skb->priority = sk->sk_priority;
|
||||
skb->priority = READ_ONCE(sk->sk_priority);
|
||||
skb->mark = sockc->mark;
|
||||
skb->tstamp = sockc->transmit_time;
|
||||
|
||||
@ -774,12 +774,12 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
*/
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
|
||||
fl6.flowi6_mark = sk->sk_mark;
|
||||
fl6.flowi6_mark = READ_ONCE(sk->sk_mark);
|
||||
fl6.flowi6_uid = sk->sk_uid;
|
||||
|
||||
ipcm6_init(&ipc6);
|
||||
ipc6.sockc.tsflags = sk->sk_tsflags;
|
||||
ipc6.sockc.mark = sk->sk_mark;
|
||||
ipc6.sockc.mark = fl6.flowi6_mark;
|
||||
|
||||
if (sin6) {
|
||||
if (addr_len < SIN6_LEN_RFC2133)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user