[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200727224444.2987641-10-jonathan.lemon@gmail.com>
Date: Mon, 27 Jul 2020 15:44:32 -0700
From: Jonathan Lemon <jonathan.lemon@...il.com>
To: <netdev@...r.kernel.org>
CC: <kernel-team@...com>
Subject: [RFC PATCH v2 09/21] core/skbuff: use skb_zdata for testing whether skb is zerocopy
From: Jonathan Lemon <bsd@...com>
skb_zcopy() flag indicates whether the skb has a zerocopy ubuf.
netgpu does not use ubufs, so skb_zdata() indicates whether the
skb is carrying zero copy data, and should be left alone, while
skb_zcopy() indicates whether there is an attached ubuf.
Signed-off-by: Jonathan Lemon <jonathan.lemon@...il.com>
---
include/linux/skbuff.h | 24 +++++++++++++++++++++++-
net/core/skbuff.c | 17 ++++++++++++++++-
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 006e10fcc7d9..017c20792c23 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -443,8 +443,12 @@ enum {
/* generate software time stamp when entering packet scheduling */
SKBTX_SCHED_TSTAMP = 1 << 6,
+
+ /* fragments are accessed only via DMA */
+ SKBTX_DEV_NETDMA = 1 << 7,
};
+#define SKBTX_ZERODATA_FRAG (SKBTX_DEV_ZEROCOPY | SKBTX_DEV_NETDMA)
#define SKBTX_ZEROCOPY_FRAG (SKBTX_DEV_ZEROCOPY | SKBTX_SHARED_FRAG)
#define SKBTX_ANY_SW_TSTAMP (SKBTX_SW_TSTAMP | \
SKBTX_SCHED_TSTAMP)
@@ -1420,6 +1424,24 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb)
return &skb_shinfo(skb)->hwtstamps;
}
+static inline bool skb_netdma(struct sk_buff *skb)
+{
+ return skb && skb_shinfo(skb)->tx_flags & SKBTX_DEV_NETDMA;
+}
+
+static inline bool skb_zdata(struct sk_buff *skb)
+{
+ return skb && skb_shinfo(skb)->tx_flags & SKBTX_ZERODATA_FRAG;
+}
+
+static inline void skb_netdma_set(struct sk_buff *skb, void *arg)
+{
+ if (skb && arg) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_DEV_NETDMA;
+ skb_shinfo(skb)->destructor_arg = arg;
+ }
+}
+
static inline struct ubuf_info *skb_zcopy(struct sk_buff *skb)
{
bool is_zcopy = skb && skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY;
@@ -3264,7 +3286,7 @@ static inline int skb_add_data(struct sk_buff *skb,
static inline bool skb_can_coalesce(struct sk_buff *skb, int i,
const struct page *page, int off)
{
- if (skb_zcopy(skb))
+ if (skb_zdata(skb))
return false;
if (i) {
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2a391042be53..1422b99b7090 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -69,6 +69,7 @@
#include <net/xfrm.h>
#include <net/mpls.h>
#include <net/mptcp.h>
+#include <net/netgpu.h>
#include <linux/uaccess.h>
#include <trace/events/skb.h>
@@ -1300,6 +1301,8 @@ int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb,
}
skb_zcopy_set(skb, uarg, NULL);
+ skb_netdma_set(skb, sk->sk_user_data);
+
return skb->len - orig_len;
}
EXPORT_SYMBOL_GPL(skb_zerocopy_iter_stream);
@@ -1307,6 +1310,16 @@ EXPORT_SYMBOL_GPL(skb_zerocopy_iter_stream);
static int skb_zerocopy_clone(struct sk_buff *nskb, struct sk_buff *orig,
gfp_t gfp_mask)
{
+ if (skb_netdma(orig)) {
+ if (skb_netdma(nskb)) {
+ WARN_ONCE(1, "zc clone, dst skb is set\n");
+ if (skb_uarg(nskb) != skb_uarg(orig))
+ return -EIO;
+ }
+ skb_netdma_set(nskb, skb_shinfo(orig)->destructor_arg);
+ return 0;
+ }
+
if (skb_zcopy(orig)) {
if (skb_zcopy(nskb)) {
/* !gfp_mask callers are verified to !skb_zcopy(nskb) */
@@ -2055,6 +2068,8 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
*/
int i, k, eat = (skb->tail + delta) - skb->end;
+ BUG_ON(skb_netdma(skb));
+
if (eat > 0 || skb_cloned(skb)) {
if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0,
GFP_ATOMIC))
@@ -3305,7 +3320,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
if (skb_headlen(skb))
return 0;
- if (skb_zcopy(tgt) || skb_zcopy(skb))
+ if (skb_zdata(tgt) || skb_zdata(skb))
return 0;
todo = shiftlen;
--
2.24.1
Powered by blists - more mailing lists