提交 8818e269 编写于 作者: W Wang Yufen 提交者: Zheng Zengkai

bpf, sockmap: Add sk_rmem_alloc check for sockmap

hulk inclusion
category: feature
bugzilla: 186640, https://gitee.com/openeuler/kernel/issues/I545NW

--------------------------------

A tcp socket in a sockmap. If the packets transmission rate is very fast
and the packets receiving rate is very slow, a large number of packets
are stacked in the ingress queue on the packets receiving side. As a
result the memory is exhausted and the system ooms.

To fix, we add sk_rmem_alloc while sk_msg queued in the ingress queue
and subtract sk_rmem_alloc while sk_msg dequeued from the ingress queue
and check sk_rmem_alloc at the beginning of bpf_tcp_ingress().
Signed-off-by: NWang Yufen <wangyufen@huawei.com>
Reviewed-by: NLiu Jian <liujian56@huawei.com>
Reviewed-by: NWei Yongjun <weiyongjun1@huawei.com>
Reviewed-by: NYue Haibing <yuehaibing@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 8207c85b
...@@ -659,6 +659,7 @@ void __sk_psock_purge_ingress_msg(struct sk_psock *psock) ...@@ -659,6 +659,7 @@ void __sk_psock_purge_ingress_msg(struct sk_psock *psock)
list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) { list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) {
list_del(&msg->list); list_del(&msg->list);
atomic_sub(msg->sg.size, &psock->sk->sk_rmem_alloc);
sk_msg_free(psock->sk, msg); sk_msg_free(psock->sk, msg);
kfree(msg); kfree(msg);
} }
......
...@@ -43,8 +43,10 @@ int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock, ...@@ -43,8 +43,10 @@ int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock,
if (likely(!peek)) { if (likely(!peek)) {
sge->offset += copy; sge->offset += copy;
sge->length -= copy; sge->length -= copy;
if (!msg_rx->skb) if (!msg_rx->skb) {
atomic_sub(copy, &sk->sk_rmem_alloc);
sk_mem_uncharge(sk, copy); sk_mem_uncharge(sk, copy);
}
msg_rx->sg.size -= copy; msg_rx->sg.size -= copy;
if (!sge->length) { if (!sge->length) {
...@@ -98,6 +100,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, ...@@ -98,6 +100,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
return -ENOMEM; return -ENOMEM;
lock_sock(sk); lock_sock(sk);
if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) {
kfree(tmp);
release_sock(sk);
return -EAGAIN;
}
tmp->sg.start = msg->sg.start; tmp->sg.start = msg->sg.start;
i = msg->sg.start; i = msg->sg.start;
do { do {
...@@ -127,6 +134,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, ...@@ -127,6 +134,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
if (!ret) { if (!ret) {
msg->sg.start = i; msg->sg.start = i;
sk_psock_queue_msg(psock, tmp); sk_psock_queue_msg(psock, tmp);
atomic_add(tmp->sg.size, &sk->sk_rmem_alloc);
sk_psock_data_ready(sk, psock); sk_psock_data_ready(sk, psock);
} else { } else {
sk_msg_free(sk, tmp); sk_msg_free(sk, tmp);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册