From patchwork Tue Nov 10 18:24:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Haslam X-Patchwork-Id: 56343 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp927912lbb; Tue, 10 Nov 2015 10:25:10 -0800 (PST) X-Received: by 10.140.175.65 with SMTP id v62mr6472705qhv.75.1447179910514; Tue, 10 Nov 2015 10:25:10 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id z195si3951346qka.41.2015.11.10.10.25.10; Tue, 10 Nov 2015 10:25:10 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: by lists.linaro.org (Postfix, from userid 109) id 0811661B63; Tue, 10 Nov 2015 18:25:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,T_DKIM_INVALID,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id A1B5161D19; Tue, 10 Nov 2015 18:24:36 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 5B6B361B40; Tue, 10 Nov 2015 18:24:33 +0000 (UTC) Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by lists.linaro.org (Postfix) with ESMTPS id 4479461B40 for ; Tue, 10 Nov 2015 18:24:31 +0000 (UTC) Received: by wmww144 with SMTP id w144so12611546wmw.0 for ; Tue, 10 Nov 2015 10:24:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id; bh=aMOAOYFD6bkdwLYZqO/tYlv/pagQqqrNTzd9f7tVc7k=; b=uKXkWnqYn/JF3UTW7sabfPrlakY20gFjmepJBh17SIcmk1FaCgyc+BaDtXUA4XAX2e 9DwLNbWWXpuAc6JKSIvqCxn8TuY3lEjCIy6/sbkoSYw9Lv7TA8CNpS9z8pnUpLyZoqhB 7Unu5i5IAcKCahxN+/p471j/eizVvbCNncuDnMf12IPhPxbph+vWWLfW+U1aTkfa45Ic NStPvvPQ2IT/knV7TKnmHqgqUgn1DRkis+AkH+8I1Y9ufnd+gbyAQoHE3HdNA87tC3kO i1PJko6+xU4foprLndW6QJzePva7/Oqy85CaM4Or3m/DLG5115+i/0VoyeD5E/Tcsqcg h3Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=aMOAOYFD6bkdwLYZqO/tYlv/pagQqqrNTzd9f7tVc7k=; b=fVYdqbZO1BQI29pIHgNEWh3Wu6K2aoTS2tT5TdBPpDqWMrpCSYPOfe5x1t2+VKu8Yu Bt8m+oLf6k1oJCrpSHAzWn69LrJMg/UZc/I6HN5UGhokXOKIKm+H/9aouuCP7uSUYICS E5/HA+g/84ISx070sHlWBW/13qh086g/kOttucPUXCeHR66xM0HJ8Aj/LR54G4CkMiDq xQhPB5YgZo1vJh1qsTcON/JRBTW/DGeP2OCGSkiC4DlJcox/KI6Herjwc3xv7IWySSDi 7jt6FpSWfkBBUrJ8287/fiO7xTwA1IoRynUNzuZessQFsXs1TUKyOgVu6Z+huC2JVwLS AaSw== X-Gm-Message-State: ALoCoQkSQVw+YLHMSQzqMKJNtSPJn5Vhb7fkgXefL1E+PSz8Ua8A1yffxDMcciLa/VBFuUZAUfND X-Received: by 10.28.144.138 with SMTP id s132mr6053973wmd.97.1447179869339; Tue, 10 Nov 2015 10:24:29 -0800 (PST) Received: from e106441.emea.arm.com ([2001:41d0:a:3cb4::abcd]) by smtp.gmail.com with ESMTPSA id om1sm4853711wjc.2.2015.11.10.10.24.28 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 10 Nov 2015 10:24:28 -0800 (PST) From: Stuart Haslam To: lng-odp@lists.linaro.org Date: Tue, 10 Nov 2015 18:24:01 +0000 Message-Id: <1447179842-2541-1-git-send-email-stuart.haslam@linaro.org> X-Mailer: git-send-email 2.1.1 X-Topics: patch Subject: [lng-odp] [PATCH 1/2] linux-generic: pktio: recover from transmit errors X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" 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 --- 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)