* Allocate a new mbuf with up to tx_pkt_nb_segs segments. * Copy packet contents and offload information into the new segmented mbuf. */
| 707 | * Copy packet contents and offload information into the new segmented mbuf. |
| 708 | */ |
| 709 | static struct rte_mbuf * |
| 710 | pkt_copy_split(const struct rte_mbuf *pkt) |
| 711 | { |
| 712 | int32_t n, rc; |
| 713 | uint32_t i, len, nb_seg; |
| 714 | struct rte_mempool *mp; |
| 715 | uint16_t seglen[RTE_MAX_SEGS_PER_PKT]; |
| 716 | struct rte_mbuf *p, *md[RTE_MAX_SEGS_PER_PKT]; |
| 717 | |
| 718 | mp = current_fwd_lcore()->mbp; |
| 719 | |
| 720 | if (tx_pkt_split == TX_PKT_SPLIT_RND) |
| 721 | nb_seg = rte_rand() % tx_pkt_nb_segs + 1; |
| 722 | else |
| 723 | nb_seg = tx_pkt_nb_segs; |
| 724 | |
| 725 | memcpy(seglen, tx_pkt_seg_lengths, nb_seg * sizeof(seglen[0])); |
| 726 | |
| 727 | /* calculate number of segments to use and their length. */ |
| 728 | len = 0; |
| 729 | for (i = 0; i != nb_seg && len < pkt->pkt_len; i++) { |
| 730 | len += seglen[i]; |
| 731 | md[i] = NULL; |
| 732 | } |
| 733 | |
| 734 | n = pkt->pkt_len - len; |
| 735 | |
| 736 | /* update size of the last segment to fit rest of the packet */ |
| 737 | if (n >= 0) { |
| 738 | seglen[i - 1] += n; |
| 739 | len += n; |
| 740 | } |
| 741 | |
| 742 | nb_seg = i; |
| 743 | while (i != 0) { |
| 744 | p = rte_pktmbuf_alloc(mp); |
| 745 | if (p == NULL) { |
| 746 | TESTPMD_LOG(ERR, |
| 747 | "failed to allocate %u-th of %u mbuf " |
| 748 | "from mempool: %s\n", |
| 749 | nb_seg - i, nb_seg, mp->name); |
| 750 | break; |
| 751 | } |
| 752 | |
| 753 | md[--i] = p; |
| 754 | if (rte_pktmbuf_tailroom(md[i]) < seglen[i]) { |
| 755 | TESTPMD_LOG(ERR, "mempool %s, %u-th segment: " |
| 756 | "expected seglen: %u, " |
| 757 | "actual mbuf tailroom: %u\n", |
| 758 | mp->name, i, seglen[i], |
| 759 | rte_pktmbuf_tailroom(md[i])); |
| 760 | break; |
| 761 | } |
| 762 | } |
| 763 | |
| 764 | /* all mbufs successfully allocated, do copy */ |
| 765 | if (i == 0) { |
| 766 | rc = mbuf_copy_split(pkt, md, seglen, nb_seg); |
no test coverage detected