Skip to content

Commit 341ac98

Browse files
fomichevAlexei Starovoitov
authored andcommitted
xsk: Support tx_metadata_len
For zerocopy mode, tx_desc->addr can point to an arbitrary offset and carry some TX metadata in the headroom. For copy mode, there is no way currently to populate skb metadata. Introduce new tx_metadata_len umem config option that indicates how many bytes to treat as metadata. Metadata bytes come prior to tx_desc address (same as in RX case). The size of the metadata has mostly the same constraints as XDP: - less than 256 bytes - 8-byte aligned (compared to 4-byte alignment on xdp, due to 8-byte timestamp in the completion) - non-zero This data is not interpreted in any way right now. Reviewed-by: Song Yoong Siang <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 40d0eb0 commit 341ac98

File tree

8 files changed

+30
-8
lines changed

8 files changed

+30
-8
lines changed

include/net/xdp_sock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct xdp_umem {
3030
struct user_struct *user;
3131
refcount_t users;
3232
u8 flags;
33+
u8 tx_metadata_len;
3334
bool zc;
3435
struct page **pgs;
3536
int id;

include/net/xsk_buff_pool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct xsk_buff_pool {
7777
u32 chunk_size;
7878
u32 chunk_shift;
7979
u32 frame_len;
80+
u8 tx_metadata_len; /* inherited from umem */
8081
u8 cached_need_wakeup;
8182
bool uses_need_wakeup;
8283
bool dma_need_sync;

include/uapi/linux/if_xdp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct xdp_umem_reg {
7676
__u32 chunk_size;
7777
__u32 headroom;
7878
__u32 flags;
79+
__u32 tx_metadata_len;
7980
};
8081

8182
struct xdp_statistics {

net/xdp/xdp_umem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
199199
if (headroom >= chunk_size - XDP_PACKET_HEADROOM)
200200
return -EINVAL;
201201

202+
if (mr->tx_metadata_len >= 256 || mr->tx_metadata_len % 8)
203+
return -EINVAL;
204+
202205
umem->size = size;
203206
umem->headroom = headroom;
204207
umem->chunk_size = chunk_size;
@@ -207,6 +210,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
207210
umem->pgs = NULL;
208211
umem->user = NULL;
209212
umem->flags = mr->flags;
213+
umem->tx_metadata_len = mr->tx_metadata_len;
210214

211215
INIT_LIST_HEAD(&umem->xsk_dma_list);
212216
refcount_set(&umem->users, 1);

net/xdp/xsk.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,14 @@ struct xdp_umem_reg_v1 {
12831283
__u32 headroom;
12841284
};
12851285

1286+
struct xdp_umem_reg_v2 {
1287+
__u64 addr; /* Start of packet data area */
1288+
__u64 len; /* Length of packet data area */
1289+
__u32 chunk_size;
1290+
__u32 headroom;
1291+
__u32 flags;
1292+
};
1293+
12861294
static int xsk_setsockopt(struct socket *sock, int level, int optname,
12871295
sockptr_t optval, unsigned int optlen)
12881296
{
@@ -1326,8 +1334,10 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
13261334

13271335
if (optlen < sizeof(struct xdp_umem_reg_v1))
13281336
return -EINVAL;
1329-
else if (optlen < sizeof(mr))
1337+
else if (optlen < sizeof(struct xdp_umem_reg_v2))
13301338
mr_size = sizeof(struct xdp_umem_reg_v1);
1339+
else if (optlen < sizeof(mr))
1340+
mr_size = sizeof(struct xdp_umem_reg_v2);
13311341

13321342
if (copy_from_sockptr(&mr, optval, mr_size))
13331343
return -EFAULT;

net/xdp/xsk_buff_pool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
8585
XDP_PACKET_HEADROOM;
8686
pool->umem = umem;
8787
pool->addrs = umem->addrs;
88+
pool->tx_metadata_len = umem->tx_metadata_len;
8889
INIT_LIST_HEAD(&pool->free_list);
8990
INIT_LIST_HEAD(&pool->xskb_list);
9091
INIT_LIST_HEAD(&pool->xsk_tx_list);

net/xdp/xsk_queue.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,17 @@ static inline bool xp_unused_options_set(u32 options)
143143
static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
144144
struct xdp_desc *desc)
145145
{
146-
u64 offset = desc->addr & (pool->chunk_size - 1);
146+
u64 addr = desc->addr - pool->tx_metadata_len;
147+
u64 len = desc->len + pool->tx_metadata_len;
148+
u64 offset = addr & (pool->chunk_size - 1);
147149

148150
if (!desc->len)
149151
return false;
150152

151-
if (offset + desc->len > pool->chunk_size)
153+
if (offset + len > pool->chunk_size)
152154
return false;
153155

154-
if (desc->addr >= pool->addrs_cnt)
156+
if (addr >= pool->addrs_cnt)
155157
return false;
156158

157159
if (xp_unused_options_set(desc->options))
@@ -162,16 +164,17 @@ static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
162164
static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool,
163165
struct xdp_desc *desc)
164166
{
165-
u64 addr = xp_unaligned_add_offset_to_addr(desc->addr);
167+
u64 addr = xp_unaligned_add_offset_to_addr(desc->addr) - pool->tx_metadata_len;
168+
u64 len = desc->len + pool->tx_metadata_len;
166169

167170
if (!desc->len)
168171
return false;
169172

170-
if (desc->len > pool->chunk_size)
173+
if (len > pool->chunk_size)
171174
return false;
172175

173-
if (addr >= pool->addrs_cnt || addr + desc->len > pool->addrs_cnt ||
174-
xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
176+
if (addr >= pool->addrs_cnt || addr + len > pool->addrs_cnt ||
177+
xp_desc_crosses_non_contig_pg(pool, addr, len))
175178
return false;
176179

177180
if (xp_unused_options_set(desc->options))

tools/include/uapi/linux/if_xdp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct xdp_umem_reg {
7676
__u32 chunk_size;
7777
__u32 headroom;
7878
__u32 flags;
79+
__u32 tx_metadata_len;
7980
};
8081

8182
struct xdp_statistics {

0 commit comments

Comments
 (0)