Merged,
thanks!
Maxim.
On 11/13/2015 11:37, Elo, Matias (Nokia - FI/Espoo) wrote:
The patch fixes socket mmap transmit bug. For both patches:
Reviewed-and-Tested-by: Matias Elo <[email protected]>
While testing the patch set I noticed that the pktio_test_send_failure()
doesn't pass when using a directly attached cable between NIC ports. However,
this seems to be unrelated to the patch set.
$ sudo ODP_PKTIO_IF0=p1p1 ODP_PKTIO_IF1=p1p2 ./test/validation/pktio/pktio_main
...
Test: pktio_test_send_failure ... Received 0 packets
FAILED
1. pktio.c:394 - CU_FAIL("failed to receive transmitted packet")
2. pktio.c:943 - CU_FAIL("failed to receive transmitted packets\n")
3. pktio.c:394 - CU_FAIL("failed to receive transmitted packet")
4. pktio.c:963 - i == TX_BATCH_LEN
-Matias
-----Original Message-----
From: lng-odp [mailto:[email protected]] On Behalf Of EXT Stuart
Haslam
Sent: Tuesday, November 10, 2015 8:24 PM
To: [email protected]
Subject: [lng-odp] [PATCH 1/2] linux-generic: pktio: recover from transmit
errors
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 <[email protected]>
---
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)
--
2.1.1
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp