* 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 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 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
* [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
* [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 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 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 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 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 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 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
* 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
* 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
* [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
* [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 2/2] cgroup: 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, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The last man standing justifying the need for populate() is the
sock memcg initialization functions. Now that we are able to pass
a struct mem_cgroup instead of a struct cgroup to the socket
initialization, there is nothing that stops us from initializing
everything in create().
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>
---
mm/memcontrol.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 704054d..02b01d2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,7 +4640,7 @@ 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 mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return mem_cgroup_sockets_init(memcg, ss);
};
@@ -4650,7 +4650,7 @@ static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
@@ -5010,6 +5010,17 @@ mem_cgroup_create(struct cgroup *cont)
memcg->move_charge_at_immigrate = 0;
mutex_init(&memcg->thresholds_lock);
spin_lock_init(&memcg->move_lock);
+
+ error = memcg_init_kmem(memcg, &mem_cgroup_subsys);
+ if (error) {
+ /*
+ * We call put now because our (and parent's) refcnts
+ * are already in place. mem_cgroup_put() will internally
+ * call __mem_cgroup_free, so return directly
+ */
+ mem_cgroup_put(memcg);
+ return ERR_PTR(error);
+ }
return &memcg->css;
free_out:
__mem_cgroup_free(memcg);
@@ -5032,13 +5043,6 @@ static void mem_cgroup_destroy(struct cgroup *cont)
mem_cgroup_put(memcg);
}
-static int mem_cgroup_populate(struct cgroup_subsys *ss,
- struct cgroup *cont)
-{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- return register_kmem_files(memcg, ss);
-}
-
#ifdef CONFIG_MMU
/* Handlers for move charge at task migration. */
#define PRECHARGE_COUNT_AT_ONCE 256
@@ -5622,7 +5626,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
.create = mem_cgroup_create,
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
- .populate = mem_cgroup_populate,
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: Tejun Heo @ 2012-04-09 22:42 UTC (permalink / raw)
To: Glauber Costa
Cc: netdev, cgroups, Li Zefan, kamezawa.hiroyu, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-3-git-send-email-glommer@parallels.com>
On Mon, Apr 09, 2012 at 07:36:34PM -0300, Glauber Costa wrote:
> The last man standing justifying the need for populate() is the
> sock memcg initialization functions. Now that we are able to pass
> a struct mem_cgroup instead of a struct cgroup to the socket
> initialization, there is nothing that stops us from initializing
> everything in create().
>
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: Tejun Heo <tj@kernel.org>
> CC: Li Zefan <lizefan@huawei.com>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> CC: Johannes Weiner <hannes@cmpxchg.org>
> CC: Michal Hocko <mhocko@suse.cz>
Will apply once memcg maintainers ack.
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
From: Will Drewry @ 2012-04-09 22:47 UTC (permalink / raw)
To: Ryan Ware, Markus Gutschke, Andrew Morton
Cc: 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: <CBA89B80.3C770%ware@linux.intel.com>
On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>
> 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().
>>
>
> I second this! They are extremely useful.
>
> Ryan
In that case, would it make sense to put up a separate tools/testing
patch and leave samples where they lie? (I'd _love_ to keep this patch
series from acquiring another 1000 lines, but either way works :)
My current tester and harness lives here:
https://github.com/redpig/seccomp/blob/master/tests/
and the licensing can be sorted out prior to a patch mail.
thanks!
will
^ permalink raw reply
* Re: [PATCH 5/9] ipvs: use adaptive pause in master thread
From: Pablo Neira Ayuso @ 2012-04-09 23:08 UTC (permalink / raw)
To: Julian Anastasov
Cc: Simon Horman, lvs-devel, netdev, netfilter-devel, Wensong Zhang
In-Reply-To: <alpine.LFD.2.00.1204082221440.6964@ja.ssi.bg>
Hi Julian,
On Sun, Apr 08, 2012 at 11:12:53PM +0300, Julian Anastasov wrote:
>
> Hello,
>
> On Thu, 5 Apr 2012, Pablo Neira Ayuso wrote:
>
> > I think you can control when the kernel thread is woken up with a
> > counting semaphore. The counter of that semaphore will be initially
> > set to zero. Then, you can up() the semaphore once per new buffer
> > that you enqueue to the sender.
> >
> > feeder:
> > add message to sync buffer
> > if buffer full:
> > enqueue buffer to sender_thread
> > up(s)
> >
> > sender_thread:
> > while (1) {
> > down(s)
> > retrieve message from queue
> > send message
> > }
> >
> > It seems to me like the classical producer/consumer problem that you
> > can resolve with semaphores.
>
> May be it is possible to use up/down but we
> have to handle the kthread_should_stop check and also
> I prefer to reduce the wakeup events. So, I'm trying
> another solution which is appended just for review.
You can still use kthread_should_stop inside a wrapper function
that calls kthread_stop and up() the semaphore.
sync_stop:
kthread_stop(k)
up(s)
kthread_routine:
while(1) {
down(s)
if (kthread_should_stop(k))
break;
get sync msg
send sync msg
}
BTW, each up() does not necessarily mean one wakeup event. up() will
delivery only one wakeup event for one process that has been already
awaken.
> > Under congestion the situation is complicated. At some point you'll
> > end up dropping messages.
> >
> > You may want to increase the socket queue to delay the moment at which
> > we start dropping messages. You can expose the socke buffer length via
> > /proc interface I guess (not sure if you're already doing that or
> > suggesting to use the global socket buffer length).
>
> I'm still thinking if sndbuf value should be exported,
> currently users have to modify the global default/max value.
I think it's a good idea.
> But in below version I'm trying to handle the sndbuf overflow
> by blocking for write_space event. By this way we should work
> with any sndbuf configuration.
You seem to be defering the overrun problem by using a longer
intermediate queue than the socket buffer. Then, that queue can be
tuned by the user via sysctl. It may happen under heavy stress that
your intermediate queue gets full again, then you'll have to drop
packets at some point.
> > You also can define some mechanism to reduce the amount of events,
> > some state filtering so you only propagate important states.
> >
> > Some partially reliable protocol, so the backup can request messages
> > that got lost in a smart way would can also in handy. Basically, the
> > master only retransmits the current state, not the whole sequence of
> > messages (this is good under congestion, since you save messages).
> > I implement that in conntrackd, but that's more complex solution,
> > of course. I'd start with something simple.
>
> The patch "reduce sync rate with time thresholds"
> that follows the discussed one in the changeset has such
> purpose to reduce the events, in tests the sync traffic is
> reduced ~10 times. But it does not modify the current
> protocol, it adds a very limited logic for retransmissions.
Not directly related to this, but I'd prefer if any retransmission
support (or any new feature) gets added in follow-up patches. So we
can things separated in logic pieces. Thanks.
^ permalink raw reply
* linux-next: manual merge of the wireless-next tree with the net-next tree
From: Stephen Rothwell @ 2012-04-10 1:32 UTC (permalink / raw)
To: John W. Linville
Cc: linux-next, linux-kernel, David Miller, netdev,
Meenakshi Venkataraman, Wey-Yi Guy
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
Hi John,
Today's linux-next merge of the wireless-next tree got a conflict in
drivers/net/wireless/iwlwifi/iwl-testmode.c between commit d33e152e1edd
("iwlwifi: Stop using NLA_PUT*()") from the net-next tree and commit
a42506eb27aa ("iwlwifi: move ucode_type from shared to op_mode") from the
wireless-next tree.
I fixed it up (see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/wireless/iwlwifi/iwl-testmode.c
index a54e20e,d65dac8..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@@ -609,10 -605,9 +612,10 @@@ static int iwl_testmode_driver(struct i
inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
}
- if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type) ||
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
++ if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:35 UTC (permalink / raw)
To: Tejun Heo
Cc: Glauber Costa, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <20120409174042.GA7522-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
(2012/04/10 2:40), Tejun Heo wrote:
> (cc'ing other memcg ppl just in case)
>
> Hello,
>
> I don't think the error handling is correct here.
>
> On Fri, Apr 06, 2012 at 08:04:10PM +0400, Glauber Costa wrote:
>> The last man standing justifying the need for populate() is the
>> sock memcg initialization functions. Now that we are able to pass
>> a struct mem_cgroup instead of a struct cgroup to the socket
>> initialization, there is nothing that stops us from initializing
>> everything in create().
>>
>> 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>
>> ---
> ...
>> @@ -5010,7 +5010,9 @@ mem_cgroup_create(struct cgroup *cont)
>> memcg->move_charge_at_immigrate = 0;
>> mutex_init(&memcg->thresholds_lock);
>> spin_lock_init(&memcg->move_lock);
>> - return &memcg->css;
>> +
>> + if (!memcg_init_kmem(memcg, &mem_cgroup_subsys))
>> + return &memcg->css;
>> free_out:
>> __mem_cgroup_free(memcg);
>> return ERR_PTR(error);
>
> So, the control is just falling through free_out: on kmem init
> failure; however, there seem to be stuff which needs to be undone -
> hotcpu_notifier() registration, which BTW seems incorrect even on its
> own - unmounting and mounting again would probably make the same
> notifier registered multiple times corrupting notification chain, and
> ref inc on the parent.
>
ok, it should be fixed.
> It probably would be best to reorganize the function slightly such
> that, it's organized as...
>
> 1. alloc
> 2. init stuff w/o other side effects
> 3. make side effects
>
> and add kmemcg init at the end of the second step.
>
> Also, memcg maintainers, once the patches get updated and acked, I'd
> like to route them through cgroup tree so that I can kill ->populate
> there. cgroup/for-3.5 is stable branch which can be pulled into other
> trees including the memcg one. Would that be okay?
>
Hm, I'm okay with that but.....Michal ?
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:37 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <4F83218E.7060502-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 2:51), Glauber Costa wrote:
> On 04/09/2012 02:40 PM, Tejun Heo wrote:
>> which BTW seems incorrect even on its
>> own - unmounting and mounting again would probably make the same
>> notifier registered multiple times corrupting notification chain, and
>> ref inc on the parent.
>
>
> For the maintainers: Should I fix those in a new submission, or do you
> intend to do it yourselves?
>
> the refcnt dropping should probably be done in my patch, it is a new
> leak (sorry). The hotplug notifier, as tejun pointed, was already there.
>
> It seems simple enough to fix, so if you guys want, I can bundle it in
> a new submission.
>
Please make notifier fix patch against mm tree, as an independent one.
Thanks,
-Kame
^ permalink raw reply
* Kernel panic with sysfs adding group for pmu device
From: Brown, Aaron F @ 2012-04-10 2:05 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hi all,
I'm getting a kernel panic on boot with the the net-next tree on a
number of test systems I work with. So far this appears on older Intel
Xeon server platforms that have an ESB based chipset with either an x86
or x86_64 kernel.
Here is the panic I am seeing:
---------------------------------
Starts to boots normally to ...
...
Trying to unpack rootfs image as initramfs...
debug: unmapping init memory f748b000..f77fe000
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c10d19a0>] internal_create_group+0xdc/0x138
*pde = 00000000
Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
Modules linked in:
Pid: 1, comm: swapper/0 Not tainted 3.4.0-rc1_net-next_igb_2107cad... #2
Intel /SE7525GP2
EIP: 0060:[<c10d19a0>] EFLAGS: 00010246 CPU: 0
EIP is at internal_create_group+0xdc/0x138
EAX: 00000001 EBX: f4fc0df8 ECX: 00000000 EDX: 00000000
ESI: 00000000 EDI: 00000000 EBP: f58fbf34 ESP: f58fbf14
DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: 00000000 CR3: 014fc000 CR4: 000007d0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
Process swapper/0 (pid: 1, ti=f58fa000 task=f58e9c60 task.ti=f58fa000)
Stack:
00000000 f4fc2238 00000000 c146b780 f4fc2238 00000001 c146b80c 00000000
f58fbf3c c10d1a19 f58fbf54 c1188d3f f4fc0df8 f4fc0df0 00000000 00000000
f58fbf90 c11893a1 c1188d81 00000000 00000000 f4fc0df0 f4fc0df8 c14e5f24
Call Trace:
[<c10d1a19>] sysfs_create_group+0xc/0xf
[<c1188d3f>] device_add_groups+0x21/0x4e
[<c11893a1>] device_add+0x2fa/0x4fb
[<c1188d81>] ? device_private_init+0x15/0x49
[<c1188da2>] ? device_private_init+0x36/0x49
[<c10605bb>] pmu_dev_alloc+0x75/0x8e
[<c14a8dbc>] perf_event_sysfs_init+0x3f/0x85
[<c1001159>] do_one_initcall+0x71/0x113
[<c14a8d7d>] ? utsname_sysctl_init+0x11/0x11
[<c149727c>] kernel_init+0xd8/0x161
[<c14971a4>] ? parse_early_options+0x21/0x21
[<c1339ef6>] kernel_thread_helper+0x6/0xd
Code: d7 66 85 c0 74 21 8b 4d e8 8b 14 b1 b9 02 00 00 00 0b 42 04 0f b7
c0 50 8b 45 e4 e8 01 e1 ff ff 89 c7 59 85 c0 75 0f 46 8b 55 e8 <8b> 04
b2 85 c0 75 a5 31 ff eb 27 8b 4d ec 8b 59 08 eb 0f 8b 08
EIP: [<c10d19a0>] internal_create_group+0xdc/0x138 SS:ESP 0068:f58fbf14
CR2: 0000000000000000
---[ end trace e93713a9d40cd06c ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
---------------------------------
I tried disabling DEBUG_PAGEALLOC as well as
different preempt settings, compiled as single proc, etc... The panic
continued, but modified "Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC" line
to represent the actual settings.
I ran a series of git bisects and found that the patch that introduced
the panics is:
-------------------------------------------
u1460:[0]/usr/src/kernels/net-next> git bisect good
641cc938815dfd09f8fa1ec72deb814f0938ac33 is first bad commit
commit 641cc938815dfd09f8fa1ec72deb814f0938ac33
Author: Jiri Olsa <jolsa@redhat.com>
Date: Thu Mar 15 20:09:14 2012 +0100
perf: Adding sysfs group format attribute for pmu device
Adding sysfs group 'format' attribute for pmu device that
contains a syntax description on how to construct raw events.
The event configuration is described in following
struct pefr_event_attr attributes:
config
config1
config2
Each sysfs attribute within the format attribute group,
describes mapping of name and bitfield definition within
one of above attributes.
eg:
"/sys/...<dev>/format/event" contains "config:0-7"
"/sys/...<dev>/format/umask" contains "config:8-15"
"/sys/...<dev>/format/usr" contains "config:16"
the attribute value syntax is:
line: config ':' bits
config: 'config' | 'config1' | 'config2"
bits: bits ',' bit_term | bit_term
bit_term: VALUE '-' VALUE | VALUE
Adding format attribute definitions for x86 cpu pmus.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Link:
http://lkml.kernel.org/n/tip-vhdk5y2hyype9j63prymty36@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
:040000 040000 6997376a7fa63ee143dd365babc373cb298148a4
1779179772124f413d1d1b18fdd6bb3bdd9713c0 M Documentation
:040000 040000 1bbb2bd82a0abee4e9f55c9ccbc0805d4d0040c4
a947cf4cfd048f98904e5fc59b67253258b6f5a3 M arch
:040000 040000 bd74f46a57eb846a2ee7e3d60813bb1c1af2d71a
d95d819d91a7049d3e7355488436c4305319ceac M include
u1460:[0]/usr/src/kernels/net-next_igb-queue>
------------------------------------------------------
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:37 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F7F1091.9040204@parallels.com>
(2012/04/07 0:49), Glauber Costa wrote:
> On 03/30/2012 05:44 AM, KAMEZAWA Hiroyuki wrote:
>> Maybe what we can do before lsf/mm summit will be this (avoid warning.)
>> This patch is onto linus's git tree. Patch description is updated.
>>
>> Thanks.
>> -Kame
>> ==
>> From 4ab80f84bbcb02a790342426c1de84aeb17fcbe9 Mon Sep 17 00:00:00 2001
>> From: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
>> Date: Thu, 29 Mar 2012 14:59:04 +0900
>> Subject: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
>>
>> tcp memcontrol starts accouting after res->limit is set. So, if a sockets
>> starts before setting res->limit, there are already used resource.
>> At setting res->limit, accounting starts. The resource will be uncharged
>> and make res_counter below 0 because they are not charged.
>> This causes warning.
>>
>
> Kame,
>
> Please test the following patch and see if it fixes your problems (I
> tested locally, and it triggers me no warnings running the test script
> you provided + an inbound scp -r copy of an iso directory from a remote
> machine)
>
> When you are reviewing, keep in mind that we're likely to have the same
> problems with slab jump labels - since the slab pages will outlive the
> cgroup as well, and it might be worthy to keep this in mind, and provide
> a central point for the jump labels to be set of on cgroup destruction.
>
Hm. What happens in following sequence ?
1. a memcg is created
2. put a task into the memcg, start tcp steam
3. set tcp memory limit
The resource used between 2 and 3 will cause the problem finally.
Then, Dave's request
==
You must either:
1) Integrate the socket's existing usage when the limit is set.
2) Avoid accounting completely for a socket that started before
the limit was set.
==
are not satisfied. So, we need to have a state per sockets, it's accounted
or not. I'll look into this problem again, today.
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:42 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-2-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 7:36), Glauber Costa wrote:
> 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>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
^ permalink raw reply
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