summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorLiu Jian <liujian56@huawei.com>2022-09-07 15:13:11 +0800
committerDaniel Borkmann <daniel@iogearbox.net>2022-09-26 17:48:05 +0200
commitbec217197b412d74168c6a42fc0f76d0cc9cad00 (patch)
treee63d07ff0f00d7820945717090e7d6169a6313ee /net/core
parent043a7356dbd0f44b2a2161649d89f4a43f3b0180 (diff)
downloadlinux-stable-bec217197b412d74168c6a42fc0f76d0cc9cad00.tar.gz
linux-stable-bec217197b412d74168c6a42fc0f76d0cc9cad00.tar.bz2
linux-stable-bec217197b412d74168c6a42fc0f76d0cc9cad00.zip
skmsg: Schedule psock work if the cached skb exists on the psock
In sk_psock_backlog function, for ingress direction skb, if no new data packet arrives after the skb is cached, the cached skb does not have a chance to be added to the receive queue of psock. As a result, the cached skb cannot be received by the upper-layer application. Fix this by reschedule the psock work to dispose the cached skb in sk_msg_recvmsg function. Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: Liu Jian <liujian56@huawei.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20220907071311.60534-1-liujian56@huawei.com
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skmsg.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 188f8558d27d..ca70525621c7 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -434,8 +434,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
if (copied + copy > len)
copy = len - copied;
copy = copy_page_to_iter(page, sge->offset, copy, iter);
- if (!copy)
- return copied ? copied : -EFAULT;
+ if (!copy) {
+ copied = copied ? copied : -EFAULT;
+ goto out;
+ }
copied += copy;
if (likely(!peek)) {
@@ -455,7 +457,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
* didn't copy the entire length lets just break.
*/
if (copy != sge->length)
- return copied;
+ goto out;
sk_msg_iter_var_next(i);
}
@@ -477,7 +479,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
}
msg_rx = sk_psock_peek_msg(psock);
}
-
+out:
+ if (psock->work_state.skb && copied > 0)
+ schedule_work(&psock->work);
return copied;
}
EXPORT_SYMBOL_GPL(sk_msg_recvmsg);