net/mlx5: fix inlining segmented TSO packet
authorYongseok Koh <yskoh@mellanox.com>
Fri, 11 May 2018 17:39:13 +0000 (10:39 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 14 May 2018 21:32:22 +0000 (22:32 +0100)
When a multi-segmented packet is inlined, data can be further inlined even
after the first segment. In case of TSO packet, extra inline data after TSO
header should be carried by an inline DSEG which has 4B inline header
recording the length of the inline data. If more than one segment is
inlined, the length doesn't count from the second segment. This will cause
a fault in HW and CQE will have an error, which is ignored by PMD.

Fixes: f895536be4fa ("net/mlx5: enable inlining data from multiple segments")
Cc: stable@dpdk.org
Signed-off-by: Xueming Li <xuemingl@mellanox.com>
Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
drivers/net/mlx5/mlx5_rxtx.c

index c887d55..734ba0b 100644 (file)
@@ -645,7 +645,8 @@ pkt_inline:
                                if (unlikely(max_wqe < n))
                                        break;
                                max_wqe -= n;
-                               if (tso && !inl) {
+                               if (tso) {
+                                       assert(inl == 0);
                                        inl = rte_cpu_to_be_32(copy_b |
                                                               MLX5_INLINE_SEG);
                                        rte_memcpy((void *)raw,
@@ -680,8 +681,17 @@ pkt_inline:
                        } else if (!segs_n) {
                                goto next_pkt;
                        } else {
-                               raw += copy_b;
-                               inline_room -= copy_b;
+                               /*
+                                * Further inline the next segment only for
+                                * non-TSO packets.
+                                */
+                               if (!tso) {
+                                       raw += copy_b;
+                                       inline_room -= copy_b;
+                               } else {
+                                       inline_room = 0;
+                               }
+                               /* Move to the next segment. */
                                --segs_n;
                                buf = buf->next;
                                assert(buf);