Netdev Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Jakub Kicinski <kuba@kernel.org>, Dave Jones <dsj@fb.com>,
"David S . Miller" <davem@davemloft.net>,
Sasha Levin <sashal@kernel.org>,
netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 5.10 119/137] net: ip: avoid OOM kills with large UDP sends over loopback
Date: Tue, 6 Jul 2021 07:21:45 -0400 [thread overview]
Message-ID: <20210706112203.2062605-119-sashal@kernel.org> (raw)
In-Reply-To: <20210706112203.2062605-1-sashal@kernel.org>
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 6d123b81ac615072a8525c13c6c41b695270a15d ]
Dave observed number of machines hitting OOM on the UDP send
path. The workload seems to be sending large UDP packets over
loopback. Since loopback has MTU of 64k kernel will try to
allocate an skb with up to 64k of head space. This has a good
chance of failing under memory pressure. What's worse if
the message length is <32k the allocation may trigger an
OOM killer.
This is entirely avoidable, we can use an skb with page frags.
af_unix solves a similar problem by limiting the head
length to SKB_MAX_ALLOC. This seems like a good and simple
approach. It means that UDP messages > 16kB will now
use fragments if underlying device supports SG, if extra
allocator pressure causes regressions in real workloads
we can switch to trying the large allocation first and
falling back.
v4: pre-calculate all the additions to alloclen so
we can be sure it won't go over order-2
Reported-by: Dave Jones <dsj@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ip_output.c | 32 ++++++++++++++++++--------------
net/ipv6/ip6_output.c | 32 +++++++++++++++++---------------
2 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 97975bed491a..560d5dc43562 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1053,7 +1053,7 @@ static int __ip_append_data(struct sock *sk,
unsigned int datalen;
unsigned int fraglen;
unsigned int fraggap;
- unsigned int alloclen;
+ unsigned int alloclen, alloc_extra;
unsigned int pagedlen;
struct sk_buff *skb_prev;
alloc_new_skb:
@@ -1073,35 +1073,39 @@ static int __ip_append_data(struct sock *sk,
fraglen = datalen + fragheaderlen;
pagedlen = 0;
+ alloc_extra = hh_len + 15;
+ alloc_extra += exthdrlen;
+
+ /* The last fragment gets additional space at tail.
+ * Note, with MSG_MORE we overallocate on fragments,
+ * because we have no idea what fragment will be
+ * the last.
+ */
+ if (datalen == length + fraggap)
+ alloc_extra += rt->dst.trailer_len;
+
if ((flags & MSG_MORE) &&
!(rt->dst.dev->features&NETIF_F_SG))
alloclen = mtu;
- else if (!paged)
+ else if (!paged &&
+ (fraglen + alloc_extra < SKB_MAX_ALLOC ||
+ !(rt->dst.dev->features & NETIF_F_SG)))
alloclen = fraglen;
else {
alloclen = min_t(int, fraglen, MAX_HEADER);
pagedlen = fraglen - alloclen;
}
- alloclen += exthdrlen;
-
- /* The last fragment gets additional space at tail.
- * Note, with MSG_MORE we overallocate on fragments,
- * because we have no idea what fragment will be
- * the last.
- */
- if (datalen == length + fraggap)
- alloclen += rt->dst.trailer_len;
+ alloclen += alloc_extra;
if (transhdrlen) {
- skb = sock_alloc_send_skb(sk,
- alloclen + hh_len + 15,
+ skb = sock_alloc_send_skb(sk, alloclen,
(flags & MSG_DONTWAIT), &err);
} else {
skb = NULL;
if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
2 * sk->sk_sndbuf)
- skb = alloc_skb(alloclen + hh_len + 15,
+ skb = alloc_skb(alloclen,
sk->sk_allocation);
if (unlikely(!skb))
err = -ENOBUFS;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 077d43af8226..e889655ca0e2 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1554,7 +1554,7 @@ static int __ip6_append_data(struct sock *sk,
unsigned int datalen;
unsigned int fraglen;
unsigned int fraggap;
- unsigned int alloclen;
+ unsigned int alloclen, alloc_extra;
unsigned int pagedlen;
alloc_new_skb:
/* There's no room in the current skb */
@@ -1581,17 +1581,28 @@ static int __ip6_append_data(struct sock *sk,
fraglen = datalen + fragheaderlen;
pagedlen = 0;
+ alloc_extra = hh_len;
+ alloc_extra += dst_exthdrlen;
+ alloc_extra += rt->dst.trailer_len;
+
+ /* We just reserve space for fragment header.
+ * Note: this may be overallocation if the message
+ * (without MSG_MORE) fits into the MTU.
+ */
+ alloc_extra += sizeof(struct frag_hdr);
+
if ((flags & MSG_MORE) &&
!(rt->dst.dev->features&NETIF_F_SG))
alloclen = mtu;
- else if (!paged)
+ else if (!paged &&
+ (fraglen + alloc_extra < SKB_MAX_ALLOC ||
+ !(rt->dst.dev->features & NETIF_F_SG)))
alloclen = fraglen;
else {
alloclen = min_t(int, fraglen, MAX_HEADER);
pagedlen = fraglen - alloclen;
}
-
- alloclen += dst_exthdrlen;
+ alloclen += alloc_extra;
if (datalen != length + fraggap) {
/*
@@ -1601,30 +1612,21 @@ static int __ip6_append_data(struct sock *sk,
datalen += rt->dst.trailer_len;
}
- alloclen += rt->dst.trailer_len;
fraglen = datalen + fragheaderlen;
- /*
- * We just reserve space for fragment header.
- * Note: this may be overallocation if the message
- * (without MSG_MORE) fits into the MTU.
- */
- alloclen += sizeof(struct frag_hdr);
-
copy = datalen - transhdrlen - fraggap - pagedlen;
if (copy < 0) {
err = -EINVAL;
goto error;
}
if (transhdrlen) {
- skb = sock_alloc_send_skb(sk,
- alloclen + hh_len,
+ skb = sock_alloc_send_skb(sk, alloclen,
(flags & MSG_DONTWAIT), &err);
} else {
skb = NULL;
if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
2 * sk->sk_sndbuf)
- skb = alloc_skb(alloclen + hh_len,
+ skb = alloc_skb(alloclen,
sk->sk_allocation);
if (unlikely(!skb))
err = -ENOBUFS;
--
2.30.2
next prev parent reply other threads:[~2021-07-06 12:24 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20210706112203.2062605-1-sashal@kernel.org>
2021-07-06 11:19 ` [PATCH AUTOSEL 5.10 009/137] net: pch_gbe: Use proper accessors to BE data in pch_ptp_match() Sasha Levin
2021-07-06 11:19 ` [PATCH AUTOSEL 5.10 013/137] atm: iphase: fix possible use-after-free in ia_module_exit() Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 014/137] mISDN: fix possible use-after-free in HFC_cleanup() Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 015/137] atm: nicstar: Fix possible use-after-free in nicstar_cleanup() Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 016/137] net: Treat __napi_schedule_irqoff() as __napi_schedule() on PREEMPT_RT Sasha Levin
2021-07-12 21:52 ` Pavel Machek
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 018/137] net: mdio: ipq8064: add regmap config to disable REGCACHE Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 023/137] bpf: Check for BPF_F_ADJ_ROOM_FIXED_GSO when bpf_skb_change_proto Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 024/137] net: mdio: provide shim implementation of devm_of_mdiobus_register Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 025/137] net/sched: cls_api: increase max_reclassify_loop Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 032/137] e100: handle eeprom as little endian Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 033/137] igb: handle vlan types with checker enabled Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 034/137] igb: fix assignment on big endian machines Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 037/137] net/mlx5e: IPsec/rep_tc: Fix rep_tc_update_skb drops IPsec packet Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 038/137] net/mlx5: Fix lag port remapping logic Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 041/137] net: stmmac: the XPCS obscures a potential "PHY not found" error Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 046/137] virtio-net: Add validation for used length Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 047/137] ipv6: use prandom_u32() for ID generation Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 052/137] net: tcp better handling of reordering then loss cases Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 057/137] net: bridge: mrp: Update ring transitions Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 059/137] ice: set the value of global config lock timeout longer Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 060/137] ice: fix clang warning regarding deadcode.DeadStores Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 061/137] virtio_net: Remove BUG() to avoid machine dead Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 062/137] net: mscc: ocelot: check return value after calling platform_get_resource() Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 063/137] net: bcmgenet: " Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 064/137] net: mvpp2: " Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 065/137] net: micrel: " Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 066/137] net: moxa: Use devm_platform_get_and_ioremap_resource() Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 072/137] net: phy: realtek: add delay to fix RXC generation issue Sasha Levin
2021-07-06 11:20 ` [PATCH AUTOSEL 5.10 073/137] selftests: Clean forgotten resources as part of cleanup() Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 074/137] net: sgi: ioc3-eth: check return value after calling platform_get_resource() Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 076/137] fjes: " Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 078/137] r8169: avoid link-up interrupt issue on RTL8106e if user enables ASPM Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 080/137] xfrm: Fix error reporting in xfrm_state_construct Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 082/137] wlcore/wl12xx: Fix wl12xx get_mac error if device is in ELP Sasha Levin
2021-07-12 22:03 ` Pavel Machek
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 083/137] wl1251: Fix possible buffer overflow in wl1251_cmd_scan Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 084/137] cw1200: add missing MODULE_DEVICE_TABLE Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 087/137] bpf: Fix up register-based shifts in interpreter to silence KUBSAN Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 088/137] ice: fix incorrect payload indicator on PTYPE Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 089/137] ice: mark PTYPE 2 as reserved Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 090/137] mt76: mt7615: fix fixed-rate tx status reporting Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 092/137] net: ipa: Add missing of_node_put() in ipa_firmware_load() Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 093/137] net: sched: fix error return code in tcf_del_walker() Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 097/137] mt76: mt7915: fix IEEE80211_HE_PHY_CAP7_MAX_NC for station mode Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 098/137] rtl8xxxu: Fix device info for RTL8192EU devices Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 100/137] net: fec: add ndo_select_queue to fix TX bandwidth fluctuations Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 101/137] atm: nicstar: use 'dma_free_coherent' instead of 'kfree' Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 102/137] atm: nicstar: register the interrupt handler in the right place Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 103/137] vsock: notify server to shutdown when client has pending signal Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 105/137] iwlwifi: mvm: don't change band on bound PHY contexts Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 106/137] iwlwifi: mvm: fix error print when session protection ends Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 107/137] iwlwifi: mvm: support LONG_GROUP for WOWLAN_GET_STATUSES version Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 108/137] iwlwifi: pcie: free IML DMA memory allocation Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 109/137] iwlwifi: pcie: fix context info freeing Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 110/137] sfc: avoid double pci_remove of VFs Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 111/137] sfc: error code if SRIOV cannot be disabled Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 112/137] net: dsa: b53: Create default VLAN entry explicitly Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 113/137] wireless: wext-spy: Fix out-of-bounds warning Sasha Levin
2021-07-06 14:08 ` Johannes Berg
2021-07-07 10:45 ` Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 114/137] cfg80211: fix default HE tx bitrate mask in 2G band Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 115/137] mac80211: consider per-CPU statistics if present Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 116/137] mac80211_hwsim: add concurrent channels scanning support over virtio Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 118/137] media, bpf: Do not copy more entries than user space requested Sasha Levin
2021-07-06 11:21 ` Sasha Levin [this message]
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 122/137] Bluetooth: Fix the HCI to MGMT status conversion table Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 123/137] Bluetooth: Fix alt settings for incoming SCO with transparent coding format Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 124/137] Bluetooth: Shutdown controller after workqueues are flushed or cancelled Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 126/137] Bluetooth: L2CAP: Fix invalid access if ECRED Reconfigure fails Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 127/137] Bluetooth: L2CAP: Fix invalid access on ECRED Connection response Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 129/137] Bluetooth: mgmt: Fix the command returns garbage parameter value Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 132/137] bpf: Fix false positive kmemleak report in bpf_ringbuf_area_alloc() Sasha Levin
2021-07-06 11:21 ` [PATCH AUTOSEL 5.10 133/137] flow_offload: action should not be NULL when it is referenced Sasha Levin
2021-07-06 11:22 ` [PATCH AUTOSEL 5.10 134/137] sctp: validate from_addr_param return Sasha Levin
2021-07-06 11:22 ` [PATCH AUTOSEL 5.10 135/137] sctp: add size validation when walking chunks Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210706112203.2062605-119-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=davem@davemloft.net \
--cc=dsj@fb.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=stable@vger.kernel.org \
--subject='Re: [PATCH AUTOSEL 5.10 119/137] net: ip: avoid OOM kills with large UDP sends over loopback' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).