| From acd6eefaeec42e581ed618c690fb27e92f0ffccf Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 7 Sep 2022 15:13:11 +0800 |
| Subject: skmsg: Schedule psock work if the cached skb exists on the psock |
| |
| From: Liu Jian <liujian56@huawei.com> |
| |
| [ Upstream commit bec217197b412d74168c6a42fc0f76d0cc9cad00 ] |
| |
| 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 |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/core/skmsg.c | 12 ++++++++---- |
| 1 file 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); |
| -- |
| 2.35.1 |
| |