> >>  int
> >>  rte_gso_segment(struct rte_mbuf *pkt,
> >> @@ -41,12 +46,53 @@
> >>            struct rte_mbuf **pkts_out,
> >>            uint16_t nb_pkts_out)
> >>  {
> >> +  struct rte_mempool *direct_pool, *indirect_pool;
> >> +  struct rte_mbuf *pkt_seg;
> >> +  uint64_t ol_flags;
> >> +  uint16_t gso_size;
> >> +  uint8_t ipid_delta;
> >> +  int ret = 1;
> >> +
> >>    if (pkt == NULL || pkts_out == NULL || gso_ctx == NULL ||
> >>                    nb_pkts_out < 1)
> >>            return -EINVAL;
> >>
> >> -  pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> >> -  pkts_out[0] = pkt;
> >> +  if ((gso_ctx->gso_size >= pkt->pkt_len) || (gso_ctx->gso_types &
> >> +                          DEV_TX_OFFLOAD_TCP_TSO) !=
> >> +                  gso_ctx->gso_types) {
> >> +          pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> >> +          pkts_out[0] = pkt;
> >> +          return 1;
> >> +  }
> >> +
> >> +  direct_pool = gso_ctx->direct_pool;
> >> +  indirect_pool = gso_ctx->indirect_pool;
> >> +  gso_size = gso_ctx->gso_size;
> >> +  ipid_delta = (gso_ctx->ipid_flag != RTE_GSO_IPID_FIXED);
> >> +  ol_flags = pkt->ol_flags;
> >> +
> >> +  if (IS_IPV4_TCP(pkt->ol_flags)) {
> >> +          pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> >> +          ret = gso_tcp4_segment(pkt, gso_size, ipid_delta,
> >> +                          direct_pool, indirect_pool,
> >> +                          pkts_out, nb_pkts_out);
> >> +  } else {
> >> +          pkt->ol_flags &= (~PKT_TX_TCP_SEG);
> >
> >Not sure why do you clean this flag if you don't support that packet type
> >and no action was perfomed?
> >Suppose you have a mix ipv4 and ipv6 packets - gso lib would do ipv4 and
> >someone else
> >(HW?) can do ipv4 segmentation.
> 
> I can't say for definite, since I didn't implement this change. However, I 
> can only presume that the assumption here is that since
> segmentation is being done in S/W that the underlying H/W does not support 
> TSO.
> Since the underlying HW can't segment the packet in HW, we should clear the 
> flag; otherwise, if an mbuf marked for TCP segmentation is
> passed to the driver of a NIC that does not support/understand that feature, 
> the behavior is undefined.
> Is this a fair assumption in your opinion, or is it the case that the packet 
> would simply be transmitted un-segmented in that case, and so we
> shouldn't clear the flag?

Yes, I think if we shouldn't clear the flag if we didn't do any segmentation 
(we just encounter a packet type that we don't support).
Konstantin

> 
> Thanks again,
> Mark
> 
> >BTW, did you notice that building of shared target fails?
> >Konstantin
> 
> I didn't, but I'll take a look right now - thanks for the catch!
> 
> >
> >
> >> +          pkts_out[0] = pkt;
> >> +          RTE_LOG(WARNING, GSO, "Unsupported packet type\n");
> >> +          return 1;
> >> +  }
> >> +
> >> +  if (ret > 1) {
> >> +          pkt_seg = pkt;
> >> +          while (pkt_seg) {
> >> +                  rte_mbuf_refcnt_update(pkt_seg, -1);
> >> +                  pkt_seg = pkt_seg->next;
> >> +          }
> >> +  } else if (ret < 0) {
> >> +          /* Revert the ol_flags in the event of failure. */
> >> +          pkt->ol_flags = ol_flags;
> >> +  }
> >>
> >> -  return 1;
> >> +  return ret;
> >>  }
> >> --
> >> 1.9.3

Reply via email to