From patchwork Thu Nov 29 21:07:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Gallatin X-Patchwork-Id: 202825 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 38A9E2C0089 for ; Fri, 30 Nov 2012 08:07:39 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754763Ab2K2VHg (ORCPT ); Thu, 29 Nov 2012 16:07:36 -0500 Received: from mail-gh0-f174.google.com ([209.85.160.174]:63251 "EHLO mail-gh0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753382Ab2K2VHf (ORCPT ); Thu, 29 Nov 2012 16:07:35 -0500 Received: by mail-gh0-f174.google.com with SMTP id g15so2603302ghb.19 for ; Thu, 29 Nov 2012 13:07:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding:x-gm-message-state; bh=rWhnwFtBKmezfRfuFWbIE8rprQX0k8Otc3SDJXCfu0E=; b=E+pGC0m4Z3fbOwvoB+V+2E3Gu0uS/8YQ0vHfQfzlrQZIYYfPsMgbYIzOK0n1zzzk1z 7AWrUzBncBKQAEFI0khDY5pZ9J0VIRkuhNuhVApVdMhLG8egSFv8t0ay36T86iQLbyOo n1rGScYQyp7C3EaP9RtUVfd//E/9ZNZYKPLcI4ijx1xglpX11HOxp2mHdeWUP9kZCsXw bQ6g3yr1IjcnWvloDCn2kF4h6zw4XRZa0qO0sZD0Stwtd2+D5IO/zJ+UeRuoqRlGbPDH LUSzCCDLsRcfBXLJOGcQm8Q4gWZ9ygZAJnmhlIRnU+gJXoRdEMzI37sFMrWcTCIAA1hS O0eg== Received: by 10.236.137.50 with SMTP id x38mr25211487yhi.87.1354223255294; Thu, 29 Nov 2012 13:07:35 -0800 (PST) Received: from [192.168.200.2] (c-24-125-204-77.hsd1.va.comcast.net. [24.125.204.77]) by mx.google.com with ESMTPS id d66sm2852510yhe.1.2012.11.29.13.07.33 (version=SSLv3 cipher=OTHER); Thu, 29 Nov 2012 13:07:34 -0800 (PST) Message-ID: <50B7CE94.6000203@myri.com> Date: Thu, 29 Nov 2012 16:07:32 -0500 From: Andrew Gallatin User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121028 Thunderbird/16.0.2 MIME-Version: 1.0 To: David Miller CC: netdev Subject: [PATCH v3 net-next 2/2] myri10ge: Add vlan rx for better GRO perf. X-Gm-Message-State: ALoCoQkEjFPXzcaidHCD6wgro30ic2G7q3zMf0fFpKG1e0l4ULe8v/EPpU3aWPqnIJkkQPjiyd5F Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Unlike LRO, GRO requires that vlan tags be removed before aggregation can occur. Since the myri10ge NIC does not support hardware vlan tag offload, we must remove the tag in the driver to achieve performance comparable to LRO for vlan tagged frames. Thanks to Eric Duzamet for his help simplifying the original patch. Signed-off-by: Andrew Gallatin --- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) napi_gro_frags(&ss->napi); @@ -3851,6 +3888,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->netdev_ops = &myri10ge_netdev_ops; netdev->mtu = myri10ge_initial_mtu; netdev->hw_features = mgp->features | NETIF_F_RXCSUM; + + /* fake NETIF_F_HW_VLAN_RX for good GRO performance */ + netdev->hw_features |= NETIF_F_HW_VLAN_RX; + netdev->features = netdev->hw_features; if (dac_enabled) diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 84207c0..2fc984a 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -1264,6 +1264,42 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, } } +/* + * GRO does not support acceleration of tagged vlan frames, and + * this NIC does not support vlan tag offload, so we must pop + * the tag ourselves to be able to achieve GRO performance that + * is comparable to LRO. + */ + +static inline void +myri10ge_vlan_rx(struct net_device *dev, void *addr, struct sk_buff *skb) +{ + u8 *va; + struct vlan_ethhdr *veh; + struct skb_frag_struct *frag; + __wsum vsum; + + va = addr; + va += MXGEFW_PAD; + veh = (struct vlan_ethhdr *)va; + if ((dev->features & NETIF_F_HW_VLAN_RX) == NETIF_F_HW_VLAN_RX && + veh->h_vlan_proto == ntohs(ETH_P_8021Q)) { + /* fixup csum if needed */ + if (skb->ip_summed == CHECKSUM_COMPLETE) { + vsum = csum_partial(va + ETH_HLEN, VLAN_HLEN, 0); + skb->csum = csum_sub(skb->csum, vsum); + } + /* pop tag */ + __vlan_hwaccel_put_tag(skb, ntohs(veh->h_vlan_TCI)); + memmove(va + VLAN_HLEN, va, 2 * ETH_ALEN); + skb->len -= VLAN_HLEN; + skb->data_len -= VLAN_HLEN; + frag = skb_shinfo(skb)->frags; + frag->page_offset += VLAN_HLEN; + skb_frag_size_set(frag, skb_frag_size(frag) - VLAN_HLEN); + } +} + static inline int myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum) { @@ -1326,6 +1362,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum) skb->ip_summed = CHECKSUM_COMPLETE; skb->csum = csum; } + myri10ge_vlan_rx(mgp->dev, va, skb); skb_record_rx_queue(skb, ss - &mgp->ss[0]);