Fixes bug #1670

Signed-off-by: Nicolas Morey-Chaisemartin <nmo...@kalray.eu>
---
 platform/linux-generic/odp_packet_socket.c | 74 +++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 16 deletions(-)

diff --git a/platform/linux-generic/odp_packet_socket.c 
b/platform/linux-generic/odp_packet_socket.c
index c0f7a55..ef87bd7 100644
--- a/platform/linux-generic/odp_packet_socket.c
+++ b/platform/linux-generic/odp_packet_socket.c
@@ -38,6 +38,7 @@
 #include <odp_packet_internal.h>
 #include <odp_align_internal.h>
 #include <odp_debug_internal.h>
+#include <odp_buffer_inlines.h>
 #include <odp/hints.h>
 
 #include <odp/helper/eth.h>
@@ -137,7 +138,8 @@ int setup_pkt_sock(pkt_sock_t *const pkt_sock, const char 
*netdev,
        /* Store eth buffer offset for pkt buffers from this pool */
        pkt_sock->frame_offset = 0;
        /* pkt buffer size */
-       pkt_sock->buf_size = odp_buffer_pool_segment_size(pool);
+       pkt_sock->buf_size = ODP_BUFFER_MAX_SEG *
+               odp_buffer_pool_segment_size(pool);
        /* max frame len taking into account the l2-offset */
        pkt_sock->max_frame_len = pkt_sock->buf_size -
                odp_buffer_pool_headroom(pool) -
@@ -204,6 +206,52 @@ int close_pkt_sock(pkt_sock_t *const pkt_sock)
        return 0;
 }
 
+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;
+}
+
+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:
  */
@@ -213,9 +261,7 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
        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;
@@ -231,12 +277,10 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
                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 */
 
@@ -277,7 +321,7 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
                       odp_packet_t pkt_table[], unsigned len)
 {
        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;
@@ -291,11 +335,9 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
        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;
_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to