xref: /linux/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Google virtual Ethernet (gve) driver
3  *
4  * Copyright (C) 2015-2024 Google, Inc.
5  */
6 
7 #include <net/xdp_sock_drv.h>
8 #include "gve.h"
9 #include "gve_utils.h"
10 
gve_buf_ref_cnt(struct gve_rx_buf_state_dqo * bs)11 int gve_buf_ref_cnt(struct gve_rx_buf_state_dqo *bs)
12 {
13 	return page_count(bs->page_info.page) - bs->page_info.pagecnt_bias;
14 }
15 
gve_alloc_buf_state(struct gve_rx_ring * rx)16 struct gve_rx_buf_state_dqo *gve_alloc_buf_state(struct gve_rx_ring *rx)
17 {
18 	struct gve_rx_buf_state_dqo *buf_state;
19 	s16 buffer_id;
20 
21 	buffer_id = rx->dqo.free_buf_states;
22 	if (unlikely(buffer_id == -1))
23 		return NULL;
24 
25 	buf_state = &rx->dqo.buf_states[buffer_id];
26 
27 	/* Remove buf_state from free list */
28 	rx->dqo.free_buf_states = buf_state->next;
29 
30 	/* Point buf_state to itself to mark it as allocated */
31 	buf_state->next = buffer_id;
32 
33 	/* Clear the buffer pointers */
34 	buf_state->page_info.page = NULL;
35 	buf_state->xsk_buff = NULL;
36 
37 	return buf_state;
38 }
39 
gve_buf_state_is_allocated(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)40 bool gve_buf_state_is_allocated(struct gve_rx_ring *rx,
41 				struct gve_rx_buf_state_dqo *buf_state)
42 {
43 	s16 buffer_id = buf_state - rx->dqo.buf_states;
44 
45 	return buf_state->next == buffer_id;
46 }
47 
gve_free_buf_state(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)48 void gve_free_buf_state(struct gve_rx_ring *rx,
49 			struct gve_rx_buf_state_dqo *buf_state)
50 {
51 	s16 buffer_id = buf_state - rx->dqo.buf_states;
52 
53 	buf_state->next = rx->dqo.free_buf_states;
54 	rx->dqo.free_buf_states = buffer_id;
55 }
56 
gve_dequeue_buf_state(struct gve_rx_ring * rx,struct gve_index_list * list)57 struct gve_rx_buf_state_dqo *gve_dequeue_buf_state(struct gve_rx_ring *rx,
58 						   struct gve_index_list *list)
59 {
60 	struct gve_rx_buf_state_dqo *buf_state;
61 	s16 buffer_id;
62 
63 	buffer_id = list->head;
64 	if (unlikely(buffer_id == -1))
65 		return NULL;
66 
67 	buf_state = &rx->dqo.buf_states[buffer_id];
68 
69 	/* Remove buf_state from list */
70 	list->head = buf_state->next;
71 	if (buf_state->next == -1)
72 		list->tail = -1;
73 
74 	/* Point buf_state to itself to mark it as allocated */
75 	buf_state->next = buffer_id;
76 
77 	return buf_state;
78 }
79 
gve_enqueue_buf_state(struct gve_rx_ring * rx,struct gve_index_list * list,struct gve_rx_buf_state_dqo * buf_state)80 void gve_enqueue_buf_state(struct gve_rx_ring *rx, struct gve_index_list *list,
81 			   struct gve_rx_buf_state_dqo *buf_state)
82 {
83 	s16 buffer_id = buf_state - rx->dqo.buf_states;
84 
85 	buf_state->next = -1;
86 
87 	if (list->head == -1) {
88 		list->head = buffer_id;
89 		list->tail = buffer_id;
90 	} else {
91 		int tail = list->tail;
92 
93 		rx->dqo.buf_states[tail].next = buffer_id;
94 		list->tail = buffer_id;
95 	}
96 }
97 
gve_get_recycled_buf_state(struct gve_rx_ring * rx)98 struct gve_rx_buf_state_dqo *gve_get_recycled_buf_state(struct gve_rx_ring *rx)
99 {
100 	struct gve_rx_buf_state_dqo *buf_state;
101 	int i;
102 
103 	/* Recycled buf states are immediately usable. */
104 	buf_state = gve_dequeue_buf_state(rx, &rx->dqo.recycled_buf_states);
105 	if (likely(buf_state))
106 		return buf_state;
107 
108 	if (unlikely(rx->dqo.used_buf_states.head == -1))
109 		return NULL;
110 
111 	/* Used buf states are only usable when ref count reaches 0, which means
112 	 * no SKBs refer to them.
113 	 *
114 	 * Search a limited number before giving up.
115 	 */
116 	for (i = 0; i < 5; i++) {
117 		buf_state = gve_dequeue_buf_state(rx, &rx->dqo.used_buf_states);
118 		if (gve_buf_ref_cnt(buf_state) == 0) {
119 			rx->dqo.used_buf_states_cnt--;
120 			return buf_state;
121 		}
122 
123 		gve_enqueue_buf_state(rx, &rx->dqo.used_buf_states, buf_state);
124 	}
125 
126 	return NULL;
127 }
128 
gve_alloc_qpl_page_dqo(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)129 int gve_alloc_qpl_page_dqo(struct gve_rx_ring *rx,
130 			   struct gve_rx_buf_state_dqo *buf_state)
131 {
132 	struct gve_priv *priv = rx->gve;
133 	u32 idx;
134 
135 	idx = rx->dqo.next_qpl_page_idx;
136 	if (idx >= gve_get_rx_pages_per_qpl_dqo(priv->rx_desc_cnt)) {
137 		net_err_ratelimited("%s: Out of QPL pages\n",
138 				    priv->dev->name);
139 		return -ENOMEM;
140 	}
141 	buf_state->page_info.page = rx->dqo.qpl->pages[idx];
142 	buf_state->addr = rx->dqo.qpl->page_buses[idx];
143 	rx->dqo.next_qpl_page_idx++;
144 	buf_state->page_info.page_offset = 0;
145 	buf_state->page_info.page_address =
146 		page_address(buf_state->page_info.page);
147 	buf_state->page_info.buf_size = rx->packet_buffer_truesize;
148 	buf_state->page_info.pad = rx->rx_headroom;
149 	buf_state->last_single_ref_offset = 0;
150 
151 	/* The page already has 1 ref. */
152 	page_ref_add(buf_state->page_info.page, INT_MAX - 1);
153 	buf_state->page_info.pagecnt_bias = INT_MAX;
154 
155 	return 0;
156 }
157 
gve_free_qpl_page_dqo(struct gve_rx_buf_state_dqo * buf_state)158 void gve_free_qpl_page_dqo(struct gve_rx_buf_state_dqo *buf_state)
159 {
160 	if (!buf_state->page_info.page)
161 		return;
162 
163 	page_ref_sub(buf_state->page_info.page,
164 		     buf_state->page_info.pagecnt_bias - 1);
165 	buf_state->page_info.page = NULL;
166 }
167 
gve_try_recycle_buf(struct gve_priv * priv,struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)168 void gve_try_recycle_buf(struct gve_priv *priv, struct gve_rx_ring *rx,
169 			 struct gve_rx_buf_state_dqo *buf_state)
170 {
171 	const u16 data_buffer_size = rx->packet_buffer_truesize;
172 	int pagecount;
173 
174 	/* Can't reuse if we only fit one buffer per page */
175 	if (data_buffer_size * 2 > PAGE_SIZE)
176 		goto mark_used;
177 
178 	pagecount = gve_buf_ref_cnt(buf_state);
179 
180 	/* Record the offset when we have a single remaining reference.
181 	 *
182 	 * When this happens, we know all of the other offsets of the page are
183 	 * usable.
184 	 */
185 	if (pagecount == 1) {
186 		buf_state->last_single_ref_offset =
187 			buf_state->page_info.page_offset;
188 	}
189 
190 	/* Use the next buffer sized chunk in the page. */
191 	buf_state->page_info.page_offset += data_buffer_size;
192 	buf_state->page_info.page_offset &= (PAGE_SIZE - 1);
193 
194 	/* If we wrap around to the same offset without ever dropping to 1
195 	 * reference, then we don't know if this offset was ever freed.
196 	 */
197 	if (buf_state->page_info.page_offset ==
198 	    buf_state->last_single_ref_offset) {
199 		goto mark_used;
200 	}
201 
202 	gve_enqueue_buf_state(rx, &rx->dqo.recycled_buf_states, buf_state);
203 	return;
204 
205 mark_used:
206 	gve_enqueue_buf_state(rx, &rx->dqo.used_buf_states, buf_state);
207 	rx->dqo.used_buf_states_cnt++;
208 }
209 
gve_free_to_page_pool(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state,bool allow_direct)210 void gve_free_to_page_pool(struct gve_rx_ring *rx,
211 			   struct gve_rx_buf_state_dqo *buf_state,
212 			   bool allow_direct)
213 {
214 	netmem_ref netmem = buf_state->page_info.netmem;
215 
216 	if (!netmem)
217 		return;
218 
219 	page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, allow_direct);
220 	buf_state->page_info.netmem = 0;
221 }
222 
gve_alloc_from_page_pool(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)223 static int gve_alloc_from_page_pool(struct gve_rx_ring *rx,
224 				    struct gve_rx_buf_state_dqo *buf_state)
225 {
226 	netmem_ref netmem;
227 
228 	buf_state->page_info.buf_size = rx->packet_buffer_truesize;
229 	netmem = page_pool_alloc_netmem(rx->dqo.page_pool,
230 					&buf_state->page_info.page_offset,
231 					&buf_state->page_info.buf_size,
232 					GFP_ATOMIC);
233 
234 	if (!netmem)
235 		return -ENOMEM;
236 
237 	buf_state->page_info.netmem = netmem;
238 	buf_state->page_info.page_address = netmem_address(netmem);
239 	buf_state->addr = page_pool_get_dma_addr_netmem(netmem);
240 	buf_state->page_info.pad = rx->dqo.page_pool->p.offset;
241 
242 	return 0;
243 }
244 
gve_rx_create_page_pool(struct gve_priv * priv,struct gve_rx_ring * rx,bool xdp)245 struct page_pool *gve_rx_create_page_pool(struct gve_priv *priv,
246 					  struct gve_rx_ring *rx,
247 					  bool xdp)
248 {
249 	u32 ntfy_id = gve_rx_idx_to_ntfy(priv, rx->q_num);
250 	struct page_pool_params pp = {
251 		.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
252 		.order = 0,
253 		.pool_size = GVE_PAGE_POOL_SIZE_MULTIPLIER * priv->rx_desc_cnt,
254 		.nid = priv->numa_node,
255 		.dev = &priv->pdev->dev,
256 		.netdev = priv->dev,
257 		.napi = &priv->ntfy_blocks[ntfy_id].napi,
258 		.max_len = PAGE_SIZE,
259 		.dma_dir = xdp ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE,
260 		.offset = xdp ? XDP_PACKET_HEADROOM : 0,
261 	};
262 
263 	return page_pool_create(&pp);
264 }
265 
gve_free_buffer(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)266 void gve_free_buffer(struct gve_rx_ring *rx,
267 		     struct gve_rx_buf_state_dqo *buf_state)
268 {
269 	if (rx->dqo.page_pool) {
270 		gve_free_to_page_pool(rx, buf_state, true);
271 		gve_free_buf_state(rx, buf_state);
272 	} else {
273 		gve_enqueue_buf_state(rx, &rx->dqo.recycled_buf_states,
274 				      buf_state);
275 	}
276 }
277 
gve_reuse_buffer(struct gve_rx_ring * rx,struct gve_rx_buf_state_dqo * buf_state)278 void gve_reuse_buffer(struct gve_rx_ring *rx,
279 		      struct gve_rx_buf_state_dqo *buf_state)
280 {
281 	if (rx->dqo.page_pool) {
282 		buf_state->page_info.netmem = 0;
283 		gve_free_buf_state(rx, buf_state);
284 	} else {
285 		gve_dec_pagecnt_bias(&buf_state->page_info);
286 		gve_try_recycle_buf(rx->gve, rx, buf_state);
287 	}
288 }
289 
gve_alloc_buffer(struct gve_rx_ring * rx,struct gve_rx_desc_dqo * desc)290 int gve_alloc_buffer(struct gve_rx_ring *rx, struct gve_rx_desc_dqo *desc)
291 {
292 	struct gve_rx_buf_state_dqo *buf_state;
293 
294 	if (rx->xsk_pool) {
295 		buf_state = gve_alloc_buf_state(rx);
296 		if (unlikely(!buf_state))
297 			return -ENOMEM;
298 
299 		buf_state->xsk_buff = xsk_buff_alloc(rx->xsk_pool);
300 		if (unlikely(!buf_state->xsk_buff)) {
301 			xsk_set_rx_need_wakeup(rx->xsk_pool);
302 			gve_free_buf_state(rx, buf_state);
303 			return -ENOMEM;
304 		}
305 		/* Allocated xsk buffer. Clear wakeup in case it was set. */
306 		xsk_clear_rx_need_wakeup(rx->xsk_pool);
307 		desc->buf_id = cpu_to_le16(buf_state - rx->dqo.buf_states);
308 		desc->buf_addr =
309 			cpu_to_le64(xsk_buff_xdp_get_dma(buf_state->xsk_buff));
310 		return 0;
311 	} else if (rx->dqo.page_pool) {
312 		buf_state = gve_alloc_buf_state(rx);
313 		if (WARN_ON_ONCE(!buf_state))
314 			return -ENOMEM;
315 
316 		if (gve_alloc_from_page_pool(rx, buf_state))
317 			goto free_buf_state;
318 	} else {
319 		buf_state = gve_get_recycled_buf_state(rx);
320 		if (unlikely(!buf_state)) {
321 			buf_state = gve_alloc_buf_state(rx);
322 			if (unlikely(!buf_state))
323 				return -ENOMEM;
324 
325 			if (unlikely(gve_alloc_qpl_page_dqo(rx, buf_state)))
326 				goto free_buf_state;
327 		}
328 	}
329 	desc->buf_id = cpu_to_le16(buf_state - rx->dqo.buf_states);
330 	desc->buf_addr = cpu_to_le64(buf_state->addr +
331 				     buf_state->page_info.page_offset +
332 				     buf_state->page_info.pad);
333 
334 	return 0;
335 
336 free_buf_state:
337 	gve_free_buf_state(rx, buf_state);
338 	return -ENOMEM;
339 }
340