Skip to content

Commit 3ce0b2c

Browse files
committed
libeth: add Tx buffer completion helpers
JIRA: https://issues.redhat.com/browse/RHEL-59099 Upstream commit(s): commit 080d72f Author: Alexander Lobakin <[email protected]> Date: Wed Sep 4 17:47:43 2024 +0200 libeth: add Tx buffer completion helpers Software-side Tx buffers for storing DMA, frame size, skb pointers etc. are pretty much generic and every driver defines them the same way. The same can be said for software Tx completions -- same napi_consume_skb()s and all that... Add a couple simple wrappers for doing that to stop repeating the old tale at least within the Intel code. Drivers are free to use 'priv' member at the end of the structure. Reviewed-by: Przemek Kitszel <[email protected]> Signed-off-by: Alexander Lobakin <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Signed-off-by: Petr Oros <[email protected]>
1 parent eb1bdb9 commit 3ce0b2c

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

include/net/libeth/tx.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* Copyright (C) 2024 Intel Corporation */
3+
4+
#ifndef __LIBETH_TX_H
5+
#define __LIBETH_TX_H
6+
7+
#include <linux/skbuff.h>
8+
9+
#include <net/libeth/types.h>
10+
11+
/* Tx buffer completion */
12+
13+
/**
14+
* enum libeth_sqe_type - type of &libeth_sqe to act on Tx completion
15+
* @LIBETH_SQE_EMPTY: unused/empty, no action required
16+
* @LIBETH_SQE_CTX: context descriptor with empty SQE, no action required
17+
* @LIBETH_SQE_SLAB: kmalloc-allocated buffer, unmap and kfree()
18+
* @LIBETH_SQE_FRAG: mapped skb frag, only unmap DMA
19+
* @LIBETH_SQE_SKB: &sk_buff, unmap and napi_consume_skb(), update stats
20+
*/
21+
enum libeth_sqe_type {
22+
LIBETH_SQE_EMPTY = 0U,
23+
LIBETH_SQE_CTX,
24+
LIBETH_SQE_SLAB,
25+
LIBETH_SQE_FRAG,
26+
LIBETH_SQE_SKB,
27+
};
28+
29+
/**
30+
* struct libeth_sqe - represents a Send Queue Element / Tx buffer
31+
* @type: type of the buffer, see the enum above
32+
* @rs_idx: index of the last buffer from the batch this one was sent in
33+
* @raw: slab buffer to free via kfree()
34+
* @skb: &sk_buff to consume
35+
* @dma: DMA address to unmap
36+
* @len: length of the mapped region to unmap
37+
* @nr_frags: number of frags in the frame this buffer belongs to
38+
* @packets: number of physical packets sent for this frame
39+
* @bytes: number of physical bytes sent for this frame
40+
* @priv: driver-private scratchpad
41+
*/
42+
struct libeth_sqe {
43+
enum libeth_sqe_type type:32;
44+
u32 rs_idx;
45+
46+
union {
47+
void *raw;
48+
struct sk_buff *skb;
49+
};
50+
51+
DEFINE_DMA_UNMAP_ADDR(dma);
52+
DEFINE_DMA_UNMAP_LEN(len);
53+
54+
u32 nr_frags;
55+
u32 packets;
56+
u32 bytes;
57+
58+
unsigned long priv;
59+
} __aligned_largest;
60+
61+
/**
62+
* LIBETH_SQE_CHECK_PRIV - check the driver's private SQE data
63+
* @p: type or name of the object the driver wants to fit into &libeth_sqe
64+
*
65+
* Make sure the driver's private data fits into libeth_sqe::priv. To be used
66+
* right after its declaration.
67+
*/
68+
#define LIBETH_SQE_CHECK_PRIV(p) \
69+
static_assert(sizeof(p) <= sizeof_field(struct libeth_sqe, priv))
70+
71+
/**
72+
* struct libeth_cq_pp - completion queue poll params
73+
* @dev: &device to perform DMA unmapping
74+
* @ss: onstack NAPI stats to fill
75+
* @napi: whether it's called from the NAPI context
76+
*
77+
* libeth uses this structure to access objects needed for performing full
78+
* Tx complete operation without passing lots of arguments and change the
79+
* prototypes each time a new one is added.
80+
*/
81+
struct libeth_cq_pp {
82+
struct device *dev;
83+
struct libeth_sq_napi_stats *ss;
84+
85+
bool napi;
86+
};
87+
88+
/**
89+
* libeth_tx_complete - perform Tx completion for one SQE
90+
* @sqe: SQE to complete
91+
* @cp: poll params
92+
*
93+
* Do Tx complete for all the types of buffers, incl. freeing, unmapping,
94+
* updating the stats etc.
95+
*/
96+
static inline void libeth_tx_complete(struct libeth_sqe *sqe,
97+
const struct libeth_cq_pp *cp)
98+
{
99+
switch (sqe->type) {
100+
case LIBETH_SQE_EMPTY:
101+
return;
102+
case LIBETH_SQE_SKB:
103+
case LIBETH_SQE_FRAG:
104+
case LIBETH_SQE_SLAB:
105+
dma_unmap_page(cp->dev, dma_unmap_addr(sqe, dma),
106+
dma_unmap_len(sqe, len), DMA_TO_DEVICE);
107+
break;
108+
default:
109+
break;
110+
}
111+
112+
switch (sqe->type) {
113+
case LIBETH_SQE_SKB:
114+
cp->ss->packets += sqe->packets;
115+
cp->ss->bytes += sqe->bytes;
116+
117+
napi_consume_skb(sqe->skb, cp->napi);
118+
break;
119+
case LIBETH_SQE_SLAB:
120+
kfree(sqe->raw);
121+
break;
122+
default:
123+
break;
124+
}
125+
126+
sqe->type = LIBETH_SQE_EMPTY;
127+
}
128+
129+
#endif /* __LIBETH_TX_H */

include/net/libeth/types.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* Copyright (C) 2024 Intel Corporation */
3+
4+
#ifndef __LIBETH_TYPES_H
5+
#define __LIBETH_TYPES_H
6+
7+
#include <linux/types.h>
8+
9+
/**
10+
* struct libeth_sq_napi_stats - "hot" counters to update in Tx completion loop
11+
* @packets: completed frames counter
12+
* @bytes: sum of bytes of completed frames above
13+
* @raw: alias to access all the fields as an array
14+
*/
15+
struct libeth_sq_napi_stats {
16+
union {
17+
struct {
18+
u32 packets;
19+
u32 bytes;
20+
};
21+
DECLARE_FLEX_ARRAY(u32, raw);
22+
};
23+
};
24+
25+
#endif /* __LIBETH_TYPES_H */

0 commit comments

Comments
 (0)