From patchwork Thu Jan 24 07:58:29 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 215270 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 8EE642C007C for ; Thu, 24 Jan 2013 19:36:54 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751430Ab3AXIgv (ORCPT ); Thu, 24 Jan 2013 03:36:51 -0500 Received: from co9ehsobe003.messaging.microsoft.com ([207.46.163.26]:17008 "EHLO co9outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750717Ab3AXIgu (ORCPT ); Thu, 24 Jan 2013 03:36:50 -0500 Received: from mail60-co9-R.bigfish.com (10.236.132.237) by CO9EHSOBE026.bigfish.com (10.236.130.89) with Microsoft SMTP Server id 14.1.225.23; Thu, 24 Jan 2013 08:36:49 +0000 Received: from mail60-co9 (localhost [127.0.0.1]) by mail60-co9-R.bigfish.com (Postfix) with ESMTP id 69A1B2C03C2; Thu, 24 Jan 2013 08:36:49 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1ee6h1de0h1202h1e76h1d1ah1d2ahzz8275bhz2dh2a8h668h839he5bhf0ah107ah11b5h121eh1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h14afh1504h1537h162dh1631h1758h1898h18e1h1155h) Received: from mail60-co9 (localhost.localdomain [127.0.0.1]) by mail60-co9 (MessageSwitch) id 1359016606805887_7427; Thu, 24 Jan 2013 08:36:46 +0000 (UTC) Received: from CO9EHSMHS024.bigfish.com (unknown [10.236.132.250]) by mail60-co9.bigfish.com (Postfix) with ESMTP id B7CE158004B; Thu, 24 Jan 2013 08:36:46 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO9EHSMHS024.bigfish.com (10.236.130.34) with Microsoft SMTP Server (TLS) id 14.1.225.23; Thu, 24 Jan 2013 08:36:46 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.2.318.3; Thu, 24 Jan 2013 08:36:42 +0000 Received: from shlinux1.ap.freescale.net (shlinux1.ap.freescale.net [10.192.225.216]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r0O8aeLr012742; Thu, 24 Jan 2013 01:36:41 -0700 Received: by shlinux1.ap.freescale.net (Postfix, from userid 1013) id A112F1AE0CA; Thu, 24 Jan 2013 15:58:32 +0800 (CST) From: Frank Li To: , , , , , CC: , Frank Li Subject: [PATCH v2 1/1 net-next] net: fec: add napi support to improve proformance Date: Thu, 24 Jan 2013 15:58:29 +0800 Message-ID: <1359014309-8636-1-git-send-email-Frank.Li@freescale.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-OriginatorOrg: freescale.net Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add napi support Before this patch iperf -s -i 1 ------------------------------------------------------------ Server listening on TCP port 5001 TCP window size: 85.3 KByte (default) ------------------------------------------------------------ [ 4] local 10.192.242.153 port 5001 connected with 10.192.242.138 port 50004 [ ID] Interval Transfer Bandwidth [ 4] 0.0- 1.0 sec 41.2 MBytes 345 Mbits/sec [ 4] 1.0- 2.0 sec 43.7 MBytes 367 Mbits/sec [ 4] 2.0- 3.0 sec 42.8 MBytes 359 Mbits/sec [ 4] 3.0- 4.0 sec 43.7 MBytes 367 Mbits/sec [ 4] 4.0- 5.0 sec 42.7 MBytes 359 Mbits/sec [ 4] 5.0- 6.0 sec 43.8 MBytes 367 Mbits/sec [ 4] 6.0- 7.0 sec 43.0 MBytes 361 Mbits/sec After this patch [ 4] 2.0- 3.0 sec 51.6 MBytes 433 Mbits/sec [ 4] 3.0- 4.0 sec 51.8 MBytes 435 Mbits/sec [ 4] 4.0- 5.0 sec 52.2 MBytes 438 Mbits/sec [ 4] 5.0- 6.0 sec 52.1 MBytes 437 Mbits/sec [ 4] 6.0- 7.0 sec 52.1 MBytes 437 Mbits/sec [ 4] 7.0- 8.0 sec 52.3 MBytes 439 Mbits/sec Signed-off-by: Frank Li Signed-off-by: Fugang Duan --- Change from v1 to v2 * Remove use_napi and napi_weight config. Support NAPI only. * using napi_gro_receive replace netif_rx drivers/net/ethernet/freescale/fec.c | 56 +++++++++++++++++++++++++++++----- drivers/net/ethernet/freescale/fec.h | 2 + 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index f52ba33..39be2ab 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -67,6 +67,7 @@ #endif #define DRIVER_NAME "fec" +#define FEC_NAPI_WEIGHT 64 /* Pause frame feild and FIFO threshold */ #define FEC_ENET_FCE (1 << 5) @@ -565,6 +566,20 @@ fec_timeout(struct net_device *ndev) } static void +fec_enet_rx_int_is_enabled(struct net_device *ndev, bool enabled) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + uint int_events; + + int_events = readl(fep->hwp + FEC_IMASK); + if (enabled) + int_events |= FEC_ENET_RXF; + else + int_events &= ~FEC_ENET_RXF; + writel(int_events, fep->hwp + FEC_IMASK); +} + +static void fec_enet_tx(struct net_device *ndev) { struct fec_enet_private *fep; @@ -656,8 +671,8 @@ fec_enet_tx(struct net_device *ndev) * not been given to the system, we just set the empty indicator, * effectively tossing the packet. */ -static void -fec_enet_rx(struct net_device *ndev) +static int +fec_enet_rx(struct net_device *ndev, int budget) { struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = @@ -667,13 +682,12 @@ fec_enet_rx(struct net_device *ndev) struct sk_buff *skb; ushort pkt_len; __u8 *data; + int pkt_received = 0; #ifdef CONFIG_M532x flush_cache_all(); #endif - spin_lock(&fep->hw_lock); - /* First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. */ @@ -681,6 +695,10 @@ fec_enet_rx(struct net_device *ndev) while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { + if (pkt_received >= budget) + break; + pkt_received++; + /* Since we have allocated space to hold a complete frame, * the last indicator should be set. */ @@ -762,7 +780,7 @@ fec_enet_rx(struct net_device *ndev) } if (!skb_defer_rx_timestamp(skb)) - netif_rx(skb); + napi_gro_receive(&fep->napi, skb); } bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, data, @@ -796,7 +814,7 @@ rx_processing_done: } fep->cur_rx = bdp; - spin_unlock(&fep->hw_lock); + return pkt_received; } static irqreturn_t @@ -805,6 +823,7 @@ fec_enet_interrupt(int irq, void *dev_id) struct net_device *ndev = dev_id; struct fec_enet_private *fep = netdev_priv(ndev); uint int_events; + ulong flags; irqreturn_t ret = IRQ_NONE; do { @@ -813,7 +832,14 @@ fec_enet_interrupt(int irq, void *dev_id) if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; - fec_enet_rx(ndev); + + spin_lock_irqsave(&fep->hw_lock, flags); + /* Disable the RX interrupt */ + if (napi_schedule_prep(&fep->napi)) { + fec_enet_rx_int_is_enabled(ndev, false); + __napi_schedule(&fep->napi); + } + spin_unlock_irqrestore(&fep->hw_lock, flags); } /* Transmit OK, or non-fatal error. Update the buffer @@ -834,7 +860,16 @@ fec_enet_interrupt(int irq, void *dev_id) return ret; } - +static int fec_enet_rx_napi(struct napi_struct *napi, int budget) +{ + struct net_device *ndev = napi->dev; + int pkgs = fec_enet_rx(ndev, budget); + if (pkgs < budget) { + napi_complete(napi); + fec_enet_rx_int_is_enabled(ndev, true); + } + return pkgs; +} /* ------------------------------------------------------------------------- */ static void fec_get_mac(struct net_device *ndev) @@ -1392,6 +1427,8 @@ fec_enet_open(struct net_device *ndev) struct fec_enet_private *fep = netdev_priv(ndev); int ret; + napi_enable(&fep->napi); + /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */ @@ -1604,6 +1641,9 @@ static int fec_enet_init(struct net_device *ndev) ndev->netdev_ops = &fec_netdev_ops; ndev->ethtool_ops = &fec_enet_ethtool_ops; + fec_enet_rx_int_is_enabled(ndev, false); + netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); + /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 2ebedaf..01579b8 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -249,6 +249,8 @@ struct fec_enet_private { int bufdesc_ex; int pause_flag; + struct napi_struct napi; + struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_caps; unsigned long last_overflow_check;