From patchwork Tue Oct 14 22:19:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 399570 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 3D3D014011D for ; Wed, 15 Oct 2014 09:19:27 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754562AbaJNWTW (ORCPT ); Tue, 14 Oct 2014 18:19:22 -0400 Received: from mail-pa0-f52.google.com ([209.85.220.52]:37941 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755615AbaJNWTV (ORCPT ); Tue, 14 Oct 2014 18:19:21 -0400 Received: by mail-pa0-f52.google.com with SMTP id fb1so16999pad.39 for ; Tue, 14 Oct 2014 15:19:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id; bh=Kem3SK4PE3aFDqUQl+PohE2RN6aYuTtDGODVfUnVMvA=; b=ND7yu6mnM2Pb4inrn7Rl/Sb+TWlZ/8fzXSER447IZHa01HLJTd2jmOeMiA4AxQCGXk SeSzNOM36nXjSRtqY8BUOGVZlDI3XeGKcUa4+11FA0uLphPSiMSLjMrKRS7q4gVY5anJ gBWtOl4Cxz8OWVJ5y2gF4oU6qJRGpJgRS24RPgIROfThGvCoLC/NgtsrqD7AOj5U3jzh pJmC4vUxKV1usjsO/ZQnMJDolybNC8mdpkM8ocsYcUCYhLuXPBznE75KPCt+UCF4VFho vBiX7HS78mdPpUORoNHWhXXnpx+Kp8TD1UC9KdeySwpTryUiyW4ldU/+LEkguj1K1ZCm 217w== 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=Kem3SK4PE3aFDqUQl+PohE2RN6aYuTtDGODVfUnVMvA=; b=IzlZDRwdXz7A73jkQ+QFyNzwd1Z0sYaif2dIzTHqLZirFy4a868olIjP7ZYvRhDjuq op2pnPe2KFBZwM7Oc61fiS6hvzHHdMeLPeZeH9KiljOEWGdth4MA6y/uxFgKixwEspsy G6Mvj9ZyFYVQIBJ4cX0uQ/WTJsyJxJfg5mzoARUiTQj8d12V77PQAI6W2wSv7KGxeXat 9DXWn5R0HD92NDZzhEwbOKGQuDs58TiMIPF76rtPfdpY5+Q4aFQQfd8gCpQvIBdOT04X tXtyxyto9KjbJ4nZawoHRVZbemer4ld3/JtrcHXh63G94J6xeblue7JzLOQzgaiVPCH7 YNsA== X-Gm-Message-State: ALoCoQlUGFKE1zRUAQAECuVaCiC1DG9X7EYR0zpS5JGOMEN6bd7O5RtWnm2FedVMO3ToaS0X1zBQ X-Received: by 10.70.132.133 with SMTP id ou5mr8119401pdb.51.1413325160991; Tue, 14 Oct 2014 15:19:20 -0700 (PDT) Received: from tomh.mtv.corp.google.com (tomh.mtv.corp.google.com [172.18.117.126]) by mx.google.com with ESMTPSA id va2sm15314861pac.15.2014.10.14.15.19.18 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 14 Oct 2014 15:19:19 -0700 (PDT) From: Tom Herbert To: davem@davemloft.net, netdev@vger.kernel.org Subject: [PATCH v2] net: Add ndo_gso_check Date: Tue, 14 Oct 2014 15:19:06 -0700 Message-Id: <1413325146-2404-1-git-send-email-therbert@google.com> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add ndo_gso_check which a device can define to indicate whether is is capable of doing GSO on a packet. This funciton would be called from the stack to determine whether software GSO is needed to be done. A driver should populate this function if it advertises GSO types for which there are combinations that it wouldn't be able to handle. For instance a device that performs UDP tunneling might only implement support for transparent Ethernet bridging type of inner packets or might have limitations on lengths of inner headers. Signed-off-by: Tom Herbert --- drivers/net/macvtap.c | 2 +- drivers/net/xen-netfront.c | 2 +- include/linux/netdevice.h | 12 +++++++++++- net/core/dev.c | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 0c6adaa..65e2892 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -298,7 +298,7 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb) */ if (q->flags & IFF_VNET_HDR) features |= vlan->tap_features; - if (netif_needs_gso(skb, features)) { + if (netif_needs_gso(dev, skb, features)) { struct sk_buff *segs = __skb_gso_segment(skb, features, false); if (IS_ERR(segs)) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ca82f54..3c0b375 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -638,7 +638,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(!netif_carrier_ok(dev) || (slots > 1 && !xennet_can_sg(dev)) || - netif_needs_gso(skb, netif_skb_features(skb)))) { + netif_needs_gso(dev, skb, netif_skb_features(skb)))) { spin_unlock_irqrestore(&queue->tx_lock, flags); goto drop; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 838407a..74fd5d3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -998,6 +998,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * Callback to use for xmit over the accelerated station. This * is used in place of ndo_start_xmit on accelerated net * devices. + * bool (*ndo_gso_check) (struct sk_buff *skb, + * struct net_device *dev); + * Called by core transmit path to determine if device is capable of + * performing GSO on a packet. The device returns true if it is + * able to GSO the packet, false otherwise. If the return value is + * false the stack will do software GSO. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1147,6 +1153,8 @@ struct net_device_ops { struct net_device *dev, void *priv); int (*ndo_get_lock_subclass)(struct net_device *dev); + bool (*ndo_gso_check) (struct sk_buff *skb, + struct net_device *dev); }; /** @@ -3572,10 +3580,12 @@ static inline bool skb_gso_ok(struct sk_buff *skb, netdev_features_t features) (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); } -static inline bool netif_needs_gso(struct sk_buff *skb, +static inline bool netif_needs_gso(struct net_device *dev, struct sk_buff *skb, netdev_features_t features) { return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || + (dev->netdev_ops->ndo_gso_check && + !dev->netdev_ops->ndo_gso_check(skb, dev)) || unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && (skb->ip_summed != CHECKSUM_UNNECESSARY))); } diff --git a/net/core/dev.c b/net/core/dev.c index 3c5bdaa..0ae59ec 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2677,7 +2677,7 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device if (skb->encapsulation) features &= dev->hw_enc_features; - if (netif_needs_gso(skb, features)) { + if (netif_needs_gso(dev, skb, features)) { struct sk_buff *segs; segs = skb_gso_segment(skb, features);