Fixes bug #1670

Signed-off-by: Nicolas Morey-Chaisemartin <[email protected]>
---
 platform/linux-generic/pktio/socket.c | 71 +++++++++++++++++++++++++++--------
 1 file changed, 55 insertions(+), 16 deletions(-)

diff --git a/platform/linux-generic/pktio/socket.c 
b/platform/linux-generic/pktio/socket.c
index 4a9cd97..f410cf1 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -260,6 +260,33 @@ static int sock_mmsg_init(odp_pktio_t id ODP_UNUSED,
        return sock_setup_pkt(pktio_entry, devname, pool);
 }
 
+static uint32_t _rx_pkt_to_iovec(odp_packet_t pkt,
+                                struct iovec iovecs[ODP_BUFFER_MAX_SEG])
+{
+       odp_packet_seg_t seg = odp_packet_first_seg(pkt);
+       uint32_t seg_count = odp_packet_num_segs(pkt);
+       uint32_t seg_id = 0;
+       uint32_t iov_count = 0;
+       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+       uint8_t *ptr;
+       uint32_t seglen;
+
+       for (seg_id = 0; seg_id < seg_count; ++seg_id) {
+               ptr = segment_map(&pkt_hdr->buf_hdr, (odp_buffer_seg_t)seg,
+                                 &seglen, pkt_hdr->frame_len,
+                                 pkt_hdr->headroom);
+
+               if (ptr) {
+                       iovecs[iov_count].iov_base = ptr;
+                       iovecs[iov_count].iov_len = seglen;
+                       iov_count++;
+               }
+               seg = odp_packet_next_seg(pkt, seg);
+       }
+
+       return iov_count;
+}
+
 /*
  * ODP_PACKET_SOCKET_MMSG:
  */
@@ -270,9 +297,7 @@ static int sock_mmsg_recv_pkt(pktio_entry_t *pktio_entry,
        const int sockfd = pkt_sock->sockfd;
        int msgvec_len;
        struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_RX];
-       struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_RX];
-       uint8_t *pkt_buf;
-       uint8_t *l2_hdr;
+       struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_RX][ODP_BUFFER_MAX_SEG];
        int nb_rx = 0;
        int recv_msgs;
        int i;
@@ -288,12 +313,10 @@ static int sock_mmsg_recv_pkt(pktio_entry_t *pktio_entry,
                if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
                        break;
 
-               pkt_buf = odp_packet_data(pkt_table[i]);
-               l2_hdr = pkt_buf + pkt_sock->frame_offset;
-               iovecs[i].iov_base = l2_hdr;
-               iovecs[i].iov_len = pkt_sock->max_frame_len;
-               msgvec[i].msg_hdr.msg_iov = &iovecs[i];
-               msgvec[i].msg_hdr.msg_iovlen = 1;
+               msgvec[i].msg_hdr.msg_iovlen =
+                       _rx_pkt_to_iovec(pkt_table[i], iovecs[i]);
+
+               msgvec[i].msg_hdr.msg_iov = iovecs[i];
        }
        msgvec_len = i; /* number of successfully allocated pkt buffers */
 
@@ -327,6 +350,25 @@ static int sock_mmsg_recv_pkt(pktio_entry_t *pktio_entry,
        return nb_rx;
 }
 
+static uint32_t _tx_pkt_to_iovec(odp_packet_t pkt,
+                                struct iovec iovecs[ODP_BUFFER_MAX_SEG])
+{
+       uint32_t pkt_len = odp_packet_len(pkt);
+       uint32_t offset = odp_packet_l2_offset(pkt);
+       uint32_t iov_count = 0;
+
+       while (offset < pkt_len) {
+               uint32_t seglen;
+
+               iovecs[iov_count].iov_base = odp_packet_offset(pkt, offset,
+                                                              &seglen, NULL);
+               iovecs[iov_count].iov_len = seglen;
+               iov_count++;
+               offset += seglen;
+       }
+       return iov_count;
+}
+
 /*
  * ODP_PACKET_SOCKET_MMSG:
  */
@@ -335,7 +377,7 @@ static int sock_mmsg_send_pkt(pktio_entry_t *pktio_entry,
 {
        pkt_sock_t *pkt_sock = &pktio_entry->s.pkt_sock;
        struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX];
-       struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_TX];
+       struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_TX][ODP_BUFFER_MAX_SEG];
        int ret;
        int sockfd;
        unsigned i;
@@ -349,12 +391,9 @@ static int sock_mmsg_send_pkt(pktio_entry_t *pktio_entry,
        memset(msgvec, 0, sizeof(msgvec));
 
        for (i = 0; i < len; i++) {
-               uint32_t seglen;
-
-               iovecs[i].iov_base = odp_packet_l2_ptr(pkt_table[i], &seglen);
-               iovecs[i].iov_len = seglen;
-               msgvec[i].msg_hdr.msg_iov = &iovecs[i];
-               msgvec[i].msg_hdr.msg_iovlen = 1;
+               msgvec[i].msg_hdr.msg_iov = iovecs[i];
+               msgvec[i].msg_hdr.msg_iovlen = _tx_pkt_to_iovec(pkt_table[i],
+                                                               iovecs[i]);
        }
 
        flags = MSG_DONTWAIT;
-- 
2.5.0.rc2.3.g9ad628c


_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to