[Devel] [PATCH rh7 1/1] net/setsockopt: switch high order allocations to kvmalloc() in do_ip_setsockopt()
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Mar 21 14:32:23 MSK 2018
In do_ip_setsockopt() IP_MSFILTER and MCAST_MSFILTER cases
allocates memory size which depends on userspace but not greater than
sysctl_optmem_max (net.core.optmem_max which is 20480 by default) =>
3rd order page allocations are possible here =>
substitute kmalloc() with kvmalloc() here.
WARNING: CPU: 2 PID: 34605 at mm/page_alloc.c:3197 __alloc_pages_nodemask+0x2e4/0x590
order 3 >= 3, gfp 0x40d0
Modules linked in: <skipped>
CPU: 2 PID: 34605 Comm: trinity-main ve: d7d30d09-1585-4ef1-99b9-893b4fb06cec Not tainted 3.10.0-693.17.1.vz7.45.8 #1 45.8
Hardware name: Virtuozzo KVM, BIOS 1.10.2-3.1.vz7.2 04/01/2014
Call Trace:
[<ffffffff816d6d81>] dump_stack+0x19/0x1b
[<ffffffff8108a8d8>] __warn+0xd8/0x100
[<ffffffff8108a95f>] warn_slowpath_fmt+0x5f/0x80
[<ffffffff811a12c4>] __alloc_pages_nodemask+0x2e4/0x590
[<ffffffff811ea978>] alloc_pages_current+0x98/0x110
[<ffffffff811bd498>] kmalloc_order+0x18/0x40
[<ffffffff811bd4e6>] kmalloc_order_trace+0x26/0xa0
[<ffffffff811f9399>] __kmalloc+0x279/0x290
[<ffffffff81604277>] do_ip_setsockopt.isra.15+0x507/0xeb0
[<ffffffff81604c50>] ip_setsockopt+0x30/0xd0
[<ffffffff8162b9fb>] udp_setsockopt+0x1b/0x40
[<ffffffff8168bee6>] ipv6_setsockopt+0x46/0xd0
[<ffffffff81690d7b>] udpv6_setsockopt+0x1b/0x40
[<ffffffff8159d204>] sock_common_setsockopt+0x14/0x20
[<ffffffff8159c390>] SyS_setsockopt+0x80/0xf0
[<ffffffff816e9a7d>] system_call_fastpath+0x16/0x1b
---[ end trace 5b208f01e4177b5b ]---
https://jira.sw.ru/browse/PSBM-82646
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
net/ipv4/ip_sockglue.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 78a20d1f1cae..0fe359a8df7b 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -826,30 +826,30 @@ static int do_ip_setsockopt(struct sock *sk, int level,
err = -ENOBUFS;
break;
}
- msf = kmalloc(optlen, GFP_KERNEL);
+ msf = kvmalloc(optlen, GFP_KERNEL);
if (!msf) {
err = -ENOBUFS;
break;
}
err = -EFAULT;
if (copy_from_user(msf, optval, optlen)) {
- kfree(msf);
+ kvfree(msf);
break;
}
/* numsrc >= (1G-4) overflow in 32 bits */
if (msf->imsf_numsrc >= 0x3ffffffcU ||
msf->imsf_numsrc > sysctl_igmp_max_msf) {
- kfree(msf);
+ kvfree(msf);
err = -ENOBUFS;
break;
}
if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
- kfree(msf);
+ kvfree(msf);
err = -EINVAL;
break;
}
err = ip_mc_msfilter(sk, msf, 0);
- kfree(msf);
+ kvfree(msf);
break;
}
case IP_BLOCK_SOURCE:
@@ -982,7 +982,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
err = -ENOBUFS;
break;
}
- gsf = kmalloc(optlen, GFP_KERNEL);
+ gsf = kvmalloc(optlen, GFP_KERNEL);
if (!gsf) {
err = -ENOBUFS;
break;
@@ -1002,7 +1002,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
goto mc_msf_out;
}
msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
- msf = kmalloc(msize, GFP_KERNEL);
+ msf = kvmalloc(msize, GFP_KERNEL);
if (!msf) {
err = -ENOBUFS;
goto mc_msf_out;
@@ -1025,13 +1025,13 @@ static int do_ip_setsockopt(struct sock *sk, int level,
goto mc_msf_out;
msf->imsf_slist[i] = psin->sin_addr.s_addr;
}
- kfree(gsf);
+ kvfree(gsf);
gsf = NULL;
err = ip_mc_msfilter(sk, msf, ifindex);
mc_msf_out:
- kfree(msf);
- kfree(gsf);
+ kvfree(msf);
+ kvfree(gsf);
break;
}
case IP_MULTICAST_ALL:
--
2.15.1
More information about the Devel
mailing list