aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sfc/efx.c3
-rw-r--r--drivers/net/sfc/net_driver.h18
-rw-r--r--drivers/net/sfc/rx.c84
3 files changed, 62 insertions, 43 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 5d9ef05e6ab..aae33471029 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -469,7 +469,8 @@ static void efx_init_channels(struct efx_nic *efx)
469 efx->rx_buffer_len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + 469 efx->rx_buffer_len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) +
470 EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + 470 EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
471 efx->type->rx_buffer_padding); 471 efx->type->rx_buffer_padding);
472 efx->rx_buffer_order = get_order(efx->rx_buffer_len); 472 efx->rx_buffer_order = get_order(efx->rx_buffer_len +
473 sizeof(struct efx_rx_page_state));
473 474
474 /* Initialise the channels */ 475 /* Initialise the channels */
475 efx_for_each_channel(channel, efx) { 476 efx_for_each_channel(channel, efx) {
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 59c8ecc39ae..40c0d931b18 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -232,6 +232,24 @@ struct efx_rx_buffer {
232}; 232};
233 233
234/** 234/**
235 * struct efx_rx_page_state - Page-based rx buffer state
236 *
237 * Inserted at the start of every page allocated for receive buffers.
238 * Used to facilitate sharing dma mappings between recycled rx buffers
239 * and those passed up to the kernel.
240 *
241 * @refcnt: Number of struct efx_rx_buffer's referencing this page.
242 * When refcnt falls to zero, the page is unmapped for dma
243 * @dma_addr: The dma address of this page.
244 */
245struct efx_rx_page_state {
246 unsigned refcnt;
247 dma_addr_t dma_addr;
248
249 unsigned int __pad[0] ____cacheline_aligned;
250};
251
252/**
235 * struct efx_rx_queue - An Efx RX queue 253 * struct efx_rx_queue - An Efx RX queue
236 * @efx: The associated Efx NIC 254 * @efx: The associated Efx NIC
237 * @queue: DMA queue number 255 * @queue: DMA queue number
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index dfebd73cf86..9fb698e3519 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -25,6 +25,9 @@
25/* Number of RX descriptors pushed at once. */ 25/* Number of RX descriptors pushed at once. */
26#define EFX_RX_BATCH 8 26#define EFX_RX_BATCH 8
27 27
28/* Maximum size of a buffer sharing a page */
29#define EFX_RX_HALF_PAGE ((PAGE_SIZE >> 1) - sizeof(struct efx_rx_page_state))
30
28/* Size of buffer allocated for skb header area. */ 31/* Size of buffer allocated for skb header area. */
29#define EFX_SKB_HEADERS 64u 32#define EFX_SKB_HEADERS 64u
30 33
@@ -82,10 +85,9 @@ static unsigned int rx_refill_limit = 95;
82 * RX maximum head room required. 85 * RX maximum head room required.
83 * 86 *
84 * This must be at least 1 to prevent overflow and at least 2 to allow 87 * This must be at least 1 to prevent overflow and at least 2 to allow
85 * pipelined receives. Then a further 1 because efx_recycle_rx_buffer() 88 * pipelined receives.
86 * might insert two buffers.
87 */ 89 */
88#define EFX_RXD_HEAD_ROOM 3 90#define EFX_RXD_HEAD_ROOM 2
89 91
90static inline unsigned int efx_rx_buf_offset(struct efx_rx_buffer *buf) 92static inline unsigned int efx_rx_buf_offset(struct efx_rx_buffer *buf)
91{ 93{
@@ -164,7 +166,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
164 struct efx_nic *efx = rx_queue->efx; 166 struct efx_nic *efx = rx_queue->efx;
165 struct efx_rx_buffer *rx_buf; 167 struct efx_rx_buffer *rx_buf;
166 struct page *page; 168 struct page *page;
167 char *page_addr; 169 void *page_addr;
170 struct efx_rx_page_state *state;
168 dma_addr_t dma_addr; 171 dma_addr_t dma_addr;
169 unsigned index, count; 172 unsigned index, count;
170 173
@@ -183,22 +186,27 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
183 __free_pages(page, efx->rx_buffer_order); 186 __free_pages(page, efx->rx_buffer_order);
184 return -EIO; 187 return -EIO;
185 } 188 }
186 EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1)); 189 page_addr = page_address(page);
187 page_addr = page_address(page) + EFX_PAGE_IP_ALIGN; 190 state = page_addr;
188 dma_addr += EFX_PAGE_IP_ALIGN; 191 state->refcnt = 0;
192 state->dma_addr = dma_addr;
193
194 page_addr += sizeof(struct efx_rx_page_state);
195 dma_addr += sizeof(struct efx_rx_page_state);
189 196
190 split: 197 split:
191 index = rx_queue->added_count & EFX_RXQ_MASK; 198 index = rx_queue->added_count & EFX_RXQ_MASK;
192 rx_buf = efx_rx_buffer(rx_queue, index); 199 rx_buf = efx_rx_buffer(rx_queue, index);
193 rx_buf->dma_addr = dma_addr; 200 rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
194 rx_buf->skb = NULL; 201 rx_buf->skb = NULL;
195 rx_buf->page = page; 202 rx_buf->page = page;
196 rx_buf->data = page_addr; 203 rx_buf->data = page_addr + EFX_PAGE_IP_ALIGN;
197 rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; 204 rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
198 ++rx_queue->added_count; 205 ++rx_queue->added_count;
199 ++rx_queue->alloc_page_count; 206 ++rx_queue->alloc_page_count;
207 ++state->refcnt;
200 208
201 if ((~count & 1) && (efx->rx_buffer_len < (PAGE_SIZE >> 1))) { 209 if ((~count & 1) && (efx->rx_buffer_len <= EFX_RX_HALF_PAGE)) {
202 /* Use the second half of the page */ 210 /* Use the second half of the page */
203 get_page(page); 211 get_page(page);
204 dma_addr += (PAGE_SIZE >> 1); 212 dma_addr += (PAGE_SIZE >> 1);
@@ -215,14 +223,14 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
215 struct efx_rx_buffer *rx_buf) 223 struct efx_rx_buffer *rx_buf)
216{ 224{
217 if (rx_buf->page) { 225 if (rx_buf->page) {
226 struct efx_rx_page_state *state;
227
218 EFX_BUG_ON_PARANOID(rx_buf->skb); 228 EFX_BUG_ON_PARANOID(rx_buf->skb);
219 229
220 /* Unmap the buffer if there's only one buffer per page(s), 230 state = page_address(rx_buf->page);
221 * or this is the second half of a two buffer page. */ 231 if (--state->refcnt == 0) {
222 if (efx->rx_buffer_order != 0 ||
223 (efx_rx_buf_offset(rx_buf) & (PAGE_SIZE >> 1)) != 0) {
224 pci_unmap_page(efx->pci_dev, 232 pci_unmap_page(efx->pci_dev,
225 rx_buf->dma_addr & ~(PAGE_SIZE - 1), 233 state->dma_addr,
226 efx_rx_buf_size(efx), 234 efx_rx_buf_size(efx),
227 PCI_DMA_FROMDEVICE); 235 PCI_DMA_FROMDEVICE);
228 } 236 }
@@ -256,21 +264,30 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
256static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, 264static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
257 struct efx_rx_buffer *rx_buf) 265 struct efx_rx_buffer *rx_buf)
258{ 266{
267 struct efx_rx_page_state *state = page_address(rx_buf->page);
259 struct efx_rx_buffer *new_buf; 268 struct efx_rx_buffer *new_buf;
260 unsigned index; 269 unsigned fill_level, index;
270
271 /* +1 because efx_rx_packet() incremented removed_count. +1 because
272 * we'd like to insert an additional descriptor whilst leaving
273 * EFX_RXD_HEAD_ROOM for the non-recycle path */
274 fill_level = (rx_queue->added_count - rx_queue->removed_count + 2);
275 if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) {
276 /* We could place "state" on a list, and drain the list in
277 * efx_fast_push_rx_descriptors(). For now, this will do. */
278 return;
279 }
261 280
262 /* We could have recycled the 1st half, then refilled 281 ++state->refcnt;
263 * the queue, and now recycle the 2nd half.
264 * EFX_RXD_HEAD_ROOM ensures that there is always room
265 * to reinsert two buffers (once). */
266 get_page(rx_buf->page); 282 get_page(rx_buf->page);
267 283
268 index = rx_queue->added_count & EFX_RXQ_MASK; 284 index = rx_queue->added_count & EFX_RXQ_MASK;
269 new_buf = efx_rx_buffer(rx_queue, index); 285 new_buf = efx_rx_buffer(rx_queue, index);
270 new_buf->dma_addr = rx_buf->dma_addr - (PAGE_SIZE >> 1); 286 new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
271 new_buf->skb = NULL; 287 new_buf->skb = NULL;
272 new_buf->page = rx_buf->page; 288 new_buf->page = rx_buf->page;
273 new_buf->data = rx_buf->data - (PAGE_SIZE >> 1); 289 new_buf->data = (void *)
290 ((__force unsigned long)rx_buf->data ^ (PAGE_SIZE >> 1));
274 new_buf->len = rx_buf->len; 291 new_buf->len = rx_buf->len;
275 ++rx_queue->added_count; 292 ++rx_queue->added_count;
276} 293}
@@ -285,26 +302,9 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
285 struct efx_rx_buffer *new_buf; 302 struct efx_rx_buffer *new_buf;
286 unsigned index; 303 unsigned index;
287 304
288 if (rx_buf->page != NULL && efx->rx_buffer_len < (PAGE_SIZE >> 1)) { 305 if (rx_buf->page != NULL && efx->rx_buffer_len <= EFX_RX_HALF_PAGE &&
289 if (efx_rx_buf_offset(rx_buf) & (PAGE_SIZE >> 1)) { 306 page_count(rx_buf->page) == 1)
290 /* This is the 2nd half of a page split between two 307 efx_resurrect_rx_buffer(rx_queue, rx_buf);
291 * buffers, If page_count() is > 1 then the kernel
292 * is holding onto the previous buffer */
293 if (page_count(rx_buf->page) != 1) {
294 efx_fini_rx_buffer(rx_queue, rx_buf);
295 return;
296 }
297
298 efx_resurrect_rx_buffer(rx_queue, rx_buf);
299 } else {
300 /* Free the 1st buffer's reference on the page. If the
301 * 2nd buffer is also discarded, this buffer will be
302 * resurrected above */
303 put_page(rx_buf->page);
304 rx_buf->page = NULL;
305 return;
306 }
307 }
308 308
309 index = rx_queue->added_count & EFX_RXQ_MASK; 309 index = rx_queue->added_count & EFX_RXQ_MASK;
310 new_buf = efx_rx_buffer(rx_queue, index); 310 new_buf = efx_rx_buffer(rx_queue, index);