Message ID | 1418858186-25251-1-git-send-email-bill.fischofer@linaro.org |
---|---|
State | Accepted |
Commit | 05b8dfc7e94ba26faeae79fa630e23419ee71504 |
Headers | show |
On 12/18/2014 01:16 AM, Bill Fischofer wrote: > Add segmented packet I/O support via sockets. RAW sockets limited to > single segment. > > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> > --- > platform/linux-generic/odp_packet_socket.c | 33 +++++++++++++++++------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c > index 2849065..340da88 100644 > --- a/platform/linux-generic/odp_packet_socket.c > +++ b/platform/linux-generic/odp_packet_socket.c > @@ -321,7 +321,8 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, > > for (i = 0; i < len; i++) { > if (odp_likely(pkt == ODP_PACKET_INVALID)) { > - pkt = _odp_packet_alloc(pkt_sock->pool); > + pkt = odp_packet_alloc(pkt_sock->pool, > + pkt_sock->max_frame_len); In seems only MMAP type supports segmented buffers as it uses odp_packet_copydata_*() API. RAW and MMSG operate only with a first segment. Should we add assert here to check that packet is unsegmented? > if (odp_unlikely(pkt == ODP_PACKET_INVALID)) > break; > }
The MMAP code here as far as I can tell is never called, so I'm not sure how it gets used. Perhaps Ciprian can comment. For the RAW code, on RX the effect is we can never receive a packet larger than one segment. So there's no way to even notice we have a problem. If a packet tries to create a large packet itself (without having first received it) then only the first segment would TX, meaning it would be discarded by whoever gets it as an incomplete/damaged packet. I'd rather just accept that as a restriction for now ("results are undefined") and figure out how to address this properly. On Thu, Dec 18, 2014 at 8:56 AM, Taras Kondratiuk < taras.kondratiuk@linaro.org> wrote: > > On 12/18/2014 01:16 AM, Bill Fischofer wrote: > >> Add segmented packet I/O support via sockets. RAW sockets limited to >> single segment. >> >> Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> >> --- >> platform/linux-generic/odp_packet_socket.c | 33 >> +++++++++++++++++------------- >> 1 file changed, 19 insertions(+), 14 deletions(-) >> >> diff --git a/platform/linux-generic/odp_packet_socket.c >> b/platform/linux-generic/odp_packet_socket.c >> index 2849065..340da88 100644 >> --- a/platform/linux-generic/odp_packet_socket.c >> +++ b/platform/linux-generic/odp_packet_socket.c >> @@ -321,7 +321,8 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, >> >> for (i = 0; i < len; i++) { >> if (odp_likely(pkt == ODP_PACKET_INVALID)) { >> - pkt = _odp_packet_alloc(pkt_sock->pool); >> + pkt = odp_packet_alloc(pkt_sock->pool, >> + pkt_sock->max_frame_len); >> > > In seems only MMAP type supports segmented buffers as it uses > odp_packet_copydata_*() API. RAW and MMSG operate only with a first > segment. Should we add assert here to check that packet is unsegmented? > > > if (odp_unlikely(pkt == ODP_PACKET_INVALID)) >> break; >> } >> > >
OK, I didn't see anything in odp_packet_socket.c that would suggest that the MMAP code is actually being used. If it is, then we have proper segmented packet I/O support in place in linux-generic and folks can play around with it by simply making adjustments to ODP_CONFIG_PACKET_BUF_LEN_MIN/MAX. Regarding the MMAP frame size, that should also be controlled by ODP_CONFIG_PACKET_BUF_LEN_MAX. Stuart, is that something you'd like to look into? On Fri, Dec 19, 2014 at 4:00 AM, Stuart Haslam <stuart.haslam@arm.com> wrote: > > On Wed, Dec 17, 2014 at 11:16:25PM +0000, Bill Fischofer wrote: > > Add segmented packet I/O support via sockets. RAW sockets limited to > > single segment. > > > > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> > > --- > > platform/linux-generic/odp_packet_socket.c | 33 > +++++++++++++++++------------- > > 1 file changed, 19 insertions(+), 14 deletions(-) > > > > diff --git a/platform/linux-generic/odp_packet_socket.c > b/platform/linux-generic/odp_packet_socket.c > > index 2849065..340da88 100644 > > --- a/platform/linux-generic/odp_packet_socket.c > > +++ b/platform/linux-generic/odp_packet_socket.c > > @@ -321,7 +321,8 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, > > > > for (i = 0; i < len; i++) { > > if (odp_likely(pkt == ODP_PACKET_INVALID)) { > > - pkt = _odp_packet_alloc(pkt_sock->pool); > > + pkt = odp_packet_alloc(pkt_sock->pool, > > + pkt_sock->max_frame_len); > > if (odp_unlikely(pkt == ODP_PACKET_INVALID)) > > break; > > } > > @@ -339,7 +340,7 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, > > continue; > > > > /* Parse and set packet header data */ > > - packet_set_len(pkt, recv_bytes); > > + odp_packet_pull_tail(pkt, pkt_sock->max_frame_len - > recv_bytes); > > _odp_packet_parse(pkt); > > > > pkt_table[nb_rx] = pkt; > > @@ -418,7 +419,8 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, > > memset(msgvec, 0, sizeof(msgvec)); > > > > for (i = 0; i < (int)len; i++) { > > - pkt_table[i] = _odp_packet_alloc(pkt_sock->pool); > > + pkt_table[i] = odp_packet_alloc(pkt_sock->pool, > > + pkt_sock->max_frame_len); > > if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) > > break; > > > > @@ -445,7 +447,9 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, > > } > > > > /* Parse and set packet header data */ > > - packet_set_len(pkt_table[i], msgvec[i].msg_len); > > + odp_packet_pull_tail(pkt_table[i], > > + pkt_sock->max_frame_len - > > + msgvec[i].msg_len); > > _odp_packet_parse(pkt_table[i]); > > > > pkt_table[nb_rx] = pkt_table[i]; > > @@ -566,7 +570,6 @@ static inline unsigned pkt_mmap_v2_rx(int sock, > struct ring *ring, > > uint8_t *pkt_buf; > > int pkt_len; > > struct ethhdr *eth_hdr; > > - uint8_t *l2_hdr; > > unsigned i = 0; > > > > (void)sock; > > @@ -591,13 +594,15 @@ static inline unsigned pkt_mmap_v2_rx(int sock, > struct ring *ring, > > continue; > > } > > > > - pkt_table[i] = _odp_packet_alloc(pool); > > + pkt_table[i] = odp_packet_alloc(pool, pkt_len); > > if (odp_unlikely(pkt_table[i] == > ODP_PACKET_INVALID)) > > break; > > > > - packet_set_len(pkt_table[i], pkt_len); > > - l2_hdr = odp_packet_data(pkt_table[i]); > > - memcpy(l2_hdr, pkt_buf, pkt_len); > > + if (odp_packet_copydata_in(pkt_table[i], 0, > > + pkt_len, pkt_buf) != 0) > { > > + odp_packet_free(pkt_table[i]); > > + break; > > + } > > By the way I think this also resolves this issue; > > http://lists.linaro.org/pipermail/lng-odp/2014-December/005811.html > > Well at least it should avoid the crash. > > -- > Stuart. > >
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c index 2849065..340da88 100644 --- a/platform/linux-generic/odp_packet_socket.c +++ b/platform/linux-generic/odp_packet_socket.c @@ -321,7 +321,8 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, for (i = 0; i < len; i++) { if (odp_likely(pkt == ODP_PACKET_INVALID)) { - pkt = _odp_packet_alloc(pkt_sock->pool); + pkt = odp_packet_alloc(pkt_sock->pool, + pkt_sock->max_frame_len); if (odp_unlikely(pkt == ODP_PACKET_INVALID)) break; } @@ -339,7 +340,7 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, continue; /* Parse and set packet header data */ - packet_set_len(pkt, recv_bytes); + odp_packet_pull_tail(pkt, pkt_sock->max_frame_len - recv_bytes); _odp_packet_parse(pkt); pkt_table[nb_rx] = pkt; @@ -418,7 +419,8 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, memset(msgvec, 0, sizeof(msgvec)); for (i = 0; i < (int)len; i++) { - pkt_table[i] = _odp_packet_alloc(pkt_sock->pool); + pkt_table[i] = odp_packet_alloc(pkt_sock->pool, + pkt_sock->max_frame_len); if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) break; @@ -445,7 +447,9 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, } /* Parse and set packet header data */ - packet_set_len(pkt_table[i], msgvec[i].msg_len); + odp_packet_pull_tail(pkt_table[i], + pkt_sock->max_frame_len - + msgvec[i].msg_len); _odp_packet_parse(pkt_table[i]); pkt_table[nb_rx] = pkt_table[i]; @@ -566,7 +570,6 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, uint8_t *pkt_buf; int pkt_len; struct ethhdr *eth_hdr; - uint8_t *l2_hdr; unsigned i = 0; (void)sock; @@ -591,13 +594,15 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, continue; } - pkt_table[i] = _odp_packet_alloc(pool); + pkt_table[i] = odp_packet_alloc(pool, pkt_len); if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) break; - packet_set_len(pkt_table[i], pkt_len); - l2_hdr = odp_packet_data(pkt_table[i]); - memcpy(l2_hdr, pkt_buf, pkt_len); + if (odp_packet_copydata_in(pkt_table[i], 0, + pkt_len, pkt_buf) != 0) { + odp_packet_free(pkt_table[i]); + break; + } mmap_rx_user_ready(ppd.raw); @@ -620,7 +625,6 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, odp_packet_t pkt_table[], unsigned len) { union frame_map ppd; - uint8_t *pkt_buf; uint32_t pkt_len; unsigned frame_num, next_frame_num; int ret; @@ -634,13 +638,14 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, next_frame_num = (frame_num + 1) % ring->rd_num; - pkt_buf = odp_packet_l2_ptr(pkt_table[i], &pkt_len); - + pkt_len = odp_packet_len(pkt_table[i]); ppd.v2->tp_h.tp_snaplen = pkt_len; ppd.v2->tp_h.tp_len = pkt_len; - memcpy((uint8_t *)ppd.raw + TPACKET2_HDRLEN - - sizeof(struct sockaddr_ll), pkt_buf, pkt_len); + odp_packet_copydata_out(pkt_table[i], 0, pkt_len, + (uint8_t *)ppd.raw + + TPACKET2_HDRLEN - + sizeof(struct sockaddr_ll)); mmap_tx_user_ready(ppd.raw);
Add segmented packet I/O support via sockets. RAW sockets limited to single segment. Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> --- platform/linux-generic/odp_packet_socket.c | 33 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 14 deletions(-)