Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] sis900: Fix mem leak in sis900_rx error path
From: David Miller @ 2011-02-06  2:09 UTC (permalink / raw)
  To: jj; +Cc: venza, netdev, linux-kernel
In-Reply-To: <alpine.LNX.2.00.1102052139150.12305@swampdragon.chaosbits.net>

From: Jesper Juhl <jj@chaosbits.net>
Date: Sat, 5 Feb 2011 21:41:53 +0100 (CET)

> Fix memory leak in error path of sis900_rx(). If we don't do this we'll 
> leak the skb we dev_alloc_skb()'ed just a few lines above when the 
> variable goes out of scope.
> 
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>

Applied, thanks Jesper.

^ permalink raw reply

* Re: [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()
From: David Miller @ 2011-02-06  1:58 UTC (permalink / raw)
  To: ajit.khaparde; +Cc: netdev, jj, linux-kernel
In-Reply-To: <20110205031828.GA12772@akhaparde-VBox>

From: Ajit Khaparde <ajit.khaparde@emulex.com>
Date: Fri, 4 Feb 2011 21:18:28 -0600

> [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()
> 
> Found by: Jesper Juhl <jj@chaosbits.net>
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>

Applied, thanks.

^ permalink raw reply

* Re: [net-next-2.6 4/5] enic: Clean up: Remove support for an older version of hardware
From: David Miller @ 2011-02-06  1:57 UTC (permalink / raw)
  To: vkolluri; +Cc: netdev


If this hardware ever shipped to any customers, you cannot
simply remove support for it.

Such code must be retained.

^ permalink raw reply

* Re: [PATCH 4/5] ipv4: share sysctl net/ipv4/conf/DEVNAME/ tables
From: Eric W. Biederman @ 2011-02-05 21:16 UTC (permalink / raw)
  To: Lucian Adrian Grijincu
  Cc: linux-kernel, netdev, Eric Dumazet, David S. Miller,
	Octavian Purdila
In-Reply-To: <cf6a4b19f6b0264f58367afb659586efb84d2a69.1296793770.git.lucian.grijincu@gmail.com>

Lucian Adrian Grijincu <lucian.grijincu@gmail.com> writes:

> Before this, for each network device DEVNAME that supports ipv4 a new
> sysctl table was registered in $PROC/sys/net/ipv4/conf/DEVNAME/.
>
> The sysctl table was identical for all network devices, except for:
> * data: pointer to the data to be accessed in the sysctl
> * extra1: the 'struct ipv4_devconf*' of the network device
> * extra2: the 'struct net*' of the network namespace
>
> Assuming we have a device name and a 'struct net*', we can get the
> 'struct net_device*'. From there we can compute:
> * data: each entry corresponds to a position in 'struct ipv4_devconf*'
> * extra1: 'struct ipv4_devconf*' can be reached from 'struct net_device*'
> * extra2: the 'struct net*' that we assumed to have
>
> The device name is determined from the path to the file (the name of
> the parent dentry).
>
> The 'struct net*' is stored in the parent 'struct ctl_table*' path by
> register_net_sysctl_table_pathdata().

I don't like this direction.  This makes the code more complicated and
probably racy (think what happens when you are running this sysctl when
someone is renaming the network device) for a questionable gain in space
efficiency.

Size of the sysctl data structures is interesting especially when we
have a lot of instances of this data structure but so is algorithmic
complexity.  The ugly problem is right now inserts of N network devices
is O(N^2) where it could/should be O(Nlog(N)).

I think these last three patches increase reliance on slightly dubious
properties of the sysctl interface and are likely to make it hard to fix
the O(N^2) complexity that increases rtnl_lock hold times and is
otherwise a real pain when adding and deleting network devices.

Eric




> Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
> ---
>  fs/proc/proc_sysctl.c      |   16 +++-
>  include/linux/inetdevice.h |   12 +++-
>  net/ipv4/devinet.c         |  203 +++++++++++++++++++++++++++++---------------
>  3 files changed, 161 insertions(+), 70 deletions(-)
>
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index fb707e0..fe392f1 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -128,6 +128,11 @@ out:
>  	return err;
>  }
>  
> +
> +typedef int proc_handler_extended(struct ctl_table *ctl, int write,
> +				  void __user *buffer, size_t *lenp, loff_t *ppos,
> +				  struct file *filp);
> +
>  static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  		size_t count, loff_t *ppos, int write)
>  {
> @@ -136,6 +141,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  	struct ctl_table *table = PROC_I(inode)->sysctl_entry;
>  	ssize_t error;
>  	size_t res;
> +	proc_handler_extended *phx = (proc_handler_extended *) table->proc_handler;
>  
>  	if (IS_ERR(head))
>  		return PTR_ERR(head);
> @@ -155,7 +161,15 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  
>  	/* careful: calling conventions are nasty here */
>  	res = count;
> -	error = table->proc_handler(table, write, buf, &res, ppos);
> +	/* Most handlers only use the first 5 arguments (without @filp).
> +	 * Changing all is too much of work, as, at the time of writting only
> +	 * the devinet.c proc_handlers know about and use the @filp.
> +	 *
> +	 * This is just a HACK for now, I did this this way to not
> +	 * waste time changing all the handlers, in the final version
> +	 * I'll change all the handlers if there's not other solution.
> +	 */
> +	error = phx(table, write, buf, &res, ppos, filp);
>  	if (!error)
>  		error = res;
>  out:
> diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
> index ae8fdc5..caf06b3 100644
> --- a/include/linux/inetdevice.h
> +++ b/include/linux/inetdevice.h
> @@ -43,8 +43,18 @@ enum
>  
>  #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
>  
> +
> +struct devinet_sysctl {
> +	/* dev_name holds a copy of dev_name, because '.procname' is
> +	 * regarded as const by sysctl and we wouldn't want anyone to
> +	 * change it under our feet (see SIOCSIFNAME). */
> +	char *dev_name;
> +	struct ctl_table_header *sysctl_header;
> +};
> +
> +
>  struct ipv4_devconf {
> -	void	*sysctl;
> +	struct devinet_sysctl devinet_sysctl;
>  	int	data[IPV4_DEVCONF_MAX];
>  	DECLARE_BITMAP(state, IPV4_DEVCONF_MAX);
>  };
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 748cb5b..774d347 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -147,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
>  }
>  EXPORT_SYMBOL(in_dev_finish_destroy);
>  
> -static struct in_device *inetdev_init(struct net_device *dev)
> +struct in_device *inetdev_init(struct net_device *dev)
>  {
>  	struct in_device *in_dev;
>  
> @@ -158,7 +158,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
>  		goto out;
>  	memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
>  			sizeof(in_dev->cnf));
> -	in_dev->cnf.sysctl = NULL;
> +	in_dev->cnf.devinet_sysctl.dev_name = NULL;
> +	in_dev->cnf.devinet_sysctl.sysctl_header = NULL;
>  	in_dev->dev = dev;
>  	in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
>  	if (!in_dev->arp_parms)
> @@ -1375,6 +1376,67 @@ static void inet_forward_change(struct net *net)
>  	}
>  }
>  
> +
> +
> +static int devinet_conf_handler(ctl_table *ctl, int write,
> +				void __user *buffer,
> +				size_t *lenp, loff_t *ppos,
> +				struct file *filp,
> +				proc_handler *proc_handler)
> +{
> +	/* The path to this file is of the form:
> +	 *  $PROC_MOUNT/sys/net/ipv4/conf/$DEVNAME/$CTL
> +	 *
> +	 * The array of 'struct ctl_table' of devinet entries is
> +	 * shared between all ipv4 network devices and the 'data'
> +	 * field of each structure only hold the offset into the
> +	 * 'data' field of 'struct ipv4_devconf'.
> +	 *
> +	 * To find the propper location of the data that must be
> +	 * accessed by this handler we need the device name and the
> +	 * network namespace in which it belongs.
> +	 */
> +
> +	/* We store the network namespace in the parent table's ->extra2 */
> +	struct inode *parent_inode = filp->f_path.dentry->d_parent->d_inode;
> +	struct ctl_table *parent_table = PROC_I(parent_inode)->sysctl_entry;
> +	struct net *net = parent_table->extra2;
> +
> +	const char *dev_name = filp->f_path.dentry->d_parent->d_name.name;
> +	struct ctl_table tmp_ctl;
> +	struct net_device *dev = NULL;
> +	struct in_device *in_dev = NULL;
> +	struct ipv4_devconf *cnf;
> +	int ret;
> +
> +	if (strcmp(dev_name, "all") == 0) {
> +		cnf = net->ipv4.devconf_all;
> +	} else if (strcmp(dev_name, "default") == 0) {
> +		cnf = net->ipv4.devconf_dflt;
> +	} else {
> +		/* the device could have been renamed (SIOCSIFADDR) or
> +		 * deleted since we started accessing it's proc sysctl */
> +		dev = dev_get_by_name(net, dev_name);
> +		if (dev == NULL)
> +			return -ENOENT;
> +		in_dev = in_dev_get(dev);
> +		cnf = &in_dev->cnf;
> +	}
> +
> +	tmp_ctl = *ctl;
> +	tmp_ctl.data += (char *)cnf - (char *)&ipv4_devconf;
> +	tmp_ctl.extra1 = cnf;
> +	tmp_ctl.extra2 = net;
> +
> +	ret = proc_handler(&tmp_ctl, write, buffer, lenp, ppos);
> +
> +	if (in_dev)
> +		in_dev_put(in_dev);
> +	if (dev)
> +		dev_put(dev);
> +	return ret;
> +}
> +
>  static int devinet_conf_proc(ctl_table *ctl, int write,
>  			     void __user *buffer,
>  			     size_t *lenp, loff_t *ppos)
> @@ -1445,6 +1507,33 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
>  	return ret;
>  }
>  
> +static int devinet_conf_proc__(ctl_table *ctl, int write,
> +			       void __user *buffer,
> +			       size_t *lenp, loff_t *ppos,
> +			       struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    devinet_conf_proc);
> +}
> +
> +static int devinet_sysctl_forward__(ctl_table *ctl, int write,
> +				    void __user *buffer,
> +				    size_t *lenp, loff_t *ppos,
> +				    struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    devinet_sysctl_forward);
> +}
> +
> +static int ipv4_doint_and_flush__(ctl_table *ctl, int write,
> +				  void __user *buffer,
> +				  size_t *lenp, loff_t *ppos,
> +				  struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    ipv4_doint_and_flush);
> +}
> +
>  #define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc) \
>  	{ \
>  		.procname	= name, \
> @@ -1452,67 +1541,60 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
>  				  IPV4_DEVCONF_ ## attr - 1, \
>  		.maxlen		= sizeof(int), \
>  		.mode		= mval, \
> -		.proc_handler	= proc, \
> -		.extra1		= &ipv4_devconf, \
> +		.proc_handler	= (proc_handler *) proc, \
>  	}
>  
>  #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc)
> +	DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc__)
>  
>  #define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc)
> +	DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc__)
>  
>  #define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
>  	DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
>  
>  #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
> -
> -static struct devinet_sysctl_table {
> -	struct ctl_table_header *sysctl_header;
> -	struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
> -	char *dev_name;
> -} devinet_sysctl = {
> -	.devinet_vars = {
> -		DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
> -					     devinet_sysctl_forward),
> -		DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
> -
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
> -		DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
> -		DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
> -					"accept_source_route"),
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
> -		DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
> -		DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
> -		DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
> -		DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
> -		DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
> -		DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
> -		DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
> -
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
> -					      "force_igmp_version"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
> -					      "promote_secondaries"),
> -	},
> +	DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush__)
> +
> +const struct ctl_table ipv4_devinet_sysctl_table[__IPV4_DEVCONF_MAX] = {
> +	DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
> +				     devinet_sysctl_forward__),
> +	DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
> +
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
> +	DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
> +	DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
> +				"accept_source_route"),
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
> +	DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
> +	DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
> +	DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
> +	DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
> +	DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
> +	DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
> +	DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
> +
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
> +				      "force_igmp_version"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
> +				      "promote_secondaries"),
> +	{ }
>  };
>  
>  static int __devinet_sysctl_register(struct net *net, char *dev_name,
> -					struct ipv4_devconf *p)
> +				     struct ipv4_devconf *cnf)
>  {
> -	int i;
> -	struct devinet_sysctl_table *t;
> +	struct devinet_sysctl *t = &cnf->devinet_sysctl;
>  
>  #define DEVINET_CTL_PATH_DEV	3
>  
> @@ -1524,16 +1606,6 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
>  		{ },
>  	};
>  
> -	t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
> -	if (!t)
> -		goto out;
> -
> -	for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
> -		t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
> -		t->devinet_vars[i].extra1 = p;
> -		t->devinet_vars[i].extra2 = net;
> -	}
> -
>  	/*
>  	 * Make a copy of dev_name, because '.procname' is regarded as const
>  	 * by sysctl and we wouldn't want anyone to change it under our feet
> @@ -1541,37 +1613,32 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
>  	 */
>  	t->dev_name = kstrdup(dev_name, GFP_KERNEL);
>  	if (!t->dev_name)
> -		goto free;
> +		goto out;
>  
>  	devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name;
>  
> -	t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path,
> -			t->devinet_vars);
> +	t->sysctl_header = register_net_sysctl_table_pathdata(net,
> +			 devinet_ctl_path, ipv4_devinet_sysctl_table, net);
>  	if (!t->sysctl_header)
>  		goto free_procname;
>  
> -	p->sysctl = t;
>  	return 0;
>  
>  free_procname:
>  	kfree(t->dev_name);
> -free:
> -	kfree(t);
>  out:
>  	return -ENOBUFS;
>  }
>  
>  static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
>  {
> -	struct devinet_sysctl_table *t = cnf->sysctl;
> +	struct devinet_sysctl *t = &cnf->devinet_sysctl;
>  
>  	if (t == NULL)
>  		return;
>  
> -	cnf->sysctl = NULL;
>  	unregister_sysctl_table(t->sysctl_header);
>  	kfree(t->dev_name);
> -	kfree(t);
>  }
>  
>  static void devinet_sysctl_register(struct in_device *idev)

^ permalink raw reply

* [PATCH] sis900: Fix mem leak in sis900_rx error path
From: Jesper Juhl @ 2011-02-05 20:41 UTC (permalink / raw)
  To: Daniele Venzano; +Cc: netdev, linux-kernel

Fix memory leak in error path of sis900_rx(). If we don't do this we'll 
leak the skb we dev_alloc_skb()'ed just a few lines above when the 
variable goes out of scope.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
 sis900.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 5976d1d..640e368 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1777,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
 					      "cur_rx:%4.4d, dirty_rx:%4.4d\n",
 					      net_dev->name, sis_priv->cur_rx,
 					      sis_priv->dirty_rx);
+				dev_kfree_skb(skb);
 				break;
 			}
 

-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.

^ permalink raw reply related

* Re: [net-2.6 PATCH 2/3] net: dcb: use _safe() version of list iterators
From: John Fastabend @ 2011-02-05 19:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20110131.204214.71133534.davem@davemloft.net>

On 1/31/2011 8:42 PM, David Miller wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
> Date: Mon, 31 Jan 2011 14:00:54 -0800
> 
>> Use _safe() version of list iterator macros in dcb_setapp().
>>
>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> 
> Why?  It's unnecessary overhead, since we always branch to "out", and
> therefore out of the list traversal loop, any time we list_del()
> something on the list.

Of course you are right there is no reason for this. Thanks.

^ permalink raw reply

* Re: [net-2.6 PATCH 1/3] net: dcb: match dcb_app protocol field with 802.1Qaz spec
From: John Fastabend @ 2011-02-05 19:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20110131.204104.226756946.davem@davemloft.net>

On 1/31/2011 8:41 PM, David Miller wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
> Date: Mon, 31 Jan 2011 14:00:49 -0800
> 
>> The dcb_app protocol field is a __u32 however the 802.1Qaz
>> specification defines it as a 16 bit field. This patch brings
>> the structure inline with the spec making it a __u16.
>>
>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
>  ...
>> @@ -101,7 +101,7 @@ struct ieee_pfc {
>>   */
>>  struct dcb_app {
>>  	__u8	selector;
>> -	__u32	protocol;
>> +	__u16	protocol;
>>  	__u8	priority;
>>  };
>>  
> 
> If we're going to do this, please fix this wasteful structure
> layout.  Put the "protocol" either first, or last, so that the
> structure size is 4 bytes, rather than something like 8.

OK I will fix this. Thanks

^ permalink raw reply

* Re: 2.6.37 regression: adding main interface to a bridge breaks vlan interface RX
From: chriss @ 2011-02-05 15:34 UTC (permalink / raw)
  To: netdev
In-Reply-To: <201101241625.45367.maciej.rutecki@gmail.com>

Maciej Rutecki <maciej.rutecki <at> gmail.com> writes:

> 
> On niedziela, 23 stycznia 2011 o 22:29:02 Jesse Gross wrote:
> > On Sun, Jan 23, 2011 at 9:45 AM, Maciej Rutecki
> > 
> > <maciej.rutecki <at> gmail.com> wrote:
> > > I created a Bugzilla entry at
> > > https://bugzilla.kernel.org/show_bug.cgi?id=27432
> > > for your bug report, please add your address to the CC list in there,
> > > thanks!
> > 
> > This isn't a bug - the change resolved behavior that varied depending
> > on what NIC was in use.
> 
> Thanks for the update. Closing.
> 
> Regards


Hi

How am i supposed to put my eth to a bridge and have a seprate vlan besides that
bridge?

regards


^ permalink raw reply

* Re: [PATCH 0/5] net: sysctl: share ipv4/ipv6 sysctl tables
From: Lucian Adrian Grijincu @ 2011-02-05 14:59 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: linux-kernel, netdev, Eric W. Biederman, Eric Dumazet,
	David S. Miller, Octavian Purdila
In-Reply-To: <20110205142648.GA9814@p183.telecom.by>

On Sat, Feb 5, 2011 at 4:26 PM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
>> I'm not sure what I have to do to pass the name of a device (e.g.
>> "eth0") instead of "default" but at least "default" and "all" work and
>> have valid dentries.
>
> You do ->parent->procname.
>
> But, but you removed parent.


To be more exact I do:
  const char *dev_name = filp->f_path.dentry->d_parent->d_name.name;


If the sysctl table is shared between all network devices, the last
registered node will set the ->parent.

So accessing /proc/sys/net/ipv4/conf/$DEVNAME/$CTL will access $CTL
for the last network device registered not for $DEVNAME.

-- 
 .
..: Lucian

^ permalink raw reply

* Re: [PATCH 0/5] net: sysctl: share ipv4/ipv6 sysctl tables
From: Alexey Dobriyan @ 2011-02-05 14:26 UTC (permalink / raw)
  To: Lucian Adrian Grijincu
  Cc: linux-kernel, netdev, Eric W. Biederman, Eric Dumazet,
	David S. Miller, Octavian Purdila
In-Reply-To: <AANLkTik=a3NmibvYM6NxvqCiSiaE0oUFNtRaqn4+g_+D@mail.gmail.com>

On Fri, Feb 04, 2011 at 05:59:24PM +0200, Lucian Adrian Grijincu wrote:
> On Fri, Feb 4, 2011 at 12:49 PM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
> >> Finally share the leaf sysctl tables for ipv4/ipv6:
> >>
> >>  [PATCH 4/5] ipv4: share sysctl net/ipv4/conf/DEVNAME/ tables
> >>  [PATCH 5/5] ipv6: share sysctl net/ipv6/conf/DEVNAME/ tables
> >
> > Meh.
> >
> > First you remove ->parent, then heroically pass "struct file *"
> > to sysctl handlers which duplicates all information already passed
> > and brings dcache into picture.
> >
> > Binary sysctl rewrite confused you into thinking that d_name.name
> > is the way, but it isn't.
> > For binary sysctl(2) you wouldn't get d_name.name.
> 
> 
> Are you really sure?
> 
> I ran this code on a machine with and without these patches. It seems
> to work fine.
> 
> It reads the value from /proc/sys/net/ipv4/conf/default/tag and writes 42 back.
> 
> I'm not sure what I have to do to pass the name of a device (e.g.
> "eth0") instead of "default" but at least "default" and "all" work and
> have valid dentries.

You do ->parent->procname.

But, but you removed parent.

^ permalink raw reply

* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: Gerrit Renker @ 2011-02-05 13:58 UTC (permalink / raw)
  To: Leandro Melo de Sales; +Cc: netdev, dccp
In-Reply-To: <AANLkTimuYxHd5AtGSB2+wg2JE7LEKPjGssoQZuOWYrw-@mail.gmail.com>

Leandro,
| >  include/net/tcp.h      |   12 +++---------
| >  net/dccp/ccids/ccid2.c |    9 +++++++++
|
David's change only affects CCID-2, CCID-3/4 remain unaffected,
they use rfc3390_initial_rate() (which does almost the same).
 
|     I don't think this change will make sense for DCCP, once IW10 is
| for the cases of short-lived flows. DCCP is used on scenarios for
| multimedia flows, which are, in general, long-lived flows. So, IMO the
| way how we calculate IW for DCCP is appropriate, at least considering
| a quick answer. 
I agree with you, and also vote to eventually bring CCID-2 on a par with
the state of art in TCP. Before we can do this, the CCID-2 implementation
needs some work (as per separate thread with Samuel Jero).

| In fact, nowadays we need better congestion control algorithms for DCCP,
| and in this sense we are working on adapt TCP Cubic for DCCP as a CCID,
| and also we started some work to make DCCP support TCP pluggable
| mechanism , which will allow us to use TCP congestion control
| algorithms in DCCP.
This is very good news and am very much looking forward to the new approach.


| DCCP should calculate its IW as specified in RFC3390 rather than set
| it to IW10. For the moment, I understand that for DCCP, we have to 
| discuss more about this in a separated thread.
Agree that we should keep an eye on this - perhaps too early to turn it into a
should. Networking speeds are growing, and many of the simulations were based
on TCP Reno which stems from the 10 Mbit ethernet era.

^ permalink raw reply

* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: Gerrit Renker @ 2011-02-05 13:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, dccp, therbert
In-Reply-To: <20110202.170750.229739784.davem@davemloft.net>

| I've left the DCCP code to keep using RFC3390 logic, if they
| wish to adopt this change in their code they can do so by
| simply deleting the rfc33390_bytes_to_packets() function and
| using TCP_INIT_CWND in their assignment.
| 
|  include/net/tcp.h      |   12 +++---------
|  net/dccp/ccids/ccid2.c |    9 +++++++++
Thank you for keeping the compatility, this seems an excellent way forward.

The change only affects CCID-2, TCP-like congestion control. This still has
some unresolved issues (related to cwnd) in its implementation.

Once these have been resolved, we can return to tracking the state of the 
art in TCP, for the moment your patch works best.

^ permalink raw reply

* Re: [PATCH v5] Gemini: Gigabit ethernet driver
From: Michał Mirosław @ 2011-02-05 13:19 UTC (permalink / raw)
  To: netdev, linux-kernel; +Cc: David Miller
In-Reply-To: <20110202171814.GA10458@rere.qmqm.pl>

On Wed, Feb 02, 2011 at 06:18:14PM +0100, Michał Mirosław wrote:
> If I make it buildable (NOT working) on other archs is it enough I add
> Kconfig dependency on (ARCH_GEMINI || BROKEN) to allow it to be
> build-tested there?

Hmm. CONFIG_BROKEN is not easily selectable anymore, so it's unlikely
that many people will even know about it. What's the correct way to
make a driver be built but not installed by default? I can use:

default m if ARCH_GEMINI
default n

But that will make it get installed on x86 allmodconfig even if it
won't ever work there - so will pollute modules for other arches
unless distribution managers remember that not every driver built
needs to be included.

Best Regards,
Michał Mirosław

^ permalink raw reply

* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: Jerry Chu @ 2011-02-05  3:39 UTC (permalink / raw)
  To: Ilpo Järvinen; +Cc: David Miller, Netdev, therbert
In-Reply-To: <alpine.DEB.2.00.1102042126440.28937@melkinpaasi.cs.helsinki.fi>

On Fri, Feb 4, 2011 at 11:43 AM, Ilpo Järvinen
<ilpo.jarvinen@helsinki.fi> wrote:
>
> On Thu, 3 Feb 2011, H.K. Jerry Chu wrote:
>
> > On Thu, Feb 3, 2011 at 2:43 PM, Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> wrote:
> > > It would perhaps be useful to change receiver advertized window to include
> > > some extra segs initially. It should be >= IW + peer's dupThresh-1 as
> > > otherwise limited transmit won't work for the initial window because we
> > > won't open more receiver window with dupacks (IIRC, I suppose Jerry might
> > > be able to correct me right away if I'm wrong and we open window with
> > > dupacks too?).
> >
> > Sorry I don't know how the receive window is updated in Linux,
> > autotuning or not.
> > But I just wonder why would it have to do with dupacks, i.e., why would
> > it not slide forward as long as the left edge of the window slides
> > forward, regardless of OOO pkt arrival?
>
> ?? DupACK by defination does not slide the left edge?!? :-) ...It
> certainly makes a difference whether the ACK is cumulative or not.
> Anyway, I tcpdumped it now and confirmed that advertized window is not
> advanced if OOO packet arrives.

Cwnd discounts packets that have left the network but rwnd won't discharge
packets until they are consumed by ULP so you are right that in case
the packets from or near the head of the retransmission queue get
dropped rwnd won't
open up room for more packets even though cwnd will. To cover that case initrwnd
needs to be larger than initcwnd.

Jerry

>
> > I am of the opinion that rwnd is for flow control purpose only thus should be
> > fully decoupled from the cwnd of the other (sender) side. Therefore
> > initrwnd should
> > normally be based on projected BDP and local memory pressure, e.g., 64KB, not
> > bearing any relation with IW of the other side. Only under special
> > circumstances should it be used to constrain the sender, e.g., for
> > devices behind slow links with
> > very small buffer.
>
> I also think along the lines that the advertized window autotuning code
> is just unnecessarily preventive (besides the IW change, also Quickstart
> couldn't be used that efficiently because of it).
>
> --
>  i.

^ permalink raw reply

* Re: [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()
From: Ajit Khaparde @ 2011-02-05  3:18 UTC (permalink / raw)
  To: netdev, jj; +Cc: linux-kernel

> From: Jesper Juhl [jj@chaosbits.net]
> ent: Thursday, February 03, 2011 3:27 PM
> To: netdev@vger.kernel.org
> Cc: linux-drivers; linux-kernel@vger.kernel.org; Khaparde, Ajit; Bandi, Sarveshwar; Seetharaman, Subramanian; Perla, Sathya
> Subject: [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()

> wrb_from_mccq() may return null, so we may crash on a null deref in
> be_cmd_get_seeprom_data().
> This avoids that potential crash.

> Signed-off-by: Jesper Juhl <jj@chaosbits.net>

Thanks Jesper.
But because we have acquired a lock, we need to release it.
I would suggest considering the following patch.
 
---

[PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()

Found by: Jesper Juhl <jj@chaosbits.net>

Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
 drivers/net/benet/be_cmds.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 0c7811f..a179cc6 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1786,6 +1786,10 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = nonemb_cmd->va;
 	sge = nonembedded_sgl(wrb);
 
@@ -1801,6 +1805,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
-- 
1.7.1

^ permalink raw reply related

* [net-next-2.6 PATCH 5/5] enic: Update MAINTAINERS
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>



Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 MAINTAINERS |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)


diff --git a/MAINTAINERS b/MAINTAINERS
index 424887b..1d2abfa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1691,6 +1691,7 @@ S:	Supported
 F:	scripts/checkpatch.pl
 
 CISCO VIC ETHERNET NIC DRIVER
+M:	Christian Benvenuti <benve@cisco.com>
 M:	Vasanthy Kolluri <vkolluri@cisco.com>
 M:	Roopa Prabhu <roprabhu@cisco.com>
 M:	David Wang <dwang2@cisco.com>


^ permalink raw reply related

* [net-next-2.6 PATCH 4/5] enic: Clean up: Remove support for an older version of hardware
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>

Remove support for an older version (A1) of hardware

Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/enic/enic.h      |    3 +-
 drivers/net/enic/enic_dev.c  |   11 --------
 drivers/net/enic/enic_dev.h  |    1 -
 drivers/net/enic/enic_main.c |   56 ++----------------------------------------
 drivers/net/enic/vnic_dev.c  |   19 --------------
 drivers/net/enic/vnic_dev.h  |    8 ------
 drivers/net/enic/vnic_rq.h   |    5 ----
 7 files changed, 4 insertions(+), 99 deletions(-)


diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 7316267..57fcaee 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.5"
+#define DRV_VERSION		"2.1.1.6"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
@@ -101,7 +101,6 @@ struct enic {
 	/* receive queue cache line section */
 	____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX];
 	unsigned int rq_count;
-	int (*rq_alloc_buf)(struct vnic_rq *rq);
 	u64 rq_truncated_pkts;
 	u64 rq_bad_fcs;
 	struct napi_struct napi[ENIC_RQ_MAX];
diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c
index 3826266..37ad3a1 100644
--- a/drivers/net/enic/enic_dev.c
+++ b/drivers/net/enic/enic_dev.c
@@ -110,17 +110,6 @@ int enic_dev_del_addr(struct enic *enic, u8 *addr)
 	return err;
 }
 
-int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_hw_version(enic->vdev, hw_ver);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 int enic_dev_notify_unset(struct enic *enic)
 {
 	int err;
diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h
index 3ac6ba1..495f57f 100644
--- a/drivers/net/enic/enic_dev.h
+++ b/drivers/net/enic/enic_dev.h
@@ -29,7 +29,6 @@ int enic_dev_add_addr(struct enic *enic, u8 *addr);
 int enic_dev_del_addr(struct enic *enic, u8 *addr);
 void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
 void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
-int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver);
 int enic_dev_notify_unset(struct enic *enic);
 int enic_dev_hang_notify(struct enic *enic);
 int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index d6cdecc..0c24370 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1348,50 +1348,6 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
 	return 0;
 }
 
-static int enic_rq_alloc_buf_a1(struct vnic_rq *rq)
-{
-	struct rq_enet_desc *desc = vnic_rq_next_desc(rq);
-
-	if (vnic_rq_posting_soon(rq)) {
-
-		/* SW workaround for A0 HW erratum: if we're just about
-		 * to write posted_index, insert a dummy desc
-		 * of type resvd
-		 */
-
-		rq_enet_desc_enc(desc, 0, RQ_ENET_TYPE_RESV2, 0);
-		vnic_rq_post(rq, 0, 0, 0, 0);
-	} else {
-		return enic_rq_alloc_buf(rq);
-	}
-
-	return 0;
-}
-
-static int enic_set_rq_alloc_buf(struct enic *enic)
-{
-	enum vnic_dev_hw_version hw_ver;
-	int err;
-
-	err = enic_dev_hw_version(enic, &hw_ver);
-	if (err)
-		return err;
-
-	switch (hw_ver) {
-	case VNIC_DEV_HW_VER_A1:
-		enic->rq_alloc_buf = enic_rq_alloc_buf_a1;
-		break;
-	case VNIC_DEV_HW_VER_A2:
-	case VNIC_DEV_HW_VER_UNKNOWN:
-		enic->rq_alloc_buf = enic_rq_alloc_buf;
-		break;
-	default:
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 static void enic_rq_indicate_buf(struct vnic_rq *rq,
 	struct cq_desc *cq_desc, struct vnic_rq_buf *buf,
 	int skipped, void *opaque)
@@ -1528,7 +1484,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
 			0 /* don't unmask intr */,
 			0 /* don't reset intr timer */);
 
-	err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
+	err = vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
 
 	/* Buffer allocation failed. Stay in polling
 	 * mode so we can try to fill the ring again.
@@ -1578,7 +1534,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
 			0 /* don't unmask intr */,
 			0 /* don't reset intr timer */);
 
-	err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf);
+	err = vnic_rq_fill(&enic->rq[rq], enic_rq_alloc_buf);
 
 	/* Buffer allocation failed. Stay in polling mode
 	 * so we can try to fill the ring again.
@@ -1781,7 +1737,7 @@ static int enic_open(struct net_device *netdev)
 	}
 
 	for (i = 0; i < enic->rq_count; i++) {
-		vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
+		vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf);
 		/* Need at least one buffer on ring to get going */
 		if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
 			netdev_err(netdev, "Unable to alloc receive buffers\n");
@@ -2347,12 +2303,6 @@ static int enic_dev_init(struct enic *enic)
 
 	enic_init_vnic_resources(enic);
 
-	err = enic_set_rq_alloc_buf(enic);
-	if (err) {
-		dev_err(dev, "Failed to set RQ buffer allocator, aborting\n");
-		goto err_out_free_vnic_resources;
-	}
-
 	err = enic_set_rss_nic_cfg(enic);
 	if (err) {
 		dev_err(dev, "Failed to config nic, aborting\n");
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index fb35d8b..c489e72 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -419,25 +419,6 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
 	return err;
 }
 
-int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver)
-{
-	struct vnic_devcmd_fw_info *fw_info;
-	int err;
-
-	err = vnic_dev_fw_info(vdev, &fw_info);
-	if (err)
-		return err;
-
-	if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0)
-		*hw_ver = VNIC_DEV_HW_VER_A1;
-	else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0)
-		*hw_ver = VNIC_DEV_HW_VER_A2;
-	else
-		*hw_ver = VNIC_DEV_HW_VER_UNKNOWN;
-
-	return 0;
-}
-
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
 	void *value)
 {
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 05f9a24..e837546 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -44,12 +44,6 @@ static inline void writeq(u64 val, void __iomem *reg)
 #undef pr_fmt
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-enum vnic_dev_hw_version {
-	VNIC_DEV_HW_VER_UNKNOWN,
-	VNIC_DEV_HW_VER_A1,
-	VNIC_DEV_HW_VER_A2,
-};
-
 enum vnic_dev_intr_mode {
 	VNIC_DEV_INTR_MODE_UNKNOWN,
 	VNIC_DEV_INTR_MODE_INTX,
@@ -93,8 +87,6 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait);
 int vnic_dev_fw_info(struct vnic_dev *vdev,
 	struct vnic_devcmd_fw_info **fw_info);
-int vnic_dev_hw_version(struct vnic_dev *vdev,
-	enum vnic_dev_hw_version *hw_ver);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
 	void *value);
 int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats);
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index 37f08de..2056586 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -141,11 +141,6 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
 	}
 }
 
-static inline int vnic_rq_posting_soon(struct vnic_rq *rq)
-{
-	return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0;
-}
-
 static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
 {
 	rq->ring.desc_avail += count;


^ permalink raw reply related

* [net-next-2.6 PATCH 3/5] enic: Bug Fix: Reorder firmware devcmds - CMD_INIT and CMD_IG_VLAN_REWRITE_MODE
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>

Firmware requires CMD_IG_VLAN_REWRITE_MODE be issued before a CMD_INIT.

Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/enic/enic.h      |    2 +-
 drivers/net/enic/enic_main.c |   28 ++++++++++++++++------------
 2 files changed, 17 insertions(+), 13 deletions(-)


diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index f38ad63..7316267 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.4"
+#define DRV_VERSION		"2.1.1.5"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 3893370..d6cdecc 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -2359,13 +2359,6 @@ static int enic_dev_init(struct enic *enic)
 		goto err_out_free_vnic_resources;
 	}
 
-	err = enic_dev_set_ig_vlan_rewrite_mode(enic);
-	if (err) {
-		dev_err(dev,
-			"Failed to set ingress vlan rewrite mode, aborting.\n");
-		goto err_out_free_vnic_resources;
-	}
-
 	switch (vnic_dev_get_intr_mode(enic->vdev)) {
 	default:
 		netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
@@ -2504,6 +2497,22 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		goto err_out_vnic_unregister;
 	}
 
+	/* Setup devcmd lock
+	 */
+
+	spin_lock_init(&enic->devcmd_lock);
+
+	/*
+	 * Set ingress vlan rewrite mode before vnic initialization
+	 */
+
+	err = enic_dev_set_ig_vlan_rewrite_mode(enic);
+	if (err) {
+		dev_err(dev,
+			"Failed to set ingress vlan rewrite mode, aborting.\n");
+		goto err_out_dev_close;
+	}
+
 	/* Issue device init to initialize the vnic-to-switch link.
 	 * We'll start with carrier off and wait for link UP
 	 * notification later to turn on carrier.  We don't need
@@ -2527,11 +2536,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		}
 	}
 
-	/* Setup devcmd lock
-	 */
-
-	spin_lock_init(&enic->devcmd_lock);
-
 	err = enic_dev_init(enic);
 	if (err) {
 		dev_err(dev, "Device initialization failed, aborting\n");


^ permalink raw reply related

* [net-next-2.6 PATCH 2/5] enic: Bug Fix: Fix return values of enic_add/del_station_addr routines
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>

Fix enic_add/del_station_addr routines to return appropriate error code when an invalid address is added or deleted.

Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/enic/enic.h     |    2 +-
 drivers/net/enic/enic_dev.c |   26 ++++++++++++++------------
 2 files changed, 15 insertions(+), 13 deletions(-)


diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 1385a60..f38ad63 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.3"
+#define DRV_VERSION		"2.1.1.4"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c
index a52dbd2..3826266 100644
--- a/drivers/net/enic/enic_dev.c
+++ b/drivers/net/enic/enic_dev.c
@@ -49,26 +49,28 @@ int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
 
 int enic_dev_add_station_addr(struct enic *enic)
 {
-	int err = 0;
+	int err;
+
+	if (!is_valid_ether_addr(enic->netdev->dev_addr))
+		return -EADDRNOTAVAIL;
 
-	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
-		spin_lock(&enic->devcmd_lock);
-		err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
-		spin_unlock(&enic->devcmd_lock);
-	}
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
+	spin_unlock(&enic->devcmd_lock);
 
 	return err;
 }
 
 int enic_dev_del_station_addr(struct enic *enic)
 {
-	int err = 0;
+	int err;
+
+	if (!is_valid_ether_addr(enic->netdev->dev_addr))
+		return -EADDRNOTAVAIL;
 
-	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
-		spin_lock(&enic->devcmd_lock);
-		err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
-		spin_unlock(&enic->devcmd_lock);
-	}
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
+	spin_unlock(&enic->devcmd_lock);
 
 	return err;
 }


^ permalink raw reply related

* [net-next-2.6 PATCH 1/5] enic: Clean up: Organize devcmd wrapper routines
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>

Organize the wrapper routines for firmware devcmds into a separate file.

Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/enic/Makefile    |    2 
 drivers/net/enic/enic.h      |    2 
 drivers/net/enic/enic_dev.c  |  230 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/enic/enic_dev.h  |   42 ++++++++
 drivers/net/enic/enic_main.c |  207 --------------------------------------
 5 files changed, 275 insertions(+), 208 deletions(-)
 create mode 100644 drivers/net/enic/enic_dev.c
 create mode 100644 drivers/net/enic/enic_dev.h


diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index e7b6c31..2e573be 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_ENIC) := enic.o
 
 enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
-	enic_res.o vnic_dev.o vnic_rq.o vnic_vic.o
+	enic_res.o enic_dev.o vnic_dev.o vnic_rq.o vnic_vic.o
 
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 44865bb..1385a60 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.2a"
+#define DRV_VERSION		"2.1.1.3"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c
new file mode 100644
index 0000000..a52dbd2
--- /dev/null
+++ b/drivers/net/enic/enic_dev.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+
+#include "vnic_dev.h"
+#include "vnic_vic.h"
+#include "enic_res.h"
+#include "enic.h"
+#include "enic_dev.h"
+
+int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_fw_info(enic->vdev, fw_info);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_stats_dump(enic->vdev, vstats);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_add_station_addr(struct enic *enic)
+{
+	int err = 0;
+
+	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
+		spin_lock(&enic->devcmd_lock);
+		err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
+		spin_unlock(&enic->devcmd_lock);
+	}
+
+	return err;
+}
+
+int enic_dev_del_station_addr(struct enic *enic)
+{
+	int err = 0;
+
+	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
+		spin_lock(&enic->devcmd_lock);
+		err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
+		spin_unlock(&enic->devcmd_lock);
+	}
+
+	return err;
+}
+
+int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
+	int broadcast, int promisc, int allmulti)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_packet_filter(enic->vdev, directed,
+		multicast, broadcast, promisc, allmulti);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_add_addr(struct enic *enic, u8 *addr)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_add_addr(enic->vdev, addr);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_del_addr(struct enic *enic, u8 *addr)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_del_addr(enic->vdev, addr);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_hw_version(enic->vdev, hw_ver);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_notify_unset(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_notify_unset(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_hang_notify(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_hang_notify(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
+		IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_enable(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_enable_wait(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_disable(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_disable(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_vnic_dev_deinit(struct enic *enic)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_deinit(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_init_prov(enic->vdev,
+		(u8 *)vp, vic_provinfo_size(vp));
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_init_done(struct enic *enic, int *done, int *error)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_init_done(enic->vdev, done, error);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+/* rtnl lock is held */
+void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	struct enic *enic = netdev_priv(netdev);
+
+	spin_lock(&enic->devcmd_lock);
+	enic_add_vlan(enic, vid);
+	spin_unlock(&enic->devcmd_lock);
+}
+
+/* rtnl lock is held */
+void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct enic *enic = netdev_priv(netdev);
+
+	spin_lock(&enic->devcmd_lock);
+	enic_del_vlan(enic, vid);
+	spin_unlock(&enic->devcmd_lock);
+}
diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h
new file mode 100644
index 0000000..3ac6ba1
--- /dev/null
+++ b/drivers/net/enic/enic_dev.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _ENIC_DEV_H_
+#define _ENIC_DEV_H_
+
+int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info);
+int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats);
+int enic_dev_add_station_addr(struct enic *enic);
+int enic_dev_del_station_addr(struct enic *enic);
+int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
+	int broadcast, int promisc, int allmulti);
+int enic_dev_add_addr(struct enic *enic, u8 *addr);
+int enic_dev_del_addr(struct enic *enic, u8 *addr);
+void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
+void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
+int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver);
+int enic_dev_notify_unset(struct enic *enic);
+int enic_dev_hang_notify(struct enic *enic);
+int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
+int enic_dev_enable(struct enic *enic);
+int enic_dev_disable(struct enic *enic);
+int enic_vnic_dev_deinit(struct enic *enic);
+int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp);
+int enic_dev_init_done(struct enic *enic, int *done, int *error);
+
+#endif /* _ENIC_DEV_H_ */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 37f907b..3893370 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -44,6 +44,7 @@
 #include "vnic_vic.h"
 #include "enic_res.h"
 #include "enic.h"
+#include "enic_dev.h"
 
 #define ENIC_NOTIFY_TIMER_PERIOD	(2 * HZ)
 #define WQ_ENET_MAX_DESC_LEN		(1 << WQ_ENET_LEN_BITS)
@@ -190,18 +191,6 @@ static int enic_get_settings(struct net_device *netdev,
 	return 0;
 }
 
-static int enic_dev_fw_info(struct enic *enic,
-	struct vnic_devcmd_fw_info **fw_info)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_fw_info(enic->vdev, fw_info);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static void enic_get_drvinfo(struct net_device *netdev,
 	struct ethtool_drvinfo *drvinfo)
 {
@@ -246,17 +235,6 @@ static int enic_get_sset_count(struct net_device *netdev, int sset)
 	}
 }
 
-static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_stats_dump(enic->vdev, vstats);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static void enic_get_ethtool_stats(struct net_device *netdev,
 	struct ethtool_stats *stats, u64 *data)
 {
@@ -919,32 +897,6 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr)
 	return 0;
 }
 
-static int enic_dev_add_station_addr(struct enic *enic)
-{
-	int err = 0;
-
-	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
-		spin_lock(&enic->devcmd_lock);
-		err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
-		spin_unlock(&enic->devcmd_lock);
-	}
-
-	return err;
-}
-
-static int enic_dev_del_station_addr(struct enic *enic)
-{
-	int err = 0;
-
-	if (is_valid_ether_addr(enic->netdev->dev_addr)) {
-		spin_lock(&enic->devcmd_lock);
-		err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
-		spin_unlock(&enic->devcmd_lock);
-	}
-
-	return err;
-}
-
 static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p)
 {
 	struct enic *enic = netdev_priv(netdev);
@@ -989,41 +941,6 @@ static int enic_set_mac_address(struct net_device *netdev, void *p)
 	return enic_dev_add_station_addr(enic);
 }
 
-static int enic_dev_packet_filter(struct enic *enic, int directed,
-	int multicast, int broadcast, int promisc, int allmulti)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_packet_filter(enic->vdev, directed,
-		multicast, broadcast, promisc, allmulti);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_add_addr(struct enic *enic, u8 *addr)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_add_addr(enic->vdev, addr);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_del_addr(struct enic *enic, u8 *addr)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_del_addr(enic->vdev, addr);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static void enic_add_multicast_addr_list(struct enic *enic)
 {
 	struct net_device *netdev = enic->netdev;
@@ -1170,26 +1087,6 @@ static void enic_vlan_rx_register(struct net_device *netdev,
 	enic->vlan_group = vlan_group;
 }
 
-/* rtnl lock is held */
-static void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
-	struct enic *enic = netdev_priv(netdev);
-
-	spin_lock(&enic->devcmd_lock);
-	enic_add_vlan(enic, vid);
-	spin_unlock(&enic->devcmd_lock);
-}
-
-/* rtnl lock is held */
-static void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
-	struct enic *enic = netdev_priv(netdev);
-
-	spin_lock(&enic->devcmd_lock);
-	enic_del_vlan(enic, vid);
-	spin_unlock(&enic->devcmd_lock);
-}
-
 /* netif_tx_lock held, BHs disabled */
 static void enic_tx_timeout(struct net_device *netdev)
 {
@@ -1197,40 +1094,6 @@ static void enic_tx_timeout(struct net_device *netdev)
 	schedule_work(&enic->reset);
 }
 
-static int enic_vnic_dev_deinit(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_deinit(enic->vdev);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_init_prov(enic->vdev,
-		(u8 *)vp, vic_provinfo_size(vp));
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_init_done(struct enic *enic, int *done, int *error)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_init_done(enic->vdev, done, error);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 {
 	struct enic *enic = netdev_priv(netdev);
@@ -1505,18 +1368,6 @@ static int enic_rq_alloc_buf_a1(struct vnic_rq *rq)
 	return 0;
 }
 
-static int enic_dev_hw_version(struct enic *enic,
-	enum vnic_dev_hw_version *hw_ver)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_hw_version(enic->vdev, hw_ver);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static int enic_set_rq_alloc_buf(struct enic *enic)
 {
 	enum vnic_dev_hw_version hw_ver;
@@ -1897,39 +1748,6 @@ static int enic_dev_notify_set(struct enic *enic)
 	return err;
 }
 
-static int enic_dev_notify_unset(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_notify_unset(enic->vdev);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_enable(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_enable_wait(enic->vdev);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_disable(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_disable(enic->vdev);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static void enic_notify_timer_start(struct enic *enic)
 {
 	switch (vnic_dev_get_intr_mode(enic->vdev)) {
@@ -2281,29 +2099,6 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
 		rss_hash_bits, rss_base_cpu, rss_enable);
 }
 
-static int enic_dev_hang_notify(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_hang_notify(enic->vdev);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
-static int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
-{
-	int err;
-
-	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
-		IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
-	spin_unlock(&enic->devcmd_lock);
-
-	return err;
-}
-
 static void enic_reset(struct work_struct *work)
 {
 	struct enic *enic = container_of(work, struct enic, reset);


^ permalink raw reply related

* [net-next-2.6 PATCH 0/5] enic: updates to version 2.1.1.6
From: Vasanthy Kolluri @ 2011-02-05  2:17 UTC (permalink / raw)
  To: davem; +Cc: netdev

The following series implements enic driver updates:

1/5 - Clean up: Organize devcmd wrapper routines
2/5 - Bug Fix: Fix return values of enic_add/del_station_addr routines
3/5 - Bug Fix: Reorder firmware devcmds - CMD_INIT and CMD_IG_VLAN_REWRITE_MODE
4/5 - Clean up: Remove support for an older version of hardware
5/5 - Update MAINTAINERS

Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>

^ permalink raw reply

* inetpeer: Move ICMP rate limiting state into inet_peer entries.
From: David Miller @ 2011-02-05  0:24 UTC (permalink / raw)
  To: netdev


Like metrics, the ICMP rate limiting bits are cached state about
a destination.  So move it into the inet_peer entries.

If an inet_peer cannot be bound (the reason is memory allocation
failure or similar), the policy is to allow.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/dst.h      |    2 -
 include/net/icmp.h     |    3 --
 include/net/inetpeer.h |    3 ++
 net/ipv4/icmp.c        |   49 ++++++-----------------------------------
 net/ipv4/inetpeer.c    |   43 ++++++++++++++++++++++++++++++++++++
 net/ipv4/route.c       |   56 ++++++++++++++++++++++++++++++++---------------
 net/ipv6/icmp.c        |   16 +++++++------
 net/ipv6/ip6_output.c  |    5 +++-
 net/ipv6/ndisc.c       |    4 ++-
 9 files changed, 108 insertions(+), 73 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 484f80b..e550195 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -78,8 +78,6 @@ struct dst_entry {
 	atomic_t		__refcnt;	/* client references	*/
 	int			__use;
 	unsigned long		lastuse;
-	unsigned long		rate_last;	/* rate limiting for ICMP */
-	unsigned int		rate_tokens;
 	int			flags;
 #define DST_HOST		0x0001
 #define DST_NOXFRM		0x0002
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 6e991e0..f0698b9 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -45,7 +45,4 @@ extern int	icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int	icmp_init(void);
 extern void	icmp_out_count(struct net *net, unsigned char type);
 
-/* Move into dst.h ? */
-extern int 	xrlim_allow(struct dst_entry *dst, int timeout);
-
 #endif	/* _ICMP_H */
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 61f2c66..ead2cb2 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -44,6 +44,8 @@ struct inet_peer {
 			__u32		tcp_ts;
 			__u32		tcp_ts_stamp;
 			u32		metrics[RTAX_MAX];
+			u32		rate_tokens;	/* rate limiting for ICMP */
+			unsigned long	rate_last;
 		};
 		struct rcu_head         rcu;
 	};
@@ -81,6 +83,7 @@ static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int cr
 
 /* can be called from BH context or outside */
 extern void inet_putpeer(struct inet_peer *p);
+extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
 
 /*
  * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 4aa1b7f..ad2bcf1 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -233,48 +233,11 @@ static inline void icmp_xmit_unlock(struct sock *sk)
  *	Send an ICMP frame.
  */
 
-/*
- *	Check transmit rate limitation for given message.
- *	The rate information is held in the destination cache now.
- *	This function is generic and could be used for other purposes
- *	too. It uses a Token bucket filter as suggested by Alexey Kuznetsov.
- *
- *	Note that the same dst_entry fields are modified by functions in
- *	route.c too, but these work for packet destinations while xrlim_allow
- *	works for icmp destinations. This means the rate limiting information
- *	for one "ip object" is shared - and these ICMPs are twice limited:
- *	by source and by destination.
- *
- *	RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate
- *			  SHOULD allow setting of rate limits
- *
- * 	Shared between ICMPv4 and ICMPv6.
- */
-#define XRLIM_BURST_FACTOR 6
-int xrlim_allow(struct dst_entry *dst, int timeout)
-{
-	unsigned long now, token = dst->rate_tokens;
-	int rc = 0;
-
-	now = jiffies;
-	token += now - dst->rate_last;
-	dst->rate_last = now;
-	if (token > XRLIM_BURST_FACTOR * timeout)
-		token = XRLIM_BURST_FACTOR * timeout;
-	if (token >= timeout) {
-		token -= timeout;
-		rc = 1;
-	}
-	dst->rate_tokens = token;
-	return rc;
-}
-EXPORT_SYMBOL(xrlim_allow);
-
-static inline int icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
+static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
 		int type, int code)
 {
 	struct dst_entry *dst = &rt->dst;
-	int rc = 1;
+	bool rc = true;
 
 	if (type > NR_ICMP_TYPES)
 		goto out;
@@ -288,8 +251,12 @@ static inline int icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
 		goto out;
 
 	/* Limit if icmp type is enabled in ratemask. */
-	if ((1 << type) & net->ipv4.sysctl_icmp_ratemask)
-		rc = xrlim_allow(dst, net->ipv4.sysctl_icmp_ratelimit);
+	if ((1 << type) & net->ipv4.sysctl_icmp_ratemask) {
+		if (!rt->peer)
+			rt_bind_peer(rt, 1);
+		rc = inet_peer_xrlim_allow(rt->peer,
+					   net->ipv4.sysctl_icmp_ratelimit);
+	}
 out:
 	return rc;
 }
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index b6513b1..709fbb4 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -513,6 +513,8 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
 		atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4));
 		p->tcp_ts_stamp = 0;
 		p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
+		p->rate_tokens = 0;
+		p->rate_last = 0;
 		INIT_LIST_HEAD(&p->unused);
 
 
@@ -580,3 +582,44 @@ void inet_putpeer(struct inet_peer *p)
 	local_bh_enable();
 }
 EXPORT_SYMBOL_GPL(inet_putpeer);
+
+/*
+ *	Check transmit rate limitation for given message.
+ *	The rate information is held in the inet_peer entries now.
+ *	This function is generic and could be used for other purposes
+ *	too. It uses a Token bucket filter as suggested by Alexey Kuznetsov.
+ *
+ *	Note that the same inet_peer fields are modified by functions in
+ *	route.c too, but these work for packet destinations while xrlim_allow
+ *	works for icmp destinations. This means the rate limiting information
+ *	for one "ip object" is shared - and these ICMPs are twice limited:
+ *	by source and by destination.
+ *
+ *	RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate
+ *			  SHOULD allow setting of rate limits
+ *
+ * 	Shared between ICMPv4 and ICMPv6.
+ */
+#define XRLIM_BURST_FACTOR 6
+bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout)
+{
+	unsigned long now, token;
+	bool rc = false;
+
+	if (!peer)
+		return true;
+
+	token = peer->rate_tokens;
+	now = jiffies;
+	token += now - peer->rate_last;
+	peer->rate_last = now;
+	if (token > XRLIM_BURST_FACTOR * timeout)
+		token = XRLIM_BURST_FACTOR * timeout;
+	if (token >= timeout) {
+		token -= timeout;
+		rc = true;
+	}
+	peer->rate_tokens = token;
+	return rc;
+}
+EXPORT_SYMBOL(inet_peer_xrlim_allow);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 0ba6a38..2e225da 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1563,6 +1563,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 {
 	struct rtable *rt = skb_rtable(skb);
 	struct in_device *in_dev;
+	struct inet_peer *peer;
 	int log_martians;
 
 	rcu_read_lock();
@@ -1574,33 +1575,41 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 	log_martians = IN_DEV_LOG_MARTIANS(in_dev);
 	rcu_read_unlock();
 
+	if (!rt->peer)
+		rt_bind_peer(rt, 1);
+	peer = rt->peer;
+	if (!peer) {
+		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
+		return;
+	}
+
 	/* No redirected packets during ip_rt_redirect_silence;
 	 * reset the algorithm.
 	 */
-	if (time_after(jiffies, rt->dst.rate_last + ip_rt_redirect_silence))
-		rt->dst.rate_tokens = 0;
+	if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence))
+		peer->rate_tokens = 0;
 
 	/* Too many ignored redirects; do not send anything
 	 * set dst.rate_last to the last seen redirected packet.
 	 */
-	if (rt->dst.rate_tokens >= ip_rt_redirect_number) {
-		rt->dst.rate_last = jiffies;
+	if (peer->rate_tokens >= ip_rt_redirect_number) {
+		peer->rate_last = jiffies;
 		return;
 	}
 
 	/* Check for load limit; set rate_last to the latest sent
 	 * redirect.
 	 */
-	if (rt->dst.rate_tokens == 0 ||
+	if (peer->rate_tokens == 0 ||
 	    time_after(jiffies,
-		       (rt->dst.rate_last +
-			(ip_rt_redirect_load << rt->dst.rate_tokens)))) {
+		       (peer->rate_last +
+			(ip_rt_redirect_load << peer->rate_tokens)))) {
 		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
-		rt->dst.rate_last = jiffies;
-		++rt->dst.rate_tokens;
+		peer->rate_last = jiffies;
+		++peer->rate_tokens;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
 		if (log_martians &&
-		    rt->dst.rate_tokens == ip_rt_redirect_number &&
+		    peer->rate_tokens == ip_rt_redirect_number &&
 		    net_ratelimit())
 			printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
 				&rt->rt_src, rt->rt_iif,
@@ -1612,7 +1621,9 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 static int ip_error(struct sk_buff *skb)
 {
 	struct rtable *rt = skb_rtable(skb);
+	struct inet_peer *peer;
 	unsigned long now;
+	bool send;
 	int code;
 
 	switch (rt->dst.error) {
@@ -1632,15 +1643,24 @@ static int ip_error(struct sk_buff *skb)
 			break;
 	}
 
-	now = jiffies;
-	rt->dst.rate_tokens += now - rt->dst.rate_last;
-	if (rt->dst.rate_tokens > ip_rt_error_burst)
-		rt->dst.rate_tokens = ip_rt_error_burst;
-	rt->dst.rate_last = now;
-	if (rt->dst.rate_tokens >= ip_rt_error_cost) {
-		rt->dst.rate_tokens -= ip_rt_error_cost;
-		icmp_send(skb, ICMP_DEST_UNREACH, code, 0);
+	if (!rt->peer)
+		rt_bind_peer(rt, 1);
+	peer = rt->peer;
+
+	send = true;
+	if (peer) {
+		now = jiffies;
+		peer->rate_tokens += now - peer->rate_last;
+		if (peer->rate_tokens > ip_rt_error_burst)
+			peer->rate_tokens = ip_rt_error_burst;
+		peer->rate_last = now;
+		if (peer->rate_tokens >= ip_rt_error_cost)
+			peer->rate_tokens -= ip_rt_error_cost;
+		else
+			send = false;
 	}
+	if (send)
+		icmp_send(skb, ICMP_DEST_UNREACH, code, 0);
 
 out:	kfree_skb(skb);
 	return 0;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 03e62f9..a31d91b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,20 +157,20 @@ static int is_ineligible(struct sk_buff *skb)
 /*
  * Check the ICMP output rate limit
  */
-static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type,
-				     struct flowi *fl)
+static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
+				      struct flowi *fl)
 {
 	struct dst_entry *dst;
 	struct net *net = sock_net(sk);
-	int res = 0;
+	bool res = false;
 
 	/* Informational messages are not limited. */
 	if (type & ICMPV6_INFOMSG_MASK)
-		return 1;
+		return true;
 
 	/* Do not limit pmtu discovery, it would break it. */
 	if (type == ICMPV6_PKT_TOOBIG)
-		return 1;
+		return true;
 
 	/*
 	 * Look up the output route.
@@ -182,7 +182,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type,
 		IP6_INC_STATS(net, ip6_dst_idev(dst),
 			      IPSTATS_MIB_OUTNOROUTES);
 	} else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
-		res = 1;
+		res = true;
 	} else {
 		struct rt6_info *rt = (struct rt6_info *)dst;
 		int tmo = net->ipv6.sysctl.icmpv6_time;
@@ -191,7 +191,9 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type,
 		if (rt->rt6i_dst.plen < 128)
 			tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
 
-		res = xrlim_allow(dst, tmo);
+		if (!rt->rt6i_peer)
+			rt6_bind_peer(rt, 1);
+		res = inet_peer_xrlim_allow(rt->rt6i_peer, tmo);
 	}
 	dst_release(dst);
 	return res;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5f8d242..2600e22 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -479,10 +479,13 @@ int ip6_forward(struct sk_buff *skb)
 		else
 			target = &hdr->daddr;
 
+		if (!rt->rt6i_peer)
+			rt6_bind_peer(rt, 1);
+
 		/* Limit redirects both by destination (here)
 		   and by source (inside ndisc_send_redirect)
 		 */
-		if (xrlim_allow(dst, 1*HZ))
+		if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
 			ndisc_send_redirect(skb, n, target);
 	} else {
 		int addrtype = ipv6_addr_type(&hdr->saddr);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2342545..7254ce3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1553,7 +1553,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 			   "ICMPv6 Redirect: destination is not a neighbour.\n");
 		goto release;
 	}
-	if (!xrlim_allow(dst, 1*HZ))
+	if (!rt->rt6i_peer)
+		rt6_bind_peer(rt, 1);
+	if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
 		goto release;
 
 	if (dev->addr_len) {
-- 
1.7.4


^ permalink raw reply related

* [net-next-2.6 PATCH] enic: Decouple mac address registration and deregistration from port profile set operation
From: Roopa Prabhu @ 2011-02-04 22:57 UTC (permalink / raw)
  To: davem; +Cc: netdev

From: Roopa Prabhu <roprabhu@cisco.com>

This patch removes VM mac address registration and deregistration code during
port profile set operation. We can delay mac address registration until
enic_open.

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/enic/enic.h      |    2 +-
 drivers/net/enic/enic_main.c |    6 ------
 2 files changed, 1 insertions(+), 7 deletions(-)


diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index ca3be4f..44865bb 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.2"
+#define DRV_VERSION		"2.1.1.2a"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 89664c6..37f907b 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1381,9 +1381,6 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 
 		if (is_zero_ether_addr(netdev->dev_addr))
 			random_ether_addr(netdev->dev_addr);
-	} else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) {
-		if (!is_zero_ether_addr(enic->pp.mac_addr))
-			enic_dev_del_addr(enic, enic->pp.mac_addr);
 	}
 
 	memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
@@ -1392,9 +1389,6 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 	if (err)
 		goto set_port_profile_cleanup;
 
-	if (!is_zero_ether_addr(enic->pp.mac_addr))
-		enic_dev_add_addr(enic, enic->pp.mac_addr);
-
 set_port_profile_cleanup:
 	memset(enic->pp.vf_mac, 0, ETH_ALEN);
 


^ permalink raw reply related

* [PATCH] ipv4: Don't miss existing cached metrics in new routes.
From: David Miller @ 2011-02-04 22:40 UTC (permalink / raw)
  To: netdev


Always lookup to see if we have an existing inetpeer entry for
a route.  Let FLOWI_FLAG_PRECOW_METRICS merely influence the
"create" argument to rt_bind_peer().

Also, call rt_bind_peer() unconditionally since it is not
possible for rt->peer to be non-NULL at this point.

Signed-off-by: David S. Miller <davem@davemloft.net>
---

Committed to net-next-2.6

 net/ipv4/route.c |   31 +++++++++++++++++--------------
 1 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e4c8165..0ba6a38 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1859,25 +1859,28 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
 
 static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
 {
-	if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) {
-	no_cow:
-		if (fi->fib_metrics != (u32 *) dst_default_metrics) {
-			rt->fi = fi;
-			atomic_inc(&fi->fib_clntref);
-		}
-		dst_init_metrics(&rt->dst, fi->fib_metrics, true);
-	} else {
-		struct inet_peer *peer;
+	struct inet_peer *peer;
+	int create = 0;
 
-		if (!rt->peer)
-			rt_bind_peer(rt, 1);
-		peer = rt->peer;
-		if (!peer)
-			goto no_cow;
+	/* If a peer entry exists for this destination, we must hook
+	 * it up in order to get at cached metrics.
+	 */
+	if (rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)
+		create = 1;
+
+	rt_bind_peer(rt, create);
+	peer = rt->peer;
+	if (peer) {
 		if (inet_metrics_new(peer))
 			memcpy(peer->metrics, fi->fib_metrics,
 			       sizeof(u32) * RTAX_MAX);
 		dst_init_metrics(&rt->dst, peer->metrics, false);
+	} else {
+		if (fi->fib_metrics != (u32 *) dst_default_metrics) {
+			rt->fi = fi;
+			atomic_inc(&fi->fib_clntref);
+		}
+		dst_init_metrics(&rt->dst, fi->fib_metrics, true);
 	}
 }
 
-- 
1.7.4


^ permalink raw reply related

* Re: [PATCH 1/6] sysctl: faster reimplementation of sysctl_check_table
From: Lucian Adrian Grijincu @ 2011-02-04 21:34 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-kernel, netdev, Eric Dumazet, David S. Miller,
	Octavian Purdila
In-Reply-To: <m1vd0zh5eh.fsf@fess.ebiederm.org>

On Fri, Feb 4, 2011 at 11:11 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
>> +static int __sysctl_check_table(struct nsproxy *namespaces,
>> +     struct ctl_table *table, struct ctl_table **parents, int depth)
>>  {
>> +     const char *fail = NULL;
>>       int error = 0;
>> +
>> +     if (depth >= CTL_MAXNAME) {
>
> This should be depth > CTL_MAXNAME.  Because there are only CTL_MAXNAME
> entries in the array.


A bit lower in the array we access 'parents[depth]'.
So the correct check should be (depth >= CTL_MAXNAME) => error.


>> -                     sysctl_check_leaf(namespaces, table, &fail);
>> +                     parents[depth] = table;
>> +                     sysctl_check_leaf(namespaces, table, &fail,
>> +                                       parents, depth);
>>               }

>> +             if (table->child) {
>> +                     parents[depth] = table;
>> +                     error |= __sysctl_check_table(namespaces, table->child,
>> +                                                   parents, depth + 1);
>> +             }



-- 
 .
..: Lucian

^ 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