From patchwork Wed Dec 31 03:10:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Gross X-Patchwork-Id: 424721 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9BFA01400EA for ; Wed, 31 Dec 2014 14:10:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751563AbaLaDK3 (ORCPT ); Tue, 30 Dec 2014 22:10:29 -0500 Received: from na3sys009aog132.obsmtp.com ([74.125.149.250]:36672 "HELO na3sys009aog132.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751374AbaLaDK0 (ORCPT ); Tue, 30 Dec 2014 22:10:26 -0500 Received: from mail-pa0-f54.google.com ([209.85.220.54]) (using TLSv1) by na3sys009aob132.postini.com ([74.125.148.12]) with SMTP ID DSNKVKNpIa+FegL+rmr45JNZeqABbobtKO90@postini.com; Tue, 30 Dec 2014 19:10:26 PST Received: by mail-pa0-f54.google.com with SMTP id fb1so20467667pad.41 for ; Tue, 30 Dec 2014 19:10:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iL7/bkNo0PNdlqKz6g6bHH9uwzM/dM9kKivotHVe7Vo=; b=STyLzTOCFJdv1YMFuMBsqSQ1N9Qwjgc9VZ9kmre6sELQzVKmS+wNLrGXWI7GAQek9b WpYF5yNITMedb4dqKxqqJ++N5VKemBLUgReneH8u+/crTkFjnR825IXaWB3TJmMwMCSv FvIPF8OlkDpbk0hk4BvWy5WY7ERdXeD94AyzEwHgwrd+LDBztT/pD/oYbS4j3iV3IaoS D/N3F+5N3XKlvX4GkMEPt75cP462RzQCzuoU2/sLL1kWdM2hTya+ixKQQ2vTMihAxDkQ FM+wvHP4qZLSKT/IbYhGDWOB+mu7LOuK86M+i0Kume1TgZ3aBTjq1rct3GKUWxcPpV+J g/Rg== X-Gm-Message-State: ALoCoQknQZKcHr3Q3xKt9uVJLeAKRL2jex2IYQK6GVJ7k542NANPa9RHgvkr25YyxJ3oox3kxcT1gLzsCRh5cSeSq9gpOBpXzZixcaPv6/xl78nuovR+TvE09/MdC8hqi1/w9FmsVoGm1tO7sCEW37hD9mBOOTfeIg== X-Received: by 10.66.55.74 with SMTP id q10mr79228462pap.94.1419995425706; Tue, 30 Dec 2014 19:10:25 -0800 (PST) X-Received: by 10.66.55.74 with SMTP id q10mr79228450pap.94.1419995425639; Tue, 30 Dec 2014 19:10:25 -0800 (PST) Received: from ubuntu.localdomain ([73.47.22.226]) by mx.google.com with ESMTPSA id a5sm17631697pat.24.2014.12.30.19.10.23 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 30 Dec 2014 19:10:25 -0800 (PST) From: Jesse Gross To: David Miller Cc: netdev@vger.kernel.org, Joe Stringer Subject: [PATCH net-next 2/2] geneve: Add Geneve GRO support Date: Tue, 30 Dec 2014 19:10:16 -0800 Message-Id: <1419995416-29987-2-git-send-email-jesse@nicira.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1419995416-29987-1-git-send-email-jesse@nicira.com> References: <1419995416-29987-1-git-send-email-jesse@nicira.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Joe Stringer This results in an approximately 30% increase in throughput when handling encapsulated bulk traffic. Signed-off-by: Joe Stringer Signed-off-by: Jesse Gross --- net/ipv4/geneve.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 394a200..19e256e 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c @@ -149,6 +149,99 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, } EXPORT_SYMBOL_GPL(geneve_xmit_skb); +static int geneve_hlen(struct genevehdr *gh) +{ + return sizeof(*gh) + gh->opt_len * 4; +} + +static struct sk_buff **geneve_gro_receive(struct sk_buff **head, + struct sk_buff *skb) +{ + struct sk_buff *p, **pp = NULL; + struct genevehdr *gh, *gh2; + unsigned int hlen, gh_len, off_gnv; + const struct packet_offload *ptype; + __be16 type; + int flush = 1; + + off_gnv = skb_gro_offset(skb); + hlen = off_gnv + sizeof(*gh); + gh = skb_gro_header_fast(skb, off_gnv); + if (skb_gro_header_hard(skb, hlen)) { + gh = skb_gro_header_slow(skb, hlen, off_gnv); + if (unlikely(!gh)) + goto out; + } + + if (gh->ver != GENEVE_VER || gh->oam) + goto out; + gh_len = geneve_hlen(gh); + + hlen = off_gnv + gh_len; + if (skb_gro_header_hard(skb, hlen)) { + gh = skb_gro_header_slow(skb, hlen, off_gnv); + if (unlikely(!gh)) + goto out; + } + + flush = 0; + + for (p = *head; p; p = p->next) { + if (!NAPI_GRO_CB(p)->same_flow) + continue; + + gh2 = (struct genevehdr *)(p->data + off_gnv); + if (gh->opt_len != gh2->opt_len || + memcmp(gh, gh2, gh_len)) { + NAPI_GRO_CB(p)->same_flow = 0; + continue; + } + } + + type = gh->proto_type; + + rcu_read_lock(); + ptype = gro_find_receive_by_type(type); + if (ptype == NULL) { + flush = 1; + goto out_unlock; + } + + skb_gro_pull(skb, gh_len); + skb_gro_postpull_rcsum(skb, gh, gh_len); + pp = ptype->callbacks.gro_receive(head, skb); + +out_unlock: + rcu_read_unlock(); +out: + NAPI_GRO_CB(skb)->flush |= flush; + + return pp; +} + +static int geneve_gro_complete(struct sk_buff *skb, int nhoff) +{ + struct genevehdr *gh; + struct packet_offload *ptype; + __be16 type; + int gh_len; + int err = -ENOSYS; + + udp_tunnel_gro_complete(skb, nhoff); + + gh = (struct genevehdr *)(skb->data + nhoff); + gh_len = geneve_hlen(gh); + type = gh->proto_type; + + rcu_read_lock(); + ptype = gro_find_complete_by_type(type); + if (ptype != NULL) + err = ptype->callbacks.gro_complete(skb, nhoff + gh_len); + + rcu_read_unlock(); + return err; +} + static void geneve_notify_add_rx_port(struct geneve_sock *gs) { struct sock *sk = gs->sock->sk; @@ -278,8 +371,8 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, /* Initialize the geneve udp offloads structure */ gs->udp_offloads.port = port; - gs->udp_offloads.callbacks.gro_receive = NULL; - gs->udp_offloads.callbacks.gro_complete = NULL; + gs->udp_offloads.callbacks.gro_receive = geneve_gro_receive; + gs->udp_offloads.callbacks.gro_complete = geneve_gro_complete; spin_lock(&gn->sock_lock); hlist_add_head_rcu(&gs->hlist, gs_head(net, port));