Sure, I'll check them.

-Matias

> -----Original Message-----
> From: EXT Maxim Uvarov [mailto:maxim.uva...@linaro.org]
> Sent: Wednesday, November 11, 2015 1:53 PM
> To: lng-odp@lists.linaro.org; Elo, Matias (Nokia - FI/Espoo)
> <matias....@nokia.com>
> Subject: Re: [lng-odp] [PATCH 1/2] linux-generic: pktio: recover from transmit
> errors
> 
> Hello Matias,
> 
> can you please review and test that patches in your env? To be sure that
> bug is totally fixed.
> 
> Thank you,
> Maxim.
> 
> On 11/10/2015 21:24, Stuart Haslam wrote:
> > Fix the way transmit errors are handled to avoid getting out of sync
> > between kernel and user space, which causes transmission to hang.
> >
> > Fixes bug https://bugs.linaro.org/show_bug.cgi?id=1890
> >
> > Signed-off-by: Stuart Haslam <stuart.has...@linaro.org>
> > ---
> >   platform/linux-generic/pktio/socket_mmap.c | 59
> +++++++++++++++++++++---------
> >   1 file changed, 41 insertions(+), 18 deletions(-)
> >
> > diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-
> generic/pktio/socket_mmap.c
> > index 79ff82d..2bdb72b 100644
> > --- a/platform/linux-generic/pktio/socket_mmap.c
> > +++ b/platform/linux-generic/pktio/socket_mmap.c
> > @@ -182,6 +182,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct
> ring *ring,
> >     unsigned n, i = 0;
> >     unsigned nb_tx = 0;
> >     int send_errno;
> > +   int total_len = 0;
> >
> >     first_frame_num = ring->frame_num;
> >     frame_num = first_frame_num;
> > @@ -195,6 +196,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct
> ring *ring,
> >             pkt_len = odp_packet_len(pkt_table[i]);
> >             ppd.v2->tp_h.tp_snaplen = pkt_len;
> >             ppd.v2->tp_h.tp_len = pkt_len;
> > +           total_len += pkt_len;
> >
> >             buf = (uint8_t *)ppd.raw + TPACKET2_HDRLEN -
> >                    sizeof(struct sockaddr_ll);
> > @@ -215,28 +217,49 @@ static inline unsigned pkt_mmap_v2_tx(int sock,
> struct ring *ring,
> >      * failure a value of -1 is returned, even if the failure occurred
> >      * after some of the packets in the ring have already been sent, so we
> >      * need to inspect the packet status to determine which were sent. */
> > -   for (frame_num = first_frame_num, n = 0; n < i; ++n) {
> > -           struct tpacket2_hdr *hdr = ring->rd[frame_num].iov_base;
> > +   if (odp_likely(ret == total_len)) {
> > +           nb_tx = i;
> > +           ring->frame_num = frame_num;
> > +   } else if (ret == -1) {
> > +           for (frame_num = first_frame_num, n = 0; n < i; ++n) {
> > +                   struct tpacket2_hdr *hdr = ring-
> >rd[frame_num].iov_base;
> > +
> > +                   if (odp_likely(hdr->tp_status == TP_STATUS_AVAILABLE
> ||
> > +                                  hdr->tp_status == TP_STATUS_SENDING)) {
> > +                           nb_tx++;
> > +                   } else {
> > +                           /* The remaining frames weren't sent, clear
> > +                            * their status to indicate we're not waiting
> > +                            * for the kernel to process them. */
> > +                           hdr->tp_status = TP_STATUS_AVAILABLE;
> > +                   }
> >
> > -           if (odp_likely(hdr->tp_status == TP_STATUS_AVAILABLE)) {
> > -                   nb_tx++;
> > -           } else if (hdr->tp_status & TP_STATUS_WRONG_FORMAT) {
> > -                   /* status will be cleared on the next send request */
> > -                   break;
> > +                   if (++frame_num >= frame_count)
> > +                           frame_num = 0;
> >             }
> >
> > -           if (++frame_num >= frame_count)
> > -                   frame_num = 0;
> > -   }
> > -
> > -   ring->frame_num = (ring->frame_num + nb_tx) % frame_count;
> > +           ring->frame_num = (first_frame_num + nb_tx) % frame_count;
> > +
> > +           if (nb_tx == 0 && SOCK_ERR_REPORT(send_errno)) {
> > +                   __odp_errno = send_errno;
> > +                   /* ENOBUFS indicates that the transmit queue is full,
> > +                    * which will happen regularly when overloaded so don't
> > +                    * print it */
> > +                   if (errno != ENOBUFS)
> > +                           ODP_ERR("sendto(pkt mmap): %s\n",
> > +                                   strerror(send_errno));
> > +                   return -1;
> > +           }
> > +   } else {
> > +           /* Short send, return value is number of bytes sent so use this
> > +            * to determine number of complete frames sent. */
> > +           for (n = 0; n < i && ret > 0; ++n) {
> > +                   ret -= odp_packet_len(pkt_table[n]);
> > +                   if (ret >= 0)
> > +                           nb_tx++;
> > +           }
> >
> > -   if (odp_unlikely(ret == -1 &&
> > -                    nb_tx == 0 &&
> > -                    SOCK_ERR_REPORT(send_errno))) {
> > -           __odp_errno = send_errno;
> > -           ODP_ERR("sendto(pkt mmap): %s\n", strerror(send_errno));
> > -           return -1;
> > +           ring->frame_num = (first_frame_num + nb_tx) % frame_count;
> >     }
> >
> >     for (i = 0; i < nb_tx; ++i)

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to