6
6
/* Rx buffer management */
7
7
8
8
/**
9
- * libeth_rx_hw_len - get the actual buffer size to be passed to HW
9
+ * libeth_rx_hw_len_mtu - get the actual buffer size to be passed to HW
10
10
* @pp: &page_pool_params of the netdev to calculate the size for
11
11
* @max_len: maximum buffer size for a single descriptor
12
12
*
13
13
* Return: HW-writeable length per one buffer to pass it to the HW accounting:
14
14
* MTU the @dev has, HW required alignment, minimum and maximum allowed values,
15
15
* and system's page size.
16
16
*/
17
- static u32 libeth_rx_hw_len (const struct page_pool_params * pp , u32 max_len )
17
+ static u32 libeth_rx_hw_len_mtu (const struct page_pool_params * pp , u32 max_len )
18
18
{
19
19
u32 len ;
20
20
@@ -26,6 +26,118 @@ static u32 libeth_rx_hw_len(const struct page_pool_params *pp, u32 max_len)
26
26
return len ;
27
27
}
28
28
29
+ /**
30
+ * libeth_rx_hw_len_truesize - get the short buffer size to be passed to HW
31
+ * @pp: &page_pool_params of the netdev to calculate the size for
32
+ * @max_len: maximum buffer size for a single descriptor
33
+ * @truesize: desired truesize for the buffers
34
+ *
35
+ * Return: HW-writeable length per one buffer to pass it to the HW ignoring the
36
+ * MTU and closest to the passed truesize. Can be used for "short" buffer
37
+ * queues to fragment pages more efficiently.
38
+ */
39
+ static u32 libeth_rx_hw_len_truesize (const struct page_pool_params * pp ,
40
+ u32 max_len , u32 truesize )
41
+ {
42
+ u32 min , len ;
43
+
44
+ min = SKB_HEAD_ALIGN (pp -> offset + LIBETH_RX_BUF_STRIDE );
45
+ truesize = clamp (roundup_pow_of_two (truesize ), roundup_pow_of_two (min ),
46
+ PAGE_SIZE << LIBETH_RX_PAGE_ORDER );
47
+
48
+ len = SKB_WITH_OVERHEAD (truesize - pp -> offset );
49
+ len = ALIGN_DOWN (len , LIBETH_RX_BUF_STRIDE ) ? : LIBETH_RX_BUF_STRIDE ;
50
+ len = min3 (len , ALIGN_DOWN (max_len ? : U32_MAX , LIBETH_RX_BUF_STRIDE ),
51
+ pp -> max_len );
52
+
53
+ return len ;
54
+ }
55
+
56
+ /**
57
+ * libeth_rx_page_pool_params - calculate params with the stack overhead
58
+ * @fq: buffer queue to calculate the size for
59
+ * @pp: &page_pool_params of the netdev
60
+ *
61
+ * Set the PP params to will all needed stack overhead (headroom, tailroom) and
62
+ * both the HW buffer length and the truesize for all types of buffers. For
63
+ * "short" buffers, truesize never exceeds the "wanted" one; for the rest,
64
+ * it can be up to the page size.
65
+ *
66
+ * Return: true on success, false on invalid input params.
67
+ */
68
+ static bool libeth_rx_page_pool_params (struct libeth_fq * fq ,
69
+ struct page_pool_params * pp )
70
+ {
71
+ pp -> offset = LIBETH_SKB_HEADROOM ;
72
+ /* HW-writeable / syncable length per one page */
73
+ pp -> max_len = LIBETH_RX_PAGE_LEN (pp -> offset );
74
+
75
+ /* HW-writeable length per buffer */
76
+ switch (fq -> type ) {
77
+ case LIBETH_FQE_MTU :
78
+ fq -> buf_len = libeth_rx_hw_len_mtu (pp , fq -> buf_len );
79
+ break ;
80
+ case LIBETH_FQE_SHORT :
81
+ fq -> buf_len = libeth_rx_hw_len_truesize (pp , fq -> buf_len ,
82
+ fq -> truesize );
83
+ break ;
84
+ case LIBETH_FQE_HDR :
85
+ fq -> buf_len = ALIGN (LIBETH_MAX_HEAD , LIBETH_RX_BUF_STRIDE );
86
+ break ;
87
+ default :
88
+ return false;
89
+ }
90
+
91
+ /* Buffer size to allocate */
92
+ fq -> truesize = roundup_pow_of_two (SKB_HEAD_ALIGN (pp -> offset +
93
+ fq -> buf_len ));
94
+
95
+ return true;
96
+ }
97
+
98
+ /**
99
+ * libeth_rx_page_pool_params_zc - calculate params without the stack overhead
100
+ * @fq: buffer queue to calculate the size for
101
+ * @pp: &page_pool_params of the netdev
102
+ *
103
+ * Set the PP params to exclude the stack overhead and both the buffer length
104
+ * and the truesize, which are equal for the data buffers. Note that this
105
+ * requires separate header buffers to be always active and account the
106
+ * overhead.
107
+ * With the MTU == ``PAGE_SIZE``, this allows the kernel to enable the zerocopy
108
+ * mode.
109
+ *
110
+ * Return: true on success, false on invalid input params.
111
+ */
112
+ static bool libeth_rx_page_pool_params_zc (struct libeth_fq * fq ,
113
+ struct page_pool_params * pp )
114
+ {
115
+ u32 mtu , max ;
116
+
117
+ pp -> offset = 0 ;
118
+ pp -> max_len = PAGE_SIZE << LIBETH_RX_PAGE_ORDER ;
119
+
120
+ switch (fq -> type ) {
121
+ case LIBETH_FQE_MTU :
122
+ mtu = READ_ONCE (pp -> netdev -> mtu );
123
+ break ;
124
+ case LIBETH_FQE_SHORT :
125
+ mtu = fq -> truesize ;
126
+ break ;
127
+ default :
128
+ return false;
129
+ }
130
+
131
+ mtu = roundup_pow_of_two (mtu );
132
+ max = min (rounddown_pow_of_two (fq -> buf_len ? : U32_MAX ),
133
+ pp -> max_len );
134
+
135
+ fq -> buf_len = clamp (mtu , LIBETH_RX_BUF_STRIDE , max );
136
+ fq -> truesize = fq -> buf_len ;
137
+
138
+ return true;
139
+ }
140
+
29
141
/**
30
142
* libeth_rx_fq_create - create a PP with the default libeth settings
31
143
* @fq: buffer queue struct to fill
@@ -44,19 +156,17 @@ int libeth_rx_fq_create(struct libeth_fq *fq, struct napi_struct *napi)
44
156
.netdev = napi -> dev ,
45
157
.napi = napi ,
46
158
.dma_dir = DMA_FROM_DEVICE ,
47
- .offset = LIBETH_SKB_HEADROOM ,
48
159
};
49
160
struct libeth_fqe * fqes ;
50
161
struct page_pool * pool ;
162
+ bool ret ;
51
163
52
- /* HW-writeable / syncable length per one page */
53
- pp .max_len = LIBETH_RX_PAGE_LEN (pp .offset );
54
-
55
- /* HW-writeable length per buffer */
56
- fq -> buf_len = libeth_rx_hw_len (& pp , fq -> buf_len );
57
- /* Buffer size to allocate */
58
- fq -> truesize = roundup_pow_of_two (SKB_HEAD_ALIGN (pp .offset +
59
- fq -> buf_len ));
164
+ if (!fq -> hsplit )
165
+ ret = libeth_rx_page_pool_params (fq , & pp );
166
+ else
167
+ ret = libeth_rx_page_pool_params_zc (fq , & pp );
168
+ if (!ret )
169
+ return - EINVAL ;
60
170
61
171
pool = page_pool_create (& pp );
62
172
if (IS_ERR (pool ))
0 commit comments