aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skmsg.h
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2018-10-16 11:07:59 -0700
committerDaniel Borkmann <daniel@iogearbox.net>2018-10-17 02:30:31 +0200
commit8734a162c13b1a893e7dff8de0df81fed04c51a6 (patch)
treec2315a4509373faded8a283081efce95a7b6ad7e /include/linux/skmsg.h
parentbpf: sockmap, fix skmsg recvmsg handler to track size correctly (diff)
downloadlinux-dev-8734a162c13b1a893e7dff8de0df81fed04c51a6.tar.xz
linux-dev-8734a162c13b1a893e7dff8de0df81fed04c51a6.zip
bpf: skmsg, improve sk_msg_used_element to work in cork context
Currently sk_msg_used_element is only called in zerocopy context where cork is not possible and if this case happens we fallback to copy mode. However the helper is more useful if it works in all contexts. This patch resolved the case where if end == head indicating a full or empty ring the helper always reports an empty ring. To fix this add a test for the full ring case to avoid reporting a full ring has 0 elements. This additional functionality will be used in the next patches from recvmsg context where end = head with a full ring is a valid case. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'include/linux/skmsg.h')
-rw-r--r--include/linux/skmsg.h13
1 files changed, 8 insertions, 5 deletions
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
index 31df0d9fa536..22347b08e1f8 100644
--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
@@ -187,18 +187,21 @@ static inline void sk_msg_xfer_full(struct sk_msg *dst, struct sk_msg *src)
sk_msg_init(src);
}
+static inline bool sk_msg_full(const struct sk_msg *msg)
+{
+ return (msg->sg.end == msg->sg.start) && msg->sg.size;
+}
+
static inline u32 sk_msg_elem_used(const struct sk_msg *msg)
{
+ if (sk_msg_full(msg))
+ return MAX_MSG_FRAGS;
+
return msg->sg.end >= msg->sg.start ?
msg->sg.end - msg->sg.start :
msg->sg.end + (MAX_MSG_FRAGS - msg->sg.start);
}
-static inline bool sk_msg_full(const struct sk_msg *msg)
-{
- return (msg->sg.end == msg->sg.start) && msg->sg.size;
-}
-
static inline struct scatterlist *sk_msg_elem(struct sk_msg *msg, int which)
{
return &msg->sg.data[which];