Skip to content

Commit f4b7b13

Browse files
committed
bpf: Allow bpf_xdp_shrink_data to shrink from head and tail
Move skb_frag_t adjustment into bpf_xdp_shrink_data() and extend its functionality to be able to shrink an xdp fragment from both head and tail. In a later patch, bpf_xdp_pull_data() will use it to shrink a xdp fragment from head. Signed-off-by: Amery Hung <[email protected]>
1 parent 5c42715 commit f4b7b13

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

include/net/xdp_sock_drv.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,23 @@ static inline struct xdp_buff *xsk_buff_get_frag(const struct xdp_buff *first)
160160
return ret;
161161
}
162162

163-
static inline void xsk_buff_del_tail(struct xdp_buff *tail)
163+
static inline void xsk_buff_del_frag(struct xdp_buff *xdp)
164164
{
165-
struct xdp_buff_xsk *xskb = container_of(tail, struct xdp_buff_xsk, xdp);
165+
struct xdp_buff_xsk *xskb = container_of(xdp, struct xdp_buff_xsk, xdp);
166166

167167
list_del(&xskb->list_node);
168168
}
169169

170+
static inline struct xdp_buff *xsk_buff_get_head(struct xdp_buff *first)
171+
{
172+
struct xdp_buff_xsk *xskb = container_of(first, struct xdp_buff_xsk, xdp);
173+
struct xdp_buff_xsk *frag;
174+
175+
frag = list_first_entry(&xskb->pool->xskb_list, struct xdp_buff_xsk,
176+
list_node);
177+
return &frag->xdp;
178+
}
179+
170180
static inline struct xdp_buff *xsk_buff_get_tail(struct xdp_buff *first)
171181
{
172182
struct xdp_buff_xsk *xskb = container_of(first, struct xdp_buff_xsk, xdp);
@@ -389,8 +399,13 @@ static inline struct xdp_buff *xsk_buff_get_frag(const struct xdp_buff *first)
389399
return NULL;
390400
}
391401

392-
static inline void xsk_buff_del_tail(struct xdp_buff *tail)
402+
static inline void xsk_buff_del_frag(struct xdp_buff *xdp)
403+
{
404+
}
405+
406+
static inline struct xdp_buff *xsk_buff_get_head(struct xdp_buff *first)
393407
{
408+
return NULL;
394409
}
395410

396411
static inline struct xdp_buff *xsk_buff_get_tail(struct xdp_buff *first)

net/core/filter.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4153,34 +4153,43 @@ static int bpf_xdp_frags_increase_tail(struct xdp_buff *xdp, int offset)
41534153
return 0;
41544154
}
41554155

4156-
static void bpf_xdp_shrink_data_zc(struct xdp_buff *xdp, int shrink,
4156+
static void bpf_xdp_shrink_data_zc(struct xdp_buff *xdp, int shrink, bool tail,
41574157
enum xdp_mem_type mem_type, bool release)
41584158
{
4159-
struct xdp_buff *zc_frag = xsk_buff_get_tail(xdp);
4159+
struct xdp_buff *zc_frag = tail? xsk_buff_get_tail(xdp) :
4160+
xsk_buff_get_head(xdp);
41604161

41614162
if (release) {
4162-
xsk_buff_del_tail(zc_frag);
4163+
xsk_buff_del_frag(zc_frag);
41634164
__xdp_return(0, mem_type, false, zc_frag);
41644165
} else {
4165-
zc_frag->data_end -= shrink;
4166+
if (tail)
4167+
zc_frag->data_end -= shrink;
4168+
else
4169+
zc_frag->data += shrink;
41664170
}
41674171
}
41684172

41694173
static bool bpf_xdp_shrink_data(struct xdp_buff *xdp, skb_frag_t *frag,
4170-
int shrink)
4174+
int shrink, bool tail)
41714175
{
41724176
enum xdp_mem_type mem_type = xdp->rxq->mem.type;
41734177
bool release = skb_frag_size(frag) == shrink;
41744178

41754179
if (mem_type == MEM_TYPE_XSK_BUFF_POOL) {
4176-
bpf_xdp_shrink_data_zc(xdp, shrink, mem_type, release);
4180+
bpf_xdp_shrink_data_zc(xdp, shrink, tail, mem_type, release);
41774181
goto out;
41784182
}
41794183

41804184
if (release)
41814185
__xdp_return(skb_frag_netmem(frag), mem_type, false, NULL);
4182-
41834186
out:
4187+
if (!release) {
4188+
if (!tail)
4189+
skb_frag_off_add(frag, shrink);
4190+
skb_frag_size_sub(frag, shrink);
4191+
}
4192+
41844193
return release;
41854194
}
41864195

@@ -4198,12 +4207,8 @@ static int bpf_xdp_frags_shrink_tail(struct xdp_buff *xdp, int offset)
41984207

41994208
len_free += shrink;
42004209
offset -= shrink;
4201-
if (bpf_xdp_shrink_data(xdp, frag, shrink)) {
4210+
if (bpf_xdp_shrink_data(xdp, frag, shrink, true))
42024211
n_frags_free++;
4203-
} else {
4204-
skb_frag_size_sub(frag, shrink);
4205-
break;
4206-
}
42074212
}
42084213
sinfo->nr_frags -= n_frags_free;
42094214
sinfo->xdp_frags_size -= len_free;

0 commit comments

Comments
 (0)