diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-14 01:05:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-14 14:13:30 -0500 |
commit | e52fcb2462ac484e6dd6e68869536609f0216938 (patch) | |
tree | 794407ff242481d5d09e3e669cabfe129d80f6df /drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |
parent | b2b5ce9d1ccf1c45f8ac68e5d901112ab76ba199 (diff) |
bnx2x: uses build_skb() in receive path
bnx2x uses following formula to compute its rx_buf_sz :
dev->mtu + 2*L1_CACHE_BYTES + 14 + 8 + 8 + 2
Then core network adds NET_SKB_PAD and SKB_DATA_ALIGN(sizeof(struct
skb_shared_info))
Final allocated size for skb head on x86_64 (L1_CACHE_BYTES = 64,
MTU=1500) : 2112 bytes : SLUB/SLAB round this to 4096 bytes.
Since skb truesize is then bigger than SK_MEM_QUANTUM, we have lot of
false sharing because of mem_reclaim in UDP stack.
One possible way to half truesize is to reduce the need by 64 bytes
(2112 -> 2048 bytes)
Instead of allocating a full cache line at the end of packet for
alignment, we can use the fact that skb_shared_info sits at the end of
skb->head, and we can use this room, if we convert bnx2x to new
build_skb() infrastructure.
skb_shared_info will be initialized after hardware finished its
transfert, so we can eventually overwrite the final padding.
Using build_skb() also reduces cache line misses in the driver, since we
use cache hot skb instead of cold ones. Number of in-flight sk_buff
structures is lower, they are recycled while still hot.
Performance results :
(820.000 pps on a rx UDP monothread benchmark, instead of 720.000 pps)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Eilon Greenstein <eilong@broadcom.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
CC: Tom Herbert <therbert@google.com>
CC: Jamal Hadi Salim <hadi@mojatatu.com>
CC: Stephen Hemminger <shemminger@vyatta.com>
CC: Thomas Graf <tgraf@infradead.org>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 267 |
1 files changed, 126 insertions, 141 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 13dad9230dbc..0d60b9e633ad 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -294,8 +294,21 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, | |||
294 | fp->last_max_sge, fp->rx_sge_prod); | 294 | fp->last_max_sge, fp->rx_sge_prod); |
295 | } | 295 | } |
296 | 296 | ||
297 | /* Set Toeplitz hash value in the skb using the value from the | ||
298 | * CQE (calculated by HW). | ||
299 | */ | ||
300 | static u32 bnx2x_get_rxhash(const struct bnx2x *bp, | ||
301 | const struct eth_fast_path_rx_cqe *cqe) | ||
302 | { | ||
303 | /* Set Toeplitz hash from CQE */ | ||
304 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
305 | (cqe->status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
306 | return le32_to_cpu(cqe->rss_hash_result); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
297 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | 310 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, |
298 | struct sk_buff *skb, u16 cons, u16 prod, | 311 | u16 cons, u16 prod, |
299 | struct eth_fast_path_rx_cqe *cqe) | 312 | struct eth_fast_path_rx_cqe *cqe) |
300 | { | 313 | { |
301 | struct bnx2x *bp = fp->bp; | 314 | struct bnx2x *bp = fp->bp; |
@@ -310,9 +323,9 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
310 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) | 323 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) |
311 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); | 324 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); |
312 | 325 | ||
313 | /* Try to map an empty skb from the aggregation info */ | 326 | /* Try to map an empty data buffer from the aggregation info */ |
314 | mapping = dma_map_single(&bp->pdev->dev, | 327 | mapping = dma_map_single(&bp->pdev->dev, |
315 | first_buf->skb->data, | 328 | first_buf->data + NET_SKB_PAD, |
316 | fp->rx_buf_size, DMA_FROM_DEVICE); | 329 | fp->rx_buf_size, DMA_FROM_DEVICE); |
317 | /* | 330 | /* |
318 | * ...if it fails - move the skb from the consumer to the producer | 331 | * ...if it fails - move the skb from the consumer to the producer |
@@ -322,15 +335,15 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
322 | 335 | ||
323 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { | 336 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { |
324 | /* Move the BD from the consumer to the producer */ | 337 | /* Move the BD from the consumer to the producer */ |
325 | bnx2x_reuse_rx_skb(fp, cons, prod); | 338 | bnx2x_reuse_rx_data(fp, cons, prod); |
326 | tpa_info->tpa_state = BNX2X_TPA_ERROR; | 339 | tpa_info->tpa_state = BNX2X_TPA_ERROR; |
327 | return; | 340 | return; |
328 | } | 341 | } |
329 | 342 | ||
330 | /* move empty skb from pool to prod */ | 343 | /* move empty data from pool to prod */ |
331 | prod_rx_buf->skb = first_buf->skb; | 344 | prod_rx_buf->data = first_buf->data; |
332 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); | 345 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); |
333 | /* point prod_bd to new skb */ | 346 | /* point prod_bd to new data */ |
334 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); | 347 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); |
335 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); | 348 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); |
336 | 349 | ||
@@ -344,6 +357,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
344 | tpa_info->tpa_state = BNX2X_TPA_START; | 357 | tpa_info->tpa_state = BNX2X_TPA_START; |
345 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); | 358 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); |
346 | tpa_info->placement_offset = cqe->placement_offset; | 359 | tpa_info->placement_offset = cqe->placement_offset; |
360 | tpa_info->rxhash = bnx2x_get_rxhash(bp, cqe); | ||
347 | 361 | ||
348 | #ifdef BNX2X_STOP_ON_ERROR | 362 | #ifdef BNX2X_STOP_ON_ERROR |
349 | fp->tpa_queue_used |= (1 << queue); | 363 | fp->tpa_queue_used |= (1 << queue); |
@@ -471,11 +485,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
471 | { | 485 | { |
472 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; | 486 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; |
473 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; | 487 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; |
474 | u8 pad = tpa_info->placement_offset; | 488 | u32 pad = tpa_info->placement_offset; |
475 | u16 len = tpa_info->len_on_bd; | 489 | u16 len = tpa_info->len_on_bd; |
476 | struct sk_buff *skb = rx_buf->skb; | 490 | struct sk_buff *skb = NULL; |
491 | u8 *data = rx_buf->data; | ||
477 | /* alloc new skb */ | 492 | /* alloc new skb */ |
478 | struct sk_buff *new_skb; | 493 | u8 *new_data; |
479 | u8 old_tpa_state = tpa_info->tpa_state; | 494 | u8 old_tpa_state = tpa_info->tpa_state; |
480 | 495 | ||
481 | tpa_info->tpa_state = BNX2X_TPA_STOP; | 496 | tpa_info->tpa_state = BNX2X_TPA_STOP; |
@@ -486,18 +501,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
486 | if (old_tpa_state == BNX2X_TPA_ERROR) | 501 | if (old_tpa_state == BNX2X_TPA_ERROR) |
487 | goto drop; | 502 | goto drop; |
488 | 503 | ||
489 | /* Try to allocate the new skb */ | 504 | /* Try to allocate the new data */ |
490 | new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 505 | new_data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC); |
491 | 506 | ||
492 | /* Unmap skb in the pool anyway, as we are going to change | 507 | /* Unmap skb in the pool anyway, as we are going to change |
493 | pool entry status to BNX2X_TPA_STOP even if new skb allocation | 508 | pool entry status to BNX2X_TPA_STOP even if new skb allocation |
494 | fails. */ | 509 | fails. */ |
495 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), | 510 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), |
496 | fp->rx_buf_size, DMA_FROM_DEVICE); | 511 | fp->rx_buf_size, DMA_FROM_DEVICE); |
512 | if (likely(new_data)) | ||
513 | skb = build_skb(data); | ||
497 | 514 | ||
498 | if (likely(new_skb)) { | 515 | if (likely(skb)) { |
499 | prefetch(skb); | ||
500 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | ||
501 | 516 | ||
502 | #ifdef BNX2X_STOP_ON_ERROR | 517 | #ifdef BNX2X_STOP_ON_ERROR |
503 | if (pad + len > fp->rx_buf_size) { | 518 | if (pad + len > fp->rx_buf_size) { |
@@ -509,8 +524,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
509 | } | 524 | } |
510 | #endif | 525 | #endif |
511 | 526 | ||
512 | skb_reserve(skb, pad); | 527 | skb_reserve(skb, pad + NET_SKB_PAD); |
513 | skb_put(skb, len); | 528 | skb_put(skb, len); |
529 | skb->rxhash = tpa_info->rxhash; | ||
514 | 530 | ||
515 | skb->protocol = eth_type_trans(skb, bp->dev); | 531 | skb->protocol = eth_type_trans(skb, bp->dev); |
516 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 532 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -526,8 +542,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
526 | } | 542 | } |
527 | 543 | ||
528 | 544 | ||
529 | /* put new skb in bin */ | 545 | /* put new data in bin */ |
530 | rx_buf->skb = new_skb; | 546 | rx_buf->data = new_data; |
531 | 547 | ||
532 | return; | 548 | return; |
533 | } | 549 | } |
@@ -539,19 +555,6 @@ drop: | |||
539 | fp->eth_q_stats.rx_skb_alloc_failed++; | 555 | fp->eth_q_stats.rx_skb_alloc_failed++; |
540 | } | 556 | } |
541 | 557 | ||
542 | /* Set Toeplitz hash value in the skb using the value from the | ||
543 | * CQE (calculated by HW). | ||
544 | */ | ||
545 | static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, | ||
546 | struct sk_buff *skb) | ||
547 | { | ||
548 | /* Set Toeplitz hash from CQE */ | ||
549 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
550 | (cqe->fast_path_cqe.status_flags & | ||
551 | ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
552 | skb->rxhash = | ||
553 | le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); | ||
554 | } | ||
555 | 558 | ||
556 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | 559 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) |
557 | { | 560 | { |
@@ -594,6 +597,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
594 | u8 cqe_fp_flags; | 597 | u8 cqe_fp_flags; |
595 | enum eth_rx_cqe_type cqe_fp_type; | 598 | enum eth_rx_cqe_type cqe_fp_type; |
596 | u16 len, pad; | 599 | u16 len, pad; |
600 | u8 *data; | ||
597 | 601 | ||
598 | #ifdef BNX2X_STOP_ON_ERROR | 602 | #ifdef BNX2X_STOP_ON_ERROR |
599 | if (unlikely(bp->panic)) | 603 | if (unlikely(bp->panic)) |
@@ -604,13 +608,6 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
604 | bd_prod = RX_BD(bd_prod); | 608 | bd_prod = RX_BD(bd_prod); |
605 | bd_cons = RX_BD(bd_cons); | 609 | bd_cons = RX_BD(bd_cons); |
606 | 610 | ||
607 | /* Prefetch the page containing the BD descriptor | ||
608 | at producer's index. It will be needed when new skb is | ||
609 | allocated */ | ||
610 | prefetch((void *)(PAGE_ALIGN((unsigned long) | ||
611 | (&fp->rx_desc_ring[bd_prod])) - | ||
612 | PAGE_SIZE + 1)); | ||
613 | |||
614 | cqe = &fp->rx_comp_ring[comp_ring_cons]; | 611 | cqe = &fp->rx_comp_ring[comp_ring_cons]; |
615 | cqe_fp = &cqe->fast_path_cqe; | 612 | cqe_fp = &cqe->fast_path_cqe; |
616 | cqe_fp_flags = cqe_fp->type_error_flags; | 613 | cqe_fp_flags = cqe_fp->type_error_flags; |
@@ -626,125 +623,110 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
626 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { | 623 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { |
627 | bnx2x_sp_event(fp, cqe); | 624 | bnx2x_sp_event(fp, cqe); |
628 | goto next_cqe; | 625 | goto next_cqe; |
626 | } | ||
627 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
628 | data = rx_buf->data; | ||
629 | 629 | ||
630 | /* this is an rx packet */ | 630 | if (!CQE_TYPE_FAST(cqe_fp_type)) { |
631 | } else { | ||
632 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
633 | skb = rx_buf->skb; | ||
634 | prefetch(skb); | ||
635 | |||
636 | if (!CQE_TYPE_FAST(cqe_fp_type)) { | ||
637 | #ifdef BNX2X_STOP_ON_ERROR | 631 | #ifdef BNX2X_STOP_ON_ERROR |
638 | /* sanity check */ | 632 | /* sanity check */ |
639 | if (fp->disable_tpa && | 633 | if (fp->disable_tpa && |
640 | (CQE_TYPE_START(cqe_fp_type) || | 634 | (CQE_TYPE_START(cqe_fp_type) || |
641 | CQE_TYPE_STOP(cqe_fp_type))) | 635 | CQE_TYPE_STOP(cqe_fp_type))) |
642 | BNX2X_ERR("START/STOP packet while " | 636 | BNX2X_ERR("START/STOP packet while " |
643 | "disable_tpa type %x\n", | 637 | "disable_tpa type %x\n", |
644 | CQE_TYPE(cqe_fp_type)); | 638 | CQE_TYPE(cqe_fp_type)); |
645 | #endif | 639 | #endif |
646 | 640 | ||
647 | if (CQE_TYPE_START(cqe_fp_type)) { | 641 | if (CQE_TYPE_START(cqe_fp_type)) { |
648 | u16 queue = cqe_fp->queue_index; | 642 | u16 queue = cqe_fp->queue_index; |
649 | DP(NETIF_MSG_RX_STATUS, | 643 | DP(NETIF_MSG_RX_STATUS, |
650 | "calling tpa_start on queue %d\n", | 644 | "calling tpa_start on queue %d\n", |
651 | queue); | 645 | queue); |
652 | |||
653 | bnx2x_tpa_start(fp, queue, skb, | ||
654 | bd_cons, bd_prod, | ||
655 | cqe_fp); | ||
656 | |||
657 | /* Set Toeplitz hash for LRO skb */ | ||
658 | bnx2x_set_skb_rxhash(bp, cqe, skb); | ||
659 | |||
660 | goto next_rx; | ||
661 | |||
662 | } else { | ||
663 | u16 queue = | ||
664 | cqe->end_agg_cqe.queue_index; | ||
665 | DP(NETIF_MSG_RX_STATUS, | ||
666 | "calling tpa_stop on queue %d\n", | ||
667 | queue); | ||
668 | 646 | ||
669 | bnx2x_tpa_stop(bp, fp, queue, | 647 | bnx2x_tpa_start(fp, queue, |
670 | &cqe->end_agg_cqe, | 648 | bd_cons, bd_prod, |
671 | comp_ring_cons); | 649 | cqe_fp); |
650 | goto next_rx; | ||
651 | } else { | ||
652 | u16 queue = | ||
653 | cqe->end_agg_cqe.queue_index; | ||
654 | DP(NETIF_MSG_RX_STATUS, | ||
655 | "calling tpa_stop on queue %d\n", | ||
656 | queue); | ||
657 | |||
658 | bnx2x_tpa_stop(bp, fp, queue, | ||
659 | &cqe->end_agg_cqe, | ||
660 | comp_ring_cons); | ||
672 | #ifdef BNX2X_STOP_ON_ERROR | 661 | #ifdef BNX2X_STOP_ON_ERROR |
673 | if (bp->panic) | 662 | if (bp->panic) |
674 | return 0; | 663 | return 0; |
675 | #endif | 664 | #endif |
676 | 665 | ||
677 | bnx2x_update_sge_prod(fp, cqe_fp); | 666 | bnx2x_update_sge_prod(fp, cqe_fp); |
678 | goto next_cqe; | 667 | goto next_cqe; |
679 | } | ||
680 | } | 668 | } |
681 | /* non TPA */ | 669 | } |
682 | len = le16_to_cpu(cqe_fp->pkt_len); | 670 | /* non TPA */ |
683 | pad = cqe_fp->placement_offset; | 671 | len = le16_to_cpu(cqe_fp->pkt_len); |
684 | dma_sync_single_for_cpu(&bp->pdev->dev, | 672 | pad = cqe_fp->placement_offset; |
673 | dma_sync_single_for_cpu(&bp->pdev->dev, | ||
685 | dma_unmap_addr(rx_buf, mapping), | 674 | dma_unmap_addr(rx_buf, mapping), |
686 | pad + RX_COPY_THRESH, | 675 | pad + RX_COPY_THRESH, |
687 | DMA_FROM_DEVICE); | 676 | DMA_FROM_DEVICE); |
688 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | 677 | pad += NET_SKB_PAD; |
678 | prefetch(data + pad); /* speedup eth_type_trans() */ | ||
679 | /* is this an error packet? */ | ||
680 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | ||
681 | DP(NETIF_MSG_RX_ERR, | ||
682 | "ERROR flags %x rx packet %u\n", | ||
683 | cqe_fp_flags, sw_comp_cons); | ||
684 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
685 | goto reuse_rx; | ||
686 | } | ||
689 | 687 | ||
690 | /* is this an error packet? */ | 688 | /* Since we don't have a jumbo ring |
691 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | 689 | * copy small packets if mtu > 1500 |
690 | */ | ||
691 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
692 | (len <= RX_COPY_THRESH)) { | ||
693 | skb = netdev_alloc_skb_ip_align(bp->dev, len); | ||
694 | if (skb == NULL) { | ||
692 | DP(NETIF_MSG_RX_ERR, | 695 | DP(NETIF_MSG_RX_ERR, |
693 | "ERROR flags %x rx packet %u\n", | 696 | "ERROR packet dropped because of alloc failure\n"); |
694 | cqe_fp_flags, sw_comp_cons); | 697 | fp->eth_q_stats.rx_skb_alloc_failed++; |
695 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
696 | goto reuse_rx; | 698 | goto reuse_rx; |
697 | } | 699 | } |
698 | 700 | memcpy(skb->data, data + pad, len); | |
699 | /* Since we don't have a jumbo ring | 701 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
700 | * copy small packets if mtu > 1500 | 702 | } else { |
701 | */ | 703 | if (likely(bnx2x_alloc_rx_data(bp, fp, bd_prod) == 0)) { |
702 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
703 | (len <= RX_COPY_THRESH)) { | ||
704 | struct sk_buff *new_skb; | ||
705 | |||
706 | new_skb = netdev_alloc_skb(bp->dev, len + pad); | ||
707 | if (new_skb == NULL) { | ||
708 | DP(NETIF_MSG_RX_ERR, | ||
709 | "ERROR packet dropped " | ||
710 | "because of alloc failure\n"); | ||
711 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
712 | goto reuse_rx; | ||
713 | } | ||
714 | |||
715 | /* aligned copy */ | ||
716 | skb_copy_from_linear_data_offset(skb, pad, | ||
717 | new_skb->data + pad, len); | ||
718 | skb_reserve(new_skb, pad); | ||
719 | skb_put(new_skb, len); | ||
720 | |||
721 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | ||
722 | |||
723 | skb = new_skb; | ||
724 | |||
725 | } else | ||
726 | if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { | ||
727 | dma_unmap_single(&bp->pdev->dev, | 704 | dma_unmap_single(&bp->pdev->dev, |
728 | dma_unmap_addr(rx_buf, mapping), | 705 | dma_unmap_addr(rx_buf, mapping), |
729 | fp->rx_buf_size, | 706 | fp->rx_buf_size, |
730 | DMA_FROM_DEVICE); | 707 | DMA_FROM_DEVICE); |
708 | skb = build_skb(data); | ||
709 | if (unlikely(!skb)) { | ||
710 | kfree(data); | ||
711 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
712 | goto next_rx; | ||
713 | } | ||
731 | skb_reserve(skb, pad); | 714 | skb_reserve(skb, pad); |
732 | skb_put(skb, len); | ||
733 | |||
734 | } else { | 715 | } else { |
735 | DP(NETIF_MSG_RX_ERR, | 716 | DP(NETIF_MSG_RX_ERR, |
736 | "ERROR packet dropped because " | 717 | "ERROR packet dropped because " |
737 | "of alloc failure\n"); | 718 | "of alloc failure\n"); |
738 | fp->eth_q_stats.rx_skb_alloc_failed++; | 719 | fp->eth_q_stats.rx_skb_alloc_failed++; |
739 | reuse_rx: | 720 | reuse_rx: |
740 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | 721 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
741 | goto next_rx; | 722 | goto next_rx; |
742 | } | 723 | } |
743 | 724 | ||
725 | skb_put(skb, len); | ||
744 | skb->protocol = eth_type_trans(skb, bp->dev); | 726 | skb->protocol = eth_type_trans(skb, bp->dev); |
745 | 727 | ||
746 | /* Set Toeplitz hash for a none-LRO skb */ | 728 | /* Set Toeplitz hash for a none-LRO skb */ |
747 | bnx2x_set_skb_rxhash(bp, cqe, skb); | 729 | skb->rxhash = bnx2x_get_rxhash(bp, cqe_fp); |
748 | 730 | ||
749 | skb_checksum_none_assert(skb); | 731 | skb_checksum_none_assert(skb); |
750 | 732 | ||
@@ -767,7 +749,7 @@ reuse_rx: | |||
767 | 749 | ||
768 | 750 | ||
769 | next_rx: | 751 | next_rx: |
770 | rx_buf->skb = NULL; | 752 | rx_buf->data = NULL; |
771 | 753 | ||
772 | bd_cons = NEXT_RX_IDX(bd_cons); | 754 | bd_cons = NEXT_RX_IDX(bd_cons); |
773 | bd_prod = NEXT_RX_IDX(bd_prod); | 755 | bd_prod = NEXT_RX_IDX(bd_prod); |
@@ -1013,9 +995,9 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1013 | struct sw_rx_bd *first_buf = | 995 | struct sw_rx_bd *first_buf = |
1014 | &tpa_info->first_buf; | 996 | &tpa_info->first_buf; |
1015 | 997 | ||
1016 | first_buf->skb = netdev_alloc_skb(bp->dev, | 998 | first_buf->data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, |
1017 | fp->rx_buf_size); | 999 | GFP_ATOMIC); |
1018 | if (!first_buf->skb) { | 1000 | if (!first_buf->data) { |
1019 | BNX2X_ERR("Failed to allocate TPA " | 1001 | BNX2X_ERR("Failed to allocate TPA " |
1020 | "skb pool for queue[%d] - " | 1002 | "skb pool for queue[%d] - " |
1021 | "disabling TPA on this " | 1003 | "disabling TPA on this " |
@@ -1118,16 +1100,16 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) | |||
1118 | 1100 | ||
1119 | for (i = 0; i < NUM_RX_BD; i++) { | 1101 | for (i = 0; i < NUM_RX_BD; i++) { |
1120 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; | 1102 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; |
1121 | struct sk_buff *skb = rx_buf->skb; | 1103 | u8 *data = rx_buf->data; |
1122 | 1104 | ||
1123 | if (skb == NULL) | 1105 | if (data == NULL) |
1124 | continue; | 1106 | continue; |
1125 | dma_unmap_single(&bp->pdev->dev, | 1107 | dma_unmap_single(&bp->pdev->dev, |
1126 | dma_unmap_addr(rx_buf, mapping), | 1108 | dma_unmap_addr(rx_buf, mapping), |
1127 | fp->rx_buf_size, DMA_FROM_DEVICE); | 1109 | fp->rx_buf_size, DMA_FROM_DEVICE); |
1128 | 1110 | ||
1129 | rx_buf->skb = NULL; | 1111 | rx_buf->data = NULL; |
1130 | dev_kfree_skb(skb); | 1112 | kfree(data); |
1131 | } | 1113 | } |
1132 | } | 1114 | } |
1133 | 1115 | ||
@@ -1509,6 +1491,7 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1509 | 1491 | ||
1510 | for_each_queue(bp, i) { | 1492 | for_each_queue(bp, i) { |
1511 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1493 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
1494 | u32 mtu; | ||
1512 | 1495 | ||
1513 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ | 1496 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ |
1514 | if (IS_FCOE_IDX(i)) | 1497 | if (IS_FCOE_IDX(i)) |
@@ -1518,13 +1501,15 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1518 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer | 1501 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer |
1519 | * overrun attack. | 1502 | * overrun attack. |
1520 | */ | 1503 | */ |
1521 | fp->rx_buf_size = | 1504 | mtu = BNX2X_FCOE_MINI_JUMBO_MTU; |
1522 | BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD + | ||
1523 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | ||
1524 | else | 1505 | else |
1525 | fp->rx_buf_size = | 1506 | mtu = bp->dev->mtu; |
1526 | bp->dev->mtu + ETH_OVREHEAD + | 1507 | fp->rx_buf_size = BNX2X_FW_RX_ALIGN_START + |
1527 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | 1508 | IP_HEADER_ALIGNMENT_PADDING + |
1509 | ETH_OVREHEAD + | ||
1510 | mtu + | ||
1511 | BNX2X_FW_RX_ALIGN_END; | ||
1512 | /* Note : rx_buf_size doesnt take into account NET_SKB_PAD */ | ||
1528 | } | 1513 | } |
1529 | } | 1514 | } |
1530 | 1515 | ||