Netdev List
 help / color / mirror / Atom feed
* Re: [net-next 0/8][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2012-07-17 10:22 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, sassmann
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 17 Jul 2012 03:09:11 -0700

> This series contains updates to ixgbevf.
> 
> The following are changes since commit 282f23c6ee343126156dd41218b22ece96d747e3:
>   tcp: implement RFC 5961 3.2
> and are available in the git repository at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master
> 
> Alexander Duyck (8):
>   ixgbevf: Drop all dead or unnecessary code
>   ixgbevf: Drop netdev_registered value since that is already stored in
>     netdev
>   ixgbevf: Make use of NETIF_F_RXCSUM instead of keeping our own flag
>   ixgbevf: Drop use of eitr_low and eitr_high for hard coded values
>   ixgbevf: Cleanup accounting for space needed at start of xmit_frame
>   ixgbevf: Update q_vector to contain ring pointers instead of bitmaps
>   ixgbevf: Move Tx clean-up into NAPI context
>   ixgbevf: Use igb style interrupt masks instead of ixgbe style

Pulled, thanks Jeff.

^ permalink raw reply

* Re: [PATCH 0/2] ipvs fixes for 3.5
From: David Miller @ 2012-07-17 10:20 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <1342519589-3348-1-git-send-email-pablo@netfilter.org>

From: pablo@netfilter.org
Date: Tue, 17 Jul 2012 12:06:27 +0200

> I know that we're in fairly late stage to request pulls, but the IPVS people
> pinged me with little patches with oops fixes last week.
> 
> One of them was recently introduced (during the 3.4 development cycle) while
> cleaning up the IPVS netns support. They are:
> 
> * Fix one regression introduced in 3.4 while cleaning up the
>   netns support for IPVS, from Julian Anastasov.
> 
> * Fix one oops triggered due to resetting the conntrack attached to the skb
>   instead of just putting it in the forward hook, from Lin Ming. This problem
>   seems to be there since 2.6.37 according to Simon Horman.
> 
> You can pull these changes from:
> 
> git://1984.lsi.us.es/nf master

Pulled, thanks Pablo.

^ permalink raw reply

* Re: [GIT PULL net] IPVS
From: Pablo Neira Ayuso @ 2012-07-17 10:15 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Hans Schillstrom, Jesper Dangaard Brouer
In-Reply-To: <20120710130503.GA21118@1984>

On Tue, Jul 10, 2012 at 03:05:03PM +0200, Pablo Neira Ayuso wrote:
> Hi Simon,
> 
> On Tue, Jul 10, 2012 at 06:20:03PM +0900, Simon Horman wrote:
> > On Mon, Apr 30, 2012 at 11:27:22AM +0200, Pablo Neira Ayuso wrote:
> > > On Fri, Apr 27, 2012 at 09:53:54AM +0900, Simon Horman wrote:
> > > > Hi Pablo,
> > > > 
> > > > please consider the following 5 changes for 3.4, they are all bug fixes.
> > > > I would also like these changes considered for stable.
> > > 
> > > Please, ping me again once these have hit Linus tree to ask for
> > > -stable submission.
> > 
> > Sorry for letting this slip through the cracks.
> > 
> > Please consider the following commits which are in Linus's tree for stable.
> > Or I can submit them directly if that is easier.
> > 
> > There are 7 patches listed below. The first 5 were the patches in this
> > pull request. The last two were patches in a git pull request
> > a few days earlier.
> 
> That's fine, I can make it, but you have to include what stable
> releases this will be applied, eg. patch 1 to releases 3.4 and 3.2.
> 
> I think -stable maintainers will ask for that.

Ping?

> > commit 8537de8a7ab6681cc72fb0411ab1ba7fdba62dd0
> > Author: Hans Schillstrom <hans.schillstrom@ericsson.com>
> > Date:   Thu Apr 26 07:47:44 2012 +0200
> > 
> >     ipvs: kernel oops - do_ip_vs_get_ctl
> >     
> >     Change order of init so netns init is ready
> >     when register ioctl and netlink.
> >     
> >     Ver2
> >     	Whitespace fixes and __init added.
> >     
> >     Reported-by: "Ryan O'Hara" <rohara@redhat.com>
> >     Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> >     Acked-by: Julian Anastasov <ja@ssi.bg>
> >     Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> > 
> > commit 582b8e3eadaec77788c1aa188081a8d5059c42a6
> > Author: Hans Schillstrom <hans.schillstrom@ericsson.com>
> > Date:   Thu Apr 26 09:45:35 2012 +0200
> > 
> >     ipvs: take care of return value from protocol init_netns
> >     
> >     ip_vs_create_timeout_table() can return NULL
> >     All functions protocol init_netns is affected of this patch.
> >     
> >     Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> >     Acked-by: Julian Anastasov <ja@ssi.bg>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> > 
> > commit 4b984cd50bc1b6d492175cd77bfabb78e76ffa67
> > Author: Hans Schillstrom <hans.schillstrom@ericsson.com>
> > Date:   Thu Apr 26 09:45:34 2012 +0200
> > 
> >     ipvs: null check of net->ipvs in lblc(r) shedulers
> >     
> >     Avoid crash when registering shedulers after
> >     the IPVS core initialization for netns fails. Do this by
> >     checking for present core (net->ipvs).
> >     
> >     Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> >     Acked-by: Julian Anastasov <ja@ssi.bg>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> > 
> > commit 39f618b4fd95ae243d940ec64c961009c74e3333
> > Author: Julian Anastasov <ja@ssi.bg>
> > Date:   Wed Apr 25 00:29:58 2012 +0300
> > 
> >     ipvs: reset ipvs pointer in netns
> >     
> >     	Make sure net->ipvs is reset on netns cleanup or failed
> >     initialization. It is needed for IPVS applications to know that
> >     IPVS core is not loaded in netns.
> >     
> >     Signed-off-by: Julian Anastasov <ja@ssi.bg>
> >     Acked-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> > 
> > commit 8d08d71ce59438a6ef06be5db07966e0c144b74e
> > Author: Julian Anastasov <ja@ssi.bg>
> > Date:   Wed Apr 25 00:29:59 2012 +0300
> > 
> >     ipvs: add check in ftp for initialized core
> >     
> >     	Avoid crash when registering ip_vs_ftp after
> >     the IPVS core initialization for netns fails. Do this by
> >     checking for present core (net->ipvs).
> >     
> >     Signed-off-by: Julian Anastasov <ja@ssi.bg>
> >     Acked-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> > 
> > commit 8f9b9a2fad47af27e14b037395e03cd8278d96d7
> > Author: Julian Anastasov <ja@ssi.bg>
> > Date:   Fri Apr 13 18:08:43 2012 +0300
> > 
> >     ipvs: fix crash in ip_vs_control_net_cleanup on unload
> >     
> >     	commit 14e405461e664b777e2a5636e10b2ebf36a686ec (2.6.39)
> >     ("Add __ip_vs_control_{init,cleanup}_sysctl()")
> >     introduced regression due to wrong __net_init for
> >     __ip_vs_control_cleanup_sysctl. This leads to crash when
> >     the ip_vs module is unloaded.
> >     
> >     	Fix it by changing __net_init to __net_exit for
> >     the function that is already renamed to ip_vs_control_net_cleanup_sysctl.
> >     
> >     Signed-off-by: Julian Anastasov <ja@ssi.bg>
> >     Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> >     Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > 
> > commit 7118c07a844d367560ee91adb2071bde2fabcdbf
> > Author: Sasha Levin <levinsasha928@gmail.com>
> > Date:   Sat Apr 14 12:37:46 2012 -0400
> > 
> >     ipvs: Verify that IP_VS protocol has been registered
> >     
> >     The registration of a protocol might fail, there were no checks
> >     and all registrations were assumed to be correct. This lead to
> >     NULL ptr dereferences when apps tried registering.
> >     
> >     For example:
> >     
> >     [ 1293.226051] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
> >     [ 1293.227038] IP: [<ffffffff822aacb0>] tcp_register_app+0x60/0xb0
> >     [ 1293.227038] PGD 391de067 PUD 6c20b067 PMD 0
> >     [ 1293.227038] Oops: 0000 [#1] PREEMPT SMP
> >     [ 1293.227038] CPU 1
> >     [ 1293.227038] Pid: 19609, comm: trinity Tainted: G        W    3.4.0-rc1-next-20120405-sasha-dirty #57
> >     [ 1293.227038] RIP: 0010:[<ffffffff822aacb0>]  [<ffffffff822aacb0>] tcp_register_app+0x60/0xb0
> >     [ 1293.227038] RSP: 0018:ffff880038c1dd18  EFLAGS: 00010286
> >     [ 1293.227038] RAX: ffffffffffffffc0 RBX: 0000000000001500 RCX: 0000000000010000
> >     [ 1293.227038] RDX: 0000000000000000 RSI: ffff88003a2d5888 RDI: 0000000000000282
> >     [ 1293.227038] RBP: ffff880038c1dd48 R08: 0000000000000000 R09: 0000000000000000
> >     [ 1293.227038] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003a2d5668
> >     [ 1293.227038] R13: ffff88003a2d5988 R14: ffff8800696a8ff8 R15: 0000000000000000
> >     [ 1293.227038] FS:  00007f01930d9700(0000) GS:ffff88007ce00000(0000) knlGS:0000000000000000
> >     [ 1293.227038] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >     [ 1293.227038] CR2: 0000000000000018 CR3: 0000000065dfc000 CR4: 00000000000406e0
> >     [ 1293.227038] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >     [ 1293.227038] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >     [ 1293.227038] Process trinity (pid: 19609, threadinfo ffff880038c1c000, task ffff88002dc73000)
> >     [ 1293.227038] Stack:
> >     [ 1293.227038]  ffff880038c1dd48 00000000fffffff4 ffff8800696aada0 ffff8800694f5580
> >     [ 1293.227038]  ffffffff8369f1e0 0000000000001500 ffff880038c1dd98 ffffffff822a716b
> >     [ 1293.227038]  0000000000000000 ffff8800696a8ff8 0000000000000015 ffff8800694f5580
> >     [ 1293.227038] Call Trace:
> >     [ 1293.227038]  [<ffffffff822a716b>] ip_vs_app_inc_new+0xdb/0x180
> >     [ 1293.227038]  [<ffffffff822a7258>] register_ip_vs_app_inc+0x48/0x70
> >     [ 1293.227038]  [<ffffffff822b2fea>] __ip_vs_ftp_init+0xba/0x140
> >     [ 1293.227038]  [<ffffffff821c9060>] ops_init+0x80/0x90
> >     [ 1293.227038]  [<ffffffff821c90cb>] setup_net+0x5b/0xe0
> >     [ 1293.227038]  [<ffffffff821c9416>] copy_net_ns+0x76/0x100
> >     [ 1293.227038]  [<ffffffff810dc92b>] create_new_namespaces+0xfb/0x190
> >     [ 1293.227038]  [<ffffffff810dca21>] unshare_nsproxy_namespaces+0x61/0x80
> >     [ 1293.227038]  [<ffffffff810afd1f>] sys_unshare+0xff/0x290
> >     [ 1293.227038]  [<ffffffff8187622e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> >     [ 1293.227038]  [<ffffffff82665539>] system_call_fastpath+0x16/0x1b
> >     [ 1293.227038] Code: 89 c7 e8 34 91 3b 00 89 de 66 c1 ee 04 31 de 83 e6 0f 48 83 c6 22 48 c1 e6 04 4a 8b 14 26 49 8d 34 34 48 8d 42 c0 48 39 d6 74 13 <66> 39 58 58 74 22 48 8b 48 40 48 8d 41 c0 48 39 ce 75 ed 49 8d
> >     [ 1293.227038] RIP  [<ffffffff822aacb0>] tcp_register_app+0x60/0xb0
> >     [ 1293.227038]  RSP <ffff880038c1dd18>
> >     [ 1293.227038] CR2: 0000000000000018
> >     [ 1293.379284] ---[ end trace 364ab40c7011a009 ]---
> >     [ 1293.381182] Kernel panic - not syncing: Fatal exception in interrupt
> >     
> >     Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> >     Acked-by: Julian Anastasov <ja@ssi.bg>
> >     Signed-off-by: Simon Horman <horms@verge.net.au>
> >     Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > 

^ permalink raw reply

* Re: [GIT PULL nf] IPVS
From: Pablo Neira Ayuso @ 2012-07-17 10:14 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Hans Schillstrom, Jesper Dangaard Brouer
In-Reply-To: <1341965963-7275-1-git-send-email-horms@verge.net.au>

On Wed, Jul 11, 2012 at 09:19:20AM +0900, Simon Horman wrote:
> 
> Hi Pablo,
> 
> this pull request consists of three bug fixes for IPVS.
> Please consider for inclusion in 3.5 and stable.
> 
> The bug fix from Julian, "ipvs: fix oops in ip_vs_dst_event on rmmod"
> fixes a regression introduced in 3.4 and thus I believe it is
> only relevant to 3.5 and 3.4-stable.
> 
> The other two fixes appear to have been present since at least 2.6.37
> (there were a lot of changes to IPVS around that time).

I have passed the two of these patches to David. The one for the FTP
needs a consistent description.

It's fairly late in the development cycle (-rc7), but these are small.
Let's see if David is still in time to accept them. Otherwise, they go
to net-next and we will ask for -stable submission.

^ permalink raw reply

* Re: [PATCH net-next] r8169: Remove rtl_ocpdr_cond
From: Francois Romieu @ 2012-07-17 10:10 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, linux-kernel
In-Reply-To: <33C8D1BCFFFF487FB7BC207EA9087C2E@realtek.com.tw>

hayeswang <hayeswang@realtek.com> :
[...]
> rtt min/avg/max/mdev = 0.028/0.040/0.101/0.011 ms, pipe 4, ipg/ewma 0.021/0.035
> rtt min/avg/max/mdev = 0.151/0.173/0.247/0.020 ms, pipe 4, ipg/ewma 0.048/0.168
[...]
> The attached file is my log. It seems fine.

A few percents packet loss at this rate does not exactly qualify as fine.

I have reproduced something similar with a 8168evl in a different slot so
it does not seem to be a 8168g only behavior. I'll ask davem to pull your
changes.

Thanks.

-- 
Ueimor

^ permalink raw reply

* [net-next 7/8] ixgbevf: Move Tx clean-up into NAPI context
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

Currently the VF driver is processing all of the transmits in interrupt
context.  This can be messy since the Rx is all handled in NAPI and this
may result in interrupts being disabled.  In order to resolve this move all
of the Tx packet processing into NAPI and combine all of the interrupt and
polling routines into just a pair of functions.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ethtool.c      |    2 -
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   12 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  257 +++++++--------------
 3 files changed, 89 insertions(+), 182 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index af9c657..15947c9 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -364,7 +364,6 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
 			}
 			goto err_tx_ring_setup;
 		}
-		tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
 	}
 
 	memcpy(rx_ring, adapter->rx_ring,
@@ -380,7 +379,6 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
 			}
 				goto err_rx_ring_setup;
 		}
-		rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
 	}
 
 	/*
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 8cae4ff..8bedd0f 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -81,11 +81,6 @@ struct ixgbevf_ring {
 		      * offset associated with this ring, which is different
 		      * for DCB and RSS modes */
 
-	u64 v_idx; /* maps directly to the index for this ring in the hardware
-		    * vector array, can also be used for finding the bit in EICR
-		    * and friends that represents the vector for this ring */
-
-	u16 work_limit;                /* max work per interrupt */
 	u16 rx_buf_len;
 };
 
@@ -140,6 +135,7 @@ struct ixgbevf_q_vector {
 	struct ixgbevf_ring_container rx, tx;
 	u32 eitr;
 	int v_idx;	  /* vector index in list */
+	char name[IFNAMSIZ + 9];
 };
 
 /* Helper macros to switch between ints/sec and what the register uses.
@@ -167,9 +163,8 @@ struct ixgbevf_q_vector {
 #define NON_Q_VECTORS (OTHER_VECTOR)
 
 #define MAX_MSIX_Q_VECTORS 2
-#define MAX_MSIX_COUNT 2
 
-#define MIN_MSIX_Q_VECTORS 2
+#define MIN_MSIX_Q_VECTORS 1
 #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
 
 /* board specific private data structure */
@@ -179,7 +174,6 @@ struct ixgbevf_adapter {
 	u16 bd_number;
 	struct work_struct reset_task;
 	struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
-	char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
 
 	/* Interrupt Throttle Rate */
 	u32 itr_setting;
@@ -187,6 +181,7 @@ struct ixgbevf_adapter {
 	/* TX */
 	struct ixgbevf_ring *tx_ring;	/* One per active queue */
 	int num_tx_queues;
+	u16 tx_itr_setting;
 	u64 restart_queue;
 	u64 hw_csum_tx_good;
 	u64 lsc_int;
@@ -197,6 +192,7 @@ struct ixgbevf_adapter {
 	/* RX */
 	struct ixgbevf_ring *rx_ring;	/* One per active queue */
 	int num_rx_queues;
+	u16 rx_itr_setting;
 	u64 hw_csum_rx_error;
 	u64 hw_rx_no_dma_resources;
 	u64 hw_csum_rx_good;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 744a026..628643b 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -97,7 +97,7 @@ module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
 /* forward decls */
-static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector);
+static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector);
 static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
 			       u32 itr_reg);
 
@@ -182,14 +182,14 @@ static void ixgbevf_tx_timeout(struct net_device *netdev);
 
 /**
  * ixgbevf_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
+ * @q_vector: board private structure
  * @tx_ring: tx ring to clean
  **/
-static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
+static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector,
 				 struct ixgbevf_ring *tx_ring)
 {
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	struct net_device *netdev = adapter->netdev;
-	struct ixgbe_hw *hw = &adapter->hw;
 	union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
 	struct ixgbevf_tx_buffer *tx_buffer_info;
 	unsigned int i, eop, count = 0;
@@ -200,7 +200,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
 	eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
 
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
-	       (count < tx_ring->work_limit)) {
+	       (count < tx_ring->count)) {
 		bool cleaned = false;
 		rmb(); /* read buffer_info after eop_desc */
 		/* eop could change between read and DD-check */
@@ -256,18 +256,12 @@ cont_loop:
 		}
 	}
 
-	/* re-arm the interrupt */
-	if ((count >= tx_ring->work_limit) &&
-	    (!test_bit(__IXGBEVF_DOWN, &adapter->state))) {
-		IXGBE_WRITE_REG(hw, IXGBE_VTEICS, tx_ring->v_idx);
-	}
-
 	u64_stats_update_begin(&tx_ring->syncp);
 	tx_ring->total_bytes += total_bytes;
 	tx_ring->total_packets += total_packets;
 	u64_stats_update_end(&tx_ring->syncp);
 
-	return count < tx_ring->work_limit;
+	return count < tx_ring->count;
 }
 
 /**
@@ -402,7 +396,7 @@ static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,
 
 static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 				 struct ixgbevf_ring *rx_ring,
-				 int *work_done, int work_to_do)
+				 int budget)
 {
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	struct pci_dev *pdev = adapter->pdev;
@@ -411,7 +405,6 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 	struct sk_buff *skb;
 	unsigned int i;
 	u32 len, staterr;
-	bool cleaned = false;
 	int cleaned_count = 0;
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 
@@ -421,13 +414,12 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 	rx_buffer_info = &rx_ring->rx_buffer_info[i];
 
 	while (staterr & IXGBE_RXD_STAT_DD) {
-		if (*work_done >= work_to_do)
+		if (!budget)
 			break;
-		(*work_done)++;
+		budget--;
 
 		rmb(); /* read descriptor and rx_buffer_info after status DD */
 		len = le16_to_cpu(rx_desc->wb.upper.length);
-		cleaned = true;
 		skb = rx_buffer_info->skb;
 		prefetch(skb->data - NET_IP_ALIGN);
 		rx_buffer_info->skb = NULL;
@@ -510,74 +502,52 @@ next_desc:
 	rx_ring->total_bytes += total_rx_bytes;
 	u64_stats_update_end(&rx_ring->syncp);
 
-	return cleaned;
-}
-
-/**
- * ixgbevf_clean_rxonly - msix (aka one shot) rx clean routine
- * @napi: napi struct with our devices info in it
- * @budget: amount of work driver is allowed to do this pass, in packets
- *
- * This function is optimized for cleaning one queue only on a single
- * q_vector!!!
- **/
-static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
-{
-	struct ixgbevf_q_vector *q_vector =
-		container_of(napi, struct ixgbevf_q_vector, napi);
-	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	int work_done = 0;
-
-	ixgbevf_clean_rx_irq(q_vector, q_vector->rx.ring, &work_done, budget);
-
-	/* If all Rx work done, exit the polling mode */
-	if (work_done < budget) {
-		napi_complete(napi);
-		if (adapter->itr_setting & 1)
-			ixgbevf_set_itr_msix(q_vector);
-		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter,
-						  1 << q_vector->v_idx);
-	}
-
-	return work_done;
+	return !!budget;
 }
 
 /**
- * ixgbevf_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * ixgbevf_poll - NAPI polling calback
  * @napi: napi struct with our devices info in it
  * @budget: amount of work driver is allowed to do this pass, in packets
  *
- * This function will clean more than one rx queue associated with a
+ * This function will clean more than one or more rings associated with a
  * q_vector.
  **/
-static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
+static int ixgbevf_poll(struct napi_struct *napi, int budget)
 {
 	struct ixgbevf_q_vector *q_vector =
 		container_of(napi, struct ixgbevf_q_vector, napi);
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	struct ixgbevf_ring *rx_ring;
-	int work_done = 0;
+	struct ixgbevf_ring *ring;
+	int per_ring_budget;
+	bool clean_complete = true;
+
+	ixgbevf_for_each_ring(ring, q_vector->tx)
+		clean_complete &= ixgbevf_clean_tx_irq(q_vector, ring);
 
 	/* attempt to distribute budget to each queue fairly, but don't allow
 	 * the budget to go below 1 because we'll exit polling */
-	budget /= (q_vector->rx.count ?: 1);
-	budget = max(budget, 1);
-
-	ixgbevf_for_each_ring(rx_ring, q_vector->rx)
-		ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
-
-	/* If all Rx work done, exit the polling mode */
-	if (work_done < budget) {
-		napi_complete(napi);
-		if (adapter->itr_setting & 1)
-			ixgbevf_set_itr_msix(q_vector);
-		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter,
-						  1 << q_vector->v_idx);
-	}
+	if (q_vector->rx.count > 1)
+		per_ring_budget = max(budget/q_vector->rx.count, 1);
+	else
+		per_ring_budget = budget;
+
+	ixgbevf_for_each_ring(ring, q_vector->rx)
+		clean_complete &= ixgbevf_clean_rx_irq(q_vector, ring,
+						       per_ring_budget);
+
+	/* If all work not completed, return budget and keep polling */
+	if (!clean_complete)
+		return budget;
+	/* all work done, exit the polling mode */
+	napi_complete(napi);
+	if (adapter->rx_itr_setting & 1)
+		ixgbevf_set_itr(q_vector);
+	if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+		ixgbevf_irq_enable_queues(adapter,
+					  1 << q_vector->v_idx);
 
-	return work_done;
+	return 0;
 }
 
 
@@ -720,7 +690,7 @@ static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
 	IXGBE_WRITE_REG(hw, IXGBE_VTEITR(v_idx), itr_reg);
 }
 
-static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector)
+static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
 {
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	u32 new_itr;
@@ -780,8 +750,7 @@ static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector)
 
 static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 {
-	struct net_device *netdev = data;
-	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbevf_adapter *adapter = data;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 eicr;
 	u32 msg;
@@ -821,59 +790,22 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data)
-{
-	struct ixgbevf_q_vector *q_vector = data;
-	struct ixgbevf_adapter  *adapter = q_vector->adapter;
-	struct ixgbevf_ring     *tx_ring;
-
-	if (!q_vector->tx.ring)
-		return IRQ_HANDLED;
-
-	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
-		tx_ring->total_bytes = 0;
-		tx_ring->total_packets = 0;
-		ixgbevf_clean_tx_irq(adapter, tx_ring);
-	}
-
-	if (adapter->itr_setting & 1)
-		ixgbevf_set_itr_msix(q_vector);
-
-	return IRQ_HANDLED;
-}
 
 /**
- * ixgbevf_msix_clean_rx - single unshared vector rx clean (all queues)
+ * ixgbevf_msix_clean_rings - single unshared vector rx clean (all queues)
  * @irq: unused
  * @data: pointer to our q_vector struct for this interrupt vector
  **/
-static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data)
+static irqreturn_t ixgbevf_msix_clean_rings(int irq, void *data)
 {
 	struct ixgbevf_q_vector *q_vector = data;
 	struct ixgbevf_adapter  *adapter = q_vector->adapter;
 	struct ixgbe_hw *hw = &adapter->hw;
-	struct ixgbevf_ring  *rx_ring;
-
-	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
-		rx_ring->total_bytes = 0;
-		rx_ring->total_packets = 0;
-	}
-
-	if (!q_vector->rx.ring)
-		return IRQ_HANDLED;
 
 	/* disable interrupts on this vector only */
 	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, 1 << q_vector->v_idx);
-	napi_schedule(&q_vector->napi);
-
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t ixgbevf_msix_clean_many(int irq, void *data)
-{
-	ixgbevf_msix_clean_rx(irq, data);
-	ixgbevf_msix_clean_tx(irq, data);
+	if (q_vector->rx.ring || q_vector->tx.ring)
+		napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -886,7 +818,6 @@ static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx,
 	a->rx_ring[r_idx].next = q_vector->rx.ring;
 	q_vector->rx.ring = &a->rx_ring[r_idx];
 	q_vector->rx.count++;
-	a->rx_ring[r_idx].v_idx = 1 << v_idx;
 }
 
 static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
@@ -897,7 +828,6 @@ static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
 	a->tx_ring[t_idx].next = q_vector->tx.ring;
 	q_vector->tx.ring = &a->tx_ring[t_idx];
 	q_vector->tx.count++;
-	a->tx_ring[t_idx].v_idx = 1 << v_idx;
 }
 
 /**
@@ -973,37 +903,30 @@ out:
 static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	irqreturn_t (*handler)(int, void *);
-	int i, vector, q_vectors, err;
+	int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+	int vector, err;
 	int ri = 0, ti = 0;
 
-	/* Decrement for Other and TCP Timer vectors */
-	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-
-#define SET_HANDLER(_v) (((_v)->rx.ring && (_v)->tx.ring)          \
-					? &ixgbevf_msix_clean_many : \
-			  (_v)->rx.ring ? &ixgbevf_msix_clean_rx   : \
-			  (_v)->tx.ring ? &ixgbevf_msix_clean_tx   : \
-			  NULL)
 	for (vector = 0; vector < q_vectors; vector++) {
-		handler = SET_HANDLER(adapter->q_vector[vector]);
-
-		if (handler == &ixgbevf_msix_clean_rx) {
-			sprintf(adapter->name[vector], "%s-%s-%d",
-				netdev->name, "rx", ri++);
-		} else if (handler == &ixgbevf_msix_clean_tx) {
-			sprintf(adapter->name[vector], "%s-%s-%d",
-				netdev->name, "tx", ti++);
-		} else if (handler == &ixgbevf_msix_clean_many) {
-			sprintf(adapter->name[vector], "%s-%s-%d",
-				netdev->name, "TxRx", vector);
+		struct ixgbevf_q_vector *q_vector = adapter->q_vector[vector];
+		struct msix_entry *entry = &adapter->msix_entries[vector];
+
+		if (q_vector->tx.ring && q_vector->rx.ring) {
+			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+				 "%s-%s-%d", netdev->name, "TxRx", ri++);
+			ti++;
+		} else if (q_vector->rx.ring) {
+			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+				 "%s-%s-%d", netdev->name, "rx", ri++);
+		} else if (q_vector->tx.ring) {
+			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+				 "%s-%s-%d", netdev->name, "tx", ti++);
 		} else {
 			/* skip this unused q_vector */
 			continue;
 		}
-		err = request_irq(adapter->msix_entries[vector].vector,
-				  handler, 0, adapter->name[vector],
-				  adapter->q_vector[vector]);
+		err = request_irq(entry->vector, &ixgbevf_msix_clean_rings, 0,
+				  q_vector->name, q_vector);
 		if (err) {
 			hw_dbg(&adapter->hw,
 			       "request_irq failed for MSIX interrupt "
@@ -1012,9 +935,8 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
 		}
 	}
 
-	sprintf(adapter->name[vector], "%s:mbx", netdev->name);
 	err = request_irq(adapter->msix_entries[vector].vector,
-			  &ixgbevf_msix_mbx, 0, adapter->name[vector], netdev);
+			  &ixgbevf_msix_mbx, 0, netdev->name, adapter);
 	if (err) {
 		hw_dbg(&adapter->hw,
 		       "request_irq for msix_mbx failed: %d\n", err);
@@ -1024,9 +946,11 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
 	return 0;
 
 free_queue_irqs:
-	for (i = vector - 1; i >= 0; i--)
-		free_irq(adapter->msix_entries[--vector].vector,
-			 &(adapter->q_vector[i]));
+	while (vector) {
+		vector--;
+		free_irq(adapter->msix_entries[vector].vector,
+			 adapter->q_vector[vector]);
+	}
 	pci_disable_msix(adapter->pdev);
 	kfree(adapter->msix_entries);
 	adapter->msix_entries = NULL;
@@ -1069,17 +993,20 @@ static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter)
 
 static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
 	int i, q_vectors;
 
 	q_vectors = adapter->num_msix_vectors;
-
 	i = q_vectors - 1;
 
-	free_irq(adapter->msix_entries[i].vector, netdev);
+	free_irq(adapter->msix_entries[i].vector, adapter);
 	i--;
 
 	for (; i >= 0; i--) {
+		/* free only the irqs that were actually requested */
+		if (!adapter->q_vector[i]->rx.ring &&
+		    !adapter->q_vector[i]->tx.ring)
+			continue;
+
 		free_irq(adapter->msix_entries[i].vector,
 			 adapter->q_vector[i]);
 	}
@@ -1317,15 +1244,8 @@ static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
 	int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
-		struct napi_struct *napi;
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rx.ring)
-			continue;
-		napi = &q_vector->napi;
-		if (q_vector->rx.count > 1)
-			napi->poll = &ixgbevf_clean_rxonly_many;
-
-		napi_enable(napi);
+		napi_enable(&q_vector->napi);
 	}
 }
 
@@ -1337,8 +1257,6 @@ static void ixgbevf_napi_disable_all(struct ixgbevf_adapter *adapter)
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rx.ring)
-			continue;
 		napi_disable(&q_vector->napi);
 	}
 }
@@ -1703,10 +1621,9 @@ static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter,
 {
 	int err, vector_threshold;
 
-	/* We'll want at least 3 (vector_threshold):
-	 * 1) TxQ[0] Cleanup
-	 * 2) RxQ[0] Cleanup
-	 * 3) Other (Link Status Change, etc.)
+	/* We'll want at least 2 (vector_threshold):
+	 * 1) TxQ[0] + RxQ[0] handler
+	 * 2) Other (Link Status Change, etc.)
 	 */
 	vector_threshold = MIN_MSIX_COUNT;
 
@@ -1821,10 +1738,12 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
 	 * It's easy to be greedy for MSI-X vectors, but it really
 	 * doesn't do us much good if we have a lot more vectors
 	 * than CPU's.  So let's be conservative and only ask for
-	 * (roughly) twice the number of vectors as there are CPU's.
+	 * (roughly) the same number of vectors as there are CPU's.
+	 * The default is to use pairs of vectors.
 	 */
-	v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
-		       (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+	v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues);
+	v_budget = min_t(int, v_budget, num_online_cpus());
+	v_budget += NON_Q_VECTORS;
 
 	/* A failure in MSI-X entry allocation isn't fatal, but it does
 	 * mean we disable MSI-X capabilities of the adapter. */
@@ -1855,12 +1774,8 @@ static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter)
 {
 	int q_idx, num_q_vectors;
 	struct ixgbevf_q_vector *q_vector;
-	int napi_vectors;
-	int (*poll)(struct napi_struct *, int);
 
 	num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-	napi_vectors = adapter->num_rx_queues;
-	poll = &ixgbevf_clean_rxonly;
 
 	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
 		q_vector = kzalloc(sizeof(struct ixgbevf_q_vector), GFP_KERNEL);
@@ -1869,9 +1784,8 @@ static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter)
 		q_vector->adapter = adapter;
 		q_vector->v_idx = q_idx;
 		q_vector->eitr = adapter->eitr_param;
-		if (q_idx < napi_vectors)
-			netif_napi_add(adapter->netdev, &q_vector->napi,
-				       (*poll), 64);
+		netif_napi_add(adapter->netdev, &q_vector->napi,
+			       ixgbevf_poll, 64);
 		adapter->q_vector[q_idx] = q_vector;
 	}
 
@@ -2272,7 +2186,6 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter,
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
-	tx_ring->work_limit = tx_ring->count;
 	return 0;
 
 err:
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 8/8] ixgbevf: Use igb style interrupt masks instead of ixgbe style
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The interrupt registers accessed in ixgbevf are more similar to the igb
style registers than they are to the ixgbe style registers.  As such we
would be better off setting up the code for the EICS, EIMS, EICS, EIAM, and
EIAC like we do in igb instead of ixgbe.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/defines.h      |   27 +--
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   29 ++-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  195 +++++++++------------
 3 files changed, 105 insertions(+), 146 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h
index e09a6cc..10cede5 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -264,32 +264,9 @@ struct ixgbe_adv_tx_context_desc {
 
 /* Interrupt register bitmasks */
 
-/* Extended Interrupt Cause Read */
-#define IXGBE_EICR_RTX_QUEUE    0x0000FFFF /* RTx Queue Interrupt */
-#define IXGBE_EICR_MAILBOX      0x00080000 /* VF to PF Mailbox Interrupt */
-#define IXGBE_EICR_OTHER        0x80000000 /* Interrupt Cause Active */
-
-/* Extended Interrupt Cause Set */
-#define IXGBE_EICS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EICS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
-#define IXGBE_EICS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
-
-/* Extended Interrupt Mask Set */
-#define IXGBE_EIMS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EIMS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
-#define IXGBE_EIMS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
-
-/* Extended Interrupt Mask Clear */
-#define IXGBE_EIMC_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EIMC_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
-#define IXGBE_EIMC_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
-
-#define IXGBE_EIMS_ENABLE_MASK ( \
-				IXGBE_EIMS_RTX_QUEUE       | \
-				IXGBE_EIMS_MAILBOX         | \
-				IXGBE_EIMS_OTHER)
-
 #define IXGBE_EITR_CNT_WDIS     0x80000000
+#define IXGBE_MAX_EITR		0x00000FF8
+#define IXGBE_MIN_EITR		8
 
 /* Error Codes */
 #define IXGBE_ERR_INVALID_MAC_ADDR              -1
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 8bedd0f..f92daca 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -118,6 +118,8 @@ struct ixgbevf_ring {
 
 struct ixgbevf_ring_container {
 	struct ixgbevf_ring *ring;	/* pointer to linked list of rings */
+	unsigned int total_bytes;	/* total bytes processed this int */
+	unsigned int total_packets;	/* total packets processed this int */
 	u8 count;			/* total number of rings in vector */
 	u8 itr;				/* current ITR setting for ring */
 };
@@ -131,13 +133,25 @@ struct ixgbevf_ring_container {
  */
 struct ixgbevf_q_vector {
 	struct ixgbevf_adapter *adapter;
+	u16 v_idx;		/* index of q_vector within array, also used for
+				 * finding the bit in EICR and friends that
+				 * represents the vector for this ring */
+	u16 itr;		/* Interrupt throttle rate written to EITR */
 	struct napi_struct napi;
 	struct ixgbevf_ring_container rx, tx;
-	u32 eitr;
-	int v_idx;	  /* vector index in list */
 	char name[IFNAMSIZ + 9];
 };
 
+/*
+ * microsecond values for various ITR rates shifted by 2 to fit itr register
+ * with the first 3 bits reserved 0
+ */
+#define IXGBE_MIN_RSC_ITR	24
+#define IXGBE_100K_ITR		40
+#define IXGBE_20K_ITR		200
+#define IXGBE_10K_ITR		400
+#define IXGBE_8K_ITR		500
+
 /* Helper macros to switch between ints/sec and what the register uses.
  * And yes, it's the same math going both ways.  The lowest value
  * supported by all of the ixgbe hardware is 8.
@@ -176,12 +190,16 @@ struct ixgbevf_adapter {
 	struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
 
 	/* Interrupt Throttle Rate */
-	u32 itr_setting;
+	u16 rx_itr_setting;
+	u16 tx_itr_setting;
+
+	/* interrupt masks */
+	u32 eims_enable_mask;
+	u32 eims_other;
 
 	/* TX */
 	struct ixgbevf_ring *tx_ring;	/* One per active queue */
 	int num_tx_queues;
-	u16 tx_itr_setting;
 	u64 restart_queue;
 	u64 hw_csum_tx_good;
 	u64 lsc_int;
@@ -192,7 +210,6 @@ struct ixgbevf_adapter {
 	/* RX */
 	struct ixgbevf_ring *rx_ring;	/* One per active queue */
 	int num_rx_queues;
-	u16 rx_itr_setting;
 	u64 hw_csum_rx_error;
 	u64 hw_rx_no_dma_resources;
 	u64 hw_csum_rx_good;
@@ -265,7 +282,7 @@ extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *,
 extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *,
 				      struct ixgbevf_ring *);
 extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
-
+void ixgbevf_write_eitr(struct ixgbevf_q_vector *);
 extern int ethtool_ioctl(struct ifreq *ifr);
 
 extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 628643b..8e022c6 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -98,8 +98,6 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
 /* forward decls */
 static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector);
-static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
-			       u32 itr_reg);
 
 static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw,
 					   struct ixgbevf_ring *rx_ring,
@@ -385,13 +383,11 @@ no_buffers:
 }
 
 static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,
-					     u64 qmask)
+					     u32 qmask)
 {
-	u32 mask;
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	mask = (qmask & 0xFFFFFFFF);
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, qmask);
 }
 
 static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
@@ -561,11 +557,10 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget)
 static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 {
 	struct ixgbevf_q_vector *q_vector;
-	struct ixgbe_hw *hw = &adapter->hw;
 	int q_vectors, v_idx;
-	u32 mask;
 
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+	adapter->eims_enable_mask = 0;
 
 	/*
 	 * Populate the IVAR table and set the ITR values to the
@@ -581,22 +576,30 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 		ixgbevf_for_each_ring(ring, q_vector->tx)
 			ixgbevf_set_ivar(adapter, 1, ring->reg_idx, v_idx);
 
-		/* if this is a tx only vector halve the interrupt rate */
-		if (q_vector->tx.ring && !q_vector->rx.ring)
-			q_vector->eitr = (adapter->eitr_param >> 1);
-		else if (q_vector->rx.ring)
-			/* rx only */
-			q_vector->eitr = adapter->eitr_param;
+		if (q_vector->tx.ring && !q_vector->rx.ring) {
+			/* tx only vector */
+			if (adapter->tx_itr_setting == 1)
+				q_vector->itr = IXGBE_10K_ITR;
+			else
+				q_vector->itr = adapter->tx_itr_setting;
+		} else {
+			/* rx or rx/tx vector */
+			if (adapter->rx_itr_setting == 1)
+				q_vector->itr = IXGBE_20K_ITR;
+			else
+				q_vector->itr = adapter->rx_itr_setting;
+		}
+
+		/* add q_vector eims value to global eims_enable_mask */
+		adapter->eims_enable_mask |= 1 << v_idx;
 
-		ixgbevf_write_eitr(adapter, v_idx, q_vector->eitr);
+		ixgbevf_write_eitr(q_vector);
 	}
 
 	ixgbevf_set_ivar(adapter, -1, 1, v_idx);
-
-	/* set up to autoclear timer, and the vectors */
-	mask = IXGBE_EIMS_ENABLE_MASK;
-	mask &= ~IXGBE_EIMS_OTHER;
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask);
+	/* setup eims_other and add value to global eims_enable_mask */
+	adapter->eims_other = 1 << v_idx;
+	adapter->eims_enable_mask |= adapter->eims_other;
 }
 
 enum latency_range {
@@ -608,11 +611,8 @@ enum latency_range {
 
 /**
  * ixgbevf_update_itr - update the dynamic ITR value based on statistics
- * @adapter: pointer to adapter
- * @eitr: eitr setting (ints per sec) to give last timeslice
- * @itr_setting: current throttle rate in ints/second
- * @packets: the number of packets during this measurement interval
- * @bytes: the number of bytes during this measurement interval
+ * @q_vector: structure containing interrupt and ring information
+ * @ring_container: structure containing ring performance data
  *
  *      Stores a new ITR value based on packets and byte
  *      counts during the last interrupt.  The advantage of per interrupt
@@ -622,17 +622,17 @@ enum latency_range {
  *      on testing data as well as attempting to minimize response time
  *      while increasing bulk throughput.
  **/
-static u8 ixgbevf_update_itr(struct ixgbevf_adapter *adapter,
-			     u32 eitr, u8 itr_setting,
-			     int packets, int bytes)
+static void ixgbevf_update_itr(struct ixgbevf_q_vector *q_vector,
+			       struct ixgbevf_ring_container *ring_container)
 {
-	unsigned int retval = itr_setting;
+	int bytes = ring_container->total_bytes;
+	int packets = ring_container->total_packets;
 	u32 timepassed_us;
 	u64 bytes_perint;
+	u8 itr_setting = ring_container->itr;
 
 	if (packets == 0)
-		goto update_itr_done;
-
+		return;
 
 	/* simple throttlerate management
 	 *    0-20MB/s lowest (100000 ints/s)
@@ -640,46 +640,48 @@ static u8 ixgbevf_update_itr(struct ixgbevf_adapter *adapter,
 	 *  100-1249MB/s bulk (8000 ints/s)
 	 */
 	/* what was last interrupt timeslice? */
-	timepassed_us = 1000000/eitr;
+	timepassed_us = q_vector->itr >> 2;
 	bytes_perint = bytes / timepassed_us; /* bytes/usec */
 
 	switch (itr_setting) {
 	case lowest_latency:
 		if (bytes_perint > 10)
-			retval = low_latency;
+			itr_setting = low_latency;
 		break;
 	case low_latency:
 		if (bytes_perint > 20)
-			retval = bulk_latency;
+			itr_setting = bulk_latency;
 		else if (bytes_perint <= 10)
-			retval = lowest_latency;
+			itr_setting = lowest_latency;
 		break;
 	case bulk_latency:
 		if (bytes_perint <= 20)
-			retval = low_latency;
+			itr_setting = low_latency;
 		break;
 	}
 
-update_itr_done:
-	return retval;
+	/* clear work counters since we have the values we need */
+	ring_container->total_bytes = 0;
+	ring_container->total_packets = 0;
+
+	/* write updated itr to ring container */
+	ring_container->itr = itr_setting;
 }
 
 /**
  * ixgbevf_write_eitr - write VTEITR register in hardware specific way
- * @adapter: pointer to adapter struct
- * @v_idx: vector index into q_vector array
- * @itr_reg: new value to be written in *register* format, not ints/s
+ * @q_vector: structure containing interrupt and ring information
  *
  * This function is made to be called by ethtool and by the driver
  * when it needs to update VTEITR registers at runtime.  Hardware
  * specific quirks/differences are taken care of here.
  */
-static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
-			       u32 itr_reg)
+void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector)
 {
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	struct ixgbe_hw *hw = &adapter->hw;
-
-	itr_reg = EITR_INTS_PER_SEC_TO_REG(itr_reg);
+	int v_idx = q_vector->v_idx;
+	u32 itr_reg = q_vector->itr & IXGBE_MAX_EITR;
 
 	/*
 	 * set the WDIS bit to not clear the timer bits and cause an
@@ -692,59 +694,37 @@ static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
 
 static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
 {
-	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	u32 new_itr;
-	u8 current_itr, ret_itr;
-	int v_idx = q_vector->v_idx;
-	struct ixgbevf_ring *rx_ring, *tx_ring;
-
-	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
-		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->tx.itr,
-					     tx_ring->total_packets,
-					     tx_ring->total_bytes);
-		/* if the result for this queue would decrease interrupt
-		 * rate for this vector then use that result */
-		q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ?
-				    q_vector->tx.itr - 1 : ret_itr);
-	}
-
-	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
-		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->rx.itr,
-					     rx_ring->total_packets,
-					     rx_ring->total_bytes);
-		/* if the result for this queue would decrease interrupt
-		 * rate for this vector then use that result */
-		q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ?
-				    q_vector->rx.itr - 1 : ret_itr);
-	}
+	u32 new_itr = q_vector->itr;
+	u8 current_itr;
+
+	ixgbevf_update_itr(q_vector, &q_vector->tx);
+	ixgbevf_update_itr(q_vector, &q_vector->rx);
 
 	current_itr = max(q_vector->rx.itr, q_vector->tx.itr);
 
 	switch (current_itr) {
 	/* counts and packets in update_itr are dependent on these numbers */
 	case lowest_latency:
-		new_itr = 100000;
+		new_itr = IXGBE_100K_ITR;
 		break;
 	case low_latency:
-		new_itr = 20000; /* aka hwitr = ~200 */
+		new_itr = IXGBE_20K_ITR;
 		break;
 	case bulk_latency:
 	default:
-		new_itr = 8000;
+		new_itr = IXGBE_8K_ITR;
 		break;
 	}
 
-	if (new_itr != q_vector->eitr) {
-		u32 itr_reg;
-
-		/* save the algorithm value here, not the smoothed one */
-		q_vector->eitr = new_itr;
+	if (new_itr != q_vector->itr) {
 		/* do an exponential smoothing */
-		new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
-		itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
-		ixgbevf_write_eitr(adapter, v_idx, itr_reg);
+		new_itr = (10 * new_itr * q_vector->itr) /
+			  ((9 * new_itr) + q_vector->itr);
+
+		/* save the algorithm value here */
+		q_vector->itr = new_itr;
+
+		ixgbevf_write_eitr(q_vector);
 	}
 }
 
@@ -752,13 +732,9 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 {
 	struct ixgbevf_adapter *adapter = data;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 eicr;
 	u32 msg;
 	bool got_ack = false;
 
-	eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
-	IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
-
 	if (!hw->mbx.ops.check_for_ack(hw))
 		got_ack = true;
 
@@ -787,6 +763,8 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 	if (got_ack)
 		hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
 
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other);
+
 	return IRQ_HANDLED;
 }
 
@@ -799,11 +777,8 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 static irqreturn_t ixgbevf_msix_clean_rings(int irq, void *data)
 {
 	struct ixgbevf_q_vector *q_vector = data;
-	struct ixgbevf_adapter  *adapter = q_vector->adapter;
-	struct ixgbe_hw *hw = &adapter->hw;
 
-	/* disable interrupts on this vector only */
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, 1 << q_vector->v_idx);
+	/* EIAM disabled interrupts (on this vector) for us */
 	if (q_vector->rx.ring || q_vector->tx.ring)
 		napi_schedule(&q_vector->napi);
 
@@ -967,7 +942,6 @@ static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
 		q_vector->tx.ring = NULL;
 		q_vector->rx.count = 0;
 		q_vector->tx.count = 0;
-		q_vector->eitr = adapter->eitr_param;
 	}
 }
 
@@ -1020,10 +994,12 @@ static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter)
  **/
 static inline void ixgbevf_irq_disable(struct ixgbevf_adapter *adapter)
 {
-	int i;
 	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
 
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, 0);
 	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, ~0);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, 0);
 
 	IXGBE_WRITE_FLUSH(hw);
 
@@ -1035,23 +1011,13 @@ static inline void ixgbevf_irq_disable(struct ixgbevf_adapter *adapter)
  * ixgbevf_irq_enable - Enable default interrupt generation settings
  * @adapter: board private structure
  **/
-static inline void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter,
-				      bool queues, bool flush)
+static inline void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 mask;
-	u64 qmask;
-
-	mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
-	qmask = ~0;
-
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
-
-	if (queues)
-		ixgbevf_irq_enable_queues(adapter, qmask);
 
-	if (flush)
-		IXGBE_WRITE_FLUSH(hw);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, adapter->eims_enable_mask);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, adapter->eims_enable_mask);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_enable_mask);
 }
 
 /**
@@ -1414,7 +1380,7 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter)
 	/* clear any pending interrupts, may auto mask */
 	IXGBE_READ_REG(hw, IXGBE_VTEICR);
 
-	ixgbevf_irq_enable(adapter, true, true);
+	ixgbevf_irq_enable(adapter);
 }
 
 /**
@@ -1783,7 +1749,6 @@ static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter)
 			goto err_out;
 		q_vector->adapter = adapter;
 		q_vector->v_idx = q_idx;
-		q_vector->eitr = adapter->eitr_param;
 		netif_napi_add(adapter->netdev, &q_vector->napi,
 			       ixgbevf_poll, 64);
 		adapter->q_vector[q_idx] = q_vector;
@@ -1932,8 +1897,8 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
 	}
 
 	/* Enable dynamic interrupt throttling rates */
-	adapter->eitr_param = 20000;
-	adapter->itr_setting = 1;
+	adapter->rx_itr_setting = 1;
+	adapter->tx_itr_setting = 1;
 
 	/* set default ring sizes */
 	adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
@@ -1998,7 +1963,7 @@ static void ixgbevf_watchdog(unsigned long data)
 {
 	struct ixgbevf_adapter *adapter = (struct ixgbevf_adapter *)data;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u64 eics = 0;
+	u32 eics = 0;
 	int i;
 
 	/*
@@ -2013,10 +1978,10 @@ static void ixgbevf_watchdog(unsigned long data)
 	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
 		struct ixgbevf_q_vector *qv = adapter->q_vector[i];
 		if (qv->rx.ring || qv->tx.ring)
-			eics |= (1 << i);
+			eics |= 1 << i;
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_VTEICS, (u32)eics);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEICS, eics);
 
 watchdog_short_circuit:
 	schedule_work(&adapter->watchdog_task);
@@ -2389,7 +2354,7 @@ static int ixgbevf_open(struct net_device *netdev)
 	if (err)
 		goto err_req_irq;
 
-	ixgbevf_irq_enable(adapter, true, true);
+	ixgbevf_irq_enable(adapter);
 
 	return 0;
 
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 6/8] ixgbevf: Update q_vector to contain ring pointers instead of bitmaps
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

For most cases the ixgbevf driver will only ever contain a single Tx and
single Rx queue.  In order to track that it makes more sense to use a
pointer instead of using a bitmap which must be search in order to locate
the ring on an adapter index.  As such I am changing the code to use
pointers and an iterator to access all rings on a given q_vector.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   18 ++-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  152 +++++++--------------
 2 files changed, 65 insertions(+), 105 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index c62caba..8cae4ff 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -55,6 +55,7 @@ struct ixgbevf_rx_buffer {
 };
 
 struct ixgbevf_ring {
+	struct ixgbevf_ring *next;
 	struct ixgbevf_adapter *adapter;  /* backlink */
 	void *desc;			/* descriptor ring memory */
 	dma_addr_t dma;			/* phys. address of descriptor ring */
@@ -120,18 +121,23 @@ struct ixgbevf_ring {
 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0x0000e000
 #define IXGBE_TX_FLAGS_VLAN_SHIFT	16
 
+struct ixgbevf_ring_container {
+	struct ixgbevf_ring *ring;	/* pointer to linked list of rings */
+	u8 count;			/* total number of rings in vector */
+	u8 itr;				/* current ITR setting for ring */
+};
+
+/* iterator for handling rings in ring container */
+#define ixgbevf_for_each_ring(pos, head) \
+	for (pos = (head).ring; pos != NULL; pos = pos->next)
+
 /* MAX_MSIX_Q_VECTORS of these are allocated,
  * but we only use one per queue-specific vector.
  */
 struct ixgbevf_q_vector {
 	struct ixgbevf_adapter *adapter;
 	struct napi_struct napi;
-	DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
-	DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
-	u8 rxr_count;     /* Rx ring count assigned to this vector */
-	u8 txr_count;     /* Tx ring count assigned to this vector */
-	u8 tx_itr;
-	u8 rx_itr;
+	struct ixgbevf_ring_container rx, tx;
 	u32 eitr;
 	int v_idx;	  /* vector index in list */
 };
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 855bb21..744a026 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -526,14 +526,9 @@ static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
 	struct ixgbevf_q_vector *q_vector =
 		container_of(napi, struct ixgbevf_q_vector, napi);
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	struct ixgbevf_ring *rx_ring = NULL;
 	int work_done = 0;
-	long r_idx;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
-
-	ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
+	ixgbevf_clean_rx_irq(q_vector, q_vector->rx.ring, &work_done, budget);
 
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
@@ -541,7 +536,8 @@ static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
 		if (adapter->itr_setting & 1)
 			ixgbevf_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter, rx_ring->v_idx);
+			ixgbevf_irq_enable_queues(adapter,
+						  1 << q_vector->v_idx);
 	}
 
 	return work_done;
@@ -560,26 +556,16 @@ static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
 	struct ixgbevf_q_vector *q_vector =
 		container_of(napi, struct ixgbevf_q_vector, napi);
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	struct ixgbevf_ring *rx_ring = NULL;
-	int work_done = 0, i;
-	long r_idx;
-	u64 enable_mask = 0;
+	struct ixgbevf_ring *rx_ring;
+	int work_done = 0;
 
 	/* attempt to distribute budget to each queue fairly, but don't allow
 	 * the budget to go below 1 because we'll exit polling */
-	budget /= (q_vector->rxr_count ?: 1);
+	budget /= (q_vector->rx.count ?: 1);
 	budget = max(budget, 1);
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
-		ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
-		enable_mask |= rx_ring->v_idx;
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
-	}
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx)
+		ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
@@ -587,7 +573,8 @@ static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
 		if (adapter->itr_setting & 1)
 			ixgbevf_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter, enable_mask);
+			ixgbevf_irq_enable_queues(adapter,
+						  1 << q_vector->v_idx);
 	}
 
 	return work_done;
@@ -605,7 +592,7 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 {
 	struct ixgbevf_q_vector *q_vector;
 	struct ixgbe_hw *hw = &adapter->hw;
-	int i, j, q_vectors, v_idx, r_idx;
+	int q_vectors, v_idx;
 	u32 mask;
 
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -615,33 +602,19 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 	 * corresponding register.
 	 */
 	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
+		struct ixgbevf_ring *ring;
 		q_vector = adapter->q_vector[v_idx];
-		/* XXX for_each_set_bit(...) */
-		r_idx = find_first_bit(q_vector->rxr_idx,
-				       adapter->num_rx_queues);
-
-		for (i = 0; i < q_vector->rxr_count; i++) {
-			j = adapter->rx_ring[r_idx].reg_idx;
-			ixgbevf_set_ivar(adapter, 0, j, v_idx);
-			r_idx = find_next_bit(q_vector->rxr_idx,
-					      adapter->num_rx_queues,
-					      r_idx + 1);
-		}
-		r_idx = find_first_bit(q_vector->txr_idx,
-				       adapter->num_tx_queues);
-
-		for (i = 0; i < q_vector->txr_count; i++) {
-			j = adapter->tx_ring[r_idx].reg_idx;
-			ixgbevf_set_ivar(adapter, 1, j, v_idx);
-			r_idx = find_next_bit(q_vector->txr_idx,
-					      adapter->num_tx_queues,
-					      r_idx + 1);
-		}
+
+		ixgbevf_for_each_ring(ring, q_vector->rx)
+			ixgbevf_set_ivar(adapter, 0, ring->reg_idx, v_idx);
+
+		ixgbevf_for_each_ring(ring, q_vector->tx)
+			ixgbevf_set_ivar(adapter, 1, ring->reg_idx, v_idx);
 
 		/* if this is a tx only vector halve the interrupt rate */
-		if (q_vector->txr_count && !q_vector->rxr_count)
+		if (q_vector->tx.ring && !q_vector->rx.ring)
 			q_vector->eitr = (adapter->eitr_param >> 1);
-		else if (q_vector->rxr_count)
+		else if (q_vector->rx.ring)
 			/* rx only */
 			q_vector->eitr = adapter->eitr_param;
 
@@ -752,40 +725,32 @@ static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector)
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	u32 new_itr;
 	u8 current_itr, ret_itr;
-	int i, r_idx, v_idx = q_vector->v_idx;
+	int v_idx = q_vector->v_idx;
 	struct ixgbevf_ring *rx_ring, *tx_ring;
 
-	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
 		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->tx_itr,
+					     q_vector->tx.itr,
 					     tx_ring->total_packets,
 					     tx_ring->total_bytes);
 		/* if the result for this queue would decrease interrupt
 		 * rate for this vector then use that result */
-		q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
-				    q_vector->tx_itr - 1 : ret_itr);
-		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-				      r_idx + 1);
+		q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ?
+				    q_vector->tx.itr - 1 : ret_itr);
 	}
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
 		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->rx_itr,
+					     q_vector->rx.itr,
 					     rx_ring->total_packets,
 					     rx_ring->total_bytes);
 		/* if the result for this queue would decrease interrupt
 		 * rate for this vector then use that result */
-		q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
-				    q_vector->rx_itr - 1 : ret_itr);
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
+		q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ?
+				    q_vector->rx.itr - 1 : ret_itr);
 	}
 
-	current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
+	current_itr = max(q_vector->rx.itr, q_vector->tx.itr);
 
 	switch (current_itr) {
 	/* counts and packets in update_itr are dependent on these numbers */
@@ -861,19 +826,14 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data)
 	struct ixgbevf_q_vector *q_vector = data;
 	struct ixgbevf_adapter  *adapter = q_vector->adapter;
 	struct ixgbevf_ring     *tx_ring;
-	int i, r_idx;
 
-	if (!q_vector->txr_count)
+	if (!q_vector->tx.ring)
 		return IRQ_HANDLED;
 
-	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
 		tx_ring->total_bytes = 0;
 		tx_ring->total_packets = 0;
 		ixgbevf_clean_tx_irq(adapter, tx_ring);
-		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-				      r_idx + 1);
 	}
 
 	if (adapter->itr_setting & 1)
@@ -893,25 +853,17 @@ static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data)
 	struct ixgbevf_adapter  *adapter = q_vector->adapter;
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct ixgbevf_ring  *rx_ring;
-	int r_idx;
-	int i;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
 		rx_ring->total_bytes = 0;
 		rx_ring->total_packets = 0;
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
 	}
 
-	if (!q_vector->rxr_count)
+	if (!q_vector->rx.ring)
 		return IRQ_HANDLED;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* disable interrupts on this vector only */
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, rx_ring->v_idx);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, 1 << q_vector->v_idx);
 	napi_schedule(&q_vector->napi);
 
 
@@ -931,8 +883,9 @@ static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx,
 {
 	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-	set_bit(r_idx, q_vector->rxr_idx);
-	q_vector->rxr_count++;
+	a->rx_ring[r_idx].next = q_vector->rx.ring;
+	q_vector->rx.ring = &a->rx_ring[r_idx];
+	q_vector->rx.count++;
 	a->rx_ring[r_idx].v_idx = 1 << v_idx;
 }
 
@@ -941,8 +894,9 @@ static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
 {
 	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-	set_bit(t_idx, q_vector->txr_idx);
-	q_vector->txr_count++;
+	a->tx_ring[t_idx].next = q_vector->tx.ring;
+	q_vector->tx.ring = &a->tx_ring[t_idx];
+	q_vector->tx.count++;
 	a->tx_ring[t_idx].v_idx = 1 << v_idx;
 }
 
@@ -1026,10 +980,10 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
 	/* Decrement for Other and TCP Timer vectors */
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
-#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count)          \
-					  ? &ixgbevf_msix_clean_many : \
-			  (_v)->rxr_count ? &ixgbevf_msix_clean_rx   : \
-			  (_v)->txr_count ? &ixgbevf_msix_clean_tx   : \
+#define SET_HANDLER(_v) (((_v)->rx.ring && (_v)->tx.ring)          \
+					? &ixgbevf_msix_clean_many : \
+			  (_v)->rx.ring ? &ixgbevf_msix_clean_rx   : \
+			  (_v)->tx.ring ? &ixgbevf_msix_clean_tx   : \
 			  NULL)
 	for (vector = 0; vector < q_vectors; vector++) {
 		handler = SET_HANDLER(adapter->q_vector[vector]);
@@ -1085,10 +1039,10 @@ static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
 
 	for (i = 0; i < q_vectors; i++) {
 		struct ixgbevf_q_vector *q_vector = adapter->q_vector[i];
-		bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
-		bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
-		q_vector->rxr_count = 0;
-		q_vector->txr_count = 0;
+		q_vector->rx.ring = NULL;
+		q_vector->tx.ring = NULL;
+		q_vector->rx.count = 0;
+		q_vector->tx.count = 0;
 		q_vector->eitr = adapter->eitr_param;
 	}
 }
@@ -1365,10 +1319,10 @@ static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		struct napi_struct *napi;
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rxr_count)
+		if (!q_vector->rx.ring)
 			continue;
 		napi = &q_vector->napi;
-		if (q_vector->rxr_count > 1)
+		if (q_vector->rx.count > 1)
 			napi->poll = &ixgbevf_clean_rxonly_many;
 
 		napi_enable(napi);
@@ -1383,7 +1337,7 @@ static void ixgbevf_napi_disable_all(struct ixgbevf_adapter *adapter)
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rxr_count)
+		if (!q_vector->rx.ring)
 			continue;
 		napi_disable(&q_vector->napi);
 	}
@@ -2144,7 +2098,7 @@ static void ixgbevf_watchdog(unsigned long data)
 	/* get one bit for every active tx/rx interrupt vector */
 	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
 		struct ixgbevf_q_vector *qv = adapter->q_vector[i];
-		if (qv->rxr_count || qv->txr_count)
+		if (qv->rx.ring || qv->tx.ring)
 			eics |= (1 << i);
 	}
 
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 5/8] ixgbevf: Cleanup accounting for space needed at start of xmit_frame
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This change cleans up the accounting needed at the start of xmit_frame so
that we can avoid doing too much work to determine how many descriptors we
will need.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   46 +++++++++++----------
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 75af192..855bb21 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -175,10 +175,8 @@ static void ixgbevf_unmap_and_free_tx_resource(struct ixgbevf_adapter *adapter,
 #define IXGBE_MAX_DATA_PER_TXD	(1 << IXGBE_MAX_TXD_PWR)
 
 /* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
-			 (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
-	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)      /* for context */
+#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD)
+#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
 
 static void ixgbevf_tx_timeout(struct net_device *netdev);
 
@@ -2932,33 +2930,37 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	unsigned int tx_flags = 0;
 	u8 hdr_len = 0;
 	int r_idx = 0, tso;
-	int count = 0;
-
-	unsigned int f;
+	u16 count = TXD_USE_COUNT(skb_headlen(skb));
+#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
+	unsigned short f;
+#endif
 
 	tx_ring = &adapter->tx_ring[r_idx];
 
+	/*
+	 * need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD,
+	 *       + 1 desc for skb_headlen/IXGBE_MAX_DATA_PER_TXD,
+	 *       + 2 desc gap to keep tail from touching head,
+	 *       + 1 desc for context descriptor,
+	 * otherwise try next time
+	 */
+#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
+	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
+		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
+#else
+	count += skb_shinfo(skb)->nr_frags;
+#endif
+	if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count + 3)) {
+		adapter->tx_busy++;
+		return NETDEV_TX_BUSY;
+	}
+
 	if (vlan_tx_tag_present(skb)) {
 		tx_flags |= vlan_tx_tag_get(skb);
 		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 	}
 
-	/* four things can cause us to need a context descriptor */
-	if (skb_is_gso(skb) ||
-	    (skb->ip_summed == CHECKSUM_PARTIAL) ||
-	    (tx_flags & IXGBE_TX_FLAGS_VLAN))
-		count++;
-
-	count += TXD_USE_COUNT(skb_headlen(skb));
-	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
-		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]));
-
-	if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count)) {
-		adapter->tx_busy++;
-		return NETDEV_TX_BUSY;
-	}
-
 	first = tx_ring->next_to_use;
 
 	if (skb->protocol == htons(ETH_P_IP))
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 4/8] ixgbevf: Drop use of eitr_low and eitr_high for hard coded values
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch drops the use of eitr_low and eitr_high as values being stored
in the adapter structure.  Since the values have no external way to be
changed they might as well just be hard coded values and save us the space
on the adapter structure.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |    2 --
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   12 ++++--------
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 773dafa..c62caba 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -177,8 +177,6 @@ struct ixgbevf_adapter {
 
 	/* Interrupt Throttle Rate */
 	u32 itr_setting;
-	u16 eitr_low;
-	u16 eitr_high;
 
 	/* TX */
 	struct ixgbevf_ring *tx_ring;	/* One per active queue */
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 2e85d79..75af192 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -704,17 +704,17 @@ static u8 ixgbevf_update_itr(struct ixgbevf_adapter *adapter,
 
 	switch (itr_setting) {
 	case lowest_latency:
-		if (bytes_perint > adapter->eitr_low)
+		if (bytes_perint > 10)
 			retval = low_latency;
 		break;
 	case low_latency:
-		if (bytes_perint > adapter->eitr_high)
+		if (bytes_perint > 20)
 			retval = bulk_latency;
-		else if (bytes_perint <= adapter->eitr_low)
+		else if (bytes_perint <= 10)
 			retval = lowest_latency;
 		break;
 	case bulk_latency:
-		if (bytes_perint <= adapter->eitr_high)
+		if (bytes_perint <= 20)
 			retval = low_latency;
 		break;
 	}
@@ -2069,10 +2069,6 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
 	adapter->eitr_param = 20000;
 	adapter->itr_setting = 1;
 
-	/* set defaults for eitr in MegaBytes */
-	adapter->eitr_low = 10;
-	adapter->eitr_high = 20;
-
 	/* set default ring sizes */
 	adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
 	adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD;
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 3/8] ixgbevf: Make use of NETIF_F_RXCSUM instead of keeping our own flag
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The IXGBE_FLAG_RX_CSUM_ENABLED flag is redundant since NETIF_F_RXCSUM is
keeping the value we want to already have.  As such we can drop the
redundant flag and just make use of NETIF_F_RXCSUM.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |    3 +--
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   19 +------------------
 2 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index ed19f7e..773dafa 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -207,8 +207,7 @@ struct ixgbevf_adapter {
 	 * thus the additional *_CAPABLE flags.
 	 */
 	u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
-#define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 1)
+#define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1)
 
 	/* OS defined structs */
 	struct net_device *netdev;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 3cd8651..2e85d79 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -307,7 +307,7 @@ static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter,
 	skb_checksum_none_assert(skb);
 
 	/* Rx csum disabled */
-	if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
+	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
 		return;
 
 	/* if IP and error */
@@ -2077,9 +2077,6 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
 	adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
 	adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD;
 
-	/* enable rx csum by default */
-	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-
 	set_bit(__IXGBEVF_DOWN, &adapter->state);
 	return 0;
 
@@ -3112,19 +3109,6 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
 	return stats;
 }
 
-static int ixgbevf_set_features(struct net_device *netdev,
-	netdev_features_t features)
-{
-	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-
-	if (features & NETIF_F_RXCSUM)
-		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
-
-	return 0;
-}
-
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open		= ixgbevf_open,
 	.ndo_stop		= ixgbevf_close,
@@ -3137,7 +3121,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_tx_timeout		= ixgbevf_tx_timeout,
 	.ndo_vlan_rx_add_vid	= ixgbevf_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= ixgbevf_vlan_rx_kill_vid,
-	.ndo_set_features	= ixgbevf_set_features,
 };
 
 static void ixgbevf_assign_netdev_ops(struct net_device *dev)
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 1/8] ixgbevf: Drop all dead or unnecessary code
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Greg Rose, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

There is a large amount of code present in this driver to support features
that either do no exist or are not supported such ask packet split, DCA, or
RSC.  This patch strips out almost all of that code and in the case of
conditionals based on unused flags I am flatting the code out to just the
path that would have been selected.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ethtool.c      |   11 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   40 +----
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  199 ++-------------------
 3 files changed, 22 insertions(+), 228 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index e8dddf5..af9c657 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -43,7 +43,6 @@
 
 #define IXGBE_ALL_RAR_ENTRIES 16
 
-#ifdef ETHTOOL_GSTATS
 struct ixgbe_stats {
 	char stat_string[ETH_GSTRING_LEN];
 	int sizeof_stat;
@@ -75,21 +74,17 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
 						zero_base)},
 	{"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,
 					      zero_base)},
-	{"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},
 };
 
 #define IXGBE_QUEUE_STATS_LEN 0
 #define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats)
 
 #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
-#endif /* ETHTOOL_GSTATS */
-#ifdef ETHTOOL_TEST
 static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register test  (offline)",
 	"Link test   (on/offline)"
 };
 #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
-#endif /* ETHTOOL_TEST */
 
 static int ixgbevf_get_settings(struct net_device *netdev,
 				struct ethtool_cmd *ecmd)
@@ -674,10 +669,8 @@ static int ixgbevf_nway_reset(struct net_device *netdev)
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 
-	if (netif_running(netdev)) {
-		if (!adapter->dev_closed)
-			ixgbevf_reinit_locked(adapter);
-	}
+	if (netif_running(netdev))
+		ixgbevf_reinit_locked(adapter);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 0a1b992..0cbce49 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -52,9 +52,6 @@ struct ixgbevf_tx_buffer {
 struct ixgbevf_rx_buffer {
 	struct sk_buff *skb;
 	dma_addr_t dma;
-	struct page *page;
-	dma_addr_t page_dma;
-	unsigned int page_offset;
 };
 
 struct ixgbevf_ring {
@@ -83,11 +80,6 @@ struct ixgbevf_ring {
 		      * offset associated with this ring, which is different
 		      * for DCB and RSS modes */
 
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
-	/* cpu for tx queue */
-	int cpu;
-#endif
-
 	u64 v_idx; /* maps directly to the index for this ring in the hardware
 		    * vector array, can also be used for finding the bit in EICR
 		    * and friends that represents the vector for this ring */
@@ -96,16 +88,6 @@ struct ixgbevf_ring {
 	u16 rx_buf_len;
 };
 
-enum ixgbevf_ring_f_enum {
-	RING_F_NONE = 0,
-	RING_F_ARRAY_SIZE      /* must be last in enum set */
-};
-
-struct ixgbevf_ring_feature {
-	int indices;
-	int mask;
-};
-
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
 #define IXGBEVF_RX_BUFFER_WRITE	16	/* Must be power of 2 */
 
@@ -120,8 +102,6 @@ struct ixgbevf_ring_feature {
 #define IXGBEVF_MIN_RXD       64
 
 /* Supported Rx Buffer Sizes */
-#define IXGBEVF_RXBUFFER_64    64     /* Used for packet split */
-#define IXGBEVF_RXBUFFER_128   128    /* Used for packet split */
 #define IXGBEVF_RXBUFFER_256   256    /* Used for packet split */
 #define IXGBEVF_RXBUFFER_2048  2048
 #define IXGBEVF_MAX_RXBUFFER   16384  /* largest size for single descriptor */
@@ -213,18 +193,13 @@ struct ixgbevf_adapter {
 	/* RX */
 	struct ixgbevf_ring *rx_ring;	/* One per active queue */
 	int num_rx_queues;
-	int num_rx_pools;               /* == num_rx_queues in 82598 */
-	int num_rx_queues_per_pool;	/* 1 if 82598, can be many if 82599 */
 	u64 hw_csum_rx_error;
 	u64 hw_rx_no_dma_resources;
 	u64 hw_csum_rx_good;
 	u64 non_eop_descs;
 	int num_msix_vectors;
-	int max_msix_q_vectors;         /* true count of q_vectors for device */
-	struct ixgbevf_ring_feature ring_feature[RING_F_ARRAY_SIZE];
 	struct msix_entry *msix_entries;
 
-	u64 rx_hdr_split;
 	u32 alloc_rx_page_failed;
 	u32 alloc_rx_buff_failed;
 
@@ -233,14 +208,8 @@ struct ixgbevf_adapter {
 	 */
 	u32 flags;
 #define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
-#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 1)
-#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 2)
-#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 3)
-#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 4)
-#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 5)
-#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 6)
-#define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 7)
-#define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 8)
+#define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 1)
+
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
@@ -254,18 +223,15 @@ struct ixgbevf_adapter {
 	u32 eitr_param;
 
 	unsigned long state;
-	u32 *config_space;
 	u64 tx_busy;
 	unsigned int tx_ring_count;
 	unsigned int rx_ring_count;
 
 	u32 link_speed;
 	bool link_up;
-	unsigned long link_check_timeout;
 
 	struct work_struct watchdog_task;
 	bool netdev_registered;
-	bool dev_closed;
 };
 
 enum ixbgevf_state_t {
@@ -302,10 +268,8 @@ extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *,
 				      struct ixgbevf_ring *);
 extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
 
-#ifdef ETHTOOL_OPS_COMPAT
 extern int ethtool_ioctl(struct ifreq *ifr);
 
-#endif
 extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter);
 extern void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter);
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 0368160..3132771 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -177,12 +177,8 @@ static void ixgbevf_unmap_and_free_tx_resource(struct ixgbevf_adapter *adapter,
 /* Tx Descriptors needed, worst case */
 #define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
 			 (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#ifdef MAX_SKB_FRAGS
 #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)      /* for context */
-#else
-#define DESC_NEEDED TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD)
-#endif
 
 static void ixgbevf_tx_timeout(struct net_device *netdev);
 
@@ -255,19 +251,11 @@ cont_loop:
 		 * sees the new next_to_clean.
 		 */
 		smp_mb();
-#ifdef HAVE_TX_MQ
 		if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
 		    !test_bit(__IXGBEVF_DOWN, &adapter->state)) {
 			netif_wake_subqueue(netdev, tx_ring->queue_index);
 			++adapter->restart_queue;
 		}
-#else
-		if (netif_queue_stopped(netdev) &&
-		    !test_bit(__IXGBEVF_DOWN, &adapter->state)) {
-			netif_wake_queue(netdev);
-			++adapter->restart_queue;
-		}
-#endif
 	}
 
 	/* re-arm the interrupt */
@@ -304,10 +292,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector,
 	if (is_vlan && test_bit(tag, adapter->active_vlans))
 		__vlan_hwaccel_put_tag(skb, tag);
 
-	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
-			napi_gro_receive(&q_vector->napi, skb);
-	else
-			netif_rx(skb);
+	napi_gro_receive(&q_vector->napi, skb);
 }
 
 /**
@@ -365,27 +350,6 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter,
 
 	while (cleaned_count--) {
 		rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
-
-		if (!bi->page_dma &&
-		    (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
-			if (!bi->page) {
-				bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD);
-				if (!bi->page) {
-					adapter->alloc_rx_page_failed++;
-					goto no_buffers;
-				}
-				bi->page_offset = 0;
-			} else {
-				/* use a half page if we're re-using */
-				bi->page_offset ^= (PAGE_SIZE / 2);
-			}
-
-			bi->page_dma = dma_map_page(&pdev->dev, bi->page,
-						    bi->page_offset,
-						    (PAGE_SIZE / 2),
-						    DMA_FROM_DEVICE);
-		}
-
 		skb = bi->skb;
 		if (!skb) {
 			skb = netdev_alloc_skb(adapter->netdev,
@@ -410,14 +374,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter,
 						 rx_ring->rx_buf_len,
 						 DMA_FROM_DEVICE);
 		}
-		/* Refresh the desc even if buffer_addrs didn't change because
-		 * each write-back erases this info. */
-		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-			rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
-			rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
-		} else {
-			rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
-		}
+		rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
 
 		i++;
 		if (i == rx_ring->count)
@@ -445,16 +402,6 @@ static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,
 	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
 }
 
-static inline u16 ixgbevf_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc)
-{
-	return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
-}
-
-static inline u16 ixgbevf_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
-{
-	return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
-}
-
 static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 				 struct ixgbevf_ring *rx_ring,
 				 int *work_done, int work_to_do)
@@ -466,7 +413,6 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 	struct sk_buff *skb;
 	unsigned int i;
 	u32 len, staterr;
-	u16 hdr_info;
 	bool cleaned = false;
 	int cleaned_count = 0;
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
@@ -477,24 +423,12 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 	rx_buffer_info = &rx_ring->rx_buffer_info[i];
 
 	while (staterr & IXGBE_RXD_STAT_DD) {
-		u32 upper_len = 0;
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
 
 		rmb(); /* read descriptor and rx_buffer_info after status DD */
-		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-			hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
-			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
-			       IXGBE_RXDADV_HDRBUFLEN_SHIFT;
-			if (hdr_info & IXGBE_RXDADV_SPH)
-				adapter->rx_hdr_split++;
-			if (len > IXGBEVF_RX_HDR_SIZE)
-				len = IXGBEVF_RX_HDR_SIZE;
-			upper_len = le16_to_cpu(rx_desc->wb.upper.length);
-		} else {
-			len = le16_to_cpu(rx_desc->wb.upper.length);
-		}
+		len = le16_to_cpu(rx_desc->wb.upper.length);
 		cleaned = true;
 		skb = rx_buffer_info->skb;
 		prefetch(skb->data - NET_IP_ALIGN);
@@ -508,26 +442,6 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 			skb_put(skb, len);
 		}
 
-		if (upper_len) {
-			dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma,
-				       PAGE_SIZE / 2, DMA_FROM_DEVICE);
-			rx_buffer_info->page_dma = 0;
-			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
-					   rx_buffer_info->page,
-					   rx_buffer_info->page_offset,
-					   upper_len);
-
-			if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
-			    (page_count(rx_buffer_info->page) != 1))
-				rx_buffer_info->page = NULL;
-			else
-				get_page(rx_buffer_info->page);
-
-			skb->len += upper_len;
-			skb->data_len += upper_len;
-			skb->truesize += upper_len;
-		}
-
 		i++;
 		if (i == rx_ring->count)
 			i = 0;
@@ -539,15 +453,8 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 		next_buffer = &rx_ring->rx_buffer_info[i];
 
 		if (!(staterr & IXGBE_RXD_STAT_EOP)) {
-			if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-				rx_buffer_info->skb = next_buffer->skb;
-				rx_buffer_info->dma = next_buffer->dma;
-				next_buffer->skb = skb;
-				next_buffer->dma = 0;
-			} else {
-				skb->next = next_buffer->skb;
-				skb->next->prev = skb;
-			}
+			skb->next = next_buffer->skb;
+			skb->next->prev = skb;
 			adapter->non_eop_descs++;
 			goto next_desc;
 		}
@@ -673,11 +580,6 @@ static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
 				      r_idx + 1);
 	}
 
-#ifndef HAVE_NETDEV_NAPI_LIST
-	if (!netif_running(adapter->netdev))
-		work_done = 0;
-
-#endif
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 	rx_ring = &(adapter->rx_ring[r_idx]);
 
@@ -1320,29 +1222,14 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index)
 
 	srrctl = IXGBE_SRRCTL_DROP_EN;
 
-	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-		u16 bufsz = IXGBEVF_RXBUFFER_2048;
-		/* grow the amount we can receive on large page machines */
-		if (bufsz < (PAGE_SIZE / 2))
-			bufsz = (PAGE_SIZE / 2);
-		/* cap the bufsz at our largest descriptor size */
-		bufsz = min((u16)IXGBEVF_MAX_RXBUFFER, bufsz);
-
-		srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-		srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
-		srrctl |= ((IXGBEVF_RX_HDR_SIZE <<
-			   IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
-			   IXGBE_SRRCTL_BSIZEHDR_MASK);
-	} else {
-		srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
+	srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
 
-		if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
-			srrctl |= IXGBEVF_RXBUFFER_2048 >>
-				IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-		else
-			srrctl |= rx_ring->rx_buf_len >>
-				IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-	}
+	if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
+		srrctl |= IXGBEVF_RXBUFFER_2048 >>
+			IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+	else
+		srrctl |= rx_ring->rx_buf_len >>
+			IXGBE_SRRCTL_BSIZEPKT_SHIFT;
 	IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl);
 }
 
@@ -1362,36 +1249,12 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
 	u32 rdlen;
 	int rx_buf_len;
 
-	/* Decide whether to use packet split mode or not */
-	if (netdev->mtu > ETH_DATA_LEN) {
-		if (adapter->flags & IXGBE_FLAG_RX_PS_CAPABLE)
-			adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
-		else
-			adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
-	} else {
-		if (adapter->flags & IXGBE_FLAG_RX_1BUF_CAPABLE)
-			adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
-		else
-			adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
-	}
-
-	/* Set the RX buffer length according to the mode */
-	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-		/* PSRTYPE must be initialized in 82599 */
-		u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
-			IXGBE_PSRTYPE_UDPHDR |
-			IXGBE_PSRTYPE_IPV4HDR |
-			IXGBE_PSRTYPE_IPV6HDR |
-			IXGBE_PSRTYPE_L2HDR;
-		IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
-		rx_buf_len = IXGBEVF_RX_HDR_SIZE;
-	} else {
-		IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
-		if (netdev->mtu <= ETH_DATA_LEN)
-			rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-		else
-			rx_buf_len = ALIGN(max_frame, 1024);
-	}
+	/* PSRTYPE must be initialized in 82599 */
+	IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
+	if (netdev->mtu <= ETH_DATA_LEN)
+		rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+	else
+		rx_buf_len = ALIGN(max_frame, 1024);
 
 	rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
@@ -1667,10 +1530,6 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
 	ixgbevf_save_reset_stats(adapter);
 	ixgbevf_init_last_counter_stats(adapter);
 
-	/* bring the link up in the watchdog, this could race with our first
-	 * link up interrupt but shouldn't be a problem */
-	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
-	adapter->link_check_timeout = jiffies;
 	mod_timer(&adapter->watchdog_timer, jiffies);
 }
 
@@ -1723,14 +1582,6 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter,
 				dev_kfree_skb(this);
 			} while (skb);
 		}
-		if (!rx_buffer_info->page)
-			continue;
-		dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma,
-			       PAGE_SIZE / 2, DMA_FROM_DEVICE);
-		rx_buffer_info->page_dma = 0;
-		put_page(rx_buffer_info->page);
-		rx_buffer_info->page = NULL;
-		rx_buffer_info->page_offset = 0;
 	}
 
 	size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;
@@ -1958,8 +1809,6 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
 	/* Start with base case */
 	adapter->num_rx_queues = 1;
 	adapter->num_tx_queues = 1;
-	adapter->num_rx_pools = adapter->num_rx_queues;
-	adapter->num_rx_queues_per_pool = 1;
 }
 
 /**
@@ -3220,9 +3069,7 @@ static void ixgbevf_shutdown(struct pci_dev *pdev)
 		ixgbevf_free_all_rx_resources(adapter);
 	}
 
-#ifdef CONFIG_PM
 	pci_save_state(pdev);
-#endif
 
 	pci_disable_device(pdev);
 }
@@ -3350,12 +3197,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-#ifdef HAVE_TX_MQ
 	netdev = alloc_etherdev_mq(sizeof(struct ixgbevf_adapter),
 				   MAX_TX_QUEUES);
-#else
-	netdev = alloc_etherdev(sizeof(struct ixgbevf_adapter));
-#endif
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
@@ -3396,10 +3239,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 	memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops,
 	       sizeof(struct ixgbe_mbx_operations));
 
-	adapter->flags &= ~IXGBE_FLAG_RX_PS_CAPABLE;
-	adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
-	adapter->flags |= IXGBE_FLAG_RX_1BUF_CAPABLE;
-
 	/* setup the private structure */
 	err = ixgbevf_sw_init(adapter);
 	if (err)
@@ -3469,8 +3308,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 
 	hw_dbg(hw, "MAC: %d\n", hw->mac.type);
 
-	hw_dbg(hw, "LRO is disabled\n");
-
 	hw_dbg(hw, "Intel(R) 82599 Virtual Function\n");
 	cards_found++;
 	return 0;
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 2/8] ixgbevf: Drop netdev_registered value since that is already stored in netdev
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1342519759-25137-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

There is no need to keep a separate netdev_registered value since that is
already stored in the netdev itself.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |    1 -
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |    6 +-----
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 0cbce49..ed19f7e 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -231,7 +231,6 @@ struct ixgbevf_adapter {
 	bool link_up;
 
 	struct work_struct watchdog_task;
-	bool netdev_registered;
 };
 
 enum ixbgevf_state_t {
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 3132771..3cd8651 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3297,8 +3297,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 	if (err)
 		goto err_register;
 
-	adapter->netdev_registered = true;
-
 	netif_carrier_off(netdev);
 
 	ixgbevf_init_last_counter_stats(adapter);
@@ -3347,10 +3345,8 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
 	cancel_work_sync(&adapter->reset_task);
 	cancel_work_sync(&adapter->watchdog_task);
 
-	if (adapter->netdev_registered) {
+	if (netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(netdev);
-		adapter->netdev_registered = false;
-	}
 
 	ixgbevf_reset_interrupt_capability(adapter);
 
-- 
1.7.10.4

^ permalink raw reply related

* [net-next 0/8][pull request] Intel Wired LAN Driver Updates
From: Jeff Kirsher @ 2012-07-17 10:09 UTC (permalink / raw)
  To: davem; +Cc: Jeff Kirsher, netdev, gospo, sassmann

This series contains updates to ixgbevf.

The following are changes since commit 282f23c6ee343126156dd41218b22ece96d747e3:
  tcp: implement RFC 5961 3.2
and are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master

Alexander Duyck (8):
  ixgbevf: Drop all dead or unnecessary code
  ixgbevf: Drop netdev_registered value since that is already stored in
    netdev
  ixgbevf: Make use of NETIF_F_RXCSUM instead of keeping our own flag
  ixgbevf: Drop use of eitr_low and eitr_high for hard coded values
  ixgbevf: Cleanup accounting for space needed at start of xmit_frame
  ixgbevf: Update q_vector to contain ring pointers instead of bitmaps
  ixgbevf: Move Tx clean-up into NAPI context
  ixgbevf: Use igb style interrupt masks instead of ixgbe style

 drivers/net/ethernet/intel/ixgbevf/defines.h      |   27 +-
 drivers/net/ethernet/intel/ixgbevf/ethtool.c      |   13 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   99 +--
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  820 ++++++---------------
 4 files changed, 276 insertions(+), 683 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* Re: [PATCH 3/3] ipvs: fix oops in ip_vs_dst_event on rmmod
From: Pablo Neira Ayuso @ 2012-07-17 10:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Hans Schillstrom, Jesper Dangaard Brouer
In-Reply-To: <1341965963-7275-4-git-send-email-horms@verge.net.au>

On Wed, Jul 11, 2012 at 09:19:23AM +0900, Simon Horman wrote:
> From: Julian Anastasov <ja@ssi.bg>
> 
> 	After commit 39f618b4fd95ae243d940ec64c961009c74e3333 (3.4)
> "ipvs: reset ipvs pointer in netns" we can oops in
> ip_vs_dst_event on rmmod ip_vs because ip_vs_control_cleanup
> is called after the ipvs_core_ops subsys is unregistered and
> net->ipvs is NULL. Fix it by exiting early from ip_vs_dst_event
> if ipvs is NULL. It is safe because all services and dests
> for the net are already freed.

Applied, thanks.

^ permalink raw reply

* Re: [PATCH 1/3] ipvs: fix oops on NAT reply in br_nf context
From: Pablo Neira Ayuso @ 2012-07-17 10:08 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Hans Schillstrom, Jesper Dangaard Brouer,
	Lin Ming
In-Reply-To: <1341965963-7275-2-git-send-email-horms@verge.net.au>

On Wed, Jul 11, 2012 at 09:19:21AM +0900, Simon Horman wrote:
> From: Lin Ming <mlin@ss.pku.edu.cn>
> 
> IPVS should not reset skb->nf_bridge in FORWARD hook
> by calling nf_reset for NAT replies. It triggers oops in
> br_nf_forward_finish.

Applied, thanks.

^ permalink raw reply

* [PATCH 2/2] ipvs: fix oops in ip_vs_dst_event on rmmod
From: pablo @ 2012-07-17 10:06 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1342519589-3348-1-git-send-email-pablo@netfilter.org>

From: Julian Anastasov <ja@ssi.bg>

	After commit 39f618b4fd95ae243d940ec64c961009c74e3333 (3.4)
"ipvs: reset ipvs pointer in netns" we can oops in
ip_vs_dst_event on rmmod ip_vs because ip_vs_control_cleanup
is called after the ipvs_core_ops subsys is unregistered and
net->ipvs is NULL. Fix it by exiting early from ip_vs_dst_event
if ipvs is NULL. It is safe because all services and dests
for the net are already freed.

Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/ipvs/ip_vs_ctl.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index d43e3c1..84444dd 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1521,11 +1521,12 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
 {
 	struct net_device *dev = ptr;
 	struct net *net = dev_net(dev);
+	struct netns_ipvs *ipvs = net_ipvs(net);
 	struct ip_vs_service *svc;
 	struct ip_vs_dest *dest;
 	unsigned int idx;
 
-	if (event != NETDEV_UNREGISTER)
+	if (event != NETDEV_UNREGISTER || !ipvs)
 		return NOTIFY_DONE;
 	IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name);
 	EnterFunction(2);
@@ -1551,7 +1552,7 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
 		}
 	}
 
-	list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) {
+	list_for_each_entry(dest, &ipvs->dest_trash, n_list) {
 		__ip_vs_dev_reset(dest, dev);
 	}
 	mutex_unlock(&__ip_vs_mutex);
-- 
1.7.10

^ permalink raw reply related

* [PATCH 1/2] ipvs: fix oops on NAT reply in br_nf context
From: pablo @ 2012-07-17 10:06 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1342519589-3348-1-git-send-email-pablo@netfilter.org>

From: Lin Ming <mlin@ss.pku.edu.cn>

IPVS should not reset skb->nf_bridge in FORWARD hook
by calling nf_reset for NAT replies. It triggers oops in
br_nf_forward_finish.

[  579.781508] BUG: unable to handle kernel NULL pointer dereference at 0000000000000004
[  579.781669] IP: [<ffffffff817b1ca5>] br_nf_forward_finish+0x58/0x112
[  579.781792] PGD 218f9067 PUD 0
[  579.781865] Oops: 0000 [#1] SMP
[  579.781945] CPU 0
[  579.781983] Modules linked in:
[  579.782047]
[  579.782080]
[  579.782114] Pid: 4644, comm: qemu Tainted: G        W    3.5.0-rc5-00006-g95e69f9 #282 Hewlett-Packard  /30E8
[  579.782300] RIP: 0010:[<ffffffff817b1ca5>]  [<ffffffff817b1ca5>] br_nf_forward_finish+0x58/0x112
[  579.782455] RSP: 0018:ffff88007b003a98  EFLAGS: 00010287
[  579.782541] RAX: 0000000000000008 RBX: ffff8800762ead00 RCX: 000000000001670a
[  579.782653] RDX: 0000000000000000 RSI: 000000000000000a RDI: ffff8800762ead00
[  579.782845] RBP: ffff88007b003ac8 R08: 0000000000016630 R09: ffff88007b003a90
[  579.782957] R10: ffff88007b0038e8 R11: ffff88002da37540 R12: ffff88002da01a02
[  579.783066] R13: ffff88002da01a80 R14: ffff88002d83c000 R15: ffff88002d82a000
[  579.783177] FS:  0000000000000000(0000) GS:ffff88007b000000(0063) knlGS:00000000f62d1b70
[  579.783306] CS:  0010 DS: 002b ES: 002b CR0: 000000008005003b
[  579.783395] CR2: 0000000000000004 CR3: 00000000218fe000 CR4: 00000000000027f0
[  579.783505] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  579.783684] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  579.783795] Process qemu (pid: 4644, threadinfo ffff880021b20000, task ffff880021aba760)
[  579.783919] Stack:
[  579.783959]  ffff88007693cedc ffff8800762ead00 ffff88002da01a02 ffff8800762ead00
[  579.784110]  ffff88002da01a02 ffff88002da01a80 ffff88007b003b18 ffffffff817b26c7
[  579.784260]  ffff880080000000 ffffffff81ef59f0 ffff8800762ead00 ffffffff81ef58b0
[  579.784477] Call Trace:
[  579.784523]  <IRQ>
[  579.784562]
[  579.784603]  [<ffffffff817b26c7>] br_nf_forward_ip+0x275/0x2c8
[  579.784707]  [<ffffffff81704b58>] nf_iterate+0x47/0x7d
[  579.784797]  [<ffffffff817ac32e>] ? br_dev_queue_push_xmit+0xae/0xae
[  579.784906]  [<ffffffff81704bfb>] nf_hook_slow+0x6d/0x102
[  579.784995]  [<ffffffff817ac32e>] ? br_dev_queue_push_xmit+0xae/0xae
[  579.785175]  [<ffffffff8187fa95>] ? _raw_write_unlock_bh+0x19/0x1b
[  579.785179]  [<ffffffff817ac417>] __br_forward+0x97/0xa2
[  579.785179]  [<ffffffff817ad366>] br_handle_frame_finish+0x1a6/0x257
[  579.785179]  [<ffffffff817b2386>] br_nf_pre_routing_finish+0x26d/0x2cb
[  579.785179]  [<ffffffff817b2cf0>] br_nf_pre_routing+0x55d/0x5c1
[  579.785179]  [<ffffffff81704b58>] nf_iterate+0x47/0x7d
[  579.785179]  [<ffffffff817ad1c0>] ? br_handle_local_finish+0x44/0x44
[  579.785179]  [<ffffffff81704bfb>] nf_hook_slow+0x6d/0x102
[  579.785179]  [<ffffffff817ad1c0>] ? br_handle_local_finish+0x44/0x44
[  579.785179]  [<ffffffff81551525>] ? sky2_poll+0xb35/0xb54
[  579.785179]  [<ffffffff817ad62a>] br_handle_frame+0x213/0x229
[  579.785179]  [<ffffffff817ad417>] ? br_handle_frame_finish+0x257/0x257
[  579.785179]  [<ffffffff816e3b47>] __netif_receive_skb+0x2b4/0x3f1
[  579.785179]  [<ffffffff816e69fc>] process_backlog+0x99/0x1e2
[  579.785179]  [<ffffffff816e6800>] net_rx_action+0xdf/0x242
[  579.785179]  [<ffffffff8107e8a8>] __do_softirq+0xc1/0x1e0
[  579.785179]  [<ffffffff8135a5ba>] ? trace_hardirqs_off_thunk+0x3a/0x6c
[  579.785179]  [<ffffffff8188812c>] call_softirq+0x1c/0x30

The steps to reproduce as follow,

1. On Host1, setup brige br0(192.168.1.106)
2. Boot a kvm guest(192.168.1.105) on Host1 and start httpd
3. Start IPVS service on Host1
   ipvsadm -A -t 192.168.1.106:80 -s rr
   ipvsadm -a -t 192.168.1.106:80 -r 192.168.1.105:80 -m
4. Run apache benchmark on Host2(192.168.1.101)
   ab -n 1000 http://192.168.1.106/

ip_vs_reply4
  ip_vs_out
    handle_response
      ip_vs_notrack
        nf_reset()
        {
          skb->nf_bridge = NULL;
        }

Actually, IPVS wants in this case just to replace nfct
with untracked version. So replace the nf_reset(skb) call
in ip_vs_notrack() with a nf_conntrack_put(skb->nfct) call.

Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/ip_vs.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index d6146b4..95374d1 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1425,7 +1425,7 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
 
 	if (!ct || !nf_ct_is_untracked(ct)) {
-		nf_reset(skb);
+		nf_conntrack_put(skb->nfct);
 		skb->nfct = &nf_ct_untracked_get()->ct_general;
 		skb->nfctinfo = IP_CT_NEW;
 		nf_conntrack_get(skb->nfct);
-- 
1.7.10

^ permalink raw reply related

* [PATCH 0/2] ipvs fixes for 3.5
From: pablo @ 2012-07-17 10:06 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>

Hi David,

I know that we're in fairly late stage to request pulls, but the IPVS people
pinged me with little patches with oops fixes last week.

One of them was recently introduced (during the 3.4 development cycle) while
cleaning up the IPVS netns support. They are:

* Fix one regression introduced in 3.4 while cleaning up the
  netns support for IPVS, from Julian Anastasov.

* Fix one oops triggered due to resetting the conntrack attached to the skb
  instead of just putting it in the forward hook, from Lin Ming. This problem
  seems to be there since 2.6.37 according to Simon Horman.

You can pull these changes from:

git://1984.lsi.us.es/nf master

Thanks!

Julian Anastasov (1):
  ipvs: fix oops in ip_vs_dst_event on rmmod

Lin Ming (1):
  ipvs: fix oops on NAT reply in br_nf context

 include/net/ip_vs.h            |    2 +-
 net/netfilter/ipvs/ip_vs_ctl.c |    5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

--
1.7.10

^ permalink raw reply

* Re: [net] ixgbevf: Fix panic when loading driver
From: David Miller @ 2012-07-17  9:57 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: alexander.h.duyck, netdev, gospo, sassmann
In-Reply-To: <1342518288-13522-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 17 Jul 2012 02:44:48 -0700

> From: Alexander Duyck <alexander.h.duyck@intel.com>
> 
> This patch addresses a kernel panic seen when setting up the interface.
> Specifically we see a NULL pointer dereference on the Tx descriptor cleanup
> path when enabling interrupts.  This change corrects that so it cannot
> occur.
> 
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
> Acked-by: Greg Rose <gregory.v.rose@intel.com>
> Tested-by: Sibai Li <sibai.li@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied, thanks Jeff.

^ permalink raw reply

* Re: [PATCH 2/3] ipvs: add missing lock in ip_vs_ftp_init_conn()
From: Pablo Neira Ayuso @ 2012-07-17  9:46 UTC (permalink / raw)
  To: Xiaotian Feng
  Cc: Simon Horman, lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Hans Schillstrom, Jesper Dangaard Brouer,
	Xiaotian Feng, Patrick McHardy, David S. Miller
In-Reply-To: <CAJn8CcEChmrFvASChJfj7qK8F-my79fn+-G8ttst02Sts15y6Q@mail.gmail.com>

Hi,

On Tue, Jul 17, 2012 at 09:44:01AM +0800, Xiaotian Feng wrote:
> On Tue, Jul 17, 2012 at 5:07 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > Hi Simon,
> >
> > On Wed, Jul 11, 2012 at 09:19:22AM +0900, Simon Horman wrote:
> >> From: Xiaotian Feng <xtfeng@gmail.com>
> >>
> >> We met a kernel panic in 2.6.32.43 kernel:
> > [...]
> >>  net/netfilter/ipvs/ip_vs_ftp.c | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
> >> index b20b29c..c2bc264 100644
> >> --- a/net/netfilter/ipvs/ip_vs_ftp.c
> >> +++ b/net/netfilter/ipvs/ip_vs_ftp.c
> >> @@ -65,8 +65,10 @@ static int ip_vs_ftp_pasv;
> >>  static int
> >>  ip_vs_ftp_init_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
> >>  {
> >> +     spin_lock(&cp->lock);
> >>       /* We use connection tracking for the command connection */
> >>       cp->flags |= IP_VS_CONN_F_NFCT;
> >> +     spin_unlock(&cp->lock);
> >>       return 0;
> >
> > The conntrack support for FTP IPVS helper seems to be there since
> > 2.6.37.
> >
> > However, the patch description mentions 2.6.32.43.
> >
> > Something doesn't match here, could you clarify this?
> >
> 
> Sorry for the misleading description in the patch. We found the panic
> in 2.6.32.43 is caused by changing cp->flags without protection. In
> 2.6.32.43, ip_vs_process_message changes cp->flags without protection
> while update active/inactive flags for the connection.
> 
> After code inspiration, we found in 3.x kernel, it is accidentally
> fixed by commit  f73181c. But with ip_vs_app changes,
> ip_vs_ftp_init_conn() will have chance to change cp->flags without
> protection. So it is a potential bug in 3.x kernel.

Please, then fix the patch description and resend the patch to me.

I have to justify why this is pushed forward to David, and using
misleading description for the patch is not the way to go.

Regarding this bitset operation, I think it's way better if you use
bitwise operations for those cp->flags. Getting the spin_lock just to
set the flag is way too much.

^ permalink raw reply

* [net] ixgbevf: Fix panic when loading driver
From: Jeff Kirsher @ 2012-07-17  9:44 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch addresses a kernel panic seen when setting up the interface.
Specifically we see a NULL pointer dereference on the Tx descriptor cleanup
path when enabling interrupts.  This change corrects that so it cannot
occur.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 8b304a4..41e3225 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -201,6 +201,9 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
 	unsigned int i, eop, count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
 
+	if (test_bit(__IXGBEVF_DOWN, &adapter->state))
+		return true;
+
 	i = tx_ring->next_to_clean;
 	eop = tx_ring->tx_buffer_info[i].next_to_watch;
 	eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH 1/4] pch_gbe: Fix the checksum fill to the error location
From: Eric Dumazet @ 2012-07-17  8:48 UTC (permalink / raw)
  To: Zhong Hongbo; +Cc: Andy Cress, netdev
In-Reply-To: <50051C83.7020504@windriver.com>

On Tue, 2012-07-17 at 16:04 +0800, Zhong Hongbo wrote:

> Hi Eric,
> 
> When forwarding network packages at the network layer, the variable
> value of skb->transport_header is unknown. In my test, the variable
> value of skb->transport_header is equal to skb->network_header. So
> When you count the checksum as following:
> 
> offset = skb_transport_offset(skb);
> 
> skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
> We should only count the TCP checksum, But it maybe include IP part.
> 
> tcp_hdr(skb)->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
> skb->len - offset, IPPROTO_TCP, skb->csum);
> We should fill the checksum in TCP package, But maybe fill it in other
> location and cover the useful information, such as source ip.
> 
> So We should count the TCP checksum and fill it in the correct
> location. Or else the forwarding network package will be drop for the
> error checksum.
> 



So maybe you should instead test 

if (skb->ip_summed == CHECKSUM_PARTIAL) {
	...
	skb_checksum_start_offset(skb); /* is valid */
}

^ permalink raw reply

* Claim requirements
From: Donna Ashworth @ 2012-07-17  2:06 UTC (permalink / raw)


You are receiving this message because you are a Winner of 300,000 Pounds from Nokia Online Lottery game 2012.
 
Claim requirements are as follows:
(1) Your full names 
(2) Contact Address 
(3) Age 
(4) Occupation 
(5) Telephone 
(6) Sex 
(7) Nationality

Contact Mr. Thomas Hillary on (nokiadp77@yahoo.cn) Tel: +447024081232
 
Copyright ©2012 Nokia. All rights reserved.

^ permalink raw reply

* Re: [PATCH net-next v2] tcp: implement RFC 5961 3.2
From: David Miller @ 2012-07-17  8:36 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, kkiran
In-Reply-To: <1342512785.2626.230.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 17 Jul 2012 10:13:05 +0200

> From: Eric Dumazet <edumazet@google.com>
> 
> Implement the RFC 5691 mitigation against Blind
> Reset attack using RST bit.
> 
> Idea is to validate incoming RST sequence,
> to match RCV.NXT value, instead of previouly accepted
> window : (RCV.NXT <= SEG.SEQ < RCV.NXT+RCV.WND)
> 
> If sequence is in window but not an exact match, send
> a "challenge ACK", so that the other part can resend an
> RST with the appropriate sequence.
> 
> Add a new sysctl, tcp_challenge_ack_limit, to limit
> number of challenge ACK sent per second.
> 
> Add a new SNMP counter to count number of challenge acks sent.
> (netstat -s | grep TCPChallengeACK)
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Looks good, applied, thanks Eric.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox