[API-NEXT] linux-generic: packet: set correct tailroom on trim of multi-seg pkts

Message ID 1482350604-24090-1-git-send-email-bill.fischofer@linaro.org
State New
Headers show

Commit Message

Bill Fischofer Dec. 21, 2016, 8:03 p.m.
Fix Bug https://bugs.linaro.org/show_bug.cgi?id=2789 by calculating
tailroom correctly when trimming multi-segment packets. Also handle
head/tail push/pull operations that result in a zero-length packet
correctly.

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

---
 platform/linux-generic/odp_packet.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

-- 
2.7.4

Patch

diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 0d3fd05..ab352f2 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -413,8 +413,8 @@  static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr,
 		 * of the metadata. */
 		pkt_hdr->buf_hdr.segcount = n;
 		pkt_hdr->frame_len -= free_len;
-		pkt_hdr->tailroom = pkt_hdr->buf_hdr.buf_end -
-				    (uint8_t *)packet_tail(pkt_hdr);
+		pkt_hdr->tailroom =
+			pkt_hdr->buf_hdr.size - packet_last_seg_len(pkt_hdr);
 
 		pull_tail(pkt_hdr, pull_len);
 	}
@@ -719,9 +719,12 @@  int odp_packet_trunc_head(odp_packet_t *pkt, uint32_t len,
 	if (len > pkt_hdr->frame_len)
 		return -1;
 
-	if (len < seg_len) {
+	/* Only the first segment may be zero length */
+	if (CONFIG_PACKET_MAX_SEGS == 1 ||
+	    len < seg_len ||
+	    pkt_hdr->buf_hdr.segcount == 1) {
 		pull_head(pkt_hdr, len);
-	} else if (CONFIG_PACKET_MAX_SEGS != 1) {
+	} else {
 		int num = 0;
 		uint32_t pull_len = 0;
 
@@ -811,9 +814,12 @@  int odp_packet_trunc_tail(odp_packet_t *pkt, uint32_t len,
 	last    = packet_last_seg(pkt_hdr);
 	seg_len = packet_seg_len(pkt_hdr, last);
 
-	if (len < seg_len) {
+	/* Only the first segment may be zero length */
+	if (CONFIG_PACKET_MAX_SEGS == 1 ||
+	    len < seg_len ||
+	    pkt_hdr->buf_hdr.segcount == 1) {
 		pull_tail(pkt_hdr, len);
-	} else if (CONFIG_PACKET_MAX_SEGS != 1) {
+	} else {
 		int num = 0;
 		uint32_t pull_len = 0;