* [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The only reason cgroup was used, was to be consistent with the populate()
interface. Now that we're getting rid of it, not only we no longer need
it, but we also *can't* call it this way.
Since we will no longer rely on populate(), this will be called from
create(). During create, the association between struct mem_cgroup
and struct cgroup does not yet exist, since cgroup internals hasn't
yet initialized its bookkeeping. This means we would not be able
to draw the memcg pointer from the cgroup pointer in these
functions, which is highly undesirable.
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 24 +++++++++---------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index a6ba1f8..b3ebe6b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,16 +70,16 @@
struct cgroup;
struct cgroup_subsys;
#ifdef CONFIG_NET
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg);
#else
static inline
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -900,9 +900,9 @@ struct proto {
* This function has to setup any files the protocol want to
* appear in the kmem cgroup filesystem.
*/
- int (*init_cgroup)(struct cgroup *cgrp,
+ int (*init_cgroup)(struct mem_cgroup *memcg,
struct cgroup_subsys *ss);
- void (*destroy_cgroup)(struct cgroup *cgrp);
+ void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
};
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 48410ff..7df18bc 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -12,8 +12,8 @@ struct tcp_memcontrol {
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp);
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct mem_cgroup *memcg);
unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
#endif /* _TCP_MEMCG_H */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bef1142..704054d 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,29 +4640,22 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
- /*
- * Part of this would be better living in a separate allocation
- * function, leaving us with just the cgroup tree population work.
- * We, however, depend on state such as network's proto_list that
- * is only initialized after cgroup creation. I found the less
- * cumbersome way to deal with it to defer it all to populate time
- */
- return mem_cgroup_sockets_init(cont, ss);
+ return mem_cgroup_sockets_init(memcg, ss);
};
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
- mem_cgroup_sockets_destroy(cont);
+ mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -5034,7 +5027,7 @@ static void mem_cgroup_destroy(struct cgroup *cont)
{
struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- kmem_cgroup_destroy(cont);
+ kmem_cgroup_destroy(memcg);
mem_cgroup_put(memcg);
}
@@ -5042,7 +5035,8 @@ static void mem_cgroup_destroy(struct cgroup *cont)
static int mem_cgroup_populate(struct cgroup_subsys *ss,
struct cgroup *cont)
{
- return register_kmem_files(cont, ss);
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+ return register_kmem_files(memcg, ss);
}
#ifdef CONFIG_MMU
diff --git a/net/core/sock.c b/net/core/sock.c
index b2e14c0..878f744 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -140,7 +140,7 @@ static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
struct proto *proto;
int ret = 0;
@@ -148,7 +148,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
mutex_lock(&proto_list_mutex);
list_for_each_entry(proto, &proto_list, node) {
if (proto->init_cgroup) {
- ret = proto->init_cgroup(cgrp, ss);
+ ret = proto->init_cgroup(memcg, ss);
if (ret)
goto out;
}
@@ -159,19 +159,19 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
out:
list_for_each_entry_continue_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
return ret;
}
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
struct proto *proto;
mutex_lock(&proto_list_mutex);
list_for_each_entry_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
}
#endif
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 8f1753d..1517037 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -18,7 +18,7 @@ static void memcg_tcp_enter_memory_pressure(struct sock *sk)
}
EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
/*
* The root cgroup does not use res_counters, but rather,
@@ -28,7 +28,6 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
struct res_counter *res_parent = NULL;
struct cg_proto *cg_proto, *parent_cg;
struct tcp_memcontrol *tcp;
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct mem_cgroup *parent = parent_mem_cgroup(memcg);
struct net *net = current->nsproxy->net_ns;
@@ -61,9 +60,8 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
}
EXPORT_SYMBOL(tcp_init_cgroup);
-void tcp_destroy_cgroup(struct cgroup *cgrp)
+void tcp_destroy_cgroup(struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct cg_proto *cg_proto;
struct tcp_memcontrol *tcp;
u64 val;
--
1.7.7.6
^ permalink raw reply related
* [PATCH v3 0/2] get rid of populate for memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A
[ v3: fix bug with failed initialization, seen by Tejun ]
Hi Tejun,
Let me know if the following is acceptable. Turns out the only
operation with a side effect we do after the last failure spot,
is a get on the parent memcg, and the setup of our very own refcnt.
Both of them can be dealt with a mem_cgroup_put in the beginning
of the failure path. So I felt no need for any code reordering.
People from the memcg side, please verify if this is indeed
okay.
I actually tested it with some test code to force memcg_kmem_init()
to fail, and it seems to go all right.
I'll be happy to address any other problems you spot.
Glauber Costa (2):
cgroup: pass struct mem_cgroup instead of struct cgroup to socket
memcg
cgroup: get rid of populate for memcg
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 39 ++++++++++++++++++---------------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 33 insertions(+), 38 deletions(-)
--
1.7.7.6
^ permalink raw reply
* Re: [net-next PATCH v1 0/7] Managing the forwarding database(FDB)
From: John Fastabend @ 2012-04-09 22:32 UTC (permalink / raw)
To: Stephen Hemminger
Cc: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher, netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409151501.23ff83f6@nehalam.linuxnetplumber.net>
On 4/9/2012 3:15 PM, Stephen Hemminger wrote:
> On Mon, 09 Apr 2012 15:00:11 -0700
> John Fastabend <john.r.fastabend@intel.com> wrote:
>
>> The following series is a submission for net-next to allow
>> embedded switches and other stacked devices other then the
>> Linux bridge to manage a forwarding database.
>>
>> This was previously posted here (where it was deferred for
>> more review and testing)
>>
>> http://lists.openwall.net/netdev/2012/03/19/26
>>
>> This series adds macvlan support per discussions with Roopa
>> and Michael. Also ixgbe was updated to support adding multicast
>> addresses per request from Greg Rose.
>>
>> Finally cleanups in the generic dump routines were added
>> for multicast to support ixgbe and macvlan use cases.
>>
>> Thanks to everyone for the helpful review and comments. As
>> always any comments/feedback welcome.
>>
>> .John
>>
>> ---
>>
>> Greg Rose (1):
>> ixgbe: UTA table incorrectly programmed
>>
>> John Fastabend (6):
>> macvlan: add FDB bridge ops and new macvlan mode
>> ixgbe: allow RAR table to be updated in promisc mode
>> ixgbe: enable FDB netdevice ops
>> net: add fdb generic dump routine
>> net: addr_list: add exclusive dev_uc_add and dev_mc_add
>> net: add generic PF_BRIDGE:RTM_ FDB hooks
>>
>>
>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 121 ++++++++++----
>> drivers/net/macvlan.c | 60 ++++++-
>> include/linux/if_link.h | 1
>> include/linux/neighbour.h | 3
>> include/linux/netdevice.h | 28 +++
>> include/linux/rtnetlink.h | 4
>> net/bridge/br_device.c | 3
>> net/bridge/br_fdb.c | 128 ++++-----------
>> net/bridge/br_netlink.c | 12 -
>> net/bridge/br_private.h | 15 +-
>> net/core/dev_addr_lists.c | 97 ++++++++++--
>> net/core/rtnetlink.c | 209 +++++++++++++++++++++++++
>> 12 files changed, 508 insertions(+), 173 deletions(-)
>>
>
> How do statistics work in this case? What if you wanted to do BRIDGE MIB?
I expect we will need to do the same sort of thing for PF_BRIDGE:RTM_GETLINK
to dump the statistics for an embedded or stacked bridge. This series only
gets the forwarding database setup. All the other entries in the MIB still
need to be populated. What I would like is to be able to write a BRIDGE MIB
implementation and have it work with any of the bridging components in the
linux kernel. But I don't think that should block this series.
Make sense?
Based on a quick scan I'm not sure the existing net/bridge code has one place
to pull all the stats from anyways looks like you might have to read some sysfs
entries AND do some netlink commands. I would have to check that though. It is
on my todo list to create a bridge mib for some of the EVB cases. Of course if
someone else got to it that would be great.
.John
^ permalink raw reply
* Re: [net-next PATCH v1 0/7] Managing the forwarding database(FDB)
From: Stephen Hemminger @ 2012-04-09 22:15 UTC (permalink / raw)
To: John Fastabend
Cc: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher, netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
On Mon, 09 Apr 2012 15:00:11 -0700
John Fastabend <john.r.fastabend@intel.com> wrote:
> The following series is a submission for net-next to allow
> embedded switches and other stacked devices other then the
> Linux bridge to manage a forwarding database.
>
> This was previously posted here (where it was deferred for
> more review and testing)
>
> http://lists.openwall.net/netdev/2012/03/19/26
>
> This series adds macvlan support per discussions with Roopa
> and Michael. Also ixgbe was updated to support adding multicast
> addresses per request from Greg Rose.
>
> Finally cleanups in the generic dump routines were added
> for multicast to support ixgbe and macvlan use cases.
>
> Thanks to everyone for the helpful review and comments. As
> always any comments/feedback welcome.
>
> .John
>
> ---
>
> Greg Rose (1):
> ixgbe: UTA table incorrectly programmed
>
> John Fastabend (6):
> macvlan: add FDB bridge ops and new macvlan mode
> ixgbe: allow RAR table to be updated in promisc mode
> ixgbe: enable FDB netdevice ops
> net: add fdb generic dump routine
> net: addr_list: add exclusive dev_uc_add and dev_mc_add
> net: add generic PF_BRIDGE:RTM_ FDB hooks
>
>
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 121 ++++++++++----
> drivers/net/macvlan.c | 60 ++++++-
> include/linux/if_link.h | 1
> include/linux/neighbour.h | 3
> include/linux/netdevice.h | 28 +++
> include/linux/rtnetlink.h | 4
> net/bridge/br_device.c | 3
> net/bridge/br_fdb.c | 128 ++++-----------
> net/bridge/br_netlink.c | 12 -
> net/bridge/br_private.h | 15 +-
> net/core/dev_addr_lists.c | 97 ++++++++++--
> net/core/rtnetlink.c | 209 +++++++++++++++++++++++++
> 12 files changed, 508 insertions(+), 173 deletions(-)
>
How do statistics work in this case? What if you wanted to do BRIDGE MIB?
^ permalink raw reply
* [net-next PATCH v1 7/7] macvlan: add FDB bridge ops and new macvlan mode
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds a new macvlan mode MACVLAN_PASSTHRU_NOPROMISC
this mode acts the same as the original passthru mode _except_
it does not set promiscuous mode on the lowerdev. Because the
lowerdev is not put in promiscuous mode any unicast or multicast
addresses the device should receive must be explicitely added
with the FDB bridge ops. In many use cases the management stack
will know the mac addresses needed (maybe negotiated via EVB/VDP)
or may require only receiving known "good" mac addresses. This
mode with the FDB ops supports this usage model.
This patch is a result of Roopa Prabhu's work. Follow up
patches are needed for VEPA and VEB macvlan modes.
CC: Roopa Prabhu <roprabhu@cisco.com>
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/macvlan.c | 60 ++++++++++++++++++++++++++++++++++++++++++-----
include/linux/if_link.h | 1 +
2 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index b17fc90..9892d8d 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -181,6 +181,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
MACVLAN_MODE_PRIVATE |
MACVLAN_MODE_VEPA |
MACVLAN_MODE_PASSTHRU|
+ MACVLAN_MODE_PASSTHRU_NOPROMISC |
MACVLAN_MODE_BRIDGE);
else if (src->mode == MACVLAN_MODE_VEPA)
/* flood to everyone except source */
@@ -312,7 +313,8 @@ static int macvlan_open(struct net_device *dev)
int err;
if (vlan->port->passthru) {
- dev_set_promiscuity(lowerdev, 1);
+ if (vlan->mode == MACVLAN_MODE_PASSTHRU)
+ dev_set_promiscuity(lowerdev, 1);
goto hash_add;
}
@@ -344,12 +346,15 @@ static int macvlan_stop(struct net_device *dev)
struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
+ dev_uc_unsync(lowerdev, dev);
+ dev_mc_unsync(lowerdev, dev);
+
if (vlan->port->passthru) {
- dev_set_promiscuity(lowerdev, -1);
+ if (vlan->mode == MACVLAN_MODE_PASSTHRU)
+ dev_set_promiscuity(lowerdev, 1);
goto hash_del;
}
- dev_mc_unsync(lowerdev, dev);
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);
@@ -399,10 +404,11 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
}
-static void macvlan_set_multicast_list(struct net_device *dev)
+static void macvlan_set_mac_lists(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ dev_uc_sync(vlan->lowerdev, dev);
dev_mc_sync(vlan->lowerdev, dev);
}
@@ -542,6 +548,43 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
return 0;
}
+static int macvlan_fdb_add(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ int err = -EINVAL;
+
+ if (!vlan->port->passthru)
+ return -EOPNOTSUPP;
+
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_add_excl(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_add_excl(dev, addr);
+
+ return err;
+}
+
+static int macvlan_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ int err = -EINVAL;
+
+ if (!vlan->port->passthru)
+ return -EOPNOTSUPP;
+
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_del(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_del(dev, addr);
+
+ return err;
+}
+
static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
@@ -572,11 +615,14 @@ static const struct net_device_ops macvlan_netdev_ops = {
.ndo_change_mtu = macvlan_change_mtu,
.ndo_change_rx_flags = macvlan_change_rx_flags,
.ndo_set_mac_address = macvlan_set_mac_address,
- .ndo_set_rx_mode = macvlan_set_multicast_list,
+ .ndo_set_rx_mode = macvlan_set_mac_lists,
.ndo_get_stats64 = macvlan_dev_get_stats64,
.ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid,
+ .ndo_fdb_add = macvlan_fdb_add,
+ .ndo_fdb_del = macvlan_fdb_del,
+ .ndo_fdb_dump = ndo_dflt_fdb_dump,
};
void macvlan_common_setup(struct net_device *dev)
@@ -648,6 +694,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
case MACVLAN_MODE_VEPA:
case MACVLAN_MODE_BRIDGE:
case MACVLAN_MODE_PASSTHRU:
+ case MACVLAN_MODE_PASSTHRU_NOPROMISC:
break;
default:
return -EINVAL;
@@ -711,7 +758,8 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
if (data && data[IFLA_MACVLAN_MODE])
vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
- if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
+ if ((vlan->mode == MACVLAN_MODE_PASSTHRU) ||
+ (vlan->mode == MACVLAN_MODE_PASSTHRU_NOPROMISC)) {
if (port->count)
return -EINVAL;
port->passthru = true;
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 2f4fa93..db67b9d 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -265,6 +265,7 @@ enum macvlan_mode {
MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+ MACVLAN_MODE_PASSTHRU_NOPROMISC = 16, /* passthru without promisc */
};
/* SR-IOV virtual function management section */
^ permalink raw reply related
* [net-next PATCH v1 6/7] ixgbe: UTA table incorrectly programmed
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
From: Greg Rose <gregory.v.rose@intel.com>
The UTA table was being set to the functional equivalent of promiscuous
mode. This was resulting in traffic from the virtual function being
flooded onto the wire and the PF device. This resulted in additional
overhead for VF traffic sent to the network and in the case of traffic
sent to the PF or another VF resulted in unwanted packets on the wire.
This was actually not the intended behavior. Now that we can program
the embedded switch correctly we can remove this snippit of code. Users
who want to support this should configure the FDB correctly using the
FDB ops.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 29 -------------------------
1 files changed, 0 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 25a7ed9..10606bd 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2904,33 +2904,6 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
}
-/**
- * ixgbe_set_uta - Set unicast filter table address
- * @adapter: board private structure
- *
- * The unicast table address is a register array of 32-bit registers.
- * The table is meant to be used in a way similar to how the MTA is used
- * however due to certain limitations in the hardware it is necessary to
- * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
- * enable bit to allow vlan tag stripping when promiscuous mode is enabled
- **/
-static void ixgbe_set_uta(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
-
- /* The UTA table only exists on 82599 hardware and newer */
- if (hw->mac.type < ixgbe_mac_82599EB)
- return;
-
- /* we only need to do this if VMDq is enabled */
- if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
- return;
-
- for (i = 0; i < 128; i++)
- IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0);
-}
-
#define IXGBE_MAX_RX_DESC_POLL 10
static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
@@ -3224,8 +3197,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Program registers for the distribution of queues */
ixgbe_setup_mrqc(adapter);
- ixgbe_set_uta(adapter);
-
/* set_rx_buffer_len must be called before ring initialization */
ixgbe_set_rx_buffer_len(adapter);
^ permalink raw reply related
* [net-next PATCH v1 5/7] ixgbe: allow RAR table to be updated in promisc mode
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This allows RAR table updates while in promiscuous. With
SR-IOV enabled it is valuable to allow the RAR table to
be updated even when in promisc mode to configure forwarding
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8b37395..25a7ed9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3462,16 +3462,17 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
}
ixgbe_vlan_filter_enable(adapter);
hw->addr_ctrl.user_set_promisc = false;
- /*
- * Write addresses to available RAR registers, if there is not
- * sufficient space to store all the addresses then enable
- * unicast promiscuous mode
- */
- count = ixgbe_write_uc_addr_list(netdev);
- if (count < 0) {
- fctrl |= IXGBE_FCTRL_UPE;
- vmolr |= IXGBE_VMOLR_ROPE;
- }
+ }
+
+ /*
+ * Write addresses to available RAR registers, if there is not
+ * sufficient space to store all the addresses then enable
+ * unicast promiscuous mode
+ */
+ count = ixgbe_write_uc_addr_list(netdev);
+ if (count < 0) {
+ fctrl |= IXGBE_FCTRL_UPE;
+ vmolr |= IXGBE_VMOLR_ROPE;
}
if (adapter->num_vfs) {
^ permalink raw reply related
* [net-next PATCH v1 4/7] ixgbe: enable FDB netdevice ops
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
Enable FDB ops on ixgbe when in SR-IOV mode.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 71 +++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3e26b1f..8b37395 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6681,6 +6681,74 @@ static int ixgbe_set_features(struct net_device *netdev,
return 0;
}
+static int ixgbe_ndo_fdb_add(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ int err = -EOPNOTSUPP;
+
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ pr_info("%s: FDB only supports static addresses\n",
+ ixgbe_driver_name);
+ return -EINVAL;
+ }
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_add_excl(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_add_excl(dev, addr);
+ else
+ err = -EINVAL;
+ }
+
+ /* Only return duplicate errors if NLM_F_EXCL is set */
+ if (err == -EEXIST && !(flags & NLM_F_EXCL))
+ err = 0;
+
+ return err;
+}
+
+static int ixgbe_ndo_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ int err = -EOPNOTSUPP;
+
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ pr_info("%s: FDB only supports static addresses\n",
+ ixgbe_driver_name);
+ return -EINVAL;
+ }
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_del(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_del(dev, addr);
+ else
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int ixgbe_ndo_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+
+ return idx;
+}
+
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
@@ -6717,6 +6785,9 @@ static const struct net_device_ops ixgbe_netdev_ops = {
#endif /* IXGBE_FCOE */
.ndo_set_features = ixgbe_set_features,
.ndo_fix_features = ixgbe_fix_features,
+ .ndo_fdb_add = ixgbe_ndo_fdb_add,
+ .ndo_fdb_del = ixgbe_ndo_fdb_del,
+ .ndo_fdb_dump = ixgbe_ndo_fdb_dump,
};
static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
^ permalink raw reply related
* [net-next PATCH v1 3/7] net: add fdb generic dump routine
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds a generic dump routine drivers can call. It
should be sufficient to handle any bridging model that
uses the unicast address list. This should be most SR-IOV
enabled NICs.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
net/core/rtnetlink.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d6ce728..2bb4f59 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2088,6 +2088,77 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
return err;
}
+static int nlmsg_populate_fdb(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int *idx,
+ struct netdev_hw_addr_list *list)
+{
+ struct netdev_hw_addr *ha;
+ struct ndmsg *ndm;
+ struct nlmsghdr *nlh;
+ u32 pid, seq;
+
+ pid = NETLINK_CB(cb->skb).pid;
+ seq = cb->nlh->nlmsg_seq;
+
+ list_for_each_entry(ha, &list->list, list) {
+ if (*idx < cb->args[0])
+ goto skip;
+
+ nlh = nlmsg_put(skb, pid, seq,
+ RTM_NEWNEIGH, sizeof(*ndm), NLM_F_MULTI);
+ if (!nlh)
+ break;
+
+ ndm = nlmsg_data(nlh);
+ ndm->ndm_family = AF_BRIDGE;
+ ndm->ndm_pad1 = 0;
+ ndm->ndm_pad2 = 0;
+ ndm->ndm_flags = NTF_SELF;
+ ndm->ndm_type = 0;
+ ndm->ndm_ifindex = dev->ifindex;
+ ndm->ndm_state = NUD_PERMANENT;
+
+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, ha->addr))
+ goto nla_put_failure;
+
+ nlmsg_end(skb, nlh);
+skip:
+ *idx += 1;
+ }
+ return 0;
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -ENOMEM;
+}
+
+/**
+ * ndo_dflt_fdb_dump: default netdevice operation to dump an FDB table.
+ * @nlh: netlink message header
+ * @dev: netdevice
+ *
+ * Default netdevice operation to dump the existing unicast address list.
+ * Returns zero on success.
+ */
+int ndo_dflt_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx)
+{
+ int err;
+
+ netif_addr_lock_bh(dev);
+ err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc);
+ if (err)
+ goto out;
+ nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->mc);
+out:
+ netif_addr_unlock_bh(dev);
+ return idx;
+}
+EXPORT_SYMBOL(ndo_dflt_fdb_dump);
+
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
int idx = 0;
^ permalink raw reply related
* [net-next PATCH v1 2/7] net: addr_list: add exclusive dev_uc_add and dev_mc_add
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds a dev_uc_add_excl() and dev_mc_add_excl() calls
similar to the original dev_{uc|mc}_add() except it sets
the global bit and returns -EEXIST for duplicat entires.
This is useful for drivers that support SR-IOV, macvlan
devices and any other devices that need to manage the
unicast and multicast lists.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/netdevice.h | 2 +
net/core/dev_addr_lists.c | 97 ++++++++++++++++++++++++++++++++++++++-------
2 files changed, 83 insertions(+), 16 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 05822e5..b68a326 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2572,6 +2572,7 @@ extern int dev_addr_init(struct net_device *dev);
/* Functions used for unicast addresses handling */
extern int dev_uc_add(struct net_device *dev, unsigned char *addr);
+extern int dev_uc_add_excl(struct net_device *dev, unsigned char *addr);
extern int dev_uc_del(struct net_device *dev, unsigned char *addr);
extern int dev_uc_sync(struct net_device *to, struct net_device *from);
extern void dev_uc_unsync(struct net_device *to, struct net_device *from);
@@ -2581,6 +2582,7 @@ extern void dev_uc_init(struct net_device *dev);
/* Functions used for multicast addresses handling */
extern int dev_mc_add(struct net_device *dev, unsigned char *addr);
extern int dev_mc_add_global(struct net_device *dev, unsigned char *addr);
+extern int dev_mc_add_excl(struct net_device *dev, unsigned char *addr);
extern int dev_mc_del(struct net_device *dev, unsigned char *addr);
extern int dev_mc_del_global(struct net_device *dev, unsigned char *addr);
extern int dev_mc_sync(struct net_device *to, struct net_device *from);
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 29c07fe..5405e28 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -21,12 +21,35 @@
* General list handling functions
*/
+static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
+ unsigned char *addr, int addr_len,
+ unsigned char addr_type, bool global)
+{
+ struct netdev_hw_addr *ha;
+ int alloc_size;
+
+ alloc_size = sizeof(*ha);
+ if (alloc_size < L1_CACHE_BYTES)
+ alloc_size = L1_CACHE_BYTES;
+ ha = kmalloc(alloc_size, GFP_ATOMIC);
+ if (!ha)
+ return -ENOMEM;
+ memcpy(ha->addr, addr, addr_len);
+ ha->type = addr_type;
+ ha->refcount = 1;
+ ha->global_use = global;
+ ha->synced = false;
+ list_add_tail_rcu(&ha->list, &list->list);
+ list->count++;
+
+ return 0;
+}
+
static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
unsigned char *addr, int addr_len,
unsigned char addr_type, bool global)
{
struct netdev_hw_addr *ha;
- int alloc_size;
if (addr_len > MAX_ADDR_LEN)
return -EINVAL;
@@ -46,21 +69,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
}
}
-
- alloc_size = sizeof(*ha);
- if (alloc_size < L1_CACHE_BYTES)
- alloc_size = L1_CACHE_BYTES;
- ha = kmalloc(alloc_size, GFP_ATOMIC);
- if (!ha)
- return -ENOMEM;
- memcpy(ha->addr, addr, addr_len);
- ha->type = addr_type;
- ha->refcount = 1;
- ha->global_use = global;
- ha->synced = false;
- list_add_tail_rcu(&ha->list, &list->list);
- list->count++;
- return 0;
+ return __hw_addr_create_ex(list, addr, addr_len, addr_type, global);
}
static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr,
@@ -377,6 +386,34 @@ EXPORT_SYMBOL(dev_addr_del_multiple);
*/
/**
+ * dev_uc_add_excl - Add a global secondary unicast address
+ * @dev: device
+ * @addr: address to add
+ */
+int dev_uc_add_excl(struct net_device *dev, unsigned char *addr)
+{
+ struct netdev_hw_addr *ha;
+ int err;
+
+ netif_addr_lock_bh(dev);
+ list_for_each_entry(ha, &dev->uc.list, list) {
+ if (!memcmp(ha->addr, addr, dev->addr_len) &&
+ ha->type == NETDEV_HW_ADDR_T_UNICAST) {
+ err = -EEXIST;
+ goto out;
+ }
+ }
+ err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len,
+ NETDEV_HW_ADDR_T_UNICAST, true);
+ if (!err)
+ __dev_set_rx_mode(dev);
+out:
+ netif_addr_unlock_bh(dev);
+ return err;
+}
+EXPORT_SYMBOL(dev_uc_add_excl);
+
+/**
* dev_uc_add - Add a secondary unicast address
* @dev: device
* @addr: address to add
@@ -501,6 +538,34 @@ EXPORT_SYMBOL(dev_uc_init);
* Multicast list handling functions
*/
+/**
+ * dev_mc_add_excl - Add a global secondary multicast address
+ * @dev: device
+ * @addr: address to add
+ */
+int dev_mc_add_excl(struct net_device *dev, unsigned char *addr)
+{
+ struct netdev_hw_addr *ha;
+ int err;
+
+ netif_addr_lock_bh(dev);
+ list_for_each_entry(ha, &dev->mc.list, list) {
+ if (!memcmp(ha->addr, addr, dev->addr_len) &&
+ ha->type == NETDEV_HW_ADDR_T_UNICAST) {
+ err = -EEXIST;
+ goto out;
+ }
+ }
+ err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len,
+ NETDEV_HW_ADDR_T_UNICAST, true);
+ if (!err)
+ __dev_set_rx_mode(dev);
+out:
+ netif_addr_unlock_bh(dev);
+ return err;
+}
+EXPORT_SYMBOL(dev_mc_add_excl);
+
static int __dev_mc_add(struct net_device *dev, unsigned char *addr,
bool global)
{
^ permalink raw reply related
* [net-next PATCH v1 1/7] net: add generic PF_BRIDGE:RTM_ FDB hooks
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds two new flags NTF_MASTER and NTF_SELF that can
now be used to specify where PF_BRIDGE netlink commands should
be sent. NTF_MASTER sends the commands to the 'dev->master'
device for parsing. Typically this will be the linux net/bridge,
or open-vswitch devices. Also without any flags set the command
will be handled by the master device as well so that current user
space tools continue to work as expected.
The NTF_SELF flag will push the PF_BRIDGE commands to the
device. In the basic example below the commands are then parsed
and programmed in the embedded bridge.
Note if both NTF_SELF and NTF_MASTER bits are set then the
command will be sent to both 'dev->master' and 'dev' this allows
user space to easily keep the embedded bridge and software bridge
in sync.
To support this new net device ops were added to call into
the device and the existing bridging code was refactored
to use these. There should be no required changes in user space
to support the current bridge behavior.
A basic setup with a SR-IOV enabled NIC looks like this,
veth0 veth2
| |
------------
| bridge0 | <---- software bridging
------------
/
/
ethx.y ethx
VF PF
\ \ <---- propagate FDB entries to HW
\ \
--------------------
| Embedded Bridge | <---- hardware offloaded switching
--------------------
In this case the embedded bridge must be managed to allow 'veth0'
to communicate with 'ethx.y' correctly. At present drivers managing
the embedded bridge either send frames onto the network which
then get dropped by the switch OR the embedded bridge will flood
these frames. With this patch we have a mechanism to manage the
embedded bridge correctly from user space. This example is specific
to SR-IOV but replacing the VF with another PF or dropping this
into the DSA framework generates similar management issues.
Examples session using the 'br'[1] tool to add, dump and then
delete a mac address with a new "embedded" option and enabled
ixgbe driver:
# br fdb add 22:35:19:ac:60:59 dev eth3
# br fdb
port mac addr flags
veth0 22:35:19:ac:60:58 static
veth0 9a:5f:81:f7:f6:ec local
eth3 00:1b:21:55:23:59 local
eth3 22:35:19:ac:60:59 static
veth0 22:35:19:ac:60:57 static
#br fdb add 22:35:19:ac:60:59 embedded dev eth3
#br fdb
port mac addr flags
veth0 22:35:19:ac:60:58 static
veth0 9a:5f:81:f7:f6:ec local
eth3 00:1b:21:55:23:59 local
eth3 22:35:19:ac:60:59 static
veth0 22:35:19:ac:60:57 static
eth3 22:35:19:ac:60:59 local embedded
#br fdb del 22:35:19:ac:60:59 embedded dev eth3
I added a couple lines to 'br' to set the flags correctly is all. It
is my opinion that the merit of this patch is now embedded and SW
bridges can both be modeled correctly in user space using very nearly
the same message passing.
[1] 'br' tool was published as an RFC here and will be renamed 'bridge'
http://patchwork.ozlabs.org/patch/117664/
Thanks to Jamal Hadi Salim, Stephen Hemminger and Ben Hutchings for
valuable feedback, suggestions, and review.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/neighbour.h | 3 +
include/linux/netdevice.h | 26 ++++++++
include/linux/rtnetlink.h | 4 +
net/bridge/br_device.c | 3 +
net/bridge/br_fdb.c | 128 ++++++++++--------------------------------
net/bridge/br_netlink.c | 12 ----
net/bridge/br_private.h | 15 ++++-
net/core/rtnetlink.c | 138 +++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 217 insertions(+), 112 deletions(-)
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h
index b188f68..275e5d6 100644
--- a/include/linux/neighbour.h
+++ b/include/linux/neighbour.h
@@ -33,6 +33,9 @@ enum {
#define NTF_PROXY 0x08 /* == ATF_PUBL */
#define NTF_ROUTER 0x80
+#define NTF_SELF 0x02
+#define NTF_MASTER 0x04
+
/*
* Neighbor Cache Entry States.
*/
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1f77540..05822e5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -54,6 +54,7 @@
#include <net/netprio_cgroup.h>
#include <linux/netdev_features.h>
+#include <linux/neighbour.h>
struct netpoll_info;
struct device;
@@ -905,6 +906,19 @@ struct netdev_fcoe_hbainfo {
* feature set might be less than what was returned by ndo_fix_features()).
* Must return >0 or -errno if it changed dev->features itself.
*
+ * int (*ndo_fdb_add)(struct ndmsg *ndm, struct net_device *dev,
+ * unsigned char *addr, u16 flags)
+ * Adds an FDB entry to dev for addr. The ndmsg contains flags to indicate
+ * if the dev->master FDB should be updated or the devices internal FDB.
+ * int (*ndo_fdb_del)(struct ndmsg *ndm, struct net_device *dev,
+ * unsigned char *addr)
+ * Deletes the FDB entry from dev coresponding to addr. The ndmsg
+ * contains flags to indicate if the dev->master FDB should be
+ * updated or the devices internal FDB.
+ * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
+ * struct net_device *dev, int idx)
+ * Used to add FDB entries to dump requests. Implementers should add
+ * entries to skb and update idx with the number of entries.
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -1002,6 +1016,18 @@ struct net_device_ops {
netdev_features_t features);
int (*ndo_neigh_construct)(struct neighbour *n);
void (*ndo_neigh_destroy)(struct neighbour *n);
+
+ int (*ndo_fdb_add)(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags);
+ int (*ndo_fdb_del)(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr);
+ int (*ndo_fdb_dump)(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx);
};
/*
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 577592e..2c1de89 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -801,6 +801,10 @@ rtattr_failure:
return table;
}
+extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx);
#endif /* __KERNEL__ */
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index ba829de..d6e5929 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -317,6 +317,9 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_add_slave = br_add_slave,
.ndo_del_slave = br_del_slave,
.ndo_fix_features = br_fix_features,
+ .ndo_fdb_add = br_fdb_add,
+ .ndo_fdb_del = br_fdb_delete,
+ .ndo_fdb_dump = br_fdb_dump,
};
static void br_dev_free(struct net_device *dev)
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 80dbce4..5945c54 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -535,44 +535,38 @@ errout:
}
/* Dump information about entries, in response to GETNEIGH */
-int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
+int br_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx)
{
- struct net *net = sock_net(skb->sk);
- struct net_device *dev;
- int idx = 0;
-
- rcu_read_lock();
- for_each_netdev_rcu(net, dev) {
- struct net_bridge *br = netdev_priv(dev);
- int i;
-
- if (!(dev->priv_flags & IFF_EBRIDGE))
- continue;
+ struct net_bridge *br = netdev_priv(dev);
+ int i;
- for (i = 0; i < BR_HASH_SIZE; i++) {
- struct hlist_node *h;
- struct net_bridge_fdb_entry *f;
+ if (!(dev->priv_flags & IFF_EBRIDGE))
+ goto out;
- hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) {
- if (idx < cb->args[0])
- goto skip;
+ for (i = 0; i < BR_HASH_SIZE; i++) {
+ struct hlist_node *h;
+ struct net_bridge_fdb_entry *f;
- if (fdb_fill_info(skb, br, f,
- NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq,
- RTM_NEWNEIGH,
- NLM_F_MULTI) < 0)
- break;
+ hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) {
+ if (idx < cb->args[0])
+ goto skip;
+
+ if (fdb_fill_info(skb, br, f,
+ NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq,
+ RTM_NEWNEIGH,
+ NLM_F_MULTI) < 0)
+ break;
skip:
- ++idx;
- }
+ ++idx;
}
}
- rcu_read_unlock();
-
- cb->args[0] = idx;
- return skb->len;
+out:
+ return idx;
}
/* Update (create or replace) forwarding database entry */
@@ -614,43 +608,11 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
}
/* Add new permanent fdb entry with RTM_NEWNEIGH */
-int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+int br_fdb_add(struct ndmsg *ndm, struct net_device *dev,
+ unsigned char *addr, u16 nlh_flags)
{
- struct net *net = sock_net(skb->sk);
- struct ndmsg *ndm;
- struct nlattr *tb[NDA_MAX+1];
- struct net_device *dev;
struct net_bridge_port *p;
- const __u8 *addr;
- int err;
-
- ASSERT_RTNL();
- err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
- if (err < 0)
- return err;
-
- ndm = nlmsg_data(nlh);
- if (ndm->ndm_ifindex == 0) {
- pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n");
- return -EINVAL;
- }
-
- dev = __dev_get_by_index(net, ndm->ndm_ifindex);
- if (dev == NULL) {
- pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n");
- return -ENODEV;
- }
-
- if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
- pr_info("bridge: RTM_NEWNEIGH with invalid address\n");
- return -EINVAL;
- }
-
- addr = nla_data(tb[NDA_LLADDR]);
- if (!is_valid_ether_addr(addr)) {
- pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
- return -EINVAL;
- }
+ int err = 0;
if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
@@ -670,14 +632,14 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
rcu_read_unlock();
} else {
spin_lock_bh(&p->br->hash_lock);
- err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags);
+ err = fdb_add_entry(p, addr, ndm->ndm_state, nlh_flags);
spin_unlock_bh(&p->br->hash_lock);
}
return err;
}
-static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
+static int fdb_delete_by_addr(struct net_bridge_port *p, u8 *addr)
{
struct net_bridge *br = p->br;
struct hlist_head *head = &br->hash[br_mac_hash(addr)];
@@ -692,40 +654,12 @@ static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
}
/* Remove neighbor entry with RTM_DELNEIGH */
-int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+int br_fdb_delete(struct ndmsg *ndm, struct net_device *dev,
+ unsigned char *addr)
{
- struct net *net = sock_net(skb->sk);
- struct ndmsg *ndm;
struct net_bridge_port *p;
- struct nlattr *llattr;
- const __u8 *addr;
- struct net_device *dev;
int err;
- ASSERT_RTNL();
- if (nlmsg_len(nlh) < sizeof(*ndm))
- return -EINVAL;
-
- ndm = nlmsg_data(nlh);
- if (ndm->ndm_ifindex == 0) {
- pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n");
- return -EINVAL;
- }
-
- dev = __dev_get_by_index(net, ndm->ndm_ifindex);
- if (dev == NULL) {
- pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n");
- return -ENODEV;
- }
-
- llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
- if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
- pr_info("bridge: RTM_DELNEIGH with invalid address\n");
- return -EINVAL;
- }
-
- addr = nla_data(llattr);
-
p = br_port_get_rtnl(dev);
if (p == NULL) {
pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 346b368..1fa0535 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -232,18 +232,6 @@ int __init br_netlink_init(void)
br_rtm_setlink, NULL, NULL);
if (err)
goto err3;
- err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH,
- br_fdb_add, NULL, NULL);
- if (err)
- goto err3;
- err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH,
- br_fdb_delete, NULL, NULL);
- if (err)
- goto err3;
- err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH,
- NULL, br_fdb_dump, NULL);
- if (err)
- goto err3;
return 0;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 0b67a63..929b9f6 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -363,9 +363,18 @@ extern int br_fdb_insert(struct net_bridge *br,
extern void br_fdb_update(struct net_bridge *br,
struct net_bridge_port *source,
const unsigned char *addr);
-extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb);
-extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
-extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
+
+extern int br_fdb_delete(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr);
+extern int br_fdb_add(struct ndmsg *nlh,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 nlh_flags);
+extern int br_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx);
/* br_forward.c */
extern void br_deliver(const struct net_bridge_port *to,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b76f8fa..d6ce728 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -35,7 +35,9 @@
#include <linux/security.h>
#include <linux/mutex.h>
#include <linux/if_addr.h>
+#include <linux/if_bridge.h>
#include <linux/pci.h>
+#include <linux/etherdevice.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -1979,6 +1981,138 @@ errout:
rtnl_set_sk_err(net, RTNLGRP_LINK, err);
}
+static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ndmsg *ndm;
+ struct nlattr *tb[NDA_MAX+1];
+ struct net_device *dev;
+ u8 *addr;
+ int err;
+
+ err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
+ if (err < 0)
+ return err;
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex == 0) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex\n");
+ return -EINVAL;
+ }
+
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid address\n");
+ return -EINVAL;
+ }
+
+ addr = nla_data(tb[NDA_LLADDR]);
+ if (!is_valid_ether_addr(addr)) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n");
+ return -EINVAL;
+ }
+
+ err = -EOPNOTSUPP;
+
+ /* Support fdb on master device the net/bridge default case */
+ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
+ (dev->priv_flags & IFF_BRIDGE_PORT)) {
+ struct net_device *master = dev->master;
+
+ if (master->netdev_ops->ndo_fdb_add)
+ err = master->netdev_ops->ndo_fdb_add(ndm, dev, addr,
+ nlh->nlmsg_flags);
+ }
+
+ /* Embedded bridge, macvlan, and any other device support */
+ if ((ndm->ndm_flags & NTF_SELF) &&
+ dev->netdev_ops->ndo_fdb_add)
+ err = dev->netdev_ops->ndo_fdb_add(ndm, dev, addr,
+ nlh->nlmsg_flags);
+
+ return err;
+}
+
+static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ndmsg *ndm;
+ struct nlattr *llattr;
+ struct net_device *dev;
+ int err = -EINVAL;
+ __u8 *addr;
+
+ if (nlmsg_len(nlh) < sizeof(*ndm))
+ return -EINVAL;
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex == 0) {
+ pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n");
+ return -EINVAL;
+ }
+
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ pr_info("PF_BRIDGE: RTM_DELNEIGH with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
+ if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
+ pr_info("PF_BRIGDE: RTM_DELNEIGH with invalid address\n");
+ return -EINVAL;
+ }
+
+ addr = nla_data(llattr);
+ err = -EOPNOTSUPP;
+
+ /* Support fdb on master device the net/bridge default case */
+ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
+ (dev->priv_flags & IFF_BRIDGE_PORT)) {
+ struct net_device *master = dev->master;
+
+ if (master->netdev_ops->ndo_fdb_del)
+ err = master->netdev_ops->ndo_fdb_del(ndm, dev, addr);
+ }
+
+ /* Embedded bridge, macvlan, and any other device support */
+ if ((ndm->ndm_flags & NTF_SELF) &&
+ dev->netdev_ops->ndo_fdb_del)
+ err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr);
+
+ return err;
+}
+
+static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int idx = 0;
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+
+ rcu_read_lock();
+ for_each_netdev_rcu(net, dev) {
+ if (dev->priv_flags & IFF_BRIDGE_PORT) {
+ struct net_device *master = dev->master;
+ const struct net_device_ops *ops = master->netdev_ops;
+
+ if (ops->ndo_fdb_dump)
+ idx = ops->ndo_fdb_dump(skb, cb, dev, idx);
+ }
+
+ if (dev->netdev_ops->ndo_fdb_dump)
+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
+ }
+ rcu_read_unlock();
+
+ cb->args[0] = idx;
+ return skb->len;
+}
+
/* Protected by RTNL sempahore. */
static struct rtattr **rta_buf;
static int rtattr_max;
@@ -2151,5 +2285,9 @@ void __init rtnetlink_init(void)
rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL);
rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL);
+
+ rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
+ rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
+ rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
}
^ permalink raw reply related
* [net-next PATCH v1 0/7] Managing the forwarding database(FDB)
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
The following series is a submission for net-next to allow
embedded switches and other stacked devices other then the
Linux bridge to manage a forwarding database.
This was previously posted here (where it was deferred for
more review and testing)
http://lists.openwall.net/netdev/2012/03/19/26
This series adds macvlan support per discussions with Roopa
and Michael. Also ixgbe was updated to support adding multicast
addresses per request from Greg Rose.
Finally cleanups in the generic dump routines were added
for multicast to support ixgbe and macvlan use cases.
Thanks to everyone for the helpful review and comments. As
always any comments/feedback welcome.
.John
---
Greg Rose (1):
ixgbe: UTA table incorrectly programmed
John Fastabend (6):
macvlan: add FDB bridge ops and new macvlan mode
ixgbe: allow RAR table to be updated in promisc mode
ixgbe: enable FDB netdevice ops
net: add fdb generic dump routine
net: addr_list: add exclusive dev_uc_add and dev_mc_add
net: add generic PF_BRIDGE:RTM_ FDB hooks
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 121 ++++++++++----
drivers/net/macvlan.c | 60 ++++++-
include/linux/if_link.h | 1
include/linux/neighbour.h | 3
include/linux/netdevice.h | 28 +++
include/linux/rtnetlink.h | 4
net/bridge/br_device.c | 3
net/bridge/br_fdb.c | 128 ++++-----------
net/bridge/br_netlink.c | 12 -
net/bridge/br_private.h | 15 +-
net/core/dev_addr_lists.c | 97 ++++++++++--
net/core/rtnetlink.c | 209 +++++++++++++++++++++++++
12 files changed, 508 insertions(+), 173 deletions(-)
--
Signature
^ permalink raw reply
* Re: [PATCH net-next] rtnetlink: fix spelling errors
From: Ben Hutchings @ 2012-04-09 22:09 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20120409132756.32daeaa6@nehalam.linuxnetplumber.net>
On Mon, 2012-04-09 at 13:27 -0700, Stephen Hemminger wrote:
> Minor spelling mistakes.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> --- a/include/net/rtnetlink.h 2012-02-27 08:43:02.400935781 -0800
> +++ b/include/net/rtnetlink.h 2012-04-09 13:24:02.705034830 -0700
> @@ -41,7 +41,7 @@ static inline int rtnl_msg_family(const
> * @get_size: Function to calculate required room for dumping device
> * specific netlink attributes
> * @fill_info: Function to dump device specific netlink attributes
> - * @get_xstats_size: Function to calculate required room for dumping devic
> + * @get_xstats_size: Function to calculate required room for dumping device
> * specific statistics
> * @fill_xstats: Function to dump device specific statistics
> */
> @@ -94,7 +94,7 @@ extern void rtnl_link_unregister(struct
> * @fill_link_af: Function to fill IFLA_AF_SPEC with address family
> * specific netlink attributes.
> * @get_link_af_size: Function to calculate size of address family specific
> - * netlink attributes exlusive the container attribute.
> + * netlink attributes exclusive the container attribute.
[...]
That's now a real word but it's not grammatically correct; 'exclusive
the' should be changed to 'exclusive of the' or 'excluding the'.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 6/6] tilegx network driver: initial support
From: Chris Metcalf @ 2012-04-09 21:30 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-kernel, netdev
In-Reply-To: <201204091349.54484.arnd@arndb.de>
On 4/9/2012 9:49 AM, Arnd Bergmann wrote:
> On Friday 06 April 2012, Chris Metcalf wrote:
>> This change adds support for the tilegx network driver based on the
>> GXIO IORPC support in the tilegx software stack, using the on-chip
>> mPIPE packet processing engine.
>>
>> Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
>> ---
>> drivers/net/ethernet/tile/Kconfig | 1 +
>> drivers/net/ethernet/tile/Makefile | 4 +-
>> drivers/net/ethernet/tile/tilegx.c | 2045 ++++++++++++++++++++++++++++++++++++
>> 3 files changed, 2048 insertions(+), 2 deletions(-)
>> create mode 100644 drivers/net/ethernet/tile/tilegx.c
> I think the directory name should be the company, not the architecture here, so make
> it drivers/net/ethernet/tilera/tilegx.c instead.
This path was picked back when Jeff Kirsher did the initial move into
drivers/net/ethernet/ for the tilepro driver. I don't have too strong an
opinion on this; at this point I'm mostly just concerned that it seems like
potentially not worth the churn to move the files for 3.2, then again for
3.5. But if folks agree we should do it, it's fine with me.
We can put that in a separate change so it sweeps up the tilepro ethernet
support as well, which is otherwise not involved in this change series.
>> +MODULE_AUTHOR("Tilera");
>> +MODULE_LICENSE("GPL");
>> +
> MODULE_AUTHOR is normally a real person with an email address.
The actual author would rather not publish his name (I just double-checked
with him). I didn't write this module, so it doesn't seem right to use my
name. I did change it to "Tilera Corporation" just because that seems a
bit better. I did a sweep and turned up a fair number of other similar
uses in our internal code and for now made them all "Tilera Corporation",
but I've encouraged our OS developers to consider using their names on
driver code they are writing, so some drivers coming from Tilera may carry
full names in the future.
>> +/* Statistics counters for a specific cpu and device. */
>> +struct tile_net_stats_t {
>> + u32 rx_packets;
>> + u32 rx_bytes;
>> + u32 tx_packets;
>> + u32 tx_bytes;
>> +};
> I think you need to drop the _t postfix here, which presumably comes
> from converting it from a typedef.
Fixed.
>> +/* The actual devices. */
>> +static struct net_device *tile_net_devs[TILE_NET_DEVS];
>> +
>> +/* The device for a given channel. HACK: We use "32", not
>> + * TILE_NET_CHANNELS, because it is fairly subtle that the 5 bit
>> + * "idesc.channel" field never exceeds TILE_NET_CHANNELS.
>> + */
>> +static struct net_device *tile_net_devs_for_channel[32];
> When you need to keep a list or array of device structures in a driver, you're
> usually doing something very wrong. The convention is to just pass the pointer
> around to where you need it.
We need "tile_net_devs_for_channel" because we share a single hardware
queue for all devices, and each packet's metadata contains a "channel"
value which indicates the device.
>> +
>> +/* Convert a "buffer ptr" into a "buffer cpa". */
>> +static inline void *buf_to_cpa(void *buf)
>> +{
>> + return (void *)__pa(buf);
>> +}
>> +
>> +
>> +/* Convert a "buffer cpa" into a "buffer ptr". */
>> +static inline void *cpa_to_buf(void *cpa)
>> +{
>> + return (void *)__va(cpa);
>> +}
> This is almost certainly wrong: The type returned by __pa is a phys_addr_t,
> which cannot be dereferenced like a pointer. On normal drivers, you would
> use dma_map_single()/dma_unmap_single() to get a token that can get
> passed into a dma engine. From what I can tell, this device is directly mapped,
> while your PCI uses an IOMMU, so that would require two different
> implementations of dma mapping operations.
Well, it's right, but ridiculously confusing. What I've done today is
eliminate these two functions, and add the following code in <asm/io.h>:
/*
* The on-chip I/O hardware on tilegx is configured with VA=PA for the
* kernel's PA range. The low-level APIs and field names use "va" and
* "void *" nomenclature, to be consistent with the general notion
* that the addresses in question are virtualizable, but in the kernel
* context we are actually manipulating PA values. To allow readers
* of the code to understand what's happening, we direct their
* attention to this comment by using the following two no-op functions.
*/
static inline unsigned long pa_to_tile_io_addr(phys_addr_t pa)
{
BUILD_BUG_ON(sizeof(phys_addr_t) != sizeof(unsigned long));
return pa;
}
static inline phys_addr_t tile_io_addr_to_pa(unsigned long tile_io_addr)
{
return tile_io_addr;
}
Then the individual uses in the network driver are just things like
"edesc_head.va = pa_to_tile_io_addr(__pa(va))" or "va =
__va(tile_io_addr_to_pa((unsigned long)gxio_mpipe_idesc_get_va(idesc)))"
which I think is a little clearer.
>> +/* Allocate and push a buffer. */
>> +static bool tile_net_provide_buffer(bool small)
>> +{
>> [...]
>> +
>> + /* Save a back-pointer to 'skb'. */
>> + *(struct sk_buff **)(skb->data - sizeof(struct sk_buff **)) = skb;
> This looks very wrong: why would you put the pointer to the skb into the
> skb itself?
Because we create skbuffs, and then feed the raw underlying buffer storage
to our hardware, and later, we get back this raw pointer from hardware,
from which we need to be able to extract the actual skbuff.
>> + /* Make sure "skb" and the back-pointer have been flushed. */
>> + __insn_mf();
> Try to use archicture independent names for flush operations like this
> to make it more readable. I assume this should be smp_wmb()?
Done, though it's just wmb() here, since we're fencing against the I/O
hardware, not against other cores.
>> +
>> + /* Compute the "ip checksum". */
>> + jsum = isum_hack + htons(s_len - eh_len) + htons(id);
>> + jsum = __insn_v2sadu(jsum, 0);
>> + jsum = __insn_v2sadu(jsum, 0);
>> + jsum = (0xFFFF ^ jsum);
>> + jh->check = jsum;
>> +
>> + /* Update the tcp "seq". */
>> + uh->seq = htonl(seq);
>> +
>> + /* Update some flags. */
>> + if (!final)
>> + uh->fin = uh->psh = 0;
>> +
>> + /* Compute the tcp pseudo-header checksum. */
>> + usum = tsum_hack + htons(s_len);
>> + usum = __insn_v2sadu(usum, 0);
>> + usum = __insn_v2sadu(usum, 0);
>> + uh->check = usum;
> Why to you open-code the ip checksum functions here? Normally the stack takes
> care of this by calling the functions you already provide in
> arch/tile/lib/checksum.c
If there is a way to do TSO without this, we'd be happy to hear it, but
it's not clear how it would be possible. We are only computing a PARTIAL
checksum here, and letting the hardware compute the "full" checksum.
Thanks!
--
Chris Metcalf, Tilera Corp.
http://www.tilera.com
^ permalink raw reply
* RE: [PATCH 06/26] bna: remove redundant NULL test before release_firmware()
From: Rasesh Mody @ 2012-04-09 21:14 UTC (permalink / raw)
To: Jesper Juhl, linux-kernel@vger.kernel.org
Cc: trivial@kernel.org, netdev@vger.kernel.org
In-Reply-To: <alpine.LNX.2.00.1204092210470.13925@swampdragon.chaosbits.net>
>From: Jesper Juhl [mailto:jj@chaosbits.net]
>Sent: Monday, April 09, 2012 1:50 PM
>To: linux-kernel@vger.kernel.org
>
>release_firmware() does its own NULL test so explicit test before call
>is unneeded.
>
>Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Thanks Jesper!
Acked-by: Rasesh Mody <rmody@brocade.com>
^ permalink raw reply
* Re: [PATCH 04/26] typhoon: get rid of redundant conditional before all to release_firmware()
From: David Dillow @ 2012-04-09 21:03 UTC (permalink / raw)
To: Jesper Juhl; +Cc: linux-kernel, trivial, netdev
In-Reply-To: <alpine.LNX.2.00.1204092208140.13925@swampdragon.chaosbits.net>
On Mon, 2012-04-09 at 22:50 +0200, Jesper Juhl wrote:
> There's no need to test for a NULL pointer before calling
> release_firmware() since the function does that check itself, so
> remove the redundant test.
>
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>
FWIW on a trivial patch,
Acked-by: David Dillow <dave@thedillows.org>
^ permalink raw reply
* RE: [PATCH 14/26] wireless, mwifiex: drop redundant NULL test before call to release_firmware()
From: Bing Zhao @ 2012-04-09 20:59 UTC (permalink / raw)
To: Jesper Juhl, linux-kernel@vger.kernel.org
Cc: trivial@kernel.org, netdev@vger.kernel.org,
linux-wireless@vger.kernel.org, John W. Linville
In-Reply-To: <alpine.LNX.2.00.1204092224080.13925@swampdragon.chaosbits.net>
Hi Jesper,
Thanks for the patch.
> Since release_firmware() does its own test for NULL it is redundant to
> do so before calling it.
>
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Acked-by: Bing Zhao <bzhao@marvell.com>
Thanks,
Bing
> ---
> drivers/net/wireless/mwifiex/main.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
> index 9d1b3ca..2ee6162 100644
> --- a/drivers/net/wireless/mwifiex/main.c
> +++ b/drivers/net/wireless/mwifiex/main.c
> @@ -342,8 +342,7 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
> ret = 0;
>
> done:
> - if (adapter->firmware)
> - release_firmware(adapter->firmware);
> + release_firmware(adapter->firmware);
> if (ret)
> ret = -1;
> return ret;
> --
> 1.7.10
>
>
> --
> Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
> Don't top-post http://www.catb.org/jargon/html/T/top-post.html
> Plain text mails only, please.
^ permalink raw reply
* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
From: Ryan Ware @ 2012-04-09 20:58 UTC (permalink / raw)
To: Markus Gutschke, Will Drewry
Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa, mingo,
oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn,
djm, scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
keescook, jmorris
In-Reply-To: <CAE6n16kMv5Y+Cp9XZ=tmK0sgoJJZ6CJUq_ttuNEUMb4JFXJ33g@mail.gmail.com>
I second this! They are extremely useful.
Ryan
On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>No matter what you do, please leave the samples accessible somewhere.
>They proved incredibly useful in figuring out how the API works. I am
>sure, other developers are going to appreciate them as well.
>
>Alternatively, if you don't want to include the samples with the
>kernel sources, figure out how you can include a sample in the
>official manual page for prctl().
>
>
>Markus
>--
>To unsubscribe from this list: send the line "unsubscribe
>linux-security-module" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 26/26] ipw2100: remove a redundant NULL check before calling release_firmware()
From: Jesper Juhl @ 2012-04-09 20:52 UTC (permalink / raw)
To: linux-kernel
Cc: trivial, netdev, linux-wireless, John W. Linville,
Stanislav Yakovlev
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
The release_firmware() function does its own NULL test so a test
before calling it is rather redundant.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/ipw2x00/ipw2100.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index f0551f8..d8d804e 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -8508,8 +8508,7 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
struct ipw2100_fw *fw)
{
fw->version = 0;
- if (fw->fw_entry)
- release_firmware(fw->fw_entry);
+ release_firmware(fw->fw_entry);
fw->fw_entry = NULL;
}
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* [PATCH 15/26] wireless, orinoco: release_firmware() tests for NULL, remove explicit tests before calls
From: Jesper Juhl @ 2012-04-09 20:51 UTC (permalink / raw)
To: linux-kernel
Cc: trivial, netdev, linux-wireless, Pavel Roskin, Paul Gortmaker,
John W. Linville
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
It is redundant to test for NULL pointers before calling
release_firmware() since the function does its own NULL test.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/orinoco/fw.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 4df8cf6..400a352 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -379,11 +379,8 @@ void orinoco_cache_fw(struct orinoco_private *priv, int ap)
void orinoco_uncache_fw(struct orinoco_private *priv)
{
- if (priv->cached_pri_fw)
- release_firmware(priv->cached_pri_fw);
- if (priv->cached_fw)
- release_firmware(priv->cached_fw);
-
+ release_firmware(priv->cached_pri_fw);
+ release_firmware(priv->cached_fw);
priv->cached_pri_fw = NULL;
priv->cached_fw = NULL;
}
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* [PATCH 14/26] wireless, mwifiex: drop redundant NULL test before call to release_firmware()
From: Jesper Juhl @ 2012-04-09 20:51 UTC (permalink / raw)
To: linux-kernel; +Cc: trivial, netdev, linux-wireless, John W. Linville, Bing Zhao
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
Since release_firmware() does its own test for NULL it is redundant to
do so before calling it.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/mwifiex/main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 9d1b3ca..2ee6162 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -342,8 +342,7 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
ret = 0;
done:
- if (adapter->firmware)
- release_firmware(adapter->firmware);
+ release_firmware(adapter->firmware);
if (ret)
ret = -1;
return ret;
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* [PATCH 13/26] wireless, libertas: remove redundant NULL tests before calling release_firmware()
From: Jesper Juhl @ 2012-04-09 20:51 UTC (permalink / raw)
To: linux-kernel
Cc: trivial, netdev, linux-wireless, libertas-dev, John W. Linville,
Dan Williams
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
release_firmware() tests for, and deals gracefully with, NULL
pointers. Remove redundant explicit tests before calling the function.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/libertas/if_cs.c | 6 ++----
drivers/net/wireless/libertas/if_sdio.c | 6 ++----
drivers/net/wireless/libertas/if_spi.c | 6 ++----
drivers/net/wireless/libertas/main.c | 12 ++++--------
4 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 234ee88..171a06b 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -951,10 +951,8 @@ out2:
out1:
pcmcia_disable_device(p_dev);
out:
- if (helper)
- release_firmware(helper);
- if (mainfw)
- release_firmware(mainfw);
+ release_firmware(helper);
+ release_firmware(mainfw);
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 9804ebc..15bfe2f 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -751,10 +751,8 @@ success:
ret = 0;
out:
- if (helper)
- release_firmware(helper);
- if (mainfw)
- release_firmware(mainfw);
+ release_firmware(helper);
+ release_firmware(mainfw);
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 50b1ee7..7a5df4f 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1095,10 +1095,8 @@ static int if_spi_init_card(struct if_spi_card *card)
goto out;
out:
- if (helper)
- release_firmware(helper);
- if (mainfw)
- release_firmware(mainfw);
+ release_firmware(helper);
+ release_firmware(mainfw);
lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 957681d..3b81b70 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1269,14 +1269,10 @@ int lbs_get_firmware(struct device *dev, const char *user_helper,
fail:
/* Failed */
- if (*helper) {
- release_firmware(*helper);
- *helper = NULL;
- }
- if (*mainfw) {
- release_firmware(*mainfw);
- *mainfw = NULL;
- }
+ release_firmware(*helper);
+ *helper = NULL;
+ release_firmware(*mainfw);
+ *mainfw = NULL;
return -ENOENT;
}
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* [PATCH 12/26] ipw2200: remove a redundant NULL check before calling release_firmware()
From: Jesper Juhl @ 2012-04-09 20:51 UTC (permalink / raw)
To: linux-kernel
Cc: trivial, netdev, linux-wireless, John W. Linville,
Stanislav Yakovlev
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
The release_firmware() function does its own NULL test, so testing
before calling it is rather redundant.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/ipw2x00/ipw2200.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 2b02257..77c5d2f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -3657,8 +3657,7 @@ static int ipw_load(struct ipw_priv *priv)
priv->rxq = NULL;
}
ipw_tx_queue_free(priv);
- if (raw)
- release_firmware(raw);
+ release_firmware(raw);
#ifdef CONFIG_PM
fw_loaded = 0;
raw = NULL;
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* [PATCH 11/26] wireless, atmel: remove pointless test for NULL before release_firmware() call
From: Jesper Juhl @ 2012-04-09 20:50 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: trivial-DgEjT+Ai2ygdnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, John W. Linville,
Simon Kelley
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925-h2p7t3/P30RzeRGmFJ5qR7ZzlVVXadcDXqFh9Ls21Oc@public.gmane.org>
release_firmware() does its own test. Explicitly checking before the
call is redundant.
Signed-off-by: Jesper Juhl <jj-IYz4IdjRLj0sV2N9l4h3zg@public.gmane.org>
---
drivers/net/wireless/atmel.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 6c87a82..d07c030 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -3989,8 +3989,7 @@ static int reset_atmel_card(struct net_device *dev)
atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
}
- if (fw_entry)
- release_firmware(fw_entry);
+ release_firmware(fw_entry);
}
err = atmel_wakeup_firmware(priv);
--
1.7.10
--
Jesper Juhl <jj-IYz4IdjRLj0sV2N9l4h3zg@public.gmane.org> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 10/26] wireless, at76c50x:: Don't needlessly test for NULL before calling release_firmware()
From: Jesper Juhl @ 2012-04-09 20:50 UTC (permalink / raw)
To: linux-kernel; +Cc: trivial, netdev, linux-wireless, John W. Linville
In-Reply-To: <alpine.LNX.2.00.1204092157340.13925@swampdragon.chaosbits.net>
The release_firmware() function deals gracefully with being passed a
NULL pointer, so explicit tests before the call are rather pointless.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
drivers/net/wireless/at76c50x-usb.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4045e5a..faa8bcb 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -2512,10 +2512,8 @@ static void __exit at76_mod_exit(void)
printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
usb_deregister(&at76_driver);
- for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
- if (firmwares[i].fw)
- release_firmware(firmwares[i].fw);
- }
+ for (i = 0; i < ARRAY_SIZE(firmwares); i++)
+ release_firmware(firmwares[i].fw);
led_trigger_unregister_simple(ledtrig_tx);
}
--
1.7.10
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox