Message ID | 1433349859-28565-2-git-send-email-zoltan.kiss@linaro.org |
---|---|
State | New |
Headers | show |
On Wed, Jun 03, 2015 at 05:44:19PM +0100, Zoltan Kiss wrote: > And change the behaviour in linux-generic implementation, where it's releasing > it during the call. > > Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org> > --- > example/packet/odp_pktio.c | 9 ++++++++- > platform/linux-generic/odp_packet_io.c | 10 +++++++++- > platform/linux-generic/odp_packet_socket.c | 6 ------ > test/performance/odp_l2fwd.c | 11 +++++++++-- > 4 files changed, 26 insertions(+), 10 deletions(-) > > diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c > index f08d9f4..4242caa 100644 > --- a/example/packet/odp_pktio.c > +++ b/example/packet/odp_pktio.c > @@ -282,9 +282,16 @@ static void *pktio_ifburst_thread(void *arg) > /* Drop packets with errors */ > pkts_ok = drop_err_pkts(pkt_tbl, pkts); > if (pkts_ok > 0) { > + int sent; > /* Swap Eth MACs and IP-addrs */ > swap_pkt_addrs(pkt_tbl, pkts_ok); > - odp_pktio_send(pktio, pkt_tbl, pkts_ok); > + sent = odp_pktio_send(pktio, pkt_tbl, pkts_ok); > + if (odp_unlikely(sent < pkts_ok)) { > + err_cnt += pkts_ok - sent; > + do > + odp_packet_free(pkt_tbl[sent++]); > + while (++sent < pkts_ok); You're incrementing sent twice. > + } > } > > if (odp_unlikely(pkts_ok != pkts)) > diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c > index 5ae24b9..6e7db41 100644 > --- a/platform/linux-generic/odp_packet_io.c > +++ b/platform/linux-generic/odp_packet_io.c > @@ -564,6 +564,9 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > int nbr; > > nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > + if (odp_unlikely(nbr == 0)) > + odp_packet_free(pkt); > + Why do this here rather than letting the caller of enqueue decide how to deal with the failure? > return (nbr == len ? 0 : -1); > } > > @@ -583,7 +586,12 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > for (i = 0; i < num; ++i) > pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle); > > - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > + i = nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > + if (odp_unlikely(i < num)) > + do > + odp_packet_free(pkt_tbl[i]); > + while (++i < num); > + Same comment as above. > return nbr; > } > > diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c > index 9272146..309980d 100644 > --- a/platform/linux-generic/odp_packet_socket.c > +++ b/platform/linux-generic/odp_packet_socket.c > @@ -301,9 +301,6 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock, > } /* end while */ > nb_tx = i; > > - for (i = 0; i < len; i++) > - odp_packet_free(pkt_table[i]); > - Now packets that were actually sent are being leaked. > return nb_tx; > } > > @@ -408,9 +405,6 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, > flags = 0; /* blocking for next rounds */ > } > > - for (i = 0; i < len; i++) > - odp_packet_free(pkt_table[i]); > - And here. > return len; > } > > diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c > index 5d4b833..8c64a9c 100644 > --- a/test/performance/odp_l2fwd.c > +++ b/test/performance/odp_l2fwd.c > @@ -224,8 +224,15 @@ static void *pktio_ifburst_thread(void *arg) > > /* Drop packets with errors */ > pkts_ok = drop_err_pkts(pkt_tbl, pkts); > - if (pkts_ok > 0) > - odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); > + if (pkts_ok > 0) { > + int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); > + if (odp_unlikely(sent < pkts_ok)) { > + stats->drops += pkts_ok - sent; > + do > + odp_packet_free(pkt_tbl[sent]); > + while (++sent < pkts_ok); > + } > + } > > if (odp_unlikely(pkts_ok != pkts)) > stats->drops += pkts - pkts_ok; > -- > 1.9.1 >
On 03/06/15 18:00, Stuart Haslam wrote: > On Wed, Jun 03, 2015 at 05:44:19PM +0100, Zoltan Kiss wrote: >> And change the behaviour in linux-generic implementation, where it's releasing >> it during the call. >> >> Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org> >> --- >> example/packet/odp_pktio.c | 9 ++++++++- >> platform/linux-generic/odp_packet_io.c | 10 +++++++++- >> platform/linux-generic/odp_packet_socket.c | 6 ------ >> test/performance/odp_l2fwd.c | 11 +++++++++-- >> 4 files changed, 26 insertions(+), 10 deletions(-) >> >> diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c >> index f08d9f4..4242caa 100644 >> --- a/example/packet/odp_pktio.c >> +++ b/example/packet/odp_pktio.c >> @@ -282,9 +282,16 @@ static void *pktio_ifburst_thread(void *arg) >> /* Drop packets with errors */ >> pkts_ok = drop_err_pkts(pkt_tbl, pkts); >> if (pkts_ok > 0) { >> + int sent; >> /* Swap Eth MACs and IP-addrs */ >> swap_pkt_addrs(pkt_tbl, pkts_ok); >> - odp_pktio_send(pktio, pkt_tbl, pkts_ok); >> + sent = odp_pktio_send(pktio, pkt_tbl, pkts_ok); >> + if (odp_unlikely(sent < pkts_ok)) { >> + err_cnt += pkts_ok - sent; >> + do >> + odp_packet_free(pkt_tbl[sent++]); >> + while (++sent < pkts_ok); > > You're incrementing sent twice. Indeed, I'll fix that. > >> + } >> } >> >> if (odp_unlikely(pkts_ok != pkts)) >> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c >> index 5ae24b9..6e7db41 100644 >> --- a/platform/linux-generic/odp_packet_io.c >> +++ b/platform/linux-generic/odp_packet_io.c >> @@ -564,6 +564,9 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) >> int nbr; >> >> nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); >> + if (odp_unlikely(nbr == 0)) >> + odp_packet_free(pkt); >> + > > Why do this here rather than letting the caller of enqueue decide how > to deal with the failure? This is bringing up an another issue: we should define the same behaviour for odp_queue_enq() and odp_queue_enq_multi(), shouldn't we? > >> return (nbr == len ? 0 : -1); >> } >> >> @@ -583,7 +586,12 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], >> for (i = 0; i < num; ++i) >> pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle); >> >> - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); >> + i = nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); >> + if (odp_unlikely(i < num)) >> + do >> + odp_packet_free(pkt_tbl[i]); >> + while (++i < num); >> + > > Same comment as above. > >> return nbr; >> } >> >> diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c >> index 9272146..309980d 100644 >> --- a/platform/linux-generic/odp_packet_socket.c >> +++ b/platform/linux-generic/odp_packet_socket.c >> @@ -301,9 +301,6 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock, >> } /* end while */ >> nb_tx = i; >> >> - for (i = 0; i < len; i++) >> - odp_packet_free(pkt_table[i]); >> - > > Now packets that were actually sent are being leaked. I'll fix these too > >> return nb_tx; >> } >> >> @@ -408,9 +405,6 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, >> flags = 0; /* blocking for next rounds */ >> } >> >> - for (i = 0; i < len; i++) >> - odp_packet_free(pkt_table[i]); >> - > > And here. > >> return len; >> } >> >> diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c >> index 5d4b833..8c64a9c 100644 >> --- a/test/performance/odp_l2fwd.c >> +++ b/test/performance/odp_l2fwd.c >> @@ -224,8 +224,15 @@ static void *pktio_ifburst_thread(void *arg) >> >> /* Drop packets with errors */ >> pkts_ok = drop_err_pkts(pkt_tbl, pkts); >> - if (pkts_ok > 0) >> - odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); >> + if (pkts_ok > 0) { >> + int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); >> + if (odp_unlikely(sent < pkts_ok)) { >> + stats->drops += pkts_ok - sent; >> + do >> + odp_packet_free(pkt_tbl[sent]); >> + while (++sent < pkts_ok); >> + } >> + } >> >> if (odp_unlikely(pkts_ok != pkts)) >> stats->drops += pkts - pkts_ok; >> -- >> 1.9.1 >> >
On that note it turned out this will be a lot bigger than I thought ... And I already have two questions: - what should we do if an assert over odp_queue_enq fails? E.g. "CU_ASSERT(odp_queue_enq(queue, ev) == 0)" Should we free the events, or just leave it? - there are numerous places where you don't know what kind of event you are actually queue, so should we make an odp_event_free() call?, e.g. odp_schedule_release_atomic On 03/06/15 18:56, Zoltan Kiss wrote: > > This is bringing up an another issue: we should define the same > behaviour for odp_queue_enq() and odp_queue_enq_multi(), shouldn't we?
On 3 June 2015 at 20:42, Zoltan Kiss <zoltan.kiss@linaro.org> wrote: > On that note it turned out this will be a lot bigger than I thought ... > And I already have two questions: > > - what should we do if an assert over odp_queue_enq fails? E.g. > "CU_ASSERT(odp_queue_enq(queue, ev) == 0)" Should we free the events, or > just leave it? > If we want the validation program to terminate cleanly, I assume the caller has to free any buffers that weren't enqueued or they will be leaked and then things will go bad when the program is terminating. > - there are numerous places where you don't know what kind of event you > are actually queue, so should we make an odp_event_free() call?, e.g. > I have also encountered this situation. I even started to write a post to the list about it. But in the end I hacked around it, probably by switching on the event type and calling different free functions. Having an odp_event_free() would be simpler and clearer so I second your suggestion here. -- Ola > odp_schedule_release_atomic > > > > On 03/06/15 18:56, Zoltan Kiss wrote: > >> >> This is bringing up an another issue: we should define the same >> behaviour for odp_queue_enq() and odp_queue_enq_multi(), shouldn't we? >> > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/lng-odp >
On Wed, Jun 03, 2015 at 06:56:00PM +0100, Zoltan Kiss wrote: > > > On 03/06/15 18:00, Stuart Haslam wrote: > >On Wed, Jun 03, 2015 at 05:44:19PM +0100, Zoltan Kiss wrote: > >>And change the behaviour in linux-generic implementation, where it's releasing > >>it during the call. > >> > >>Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org> > >>--- > >> example/packet/odp_pktio.c | 9 ++++++++- > >> platform/linux-generic/odp_packet_io.c | 10 +++++++++- > >> platform/linux-generic/odp_packet_socket.c | 6 ------ > >> test/performance/odp_l2fwd.c | 11 +++++++++-- > >> 4 files changed, 26 insertions(+), 10 deletions(-) > >> > >>diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c > >>index f08d9f4..4242caa 100644 > >>--- a/example/packet/odp_pktio.c > >>+++ b/example/packet/odp_pktio.c > >>@@ -282,9 +282,16 @@ static void *pktio_ifburst_thread(void *arg) > >> /* Drop packets with errors */ > >> pkts_ok = drop_err_pkts(pkt_tbl, pkts); > >> if (pkts_ok > 0) { > >>+ int sent; > >> /* Swap Eth MACs and IP-addrs */ > >> swap_pkt_addrs(pkt_tbl, pkts_ok); > >>- odp_pktio_send(pktio, pkt_tbl, pkts_ok); > >>+ sent = odp_pktio_send(pktio, pkt_tbl, pkts_ok); > >>+ if (odp_unlikely(sent < pkts_ok)) { > >>+ err_cnt += pkts_ok - sent; > >>+ do > >>+ odp_packet_free(pkt_tbl[sent++]); > >>+ while (++sent < pkts_ok); > > > >You're incrementing sent twice. > > Indeed, I'll fix that. > > > > >>+ } > >> } > >> > >> if (odp_unlikely(pkts_ok != pkts)) > >>diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c > >>index 5ae24b9..6e7db41 100644 > >>--- a/platform/linux-generic/odp_packet_io.c > >>+++ b/platform/linux-generic/odp_packet_io.c > >>@@ -564,6 +564,9 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) > >> int nbr; > >> > >> nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); > >>+ if (odp_unlikely(nbr == 0)) > >>+ odp_packet_free(pkt); > >>+ > > > >Why do this here rather than letting the caller of enqueue decide how > >to deal with the failure? > > This is bringing up an another issue: we should define the same > behaviour for odp_queue_enq() and odp_queue_enq_multi(), shouldn't > we? > Yes, Leo mentioned that in the egress API document. > > > >> return (nbr == len ? 0 : -1); > >> } > >> > >>@@ -583,7 +586,12 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], > >> for (i = 0; i < num; ++i) > >> pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle); > >> > >>- nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > >>+ i = nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); > >>+ if (odp_unlikely(i < num)) > >>+ do > >>+ odp_packet_free(pkt_tbl[i]); > >>+ while (++i < num); > >>+ > > > >Same comment as above. > > > >> return nbr; > >> } > >> > >>diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c > >>index 9272146..309980d 100644 > >>--- a/platform/linux-generic/odp_packet_socket.c > >>+++ b/platform/linux-generic/odp_packet_socket.c > >>@@ -301,9 +301,6 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock, > >> } /* end while */ > >> nb_tx = i; > >> > >>- for (i = 0; i < len; i++) > >>- odp_packet_free(pkt_table[i]); > >>- > > > >Now packets that were actually sent are being leaked. > I'll fix these too > By the way I submitted a patch (https://patches.linaro.org/46723/) a while back to tidy up the handling of transmit errors in odp_packet_socket.c. There's an outstanding comment I need to address, I'll send an updated version later today or tomorrow.
On Wed, Jun 03, 2015 at 09:37:54PM +0200, Ola Liljedahl wrote: > On 3 June 2015 at 20:42, Zoltan Kiss <zoltan.kiss@linaro.org> wrote: > > > On that note it turned out this will be a lot bigger than I thought ... > > And I already have two questions: > > > > - what should we do if an assert over odp_queue_enq fails? E.g. > > "CU_ASSERT(odp_queue_enq(queue, ev) == 0)" Should we free the events, or > > just leave it? > > > If we want the validation program to terminate cleanly, I assume the caller > has to free any buffers that weren't enqueued or they will be leaked and > then things will go bad when the program is terminating. > > > > - there are numerous places where you don't know what kind of event you > > are actually queue, so should we make an odp_event_free() call?, e.g. > > > I have also encountered this situation. I even started to write a post to > the list about it. But in the end I hacked around it, probably by switching > on the event type and calling different free functions. Having an > odp_event_free() would be simpler and clearer so I second your suggestion > here. > > -- Ola Me too. Actually it looks like I did; odp_buffer_free(odp_buffer_from_event(ev)); Is this not sufficient?.. anyway I agree odp_event_free() would be clearer.
On 04/06/15 10:22, Stuart Haslam wrote: > On Wed, Jun 03, 2015 at 09:37:54PM +0200, Ola Liljedahl wrote: >> On 3 June 2015 at 20:42, Zoltan Kiss <zoltan.kiss@linaro.org> wrote: >> >>> On that note it turned out this will be a lot bigger than I thought ... >>> And I already have two questions: >>> >>> - what should we do if an assert over odp_queue_enq fails? E.g. >>> "CU_ASSERT(odp_queue_enq(queue, ev) == 0)" Should we free the events, or >>> just leave it? >>> >> If we want the validation program to terminate cleanly, I assume the caller >> has to free any buffers that weren't enqueued or they will be leaked and >> then things will go bad when the program is terminating. >> >> >>> - there are numerous places where you don't know what kind of event you >>> are actually queue, so should we make an odp_event_free() call?, e.g. >>> >> I have also encountered this situation. I even started to write a post to >> the list about it. But in the end I hacked around it, probably by switching >> on the event type and calling different free functions. Having an >> odp_event_free() would be simpler and clearer so I second your suggestion >> here. >> >> -- Ola > > Me too. Actually it looks like I did; > > odp_buffer_free(odp_buffer_from_event(ev)); > > Is this not sufficient?.. No, it releases the buffer as it would be a raw buffer. A related issue is that odp_buffer_* functions seem to handle the input as a raw buffer, while an unsuspecting developer might think they are generic buffer functions which can handle any kind of buffers. anyway I agree odp_event_free() would be > clearer. I'll send in a patch for that too
On 4 June 2015 at 11:22, Stuart Haslam <stuart.haslam@linaro.org> wrote: > On Wed, Jun 03, 2015 at 09:37:54PM +0200, Ola Liljedahl wrote: > > On 3 June 2015 at 20:42, Zoltan Kiss <zoltan.kiss@linaro.org> wrote: > > > > > On that note it turned out this will be a lot bigger than I thought ... > > > And I already have two questions: > > > > > > - what should we do if an assert over odp_queue_enq fails? E.g. > > > "CU_ASSERT(odp_queue_enq(queue, ev) == 0)" Should we free the events, > or > > > just leave it? > > > > > If we want the validation program to terminate cleanly, I assume the > caller > > has to free any buffers that weren't enqueued or they will be leaked and > > then things will go bad when the program is terminating. > > > > > > > - there are numerous places where you don't know what kind of event you > > > are actually queue, so should we make an odp_event_free() call?, e.g. > > > > > I have also encountered this situation. I even started to write a post to > > the list about it. But in the end I hacked around it, probably by > switching > > on the event type and calling different free functions. Having an > > odp_event_free() would be simpler and clearer so I second your suggestion > > here. > > > > -- Ola > > Me too. Actually it looks like I did; > > odp_buffer_free(odp_buffer_from_event(ev)); > But this require the code snippet here to be aware of *all* different (current and *future*) event types. -- Ola > Is this not sufficient?.. anyway I agree odp_event_free() would be > clearer. > > -- > Stuart. >
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index f08d9f4..4242caa 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -282,9 +282,16 @@ static void *pktio_ifburst_thread(void *arg) /* Drop packets with errors */ pkts_ok = drop_err_pkts(pkt_tbl, pkts); if (pkts_ok > 0) { + int sent; /* Swap Eth MACs and IP-addrs */ swap_pkt_addrs(pkt_tbl, pkts_ok); - odp_pktio_send(pktio, pkt_tbl, pkts_ok); + sent = odp_pktio_send(pktio, pkt_tbl, pkts_ok); + if (odp_unlikely(sent < pkts_ok)) { + err_cnt += pkts_ok - sent; + do + odp_packet_free(pkt_tbl[sent++]); + while (++sent < pkts_ok); + } } if (odp_unlikely(pkts_ok != pkts)) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 5ae24b9..6e7db41 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -564,6 +564,9 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) int nbr; nbr = odp_pktio_send(qentry->s.pktout, &pkt, len); + if (odp_unlikely(nbr == 0)) + odp_packet_free(pkt); + return (nbr == len ? 0 : -1); } @@ -583,7 +586,12 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], for (i = 0; i < num; ++i) pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle); - nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); + i = nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num); + if (odp_unlikely(i < num)) + do + odp_packet_free(pkt_tbl[i]); + while (++i < num); + return nbr; } diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c index 9272146..309980d 100644 --- a/platform/linux-generic/odp_packet_socket.c +++ b/platform/linux-generic/odp_packet_socket.c @@ -301,9 +301,6 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock, } /* end while */ nb_tx = i; - for (i = 0; i < len; i++) - odp_packet_free(pkt_table[i]); - return nb_tx; } @@ -408,9 +405,6 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, flags = 0; /* blocking for next rounds */ } - for (i = 0; i < len; i++) - odp_packet_free(pkt_table[i]); - return len; } diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 5d4b833..8c64a9c 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -224,8 +224,15 @@ static void *pktio_ifburst_thread(void *arg) /* Drop packets with errors */ pkts_ok = drop_err_pkts(pkt_tbl, pkts); - if (pkts_ok > 0) - odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); + if (pkts_ok > 0) { + int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok); + if (odp_unlikely(sent < pkts_ok)) { + stats->drops += pkts_ok - sent; + do + odp_packet_free(pkt_tbl[sent]); + while (++sent < pkts_ok); + } + } if (odp_unlikely(pkts_ok != pkts)) stats->drops += pkts - pkts_ok;
And change the behaviour in linux-generic implementation, where it's releasing it during the call. Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org> --- example/packet/odp_pktio.c | 9 ++++++++- platform/linux-generic/odp_packet_io.c | 10 +++++++++- platform/linux-generic/odp_packet_socket.c | 6 ------ test/performance/odp_l2fwd.c | 11 +++++++++-- 4 files changed, 26 insertions(+), 10 deletions(-)