From patchwork Wed Sep 11 08:11:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160760 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46SvtN4wGbz9s00 for ; Wed, 11 Sep 2019 18:18:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 48502110B; Wed, 11 Sep 2019 08:12:19 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 3DD621104 for ; Wed, 11 Sep 2019 08:12:17 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id D290A7DB for ; Wed, 11 Sep 2019 08:12:15 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599366" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:14 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:21 +0200 Message-Id: <20190911081127.2140-2-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 1/7] netdev-dpdk: Validate packets burst before Tx. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Tiago Lam Given that multi-segment mbufs might be sent between interfaces that support different capabilities, and may even support different layouts of mbufs, outgoing packets should be validated before sent on the egress interface. Thus, netdev_dpdk_eth_tx_burst() now calls DPDK's rte_eth_tx_prepare() function, if and only multi-segments is enbaled, in order to validate the following (taken from the DPDK documentation), on a device specific manner: - Check if packet meets devices requirements for tx offloads. - Check limitations about number of segments. - Check additional requirements when debug is enabled. - Update and/or reset required checksums when tx offload is set for packet. Signed-off-by: Tiago Lam Signed-off-by: Michal Obrembski --- lib/netdev-dpdk.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 084a54e..6797081 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -2106,6 +2106,10 @@ netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq) /* Tries to transmit 'pkts' to txq 'qid' of device 'dev'. Takes ownership of * 'pkts', even in case of failure. + * In case multi-segment mbufs / TSO is being used, it also prepares. In such + * cases, only the prepared packets will be sent to Tx burst, meaning that if + * an invalid packet appears in 'pkts'[3] only the validated packets in indices + * 0, 1 and 2 will be sent. * * Returns the number of packets that weren't transmitted. */ static inline int @@ -2113,11 +2117,24 @@ netdev_dpdk_eth_tx_burst(struct netdev_dpdk *dev, int qid, struct rte_mbuf **pkts, int cnt) { uint32_t nb_tx = 0; + uint16_t nb_prep = cnt; + + /* If multi-segments is enabled, validate the burst of packets for Tx. */ + if (OVS_UNLIKELY(dpdk_multi_segment_mbufs)) { + nb_prep = rte_eth_tx_prepare(dev->port_id, qid, pkts, cnt); + if (nb_prep != cnt) { + VLOG_WARN_RL(&rl, "%s: Preparing packet tx burst failed (%u/%u " + "packets valid): %s", dev->up.name, nb_prep, cnt, + rte_strerror(rte_errno)); + } + } - while (nb_tx != cnt) { + /* Tx the validated burst of packets only. */ + while (nb_tx != nb_prep) { uint32_t ret; - ret = rte_eth_tx_burst(dev->port_id, qid, pkts + nb_tx, cnt - nb_tx); + ret = rte_eth_tx_burst(dev->port_id, qid, pkts + nb_tx, + nb_prep - nb_tx); if (!ret) { break; } From patchwork Wed Sep 11 08:11:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160761 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Svtv6tTFz9sCJ for ; Wed, 11 Sep 2019 18:19:03 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id EB7B11133; Wed, 11 Sep 2019 08:12:21 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7EE92F54 for ; Wed, 11 Sep 2019 08:12:18 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 8C99E7D2 for ; Wed, 11 Sep 2019 08:12:17 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599373" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:15 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:22 +0200 Message-Id: <20190911081127.2140-3-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 2/7] netdev-dpdk: Consider packets marked for TSO. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Tiago Lam Previously, TSO was being explicity disabled on vhost interfaces, meaning the guests wouldn't have TSO support negotiated in. With TSO negotiated and enabled, packets are now marked for TSO, through the PKT_TX_TCP_SEG flag. In order to deal with this type of packets, a new function, netdev_dpdk_prep_tso_packet(), has been introduced, with the main purpose of setting correctly the l2, l3 and l4 length members of the mbuf struct, and the appropriate ol_flags. This function supports TSO both in IPv4 and IPv6. netdev_dpdk_prep_tso_packet() is then only called when packets are marked with the PKT_TX_TCP_SEG flag, meaning they have been marked for TSO, and when the packet will be traversing the NIC. Additionally, if a packet is marked for TSO but the egress netdev doesn't support it, the packet is dropped. Co-authored-by: Mark Kavanagh Signed-off-by: Mark Kavanagh Signed-off-by: Tiago Lam Signed-off-by: Michal Obrembski --- lib/dp-packet.h | 16 +++++++ lib/netdev-bsd.c | 11 ++++- lib/netdev-dpdk.c | 122 ++++++++++++++++++++++++++++++++++++++++++----------- lib/netdev-dummy.c | 11 ++++- lib/netdev-linux.c | 15 +++++++ 5 files changed, 149 insertions(+), 26 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index f091265..96136ed 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -122,6 +122,8 @@ static inline void dp_packet_set_size(struct dp_packet *, uint32_t); static inline uint16_t dp_packet_get_allocated(const struct dp_packet *); static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t); +static inline bool dp_packet_is_tso(struct dp_packet *b); + void *dp_packet_resize_l2(struct dp_packet *, int increment); void *dp_packet_resize_l2_5(struct dp_packet *, int increment); static inline void *dp_packet_eth(const struct dp_packet *); @@ -797,6 +799,14 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s) b->mbuf.buf_len = s; } +static inline bool +dp_packet_is_tso(struct dp_packet *b) +{ + return (b->mbuf.ol_flags & (PKT_TX_TCP_SEG | PKT_TX_L4_MASK)) + ? true + : false; +} + static inline void dp_packet_copy_mbuf_flags(struct dp_packet *dst, const struct dp_packet *src) { @@ -1007,6 +1017,12 @@ dp_packet_get_allocated(const struct dp_packet *b) return b->allocated_; } +static inline bool +dp_packet_is_tso(struct dp_packet *b OVS_UNUSED) +{ + return false; +} + static inline void dp_packet_set_allocated(struct dp_packet *b, uint16_t s) { diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 6224dab..a1172a5 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -700,11 +700,20 @@ netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED, } DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { + size_t size = dp_packet_size(packet); + + /* TSO not supported in BSD netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN_RL(&rl, "%s: No TSO support on port, TSO packet of size " + "%" PRIuSIZE " dropped", name, size); + + continue; + } + /* We need the whole data to send the packet on the device */ dp_packet_linearize(packet); const void *data = dp_packet_data(packet); - size_t size = dp_packet_size(packet); while (!error) { ssize_t retval; diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 6797081..2304f28 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -1384,14 +1384,16 @@ netdev_dpdk_vhost_construct(struct netdev *netdev) goto out; } - err = rte_vhost_driver_disable_features(dev->vhost_id, - 1ULL << VIRTIO_NET_F_HOST_TSO4 - | 1ULL << VIRTIO_NET_F_HOST_TSO6 - | 1ULL << VIRTIO_NET_F_CSUM); - if (err) { - VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " - "port: %s\n", name); - goto out; + if (!dpdk_multi_segment_mbufs) { + err = rte_vhost_driver_disable_features(dev->vhost_id, + 1ULL << VIRTIO_NET_F_HOST_TSO4 + | 1ULL << VIRTIO_NET_F_HOST_TSO6 + | 1ULL << VIRTIO_NET_F_CSUM); + if (err) { + VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " + "client port: %s\n", dev->up.name); + goto out; + } } err = rte_vhost_driver_start(dev->vhost_id); @@ -2104,6 +2106,44 @@ netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq) rte_free(rx); } +/* Should only be called if PKT_TX_TCP_SEG is set in ol_flags. + * Furthermore, it also sets the PKT_TX_TCP_CKSUM and PKT_TX_IP_CKSUM flags, + * and PKT_TX_IPV4 and PKT_TX_IPV6 in case the packet is IPv4 or IPv6, + * respectively. */ +static void +netdev_dpdk_prep_tso_packet(struct rte_mbuf *mbuf, int mtu) +{ + struct dp_packet *pkt; + struct tcp_header *th; + + pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); + mbuf->l2_len = (char *) dp_packet_l3(pkt) - (char *) dp_packet_eth(pkt); + mbuf->l3_len = (char *) dp_packet_l4(pkt) - (char *) dp_packet_l3(pkt); + th = dp_packet_l4(pkt); + /* There's no layer 4 in the packet. */ + if (!th) { + return; + } + mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4; + mbuf->outer_l2_len = 0; + mbuf->outer_l3_len = 0; + + /* Reset packet RX RSS flag to reuse in egress. */ + dp_packet_mbuf_rss_flag_reset(pkt); + + if (!(mbuf->ol_flags & PKT_TX_TCP_SEG)) { + return; + } + + /* Prepare packet for egress. */ + mbuf->ol_flags |= PKT_TX_TCP_SEG; + mbuf->ol_flags |= PKT_TX_TCP_CKSUM; + mbuf->ol_flags |= PKT_TX_IP_CKSUM; + + /* Set the size of each TCP segment, based on the MTU of the device. */ + mbuf->tso_segsz = mtu - mbuf->l3_len - mbuf->l4_len; +} + /* Tries to transmit 'pkts' to txq 'qid' of device 'dev'. Takes ownership of * 'pkts', even in case of failure. * In case multi-segment mbufs / TSO is being used, it also prepares. In such @@ -2413,13 +2453,29 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, int cnt = 0; struct rte_mbuf *pkt; + /* Filter oversized packets, unless are marked for TSO. */ for (i = 0; i < pkt_cnt; i++) { pkt = pkts[i]; + if (OVS_UNLIKELY(pkt->pkt_len > dev->max_packet_len)) { - VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " max_packet_len %d", - dev->up.name, pkt->pkt_len, dev->max_packet_len); - rte_pktmbuf_free(pkt); - continue; + if (!(pkt->ol_flags & PKT_TX_TCP_SEG)) { + VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " " + "max_packet_len %d", + dev->up.name, pkt->pkt_len, dev->max_packet_len); + rte_pktmbuf_free(pkt); + continue; + } else { + /* 'If' the 'pkt' is intended for a VM, prepare it for sending, + * 'else' the 'pkt' will not actually traverse the NIC, but + * rather travel between VMs on the same host. */ + if (dev->type != DPDK_DEV_VHOST) { + netdev_dpdk_prep_tso_packet(pkt, dev->mtu); + } + } + } else { + if (dev->type != DPDK_DEV_VHOST) { + netdev_dpdk_prep_tso_packet(pkt, dev->mtu); + } } if (OVS_UNLIKELY(i != cnt)) { @@ -2519,6 +2575,7 @@ dpdk_copy_dp_packet_to_mbuf(struct dp_packet *packet, struct rte_mbuf **head, struct rte_mempool *mp) { struct rte_mbuf *mbuf, *fmbuf; + struct dp_packet *pkt = NULL; uint16_t max_data_len; uint32_t nb_segs = 0; uint32_t size = 0; @@ -2559,6 +2616,12 @@ dpdk_copy_dp_packet_to_mbuf(struct dp_packet *packet, struct rte_mbuf **head, fmbuf->nb_segs = nb_segs; fmbuf->pkt_len = size; + pkt = CONTAINER_OF(fmbuf, struct dp_packet, mbuf); + pkt->l2_pad_size = packet->l2_pad_size; + pkt->l2_5_ofs = packet->l2_5_ofs; + pkt->l3_ofs = packet->l3_ofs; + pkt->l4_ofs = packet->l4_ofs; + dp_packet_mbuf_write(fmbuf, 0, size, dp_packet_data(packet)); return 0; @@ -2593,14 +2656,17 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) for (i = 0; i < cnt; i++) { struct dp_packet *packet = batch->packets[i]; + struct rte_mbuf *pkt = &batch->packets[i]->mbuf; uint32_t size = dp_packet_size(packet); int err = 0; if (OVS_UNLIKELY(size > dev->max_packet_len)) { - VLOG_WARN_RL(&rl, "Too big size %u max_packet_len %d", - size, dev->max_packet_len); - dropped++; - continue; + if (!(pkt->ol_flags & PKT_TX_TCP_SEG)) { + VLOG_WARN_RL(&rl, "Too big size %u max_packet_len %d", + size, dev->max_packet_len); + dropped++; + continue; + } } err = dpdk_copy_dp_packet_to_mbuf(packet, &pkts[txcnt], @@ -2616,6 +2682,12 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) } dp_packet_copy_mbuf_flags((struct dp_packet *)pkts[txcnt], packet); + if (dev->type != DPDK_DEV_VHOST) { + /* If packet is non-DPDK, at the very least, we need to update the + * mbuf length members, even if TSO is not to be performed. */ + netdev_dpdk_prep_tso_packet(pkts[txcnt], dev->mtu); + } + txcnt++; } @@ -4466,14 +4538,16 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) goto unlock; } - err = rte_vhost_driver_disable_features(dev->vhost_id, - 1ULL << VIRTIO_NET_F_HOST_TSO4 - | 1ULL << VIRTIO_NET_F_HOST_TSO6 - | 1ULL << VIRTIO_NET_F_CSUM); - if (err) { - VLOG_ERR("rte_vhost_driver_disable_features failed for vhost user " - "client port: %s\n", dev->up.name); - goto unlock; + if (!dpdk_multi_segment_mbufs) { + err = rte_vhost_driver_disable_features(dev->vhost_id, + 1ULL << VIRTIO_NET_F_HOST_TSO4 + | 1ULL << VIRTIO_NET_F_HOST_TSO6 + | 1ULL << VIRTIO_NET_F_CSUM); + if (err) { + VLOG_ERR("rte_vhost_driver_disable_features failed for vhost " + "user client port: %s\n", dev->up.name); + goto unlock; + } } err = rte_vhost_driver_start(dev->vhost_id); diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 048725a..11f269f 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -1108,11 +1108,20 @@ netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED, struct dp_packet *packet; DP_PACKET_BATCH_FOR_EACH(i, packet, batch) { + size_t size = dp_packet_size(packet); + + /* TSO not supported in Dummy netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN("%s: No TSO support on port, TSO packet of size " + "%" PRIuSIZE " dropped", netdev_get_name(netdev), size); + + continue; + } + /* We need the whole data to send the packet on the device */ dp_packet_linearize(packet); const void *buffer = dp_packet_data(packet); - size_t size = dp_packet_size(packet); if (packet->packet_type != htonl(PT_ETH)) { error = EPFNOSUPPORT; diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 6439d7c..9a88fb6 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -1316,6 +1316,13 @@ netdev_linux_sock_batch_send(int sock, int ifindex, struct dp_packet *packet; DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { + /* TSO not supported in Linux netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN_RL(&rl, "%d: No TSO support on port, TSO packet of size " + "%" PRIuSIZE " dropped", sock, size); + continue; + } + /* We need the whole data to send the packet on the device */ dp_packet_linearize(packet); @@ -1372,6 +1379,14 @@ netdev_linux_tap_batch_send(struct netdev *netdev_, ssize_t retval; int error; + /* TSO not supported in Linux netdev */ + if (dp_packet_is_tso(packet)) { + VLOG_WARN_RL(&rl, "%s: No TSO support on port, TSO packet of size " + "%" PRIuSIZE " dropped", netdev_get_name(netdev_), + size); + continue; + } + /* We need the whole data to send the packet on the device */ dp_packet_linearize(packet); From patchwork Wed Sep 11 08:11:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46SvvY6hl3z9s00 for ; Wed, 11 Sep 2019 18:19:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A587E113F; Wed, 11 Sep 2019 08:12:22 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 459D41115 for ; Wed, 11 Sep 2019 08:12:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 2C6377D2 for ; Wed, 11 Sep 2019 08:12:19 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599376" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:17 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:23 +0200 Message-Id: <20190911081127.2140-4-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 3/7] netdev-dpdk: Enable TSO when using multi-seg mbufs X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Tiago Lam TCP Segmentation Offload (TSO) is a feature which enables the TCP/IP network stack to delegate segmentation of a TCP segment to the hardware NIC, thus saving compute resources. This may improve performance significantly for TCP workload in virtualized environments. While a previous commit already added the necesary logic to netdev-dpdk to deal with packets marked for TSO, this set of changes enables TSO by default when using multi-segment mbufs. Thus, to enable TSO on the physical DPDK interfaces, only the following command needs to be issued before starting OvS: ovs-vsctl set Open_vSwitch . other_config:dpdk-multi-seg-mbufs=true Co-authored-by: Mark Kavanagh Signed-off-by: Mark Kavanagh Signed-off-by: Tiago Lam Signed-off-by: Michal Obrembski --- Documentation/automake.mk | 1 + Documentation/topics/dpdk/index.rst | 1 + Documentation/topics/dpdk/tso.rst | 99 +++++++++++++++++++++++++++++++++++++ NEWS | 1 + lib/netdev-dpdk.c | 70 ++++++++++++++++++++++++-- 5 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 Documentation/topics/dpdk/tso.rst diff --git a/Documentation/automake.mk b/Documentation/automake.mk index 2a3214a..5955dd7 100644 --- a/Documentation/automake.mk +++ b/Documentation/automake.mk @@ -40,6 +40,7 @@ DOC_SOURCE = \ Documentation/topics/dpdk/index.rst \ Documentation/topics/dpdk/bridge.rst \ Documentation/topics/dpdk/jumbo-frames.rst \ + Documentation/topics/dpdk/tso.rst \ Documentation/topics/dpdk/memory.rst \ Documentation/topics/dpdk/pdump.rst \ Documentation/topics/dpdk/phy.rst \ diff --git a/Documentation/topics/dpdk/index.rst b/Documentation/topics/dpdk/index.rst index cf24a7b..eb2a04d 100644 --- a/Documentation/topics/dpdk/index.rst +++ b/Documentation/topics/dpdk/index.rst @@ -40,4 +40,5 @@ The DPDK Datapath /topics/dpdk/qos /topics/dpdk/pdump /topics/dpdk/jumbo-frames + /topics/dpdk/tso /topics/dpdk/memory diff --git a/Documentation/topics/dpdk/tso.rst b/Documentation/topics/dpdk/tso.rst new file mode 100644 index 0000000..14f8c39 --- /dev/null +++ b/Documentation/topics/dpdk/tso.rst @@ -0,0 +1,99 @@ +.. + Copyright 2018, Red Hat, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + + Convention for heading levels in Open vSwitch documentation: + + ======= Heading 0 (reserved for the title in a document) + ------- Heading 1 + ~~~~~~~ Heading 2 + +++++++ Heading 3 + ''''''' Heading 4 + + Avoid deeper levels because they do not render well. + +=== +TSO +=== + +**Note:** This feature is considered experimental. + +TCP Segmentation Offload (TSO) is a mechanism which allows a TCP/IP stack to +offload the TCP segmentation into hardware, thus saving the cycles that would +be required to perform this same segmentation in software. + +TCP Segmentation Offload (TSO) enables a network stack to delegate segmentation +of an oversized TCP segment to the underlying physical NIC. Offload of frame +segmentation achieves computational savings in the core, freeing up CPU cycles +for more useful work. + +A common use case for TSO is when using virtualization, where traffic that's +coming in from a VM can offload the TCP segmentation, thus avoiding the +fragmentation in software. Additionally, if the traffic is headed to a VM +within the same host further optimization can be expected. As the traffic never +leaves the machine, no MTU needs to be accounted for, and thus no segmentation +and checksum calculations are required, which saves yet more cycles. Only when +the traffic actually leaves the host the segmentation needs to happen, in which +case it will be performed by the egress NIC. + +When using TSO with DPDK, the implementation relies on the multi-segment mbufs +feature, described in :doc:`/topics/dpdk/jumbo-frames`, where each mbuf +contains ~2KiB of the entire packet's data and is linked to the next mbuf that +contains the next portion of data. + +Enabling TSO +~~~~~~~~~~~~ +.. Important:: + + Once multi-segment mbufs is enabled, TSO will be enabled by default, if + there's support for it in the underlying physical NICs attached to + OvS-DPDK. + +When using :doc:`vHost User ports `, TSO may be enabled in one of +two ways, as follows. + +`TSO` is enabled in OvS by the DPDK vHost User backend; when a new guest +connection is established, `TSO` is thus advertised to the guest as an +available feature: + +1. QEMU Command Line Parameter:: + + $ sudo $QEMU_DIR/x86_64-softmmu/qemu-system-x86_64 \ + ... + -device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1,\ + csum=on,guest_csum=on,guest_tso4=on,guest_tso6=on\ + ... + +2. Ethtool. Assuming that the guest's OS also supports `TSO`, ethtool can be used to enable same:: + + $ ethtool -K eth0 sg on # scatter-gather is a prerequisite for TSO + $ ethtool -K eth0 tso on + $ ethtool -k eth0 + +To enable TSO in a guest, the underlying NIC must first support `TSO` - consult +your controller's datasheet for compatibility. Secondly, the NIC must have an +associated DPDK Poll Mode Driver (PMD) which supports `TSO`. + +~~~~~~~~~~~ +Limitations +~~~~~~~~~~~ +The current OvS `TSO` implementation supports flat and VLAN networks only (i.e. +no support for `TSO` over tunneled connection [VxLAN, GRE, IPinIP, etc.]). + +Also, as TSO is built on top of multi-segments mbufs, the constraints pointed +out in :doc:`/topics/dpdk/jumbo-frames` also apply for TSO. Thus, some +performance hits might be noticed when running specific functionality, like +the Userspace Connection tracker. And as mentioned in the same section, it is +paramount that a packet's headers is contained within the first mbuf (~2KiB in +size). diff --git a/NEWS b/NEWS index 1278ada..e219822 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,7 @@ v2.12.0 - xx xxx xxxx specific subtables based on the miniflow attributes, enhancing the performance of the subtable search. * Add Linux AF_XDP support through a new experimental netdev type "afxdp". + * Add support for TSO (experimental, between DPDK interfaces only). - OVSDB: * OVSDB clients can now resynchronize with clustered servers much more quickly after a brief disconnection, saving bandwidth and CPU time. diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 2304f28..7552caa 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -345,7 +345,8 @@ struct ingress_policer { enum dpdk_hw_ol_features { NETDEV_RX_CHECKSUM_OFFLOAD = 1 << 0, NETDEV_RX_HW_CRC_STRIP = 1 << 1, - NETDEV_RX_HW_SCATTER = 1 << 2 + NETDEV_RX_HW_SCATTER = 1 << 2, + NETDEV_TX_TSO_OFFLOAD = 1 << 3, }; /* @@ -996,8 +997,18 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) return -ENOTSUP; } + if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO; + conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM; + conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM; + } + txconf = info.default_txconf; txconf.offloads = conf.txmode.offloads; + } else if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + VLOG_WARN("Failed to set Tx TSO offload in %s. Requires option " + "`dpdk-multi-seg-mbufs` to be enabled.", dev->up.name); } conf.intr_conf.lsc = dev->lsc_interrupt_mode; @@ -1114,6 +1125,9 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) uint32_t rx_chksm_offload_capa = DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM | DEV_RX_OFFLOAD_IPV4_CKSUM; + uint32_t tx_tso_offload_capa = DEV_TX_OFFLOAD_TCP_TSO | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_IPV4_CKSUM; rte_eth_dev_info_get(dev->port_id, &info); @@ -1140,6 +1154,18 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) dev->hw_ol_features &= ~NETDEV_RX_HW_SCATTER; } + if (dpdk_multi_segment_mbufs) { + if (info.tx_offload_capa & tx_tso_offload_capa) { + dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + } else { + dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + VLOG_WARN("Tx TSO offload is not supported on port " + DPDK_PORT_ID_FMT, dev->port_id); + } + } else { + dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + } + n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq); n_txq = MIN(info.max_tx_queues, dev->up.n_txq); @@ -1727,6 +1753,11 @@ netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args) } else { smap_add(args, "rx_csum_offload", "false"); } + if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + smap_add(args, "tx_tso_offload", "true"); + } else { + smap_add(args, "tx_tso_offload", "false"); + } smap_add(args, "lsc_interrupt_mode", dev->lsc_interrupt_mode ? "true" : "false"); } @@ -2445,9 +2476,21 @@ netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts, return cnt; } +/* Filters a DPDK packet by the following criteria: + * - A packet is marked for TSO but the egress dev doesn't + * support TSO; + * - A packet pkt_len is bigger than the pre-defined + * max_packet_len, and the packet isn't marked for TSO. + * + * If any of the above case applies, the packet is then freed + * from 'pkts'. Otherwise the packet is kept in 'pkts' + * untouched. + * + * Returns the number of unfiltered packets left in 'pkts'. + */ static int -netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, - int pkt_cnt) +netdev_dpdk_filter_packet(struct netdev_dpdk *dev, struct rte_mbuf **pkts, + int pkt_cnt) { int i = 0; int cnt = 0; @@ -2457,6 +2500,15 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, for (i = 0; i < pkt_cnt; i++) { pkt = pkts[i]; + /* Drop TSO packet if there's no TSO support on egress port. */ + if ((pkt->ol_flags & PKT_TX_TCP_SEG) && + !(dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD)) { + VLOG_WARN_RL(&rl, "%s: TSO is disabled on port, TSO packet dropped" + "%" PRIu32 " ", dev->up.name, pkt->pkt_len); + rte_pktmbuf_free(pkt); + continue; + } + if (OVS_UNLIKELY(pkt->pkt_len > dev->max_packet_len)) { if (!(pkt->ol_flags & PKT_TX_TCP_SEG)) { VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " " @@ -2528,7 +2580,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, rte_spinlock_lock(&dev->tx_q[qid].tx_lock); - cnt = netdev_dpdk_filter_packet_len(dev, cur_pkts, cnt); + cnt = netdev_dpdk_filter_packet(dev, cur_pkts, cnt); /* Check has QoS has been configured for the netdev */ cnt = netdev_dpdk_qos_run(dev, cur_pkts, cnt, true); dropped = total_pkts - cnt; @@ -2747,7 +2799,7 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, int batch_cnt = dp_packet_batch_size(batch); struct rte_mbuf **pkts = (struct rte_mbuf **) batch->packets; - tx_cnt = netdev_dpdk_filter_packet_len(dev, pkts, batch_cnt); + tx_cnt = netdev_dpdk_filter_packet(dev, pkts, batch_cnt); tx_cnt = netdev_dpdk_qos_run(dev, pkts, tx_cnt, true); dropped = batch_cnt - tx_cnt; @@ -4445,6 +4497,14 @@ dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev) dev->tx_q[0].map = 0; } + if (dpdk_multi_segment_mbufs) { + dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + + VLOG_DBG("%s: TSO enabled on vhost port", dev->up.name); + } else { + dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + } + netdev_dpdk_remap_txqs(dev); err = netdev_dpdk_mempool_configure(dev); From patchwork Wed Sep 11 08:11:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Svwh64rWz9s00 for ; Wed, 11 Sep 2019 18:20:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 5C746115A; Wed, 11 Sep 2019 08:12:24 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 88BA410F3 for ; Wed, 11 Sep 2019 08:12:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 95C0F7D2 for ; Wed, 11 Sep 2019 08:12:20 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599384" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:19 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:24 +0200 Message-Id: <20190911081127.2140-5-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 4/7] Performance improvements and native tnl fixes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Tiago Lam Make miniflow_extract() perform by checking if the header fits in the first mbuf only in a single place, since the multiple checks would bring some performance penalties. Furthermore, in some functions, such as dp_packet_set_size(), to distinguish between multi-segment mbufs and a single segment mbuf only the "b->source == DPBUF_DPDK" was being used. This could lead to the case where a single-segment mbuf would enter a loop where only a single segment needs processing, thus leading to some extra logic and some performance penalty. Finally, fix some tunnel cases to check if the tunneling headers (VXLAN, GRE, ...) fit on the first mbuf. Otherwise return an error. Signed-off-by: Tiago Lam Signed-off-by: Michal Obrembski --- lib/dp-packet.h | 18 +++++------ lib/flow.c | 81 ++++++++++++++++--------------------------------- lib/netdev-dpdk.c | 13 +++----- lib/netdev-native-tnl.c | 10 +++--- 4 files changed, 45 insertions(+), 77 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 96136ed..68da4e9 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -258,7 +258,7 @@ dp_packet_copy_common_members(struct dp_packet *new_b, static inline void * dp_packet_at(const struct dp_packet *b, size_t offset, size_t size) { - if (offset + size > dp_packet_size(b)) { + if (OVS_UNLIKELY(offset + size > dp_packet_size(b))) { return NULL; } @@ -266,7 +266,7 @@ dp_packet_at(const struct dp_packet *b, size_t offset, size_t size) if (b->source == DPBUF_DPDK) { const struct rte_mbuf *mbuf = dp_packet_mbuf_from_offset(b, &offset); - if (!mbuf || offset + size > mbuf->data_len) { + if (OVS_UNLIKELY(!mbuf || offset + size > mbuf->data_len)) { return NULL; } @@ -290,7 +290,7 @@ static inline void * dp_packet_tail(const struct dp_packet *b) { #ifdef DPDK_NETDEV - if (b->source == DPBUF_DPDK) { + if (OVS_UNLIKELY(b->source == DPBUF_DPDK && !dp_packet_is_linear(b))) { struct rte_mbuf *buf = CONST_CAST(struct rte_mbuf *, &b->mbuf); /* Find last segment where data ends, meaning the tail of the chained * mbufs must be there */ @@ -308,7 +308,7 @@ static inline void * dp_packet_end(const struct dp_packet *b) { #ifdef DPDK_NETDEV - if (b->source == DPBUF_DPDK) { + if (OVS_UNLIKELY(b->source == DPBUF_DPDK && !dp_packet_is_linear(b))) { struct rte_mbuf *buf = CONST_CAST(struct rte_mbuf *, &(b->mbuf)); buf = rte_pktmbuf_lastseg(buf); @@ -342,7 +342,7 @@ static inline void dp_packet_clear(struct dp_packet *b) { #ifdef DPDK_NETDEV - if (b->source == DPBUF_DPDK) { + if (OVS_UNLIKELY(b->source == DPBUF_DPDK && !dp_packet_is_linear(b))) { /* sets pkt_len and data_len to zero and frees unused mbufs */ dp_packet_set_size(b, 0); rte_pktmbuf_reset(&b->mbuf); @@ -383,7 +383,7 @@ dp_packet_may_pull(const struct dp_packet *b, uint16_t offset, size_t size) } #ifdef DPDK_NETDEV /* Offset needs to be within the first mbuf */ - if (offset + size > b->mbuf.data_len) { + if (OVS_UNLIKELY(offset + size > b->mbuf.data_len)) { return false; } #endif @@ -693,7 +693,7 @@ dp_packet_size(const struct dp_packet *b) static inline void dp_packet_set_size(struct dp_packet *b, uint32_t v) { - if (b->source == DPBUF_DPDK) { + if (OVS_UNLIKELY(b->source == DPBUF_DPDK && !dp_packet_is_linear(b))) { struct rte_mbuf *mbuf = &b->mbuf; uint16_t new_len = v; uint16_t data_len; @@ -906,8 +906,8 @@ dp_packet_copy_from_offset(const struct dp_packet *b, size_t offset, static inline bool dp_packet_is_linear(const struct dp_packet *b) { - if (b->source == DPBUF_DPDK) { - return rte_pktmbuf_is_contiguous(&b->mbuf); + if (OVS_UNLIKELY(b->mbuf.nb_segs > 1)) { + return false; } return true; diff --git a/lib/flow.c b/lib/flow.c index e6019bf..1465d28 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -711,6 +711,25 @@ ipv6_sanity_check(const struct ovs_16aligned_ip6_hdr *nh, size_t size) return true; } +#define MAX_IPV4_LEN \ + (ETH_HEADER_LEN + IP_HEADER_LEN + \ + MAX(TCP_HEADER_LEN, \ + MAX(UDP_HEADER_LEN, \ + MAX(SCTP_HEADER_LEN, MAX(ICMP_HEADER_LEN, \ + IGMP_HEADER_LEN))))) + +#define MAX_IPV6_LEN \ + (ETH_HEADER_LEN + IPV6_HEADER_LEN + \ + MAX(TCP_HEADER_LEN, \ + MAX(UDP_HEADER_LEN, \ + MAX(SCTP_HEADER_LEN, \ + MAX(sizeof(struct tcp_header), IGMP_HEADER_LEN))))) + +#define MAX_ARP_NSH_LEN (ETH_HEADER_LEN + MAX(ARP_ETH_HEADER_LEN, \ + NSH_BASE_HDR_LEN)) + +#define MAX_HEADER_LEN MAX(MAX_IPV4_LEN, MAX(MAX_IPV6_LEN, MAX_ARP_NSH_LEN)) + /* Initializes 'dst' from 'packet' and 'md', taking the packet type into * account. 'dst' must have enough space for FLOW_U64S * 8 bytes. * @@ -759,6 +778,13 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) uint8_t *ct_nw_proto_p = NULL; ovs_be16 ct_tp_src = 0, ct_tp_dst = 0; + /* Check if header is in first mbuf, otherwise return error */ + if (OVS_UNLIKELY(!dp_packet_is_linear(packet))) { + if (!dp_packet_may_pull(packet, 0, MAX_HEADER_LEN)) { + return -EINVAL; + } + } + /* Metadata. */ if (flow_tnl_dst_is_set(&md->tunnel)) { miniflow_push_words(mf, tunnel, &md->tunnel, @@ -862,13 +888,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) int ip_len; uint16_t tot_len; - /* Check if header is in first mbuf, otherwise return error */ - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l3_ofs, sizeof *nh)) { - return -EINVAL; - } - } - if (OVS_UNLIKELY(!ipv4_sanity_check(nh, size, &ip_len, &tot_len))) { goto out; } @@ -899,12 +918,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) ovs_be32 tc_flow; uint16_t plen; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l3_ofs, sizeof *nh)) { - return -EINVAL; - } - } - if (OVS_UNLIKELY(!ipv6_sanity_check(nh, size))) { goto out; } @@ -951,13 +964,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) dl_type == htons(ETH_TYPE_RARP)) { struct eth_addr arp_buf[2]; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l3_ofs, - ARP_ETH_HEADER_LEN)) { - return -EINVAL; - } - } - const struct arp_eth_header *arp = (const struct arp_eth_header *) data_try_pull(&data, &size, ARP_ETH_HEADER_LEN); @@ -1005,13 +1011,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) if (OVS_LIKELY(size >= TCP_HEADER_LEN)) { const struct tcp_header *tcp = data; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l4_ofs, - TCP_HEADER_LEN)) { - return -EINVAL; - } - } - miniflow_push_be32(mf, arp_tha.ea[2], 0); miniflow_push_be32(mf, tcp_flags, TCP_FLAGS_BE32(tcp->tcp_ctl)); @@ -1024,13 +1023,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) if (OVS_LIKELY(size >= UDP_HEADER_LEN)) { const struct udp_header *udp = data; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l4_ofs, - UDP_HEADER_LEN)) { - return -EINVAL; - } - } - miniflow_push_be16(mf, tp_src, udp->udp_src); miniflow_push_be16(mf, tp_dst, udp->udp_dst); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); @@ -1040,13 +1032,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) if (OVS_LIKELY(size >= SCTP_HEADER_LEN)) { const struct sctp_header *sctp = data; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l4_ofs, - SCTP_HEADER_LEN)) { - return -EINVAL; - } - } - miniflow_push_be16(mf, tp_src, sctp->sctp_src); miniflow_push_be16(mf, tp_dst, sctp->sctp_dst); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); @@ -1056,13 +1041,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) if (OVS_LIKELY(size >= ICMP_HEADER_LEN)) { const struct icmp_header *icmp = data; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l4_ofs, - ICMP_HEADER_LEN)) { - return -EINVAL; - } - } - miniflow_push_be16(mf, tp_src, htons(icmp->icmp_type)); miniflow_push_be16(mf, tp_dst, htons(icmp->icmp_code)); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); @@ -1072,13 +1050,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) if (OVS_LIKELY(size >= IGMP_HEADER_LEN)) { const struct igmp_header *igmp = data; - if (!dp_packet_is_linear(packet)) { - if (!dp_packet_may_pull(packet, packet->l4_ofs, - IGMP_HEADER_LEN)) { - return -EINVAL; - } - } - miniflow_push_be16(mf, tp_src, htons(igmp->igmp_type)); miniflow_push_be16(mf, tp_dst, htons(igmp->igmp_code)); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 7552caa..159cd7a 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -559,17 +559,17 @@ void free_dpdk_buf(struct dp_packet *p) { /* If non-pmd we need to lock on nonpmd_mp_mutex mutex */ - if (!dpdk_thread_is_pmd()) { + if (dpdk_thread_is_pmd()) { + rte_pktmbuf_free(&p->mbuf); + + return; + } else { ovs_mutex_lock(&nonpmd_mp_mutex); rte_pktmbuf_free(&p->mbuf); ovs_mutex_unlock(&nonpmd_mp_mutex); - - return; } - - rte_pktmbuf_free(&p->mbuf); } static void @@ -2159,9 +2159,6 @@ netdev_dpdk_prep_tso_packet(struct rte_mbuf *mbuf, int mtu) mbuf->outer_l2_len = 0; mbuf->outer_l3_len = 0; - /* Reset packet RX RSS flag to reuse in egress. */ - dp_packet_mbuf_rss_flag_reset(pkt); - if (!(mbuf->ol_flags & PKT_TX_TCP_SEG)) { return; } diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 285b927..145ae46 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -363,7 +363,7 @@ parse_gre_header(struct dp_packet *packet, } hlen = ulen + gre_header_len(greh->flags); - if (hlen > dp_packet_size(packet)) { + if (!dp_packet_may_pull(packet, packet->l3_ofs, hlen)) { return -EINVAL; } @@ -534,7 +534,7 @@ netdev_erspan_pop_header(struct dp_packet *packet) IPV6_HEADER_LEN : IP_HEADER_LEN; pkt_metadata_init_tnl(md); - if (hlen > dp_packet_size(packet)) { + if (!dp_packet_may_pull(packet, packet->l3_ofs, hlen)) { goto err; } @@ -719,7 +719,7 @@ netdev_vxlan_pop_header(struct dp_packet *packet) ovs_assert(packet->l4_ofs > 0); pkt_metadata_init_tnl(md); - if (VXLAN_HLEN > dp_packet_l4_size(packet)) { + if (!dp_packet_may_pull(packet, packet->l4_ofs, VXLAN_HLEN)) { goto err; } @@ -841,7 +841,7 @@ netdev_geneve_pop_header(struct dp_packet *packet) unsigned int hlen, opts_len, ulen; pkt_metadata_init_tnl(md); - if (GENEVE_BASE_HLEN > dp_packet_l4_size(packet)) { + if (!dp_packet_may_pull(packet, packet->l4_ofs, GENEVE_BASE_HLEN)) { VLOG_WARN_RL(&err_rl, "geneve packet too small: min header=%u packet size=%"PRIuSIZE"\n", (unsigned int)GENEVE_BASE_HLEN, dp_packet_l4_size(packet)); goto err; @@ -854,7 +854,7 @@ netdev_geneve_pop_header(struct dp_packet *packet) opts_len = gnh->opt_len * 4; hlen = ulen + GENEVE_BASE_HLEN + opts_len; - if (hlen > dp_packet_size(packet)) { + if (!dp_packet_may_pull(packet, packet->l4_ofs, hlen)) { VLOG_WARN_RL(&err_rl, "geneve packet too small: header len=%u packet size=%u\n", hlen, dp_packet_size(packet)); goto err; From patchwork Wed Sep 11 08:11:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Svxn0S3dz9s00 for ; Wed, 11 Sep 2019 18:21:32 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 1787A115F; Wed, 11 Sep 2019 08:12:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id F189F1147 for ; Wed, 11 Sep 2019 08:12:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C4B447D2 for ; Wed, 11 Sep 2019 08:12:21 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599389" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:20 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:25 +0200 Message-Id: <20190911081127.2140-6-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 5/7] Fix OVN failing tests. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Michal Obrembski An unnecessary offset has been added while introducing dp_packet_may_pull in netdev-native-tnl.c Signed-off-by: Michal Obrembski --- lib/netdev-native-tnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 145ae46..54ed0e9 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -854,7 +854,7 @@ netdev_geneve_pop_header(struct dp_packet *packet) opts_len = gnh->opt_len * 4; hlen = ulen + GENEVE_BASE_HLEN + opts_len; - if (!dp_packet_may_pull(packet, packet->l4_ofs, hlen)) { + if (!dp_packet_may_pull(packet, packet->l4_ofs, hlen - ulen)) { VLOG_WARN_RL(&err_rl, "geneve packet too small: header len=%u packet size=%u\n", hlen, dp_packet_size(packet)); goto err; From patchwork Wed Sep 11 08:11:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160765 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46SvyL3myFz9s4Y for ; Wed, 11 Sep 2019 18:22:02 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id DC8601157; Wed, 11 Sep 2019 08:12:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 4A351114E for ; Wed, 11 Sep 2019 08:12:23 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id D76707DB for ; Wed, 11 Sep 2019 08:12:22 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599400" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:21 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:26 +0200 Message-Id: <20190911081127.2140-7-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 6/7] Give the variables more meaningful names X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Artur Twardowski Replaced variable names "hlen", "ulen", "gnh" with longer ones to make the code analysis easier. Additionally, UDP header len is no longer accumulated into GENEVE header length, additions are used in the places where the sum of both headers is used. Signed-off-by: Artur Twardowski --- lib/netdev-native-tnl.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 54ed0e9..d0ea3d5 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -837,8 +837,8 @@ netdev_geneve_pop_header(struct dp_packet *packet) { struct pkt_metadata *md = &packet->md; struct flow_tnl *tnl = &md->tunnel; - struct genevehdr *gnh; - unsigned int hlen, opts_len, ulen; + struct genevehdr *geneve_hdr; + unsigned int geneve_hdr_len, opts_len, udp_hdr_len; pkt_metadata_init_tnl(md); if (!dp_packet_may_pull(packet, packet->l4_ofs, GENEVE_BASE_HLEN)) { @@ -847,40 +847,42 @@ netdev_geneve_pop_header(struct dp_packet *packet) goto err; } - gnh = udp_extract_tnl_md(packet, tnl, &ulen); - if (!gnh) { + geneve_hdr = udp_extract_tnl_md(packet, tnl, &udp_hdr_len); + if (!geneve_hdr) { goto err; } - opts_len = gnh->opt_len * 4; - hlen = ulen + GENEVE_BASE_HLEN + opts_len; - if (!dp_packet_may_pull(packet, packet->l4_ofs, hlen - ulen)) { - VLOG_WARN_RL(&err_rl, "geneve packet too small: header len=%u packet size=%u\n", - hlen, dp_packet_size(packet)); + opts_len = geneve_hdr->opt_len * 4; + geneve_hdr_len = GENEVE_BASE_HLEN + opts_len; + if (!dp_packet_may_pull(packet, udp_hdr_len, geneve_hdr_len)) { + VLOG_WARN_RL(&err_rl, "geneve packet too small: " + "wanted headers=%u, but packet size=%u\n", + geneve_hdr_len + udp_hdr_len, + dp_packet_size(packet)); goto err; } - if (gnh->ver != 0) { - VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", gnh->ver); + if (geneve_hdr->ver != 0) { + VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", geneve_hdr->ver); goto err; } - if (gnh->proto_type != htons(ETH_TYPE_TEB)) { + if (geneve_hdr->proto_type != htons(ETH_TYPE_TEB)) { VLOG_WARN_RL(&err_rl, "unknown geneve encapsulated protocol: %#x\n", - ntohs(gnh->proto_type)); + ntohs(geneve_hdr->proto_type)); goto err; } - tnl->flags |= gnh->oam ? FLOW_TNL_F_OAM : 0; - tnl->tun_id = htonll(ntohl(get_16aligned_be32(&gnh->vni)) >> 8); + tnl->flags |= geneve_hdr->oam ? FLOW_TNL_F_OAM : 0; + tnl->tun_id = htonll(ntohl(get_16aligned_be32(&geneve_hdr->vni)) >> 8); tnl->flags |= FLOW_TNL_F_KEY; - memcpy(tnl->metadata.opts.gnv, gnh->options, opts_len); + memcpy(tnl->metadata.opts.gnv, geneve_hdr->options, opts_len); tnl->metadata.present.len = opts_len; tnl->flags |= FLOW_TNL_F_UDPIF; packet->packet_type = htonl(PT_ETH); - dp_packet_reset_packet(packet, hlen); + dp_packet_reset_packet(packet, geneve_hdr_len + udp_hdr_len); return packet; err: From patchwork Wed Sep 11 08:11:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Obrembski X-Patchwork-Id: 1160766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Svyy01lhz9s4Y for ; Wed, 11 Sep 2019 18:22:33 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 95F0D1164; Wed, 11 Sep 2019 08:12:27 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 214C2115A for ; Wed, 11 Sep 2019 08:12:24 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C9BC57D2 for ; Wed, 11 Sep 2019 08:12:23 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Sep 2019 01:12:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="214599404" Received: from mobrembx-mobl.ger.corp.intel.com ([10.103.104.26]) by fmsmga002.fm.intel.com with ESMTP; 11 Sep 2019 01:12:22 -0700 From: Obrembski To: dev@openvswitch.org Date: Wed, 11 Sep 2019 10:11:27 +0200 Message-Id: <20190911081127.2140-8-michalx.obrembski@intel.com> X-Mailer: git-send-email 2.23.0.windows.1 In-Reply-To: <20190911081127.2140-1-michalx.obrembski@intel.com> References: <20190911081127.2140-1-michalx.obrembski@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 7/7] Too long line split into two X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Artur Twardowski Signed-off-by: Artur Twardowski --- lib/netdev-native-tnl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index d0ea3d5..f542858 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -863,7 +863,8 @@ netdev_geneve_pop_header(struct dp_packet *packet) } if (geneve_hdr->ver != 0) { - VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", geneve_hdr->ver); + VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", + geneve_hdr->ver); goto err; }