* Re: [PATCH 0/8] netdev/MIPS: Improvements to octeon_mgmt Ethernet driver.
From: John Crispin @ 2012-08-23 6:35 UTC (permalink / raw)
To: ddaney.cavm; +Cc: linux-mips, ralf, netdev, linux-kernel, david.daney
In-Reply-To: <20120822.191654.1727215659090597701.davem@davemloft.net>
On 23/08/12 04:16, David Miller wrote:
> From: David Daney <ddaney.cavm@gmail.com>
> Date: Tue, 21 Aug 2012 11:45:04 -0700
>
>> From: David Daney <david.daney@cavium.com>
>>
>> Recent additions to the OCTEON SoC family have included enhancements
>> to the MIX (octeon_mgmt) Ethernet hardware. These include:
>>
>> o 1Gig support (up from 100M).
>>
>> o Hardware timestamping for PTP.
>>
>> Here we add support for these two features as well as some ethtool
>> improvements and cleanup of the MAC address handling.
>>
>> Patch 1/8 is a prerequisite for the rest, and lives in the MIPS
>> architecture part of the tree. Since octeon_mgmt devices are only
>> found in OCTEON SoCs we could merge the whole set via Ralf's tree, or
>> get Ralf to affix his Acked-by and have it go via the netdev tree.
>
> You can send this all via the MIPS tree, and feel free to add my:
>
> Acked-by: David S. Miller <davem@davemloft.net>
Thanks, queued for 3.7
John
^ permalink raw reply
* RE: [PATCH v2] net: add new QCA alx ethernet driver
From: Huang, Xiong @ 2012-08-23 6:35 UTC (permalink / raw)
To: David Miller, Ren, Cloud
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
qca-linux-team, nic-devel, Rodriguez, Luis
In-Reply-To: <20120822.225700.714020017287504609.davem@davemloft.net>
> This is why we require that portable, sane, interfaces are added to ethtool for
> driver diagnostics. That way users can perform a task in the same way
> regardless of what hardware and driver are underneath.
I quite agree you on using ethtool to implement it. we did consider it.
But ethtool has some limitation, for example, the NIC has built-in OTP (TWSI interface)
And Flash (External SPI interface), their properties are quite different with EEPROM which
Ethtool supports.
To support such memory (OTP/Flash), we need additional input parameters.
Same situation exists in diagnostic utility. Ethtool only provide two options : offline & online
That's too gross to locate which part/module of the chip is malfunction. we also need
more options to detect it.
that's why we finally selected a custom debugfs interface.
Thanks
Xiong
^ permalink raw reply
* Re: [PATCH net-next v3] net: remove delay at device dismantle
From: Eric W. Biederman @ 2012-08-23 6:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, gaofeng, netdev, maheshb, therbert
In-Reply-To: <1345691986.5904.40.camel@edumazet-glaptop>
Eric Dumazet <eric.dumazet@gmail.com> writes:
> From: Eric Dumazet <edumazet@google.com>
>
> I noticed extra one second delay in device dismantle, tracked down to
> a call to dst_dev_event() while some call_rcu() are still in RCU queues.
>
> These call_rcu() were posted by rt_free(struct rtable *rt) calls.
>
> We then wait a little (but one second) in netdev_wait_allrefs() before
> kicking again NETDEV_UNREGISTER.
>
> As the call_rcu() are now completed, dst_dev_event() can do the needed
> device swap on busy dst.
>
> To solve this problem, add a new NETDEV_UNREGISTER_FINAL, called
> after a rcu_barrier(), but outside of RTNL lock.
>
> Use NETDEV_UNREGISTER_FINAL with care !
>
> Change dst_dev_event() handler to react to NETDEV_UNREGISTER_FINAL
>
> Also remove NETDEV_UNREGISTER_BATCH, as its not used anymore after
> IP cache removal.
>
> With help from Gao feng
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Tom Herbert <therbert@google.com>
> Cc: Mahesh Bandewar <maheshb@google.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Gao feng <gaofeng@cn.fujitsu.com>
> ---
> v3: Gao Feng reported a lockdep issue.
> I had to change some notifiers to check NETDEV_UNREGISTER_FINAL
>
> v2: NETDEV_UNREGISTER_FINAL called outside of rtnl lock
> as its more risky, base this patch on net-next
>
> include/linux/netdevice.h | 2 +-
> net/core/dev.c | 22 ++++++++--------------
> net/core/dst.c | 2 +-
> net/core/fib_rules.c | 3 ++-
> net/core/rtnetlink.c | 2 +-
> net/ipv4/devinet.c | 6 +++++-
> net/ipv4/fib_frontend.c | 8 ++++----
> net/ipv6/addrconf.c | 6 +++++-
> 8 files changed, 27 insertions(+), 24 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 4936f09..9ad7fa8 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1553,7 +1553,7 @@ struct packet_type {
> #define NETDEV_PRE_TYPE_CHANGE 0x000E
> #define NETDEV_POST_TYPE_CHANGE 0x000F
> #define NETDEV_POST_INIT 0x0010
> -#define NETDEV_UNREGISTER_BATCH 0x0011
> +#define NETDEV_UNREGISTER_FINAL 0x0011
> #define NETDEV_RELEASE 0x0012
> #define NETDEV_NOTIFY_PEERS 0x0013
> #define NETDEV_JOIN 0x0014
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 088923f..0640d2a 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1406,7 +1406,6 @@ rollback:
> nb->notifier_call(nb, NETDEV_DOWN, dev);
> }
> nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
> - nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
> }
> }
>
> @@ -1448,7 +1447,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
> nb->notifier_call(nb, NETDEV_DOWN, dev);
> }
> nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
> - nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
> }
> }
> unlock:
> @@ -1468,7 +1466,8 @@ EXPORT_SYMBOL(unregister_netdevice_notifier);
>
> int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
> {
> - ASSERT_RTNL();
> + if (val != NETDEV_UNREGISTER_FINAL)
> + ASSERT_RTNL();
raw_notifier_call_chain isn't safe without holding some sort of lock.
So removing the ASSERT_RTNL assert here is papering over a bug elsewhere
in this patch.
Without holding a lock for traversing the notifier chain there will
be races with network module load and unload that could corrupt
this list while we are traversing it.
load/unlod.
You already have one of your NETDEV_UNREGISTER_FINAL calls under the
rtnl_lock so it doesn't look like a burden to put the other call under
the rtnl_lock as well.
> return raw_notifier_call_chain(&netdev_chain, val, dev);
> }
> EXPORT_SYMBOL(call_netdevice_notifiers);
> @@ -5331,10 +5330,6 @@ static void rollback_registered_many(struct list_head *head)
> netdev_unregister_kobject(dev);
> }
>
> - /* Process any work delayed until the end of the batch */
> - dev = list_first_entry(head, struct net_device, unreg_list);
> - call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
> -
> synchronize_net();
>
> list_for_each_entry(dev, head, unreg_list)
> @@ -5787,9 +5782,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
>
> /* Rebroadcast unregister notification */
> call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
> - /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users
> - * should have already handle it the first time */
> -
> + rcu_barrier();
You have just added an rcu_barrier() under the rtnl_lock.
Can you make this.
__rtnl_unlock();
rcu_barrier();
rtnl_lock();
Which will be much better for rtnl_lock hold times.
> + call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
> if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
> &dev->state)) {
> /* We must not have linkwatch events
> @@ -5851,9 +5845,8 @@ void netdev_run_todo(void)
>
> __rtnl_unlock();
>
> - /* Wait for rcu callbacks to finish before attempting to drain
> - * the device list. This usually avoids a 250ms wait.
> - */
> +
> + /* Wait for rcu callbacks to finish before next phase */
> if (!list_empty(&list))
> rcu_barrier();
>
> @@ -5862,6 +5855,8 @@ void netdev_run_todo(void)
> = list_first_entry(&list, struct net_device, todo_list);
> list_del(&dev->todo_list);
> + call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
> +
Why are you skipping grapping the rtl_lock here?
rtnl_lock();
__rtnl_unlock() doesn't look scary.
> if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
> pr_err("network todo '%s' but state %d\n",
> dev->name, dev->reg_state);
> @@ -6256,7 +6251,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
> the device is just moving and can keep their slaves up.
> */
> call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
> - call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
> rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
>
> /*
> diff --git a/net/core/dst.c b/net/core/dst.c
> index 56d6361..f6593d2 100644
> --- a/net/core/dst.c
> +++ b/net/core/dst.c
> @@ -374,7 +374,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event,
> struct dst_entry *dst, *last = NULL;
>
> switch (event) {
> - case NETDEV_UNREGISTER:
> + case NETDEV_UNREGISTER_FINAL:
> case NETDEV_DOWN:
> mutex_lock(&dst_gc_mutex);
> for (dst = dst_busy_list; dst; dst = dst->next) {
> diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> index ab7db83..5850937 100644
> --- a/net/core/fib_rules.c
> +++ b/net/core/fib_rules.c
> @@ -711,15 +711,16 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event,
> struct net *net = dev_net(dev);
> struct fib_rules_ops *ops;
>
> - ASSERT_RTNL();
>
> switch (event) {
> case NETDEV_REGISTER:
> + ASSERT_RTNL();
> list_for_each_entry(ops, &net->rules_ops, list)
> attach_rules(&ops->rules_list, dev);
> break;
>
> case NETDEV_UNREGISTER:
> + ASSERT_RTNL();
> list_for_each_entry(ops, &net->rules_ops, list)
> detach_rules(&ops->rules_list, dev);
> break;
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 34d975b..c64efcf 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -2358,7 +2358,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
> case NETDEV_PRE_TYPE_CHANGE:
> case NETDEV_GOING_DOWN:
> case NETDEV_UNREGISTER:
> - case NETDEV_UNREGISTER_BATCH:
> + case NETDEV_UNREGISTER_FINAL:
> case NETDEV_RELEASE:
> case NETDEV_JOIN:
> break;
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index adf273f..6a5e6e4 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -1147,8 +1147,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
> void *ptr)
> {
> struct net_device *dev = ptr;
> - struct in_device *in_dev = __in_dev_get_rtnl(dev);
> + struct in_device *in_dev;
>
> + if (event == NETDEV_UNREGISTER_FINAL)
> + goto out;
> +
> + in_dev = __in_dev_get_rtnl(dev);
> ASSERT_RTNL();
>
> if (!in_dev) {
> diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
> index 7f073a3..fd7d9ae 100644
> --- a/net/ipv4/fib_frontend.c
> +++ b/net/ipv4/fib_frontend.c
> @@ -1041,7 +1041,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
> static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
> {
> struct net_device *dev = ptr;
> - struct in_device *in_dev = __in_dev_get_rtnl(dev);
> + struct in_device *in_dev;
> struct net *net = dev_net(dev);
>
> if (event == NETDEV_UNREGISTER) {
> @@ -1050,9 +1050,11 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
> return NOTIFY_DONE;
> }
>
> - if (!in_dev)
> + if (event == NETDEV_UNREGISTER_FINAL)
> return NOTIFY_DONE;
>
> + in_dev = __in_dev_get_rtnl(dev);
> +
> switch (event) {
> case NETDEV_UP:
> for_ifa(in_dev) {
> @@ -1071,8 +1073,6 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
> case NETDEV_CHANGE:
> rt_cache_flush(dev_net(dev), 0);
> break;
> - case NETDEV_UNREGISTER_BATCH:
> - break;
> }
> return NOTIFY_DONE;
> }
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 6bc85f7..e581009 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -2566,10 +2566,14 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
> void *data)
> {
> struct net_device *dev = (struct net_device *) data;
> - struct inet6_dev *idev = __in6_dev_get(dev);
> + struct inet6_dev *idev;
> int run_pending = 0;
> int err;
>
> + if (event == NETDEV_UNREGISTER_FINAL)
> + return NOTIFY_DONE;
> +
> + idev = __in6_dev_get(dev);
> switch (event) {
> case NETDEV_REGISTER:
> if (!idev && dev->mtu >= IPV6_MIN_MTU) {
^ permalink raw reply
* Which one is chosen on multiple default gateway set?
From: Wei Huang @ 2012-08-23 6:31 UTC (permalink / raw)
To: netdev, netfilter
Hi,
If multiple default gateways are set, which one will be chosen? And if
the chosen one is down, will others take over?
It works sometime, but not most of the time. (example below) The
behavior is inconsistent.
How the case is handled? On what condition another default gateway is
chosen? Thank you!
=======================
~ # ip r
10.65.30.0/24 dev bond0 src 10.65.30.71
default via 10.65.30.221 dev bond0 (this one is down!)
default via 10.65.30.1 dev bond0
~ # ip r get 8.8.8.8
8.8.8.8 via 10.65.30.221 dev bond0 src 10.65.30.71
~ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
// after a while
~ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=56 time=5.0 ms
~ # ip r get 8.8.8.8
8.8.8.8 via 10.65.30.1 dev bond0 src 10.65.30.71
// after two while
~ # ip r get 8.8.8.8
8.8.8.8 via 10.65.30.221 dev bond0 src 10.65.30.71
~ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
==================================
Best regards,
Wei
^ permalink raw reply
* [PATCH 2/2] netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_queue()
From: Michael Wang @ 2012-08-23 6:00 UTC (permalink / raw)
To: LKML, netdev@vger.kernel.org, coreteam, netfilter,
netfilter-devel
Cc: David Miller, kaber, pablo
From: Michael Wang <wangyun@linux.vnet.ibm.com>
Since 'list_for_each_continue_rcu' has already been replaced by
'list_for_each_entry_continue_rcu', pass 'list_head' to nf_queue() as a
parameter can not benefit us any more.
This patch will replace 'list_head' with 'nf_hook_ops' as the parameter of
nf_queue() and __nf_queue() to save code.
Signed-off-by: Michael Wang <wangyun@linux.vnet.ibm.com>
---
net/netfilter/core.c | 4 ++--
net/netfilter/nf_internals.h | 2 +-
net/netfilter/nf_queue.c | 8 ++++----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index b4cd2a2..8bf1eef 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -189,8 +189,8 @@ next_hook:
if (ret == 0)
ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
- int err = nf_queue(skb, &elem->list, pf, hook, indev, outdev,
- okfn, verdict >> NF_VERDICT_QBITS);
+ int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
+ verdict >> NF_VERDICT_QBITS);
if (err < 0) {
if (err == -ECANCELED)
goto next_hook;
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 2886231..3deec99 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -24,7 +24,7 @@ extern unsigned int nf_iterate(struct list_head *head,
/* nf_queue.c */
extern int nf_queue(struct sk_buff *skb,
- struct list_head *elem,
+ struct nf_hook_ops *elem,
u_int8_t pf, unsigned int hook,
struct net_device *indev,
struct net_device *outdev,
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 29fe102..8d2cf9e 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -118,7 +118,7 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
* through nf_reinject().
*/
static int __nf_queue(struct sk_buff *skb,
- struct list_head *elem,
+ struct nf_hook_ops *elem,
u_int8_t pf, unsigned int hook,
struct net_device *indev,
struct net_device *outdev,
@@ -155,7 +155,7 @@ static int __nf_queue(struct sk_buff *skb,
*entry = (struct nf_queue_entry) {
.skb = skb,
- .elem = list_entry(elem, struct nf_hook_ops, list),
+ .elem = elem,
.pf = pf,
.hook = hook,
.indev = indev,
@@ -225,7 +225,7 @@ static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
#endif
int nf_queue(struct sk_buff *skb,
- struct list_head *elem,
+ struct nf_hook_ops *elem,
u_int8_t pf, unsigned int hook,
struct net_device *indev,
struct net_device *outdev,
@@ -323,7 +323,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
local_bh_enable();
break;
case NF_QUEUE:
- err = __nf_queue(skb, &elem->list, entry->pf, entry->hook,
+ err = __nf_queue(skb, elem, entry->pf, entry->hook,
entry->indev, entry->outdev, entry->okfn,
verdict >> NF_VERDICT_QBITS);
if (err < 0) {
--
1.7.4.1
^ permalink raw reply related
* [PATCH 1/2] netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_iterate()
From: Michael Wang @ 2012-08-23 5:59 UTC (permalink / raw)
To: LKML, netdev@vger.kernel.org, coreteam, netfilter,
netfilter-devel
Cc: David Miller, kaber, pablo
From: Michael Wang <wangyun@linux.vnet.ibm.com>
Since 'list_for_each_continue_rcu' has already been replaced by
'list_for_each_entry_continue_rcu', pass 'list_head' to nf_iterate() as a
parameter can not benefit us any more.
This patch will replace 'list_head' with 'nf_hook_ops' as the parameter of
nf_iterate() to save code.
Signed-off-by: Michael Wang <wangyun@linux.vnet.ibm.com>
---
net/netfilter/core.c | 24 ++++++++++--------------
net/netfilter/nf_internals.h | 2 +-
net/netfilter/nf_queue.c | 6 +++---
3 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 8f4b0b2..b4cd2a2 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -126,42 +126,38 @@ unsigned int nf_iterate(struct list_head *head,
unsigned int hook,
const struct net_device *indev,
const struct net_device *outdev,
- struct list_head **i,
+ struct nf_hook_ops **elemp,
int (*okfn)(struct sk_buff *),
int hook_thresh)
{
unsigned int verdict;
- struct nf_hook_ops *elem = list_entry_rcu(*i, struct nf_hook_ops, list);
/*
* The caller must not block between calls to this
* function because of risk of continuing from deleted element.
*/
- list_for_each_entry_continue_rcu(elem, head, list) {
- if (hook_thresh > elem->priority)
+ list_for_each_entry_continue_rcu((*elemp), head, list) {
+ if (hook_thresh > (*elemp)->priority)
continue;
/* Optimization: we don't need to hold module
reference here, since function can't sleep. --RR */
repeat:
- verdict = elem->hook(hook, skb, indev, outdev, okfn);
+ verdict = (*elemp)->hook(hook, skb, indev, outdev, okfn);
if (verdict != NF_ACCEPT) {
#ifdef CONFIG_NETFILTER_DEBUG
if (unlikely((verdict & NF_VERDICT_MASK)
> NF_MAX_VERDICT)) {
NFDEBUG("Evil return from %p(%u).\n",
- elem->hook, hook);
+ (*elemp)->hook, hook);
continue;
}
#endif
- if (verdict != NF_REPEAT) {
- *i = &elem->list;
+ if (verdict != NF_REPEAT)
return verdict;
- }
goto repeat;
}
}
- *i = &elem->list;
return NF_ACCEPT;
}
@@ -174,14 +170,14 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
int (*okfn)(struct sk_buff *),
int hook_thresh)
{
- struct list_head *elem;
+ struct nf_hook_ops *elem;
unsigned int verdict;
int ret = 0;
/* We may already have this, but read-locks nest anyway */
rcu_read_lock();
- elem = &nf_hooks[pf][hook];
+ elem = list_entry_rcu(&nf_hooks[pf][hook], struct nf_hook_ops, list);
next_hook:
verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev,
outdev, &elem, okfn, hook_thresh);
@@ -193,8 +189,8 @@ next_hook:
if (ret == 0)
ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
- int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
- verdict >> NF_VERDICT_QBITS);
+ int err = nf_queue(skb, &elem->list, pf, hook, indev, outdev,
+ okfn, verdict >> NF_VERDICT_QBITS);
if (err < 0) {
if (err == -ECANCELED)
goto next_hook;
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 770f764..2886231 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -18,7 +18,7 @@ extern unsigned int nf_iterate(struct list_head *head,
unsigned int hook,
const struct net_device *indev,
const struct net_device *outdev,
- struct list_head **i,
+ struct nf_hook_ops **elemp,
int (*okfn)(struct sk_buff *),
int hook_thresh);
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index ce60cf0..29fe102 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -287,7 +287,7 @@ int nf_queue(struct sk_buff *skb,
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
{
struct sk_buff *skb = entry->skb;
- struct list_head *elem = &entry->elem->list;
+ struct nf_hook_ops *elem = entry->elem;
const struct nf_afinfo *afinfo;
int err;
@@ -297,7 +297,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
/* Continue traversal iff userspace said ok... */
if (verdict == NF_REPEAT) {
- elem = elem->prev;
+ elem = list_entry(elem->list.prev, struct nf_hook_ops, list);
verdict = NF_ACCEPT;
}
@@ -323,7 +323,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
local_bh_enable();
break;
case NF_QUEUE:
- err = __nf_queue(skb, elem, entry->pf, entry->hook,
+ err = __nf_queue(skb, &elem->list, entry->pf, entry->hook,
entry->indev, entry->outdev, entry->okfn,
verdict >> NF_VERDICT_QBITS);
if (err < 0) {
--
1.7.4.1
^ permalink raw reply related
* [PATCH 0/2] netfilter: code refine for using new interface 'list_for_each_entry_continue_rcu'
From: Michael Wang @ 2012-08-23 5:59 UTC (permalink / raw)
To: LKML, netdev@vger.kernel.org, coreteam, netfilter,
netfilter-devel
Cc: David Miller, kaber, pablo
From: Michael Wang <wangyun@linux.vnet.ibm.com>
Since 'list_for_each_continue_rcu' has been replaced with the new interface
'list_for_each_entry_continue_rcu' by commit 6705e86, we can no longer saving
code by passing 'list_head' to nf_iterate() and nf_queue() any more.
This patch set will pass 'nf_hook_ops' instead of 'list_head' to nf_iterate()
and nf_queue() as the parameter and saving some code.
Tested:
add rule to iptables and check result by ping.
nfqnl_test which is a test utility of libnetfilter_queue.
Signed-off-by: Michael Wang <wangyun@linux.vnet.ibm.com>
---
b/net/netfilter/core.c | 24 ++++++++++--------------
b/net/netfilter/nf_internals.h | 2 +-
b/net/netfilter/nf_queue.c | 6 +++---
net/netfilter/core.c | 4 ++--
net/netfilter/nf_internals.h | 2 +-
net/netfilter/nf_queue.c | 8 ++++----
6 files changed, 21 insertions(+), 25 deletions(-)
^ permalink raw reply
* Re: [PATCH net-next] packet: Protect packet sk list with mutex (v2)
From: David Miller @ 2012-08-23 5:59 UTC (permalink / raw)
To: eric.dumazet; +Cc: xemul, netdev
In-Reply-To: <1345618757.5158.612.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 22 Aug 2012 08:59:17 +0200
> On Tue, 2012-08-21 at 15:06 +0400, Pavel Emelyanov wrote:
>> Change since v1:
>>
>> * Fixed inuse counters access spotted by Eric
>>
>> In patch eea68e2f (packet: Report socket mclist info via diag module) I've
>> introduced a "scheduling in atomic" problem in packet diag module -- the
>> socket list is traversed under rcu_read_lock() while performed under it sk
>> mclist access requires rtnl lock (i.e. -- mutex) to be taken.
>>
>> [152363.820563] BUG: scheduling while atomic: crtools/12517/0x10000002
>> [152363.820573] 4 locks held by crtools/12517:
>> [152363.820581] #0: (sock_diag_mutex){+.+.+.}, at: [<ffffffff81a2dcb5>] sock_diag_rcv+0x1f/0x3e
>> [152363.820613] #1: (sock_diag_table_mutex){+.+.+.}, at: [<ffffffff81a2de70>] sock_diag_rcv_msg+0xdb/0x11a
>> [152363.820644] #2: (nlk->cb_mutex){+.+.+.}, at: [<ffffffff81a67d01>] netlink_dump+0x23/0x1ab
>> [152363.820693] #3: (rcu_read_lock){.+.+..}, at: [<ffffffff81b6a049>] packet_diag_dump+0x0/0x1af
>>
>> Similar thing was then re-introduced by further packet diag patches (fanount
>> mutex and pgvec mutex for rings) :(
>>
>> Apart from being terribly sorry for the above, I propose to change the packet
>> sk list protection from spinlock to mutex. This lock currently protects two
>> modifications:
>>
>> * sklist
>> * prot inuse counters
>>
>> The sklist modifications can be just reprotected with mutex since they already
>> occur in a sleeping context. The inuse counters modifications are trickier -- the
>> __this_cpu_-s are used inside, thus requiring the caller to handle the potential
>> issues with contexts himself. Since packet sockets' counters are modified in two
>> places only (packet_create and packet_release) we only need to protect the context
>> from being preempted. BH disabling is not required in this case.
>>
>> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
...
> Acked-by: Eric Dumazet <edumazet@google.com>
Applied, thanks.
^ permalink raw reply
* Re: [net-next PATCH] mdio: translation of MMD EEE registers to/from ethtool settings
From: David Miller @ 2012-08-23 5:59 UTC (permalink / raw)
To: bruce.w.allan; +Cc: netdev, peppe.cavallaro
In-Reply-To: <20120820145529.19390.66175.stgit@bwallan-smackover2.jf.intel.com>
From: Bruce Allan <bruce.w.allan@intel.com>
Date: Mon, 20 Aug 2012 07:55:29 -0700
> The helper functions which translate IEEE MDIO Manageable Device (MMD)
> Energy-Efficient Ethernet (EEE) registers 3.20, 7.60 and 7.61 to and from
> the comparable ethtool supported/advertised settings will be needed by
> drivers other than those in PHYLIB (e.g. e1000e in a follow-on patch).
>
> In the same fashion as similar translation functions in linux/mii.h, move
> these functions from the PHYLIB core to the linux/mdio.h header file so the
> code will not have to be duplicated in each driver needing MMD-to-ethtool
> (and vice-versa) translations. The function and some variable names have
> been renamed to be more descriptive.
>
> Not tested on the only hardware that currently calls the related functions,
> stmmac, because I don't have access to any. Has been compile tested and
> the translations have been tested on a locally modified version of e1000e.
>
> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] af_packet: use define instead of constant
From: David Miller @ 2012-08-23 5:58 UTC (permalink / raw)
To: danborkmann; +Cc: netdev
In-Reply-To: <1345469643.22726.2.camel@thinkbox>
From: Daniel Borkmann <danborkmann@iogearbox.net>
Date: Mon, 20 Aug 2012 15:34:03 +0200
> Instead of using a hard-coded value for the status variable, it would make
> the code more readable to use its destined define from linux/if_packet.h.
>
> Signed-off-by: daniel.borkmann@tik.ee.ethz.ch
Applied.
^ permalink raw reply
* Re: [PATCH v2] net: add new QCA alx ethernet driver
From: David Miller @ 2012-08-23 5:57 UTC (permalink / raw)
To: cjren; +Cc: netdev, linux-kernel, qca-linux-team, nic-devel, xiong, rodrigue
In-Reply-To: <1345480949-14800-1-git-send-email-cjren@qca.qualcomm.com>
From: <cjren@qca.qualcomm.com>
Date: Tue, 21 Aug 2012 00:42:29 +0800
> +config ALX_DEBUGFS
> + bool "Qualcomm Atheros debugging interface"
> + depends on ALX && DEBUG_FS
> + ---help---
> + This option adds ability to debug and test L1F. It can
> + support Qualcomm Atheros tools, including diagnostic, memcfg
> + and SWOI.
Sorry, no vendor specific interfaces, you have to remove this.
Anything diagnostic you think is special and unique to your piece of
hardware, is almost certainly not, and therefore needs to exist as a
generic ethtool or similar interface that other drivers can plug into,
not just your's.
Driver specific interfaces suck for several reasons, not least of
which is the fact that it leads to a terrible user experience. The
same task must be done in different ways depending upon what piece of
networking hardware and device driver are being used, which the user
should never need to know.
This is why we require that portable, sane, interfaces are added
to ethtool for driver diagnostics. That way users can perform
a task in the same way regardless of what hardware and driver
are underneath.
^ permalink raw reply
* Re: [PATCH] rds: Don't disable BH on BH context
From: David Miller @ 2012-08-23 5:52 UTC (permalink / raw)
To: ying.xue; +Cc: venkat.x.venkatsubra, netdev
In-Reply-To: <1345448648-30449-1-git-send-email-ying.xue@windriver.com>
From: Ying Xue <ying.xue@windriver.com>
Date: Mon, 20 Aug 2012 15:44:08 +0800
> Since we have already in BH context when *_write_space(),
> *_data_ready() as well as *_state_change() are called, it's
> unnecessary to disable BH.
>
> Signed-off-by: Ying Xue <ying.xue@windriver.com>
Applied to net-next, thanks.
^ permalink raw reply
* Re: [PATCH v8] bonding: support for IPv6 transmit hashing
From: David Miller @ 2012-08-23 5:49 UTC (permalink / raw)
To: linux; +Cc: netdev
In-Reply-To: <2e01d8f94c42c61af9886683a4c35caf6816bc3d.1345615999.git.linux@8192.net>
From: John Eaglesham <linux@8192.net>
Date: Tue, 21 Aug 2012 23:43:35 -0700
> From: John Eaglesham <linux@8192.net>
>
> Currently the "bonding" driver does not support load balancing outgoing
> traffic in LACP mode for IPv6 traffic. IPv4 (and TCP or UDP over IPv4)
> are currently supported; this patch adds transmit hashing for IPv6 (and
> TCP or UDP over IPv6), bringing IPv6 up to par with IPv4 support in the
> bonding driver. In addition, bounds checking has been added to all
> transmit hashing functions.
>
> The algorithm chosen (xor'ing the bottom three quads of the source and
> destination addresses together, then xor'ing each byte of that result into
> the bottom byte, finally xor'ing with the last bytes of the MAC addresses)
> was selected after testing almost 400,000 unique IPv6 addresses harvested
> from server logs. This algorithm had the most even distribution for both
> big- and little-endian architectures while still using few instructions. Its
> behavior also attempts to closely match that of the IPv4 algorithm.
>
> The IPv6 flow label was intentionally not included in the hash as it appears
> to be unset in the vast majority of IPv6 traffic sampled, and the current
> algorithm not using the flow label already offers a very even distribution.
>
> Fragmented IPv6 packets are handled the same way as fragmented IPv4 packets,
> ie, they are not balanced based on layer 4 information. Additionally,
> IPv6 packets with intermediate headers are not balanced based on layer
> 4 information. In practice these intermediate headers are not common and
> this should not cause any problems, and the alternative (a packet-parsing
> loop and look-up table) seemed slow and complicated for little gain.
>
> Tested-by: John Eaglesham <linux@8192.net>
> Signed-off-by: John Eaglesham <linux@8192.net>
Applied, thanks a lot.
^ permalink raw reply
* Re: [PATCH net-next] ipv6: gre: fix ip6gre_err()
From: David Miller @ 2012-08-23 5:48 UTC (permalink / raw)
To: eric.dumazet; +Cc: xeb, netdev
In-Reply-To: <1345384050.5158.208.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 19 Aug 2012 15:47:30 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> ip6gre_err() miscomputes grehlen (sizeof(ipv6h) is 4 or 8,
> not 40 as expected), and should take into account 'offset' parameter.
>
> Also uses pskb_may_pull() to cope with some fragged skbs
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Dmitry Kozlov <xeb@mail.ru>
Applied, thanks Eric.
^ permalink raw reply
* Re: [RFC] Interface for TCP Metrics
From: David Miller @ 2012-08-23 5:47 UTC (permalink / raw)
To: ja; +Cc: netdev
In-Reply-To: <alpine.LFD.2.00.1208191402560.1893@ja.ssi.bg>
From: Julian Anastasov <ja@ssi.bg>
Date: Sun, 19 Aug 2012 14:42:15 +0300 (EEST)
> - will use genl with TCP_METRICS_GENL_NAME "tcp_metrics",
> TCP_METRICS_GENL_VERSION 0x01
Sounds good.
> - provide dumpit method and one cmd to read metrics by exact addr,
> will use TCP_METRICS_CMD_{GET,...} and TCP_METRICS_ATTR_xxx in
> new file include/linux/tcp_metrics.h
Ok.
Eric thinks we can filter in userspace, but since it's so easy to
lookup entries in the kernel and the demux for that is already there,
I have no objections to have a bonafide netlink operation for
getting a single entry.
> - Is command to delete cached entry needed? Delete will need
> new rcu_head. Useful to flush the cache or to delete entries
> with filter.
Having a way to flush the entire table is useful. Specific entries,
is less useful.
> - without support for delete cmd, may be we can add command to
> reset entry with default values from dst?
>
> - Where to put the new netlink code?
> tcp_metrics_netlink.c
> tcp_metrics_nl.c
> or just in current tcp_metrics.c ?
Put it in tcp_metrics.c, that way we don't need to export any
internals.
> - command to modify specific metric for addr, by name? Only
> for tcpm_vals? If not locked?
>
> Do we need modify/delete/reset support or just read
> support is enough? Comments?
I would say that you can support fancy things as long as new
locking constraints are not added.
^ permalink raw reply
* Re: [PATCH net-next] xfrm: fix RCU bugs
From: David Miller @ 2012-08-23 5:40 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, fan.du, fengguang.wu, Priyanka.Jain
In-Reply-To: <1345372308.5158.54.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 19 Aug 2012 12:31:48 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> This patch reverts commit 56892261ed1a (xfrm: Use rcu_dereference_bh to
> deference pointer protected by rcu_read_lock_bh), and fixes bugs
> introduced in commit 418a99ac6ad ( Replace rwlock on xfrm_policy_afinfo
> with rcu )
>
> 1) We properly use RCU variant in this file, not a mix of RCU/RCU_BH
>
> 2) We must defer some writes after the synchronize_rcu() call or a reader
> can crash dereferencing NULL pointer.
>
> 3) Now we use the xfrm_policy_afinfo_lock spinlock only from process
> context, we no longer need to block BH in xfrm_policy_register_afinfo()
> and xfrm_policy_unregister_afinfo()
>
> 4) Can use RCU_INIT_POINTER() instead of rcu_assign_pointer() in
> xfrm_policy_unregister_afinfo()
>
> 5) Remove a forward inline declaration (xfrm_policy_put_afinfo()),
> and also move xfrm_policy_get_afinfo() declaration.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH 2/2] [RFC] netlink: fix possible spoofing from non-root processes
From: David Miller @ 2012-08-23 4:53 UTC (permalink / raw)
To: pablo; +Cc: netdev
In-Reply-To: <20120820190915.GA3727@1984>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 20 Aug 2012 21:09:15 +0200
> On Sun, Aug 19, 2012 at 11:23:27PM +0200, Pablo Neira Ayuso wrote:
>> On Fri, Aug 17, 2012 at 07:22:29PM +0200, pablo@netfilter.org wrote:
>> [...]
>> > [ I don't know any FOSS program making use of Netlink to communicate
>> > to processes, please, let me know if I'm missing anyone important ]
>>
>> Patrick pinged me for little reminder on NETLINK_USERSOCK. We still
>> have to allow netlink-to-netlink userspace communication for it.
>>
>> So, please find a new version of this patch that allows non-root
>> processes for that Netlink bus. For others, my patch restricts to root
>> processes the ability of sending messages with dst_pid != 0.
>
> Sorry, I just noticed that you cannot apply this to your net tree
> since it depends on patch 1/2 which is not a fix.
>
> I'll get back to you with one path that you can apply to your net
> tree.
>
> I'll resend 1/2 later to net-next once this has been sorted out.
Ok, waiting for new versions of these patches, thanks.
^ permalink raw reply
* wireless router performance differ with 2.4Ghz vs 5.0Ghz frequency
From: Lin Ming @ 2012-08-23 4:50 UTC (permalink / raw)
To: linux-wireless; +Cc: networking
Hi list,
I have a wireless router with 2 wireless cards: 2.4Ghz and 5.0Ghz frequency.
The performance for 2.4Ghz is much worse than 5.0Ghz.
Does the frequency affect performance so much?
Thanks,
Lin Ming
^ permalink raw reply
* Re: [PATCH net-next v3] net: remove delay at device dismantle
From: David Miller @ 2012-08-23 4:50 UTC (permalink / raw)
To: gaofeng; +Cc: eric.dumazet, netdev, maheshb, therbert, ebiederm
In-Reply-To: <5035B27F.9060002@cn.fujitsu.com>
From: Gao feng <gaofeng@cn.fujitsu.com>
Date: Thu, 23 Aug 2012 12:33:03 +0800
> 于 2012年08月23日 11:19, Eric Dumazet 写道:
>> From: Eric Dumazet <edumazet@google.com>
>>
>> I noticed extra one second delay in device dismantle, tracked down to
>> a call to dst_dev_event() while some call_rcu() are still in RCU queues.
>>
>> These call_rcu() were posted by rt_free(struct rtable *rt) calls.
>>
>> We then wait a little (but one second) in netdev_wait_allrefs() before
>> kicking again NETDEV_UNREGISTER.
>>
>> As the call_rcu() are now completed, dst_dev_event() can do the needed
>> device swap on busy dst.
>>
>> To solve this problem, add a new NETDEV_UNREGISTER_FINAL, called
>> after a rcu_barrier(), but outside of RTNL lock.
>>
>> Use NETDEV_UNREGISTER_FINAL with care !
>>
>> Change dst_dev_event() handler to react to NETDEV_UNREGISTER_FINAL
>>
>> Also remove NETDEV_UNREGISTER_BATCH, as its not used anymore after
>> IP cache removal.
>>
>> With help from Gao feng
>>
>> Signed-off-by: Eric Dumazet <edumazet@google.com>
>> Cc: Tom Herbert <therbert@google.com>
>> Cc: Mahesh Bandewar <maheshb@google.com>
>> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
>> Cc: Gao feng <gaofeng@cn.fujitsu.com>
>
> looks good to me, the lockdep warning message disappeared.
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH net-next v3] net: remove delay at device dismantle
From: Gao feng @ 2012-08-23 4:33 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, maheshb, therbert, ebiederm
In-Reply-To: <1345691986.5904.40.camel@edumazet-glaptop>
于 2012年08月23日 11:19, Eric Dumazet 写道:
> From: Eric Dumazet <edumazet@google.com>
>
> I noticed extra one second delay in device dismantle, tracked down to
> a call to dst_dev_event() while some call_rcu() are still in RCU queues.
>
> These call_rcu() were posted by rt_free(struct rtable *rt) calls.
>
> We then wait a little (but one second) in netdev_wait_allrefs() before
> kicking again NETDEV_UNREGISTER.
>
> As the call_rcu() are now completed, dst_dev_event() can do the needed
> device swap on busy dst.
>
> To solve this problem, add a new NETDEV_UNREGISTER_FINAL, called
> after a rcu_barrier(), but outside of RTNL lock.
>
> Use NETDEV_UNREGISTER_FINAL with care !
>
> Change dst_dev_event() handler to react to NETDEV_UNREGISTER_FINAL
>
> Also remove NETDEV_UNREGISTER_BATCH, as its not used anymore after
> IP cache removal.
>
> With help from Gao feng
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Tom Herbert <therbert@google.com>
> Cc: Mahesh Bandewar <maheshb@google.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Gao feng <gaofeng@cn.fujitsu.com>
looks good to me, the lockdep warning message disappeared.
^ permalink raw reply
* [PATCH net-next v3] net: remove delay at device dismantle
From: Eric Dumazet @ 2012-08-23 3:19 UTC (permalink / raw)
To: David Miller; +Cc: gaofeng, netdev, maheshb, therbert, ebiederm
From: Eric Dumazet <edumazet@google.com>
I noticed extra one second delay in device dismantle, tracked down to
a call to dst_dev_event() while some call_rcu() are still in RCU queues.
These call_rcu() were posted by rt_free(struct rtable *rt) calls.
We then wait a little (but one second) in netdev_wait_allrefs() before
kicking again NETDEV_UNREGISTER.
As the call_rcu() are now completed, dst_dev_event() can do the needed
device swap on busy dst.
To solve this problem, add a new NETDEV_UNREGISTER_FINAL, called
after a rcu_barrier(), but outside of RTNL lock.
Use NETDEV_UNREGISTER_FINAL with care !
Change dst_dev_event() handler to react to NETDEV_UNREGISTER_FINAL
Also remove NETDEV_UNREGISTER_BATCH, as its not used anymore after
IP cache removal.
With help from Gao feng
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Mahesh Bandewar <maheshb@google.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Gao feng <gaofeng@cn.fujitsu.com>
---
v3: Gao Feng reported a lockdep issue.
I had to change some notifiers to check NETDEV_UNREGISTER_FINAL
v2: NETDEV_UNREGISTER_FINAL called outside of rtnl lock
as its more risky, base this patch on net-next
include/linux/netdevice.h | 2 +-
net/core/dev.c | 22 ++++++++--------------
net/core/dst.c | 2 +-
net/core/fib_rules.c | 3 ++-
net/core/rtnetlink.c | 2 +-
net/ipv4/devinet.c | 6 +++++-
net/ipv4/fib_frontend.c | 8 ++++----
net/ipv6/addrconf.c | 6 +++++-
8 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4936f09..9ad7fa8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1553,7 +1553,7 @@ struct packet_type {
#define NETDEV_PRE_TYPE_CHANGE 0x000E
#define NETDEV_POST_TYPE_CHANGE 0x000F
#define NETDEV_POST_INIT 0x0010
-#define NETDEV_UNREGISTER_BATCH 0x0011
+#define NETDEV_UNREGISTER_FINAL 0x0011
#define NETDEV_RELEASE 0x0012
#define NETDEV_NOTIFY_PEERS 0x0013
#define NETDEV_JOIN 0x0014
diff --git a/net/core/dev.c b/net/core/dev.c
index 088923f..0640d2a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1406,7 +1406,6 @@ rollback:
nb->notifier_call(nb, NETDEV_DOWN, dev);
}
nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
- nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
}
}
@@ -1448,7 +1447,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
nb->notifier_call(nb, NETDEV_DOWN, dev);
}
nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
- nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
}
}
unlock:
@@ -1468,7 +1466,8 @@ EXPORT_SYMBOL(unregister_netdevice_notifier);
int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
{
- ASSERT_RTNL();
+ if (val != NETDEV_UNREGISTER_FINAL)
+ ASSERT_RTNL();
return raw_notifier_call_chain(&netdev_chain, val, dev);
}
EXPORT_SYMBOL(call_netdevice_notifiers);
@@ -5331,10 +5330,6 @@ static void rollback_registered_many(struct list_head *head)
netdev_unregister_kobject(dev);
}
- /* Process any work delayed until the end of the batch */
- dev = list_first_entry(head, struct net_device, unreg_list);
- call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
-
synchronize_net();
list_for_each_entry(dev, head, unreg_list)
@@ -5787,9 +5782,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
/* Rebroadcast unregister notification */
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
- /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users
- * should have already handle it the first time */
-
+ rcu_barrier();
+ call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
&dev->state)) {
/* We must not have linkwatch events
@@ -5851,9 +5845,8 @@ void netdev_run_todo(void)
__rtnl_unlock();
- /* Wait for rcu callbacks to finish before attempting to drain
- * the device list. This usually avoids a 250ms wait.
- */
+
+ /* Wait for rcu callbacks to finish before next phase */
if (!list_empty(&list))
rcu_barrier();
@@ -5862,6 +5855,8 @@ void netdev_run_todo(void)
= list_first_entry(&list, struct net_device, todo_list);
list_del(&dev->todo_list);
+ call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
+
if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
pr_err("network todo '%s' but state %d\n",
dev->name, dev->reg_state);
@@ -6256,7 +6251,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
the device is just moving and can keep their slaves up.
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
- call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
/*
diff --git a/net/core/dst.c b/net/core/dst.c
index 56d6361..f6593d2 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -374,7 +374,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event,
struct dst_entry *dst, *last = NULL;
switch (event) {
- case NETDEV_UNREGISTER:
+ case NETDEV_UNREGISTER_FINAL:
case NETDEV_DOWN:
mutex_lock(&dst_gc_mutex);
for (dst = dst_busy_list; dst; dst = dst->next) {
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index ab7db83..5850937 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -711,15 +711,16 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event,
struct net *net = dev_net(dev);
struct fib_rules_ops *ops;
- ASSERT_RTNL();
switch (event) {
case NETDEV_REGISTER:
+ ASSERT_RTNL();
list_for_each_entry(ops, &net->rules_ops, list)
attach_rules(&ops->rules_list, dev);
break;
case NETDEV_UNREGISTER:
+ ASSERT_RTNL();
list_for_each_entry(ops, &net->rules_ops, list)
detach_rules(&ops->rules_list, dev);
break;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 34d975b..c64efcf 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2358,7 +2358,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
case NETDEV_PRE_TYPE_CHANGE:
case NETDEV_GOING_DOWN:
case NETDEV_UNREGISTER:
- case NETDEV_UNREGISTER_BATCH:
+ case NETDEV_UNREGISTER_FINAL:
case NETDEV_RELEASE:
case NETDEV_JOIN:
break;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index adf273f..6a5e6e4 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1147,8 +1147,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
- struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev;
+ if (event == NETDEV_UNREGISTER_FINAL)
+ goto out;
+
+ in_dev = __in_dev_get_rtnl(dev);
ASSERT_RTNL();
if (!in_dev) {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 7f073a3..fd7d9ae 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1041,7 +1041,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
- struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev;
struct net *net = dev_net(dev);
if (event == NETDEV_UNREGISTER) {
@@ -1050,9 +1050,11 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
return NOTIFY_DONE;
}
- if (!in_dev)
+ if (event == NETDEV_UNREGISTER_FINAL)
return NOTIFY_DONE;
+ in_dev = __in_dev_get_rtnl(dev);
+
switch (event) {
case NETDEV_UP:
for_ifa(in_dev) {
@@ -1071,8 +1073,6 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
case NETDEV_CHANGE:
rt_cache_flush(dev_net(dev), 0);
break;
- case NETDEV_UNREGISTER_BATCH:
- break;
}
return NOTIFY_DONE;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6bc85f7..e581009 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2566,10 +2566,14 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
void *data)
{
struct net_device *dev = (struct net_device *) data;
- struct inet6_dev *idev = __in6_dev_get(dev);
+ struct inet6_dev *idev;
int run_pending = 0;
int err;
+ if (event == NETDEV_UNREGISTER_FINAL)
+ return NOTIFY_DONE;
+
+ idev = __in6_dev_get(dev);
switch (event) {
case NETDEV_REGISTER:
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
^ permalink raw reply related
* Re: [PATCH] net: dev: fix the incorrect hold of net namespace's lo device
From: Eric Dumazet @ 2012-08-23 3:13 UTC (permalink / raw)
To: Gao feng; +Cc: ebiederm, davem, netdev
In-Reply-To: <1345624786.5158.759.camel@edumazet-glaptop>
On Wed, 2012-08-22 at 10:39 +0200, Eric Dumazet wrote:
> rcu_barrier() at this place will kill some workloads.
For example, I tested the following one :
modprobe dummy numdummies=1000
time rmmod dummy
-> 16.5 seconds instead of 0.4 second
^ permalink raw reply
* Re: [PATCH] net: dev: fix the incorrect hold of net namespace's lo device
From: Gao feng @ 2012-08-23 3:09 UTC (permalink / raw)
To: Eric Dumazet; +Cc: ebiederm, davem, netdev
In-Reply-To: <1345634667.5158.1114.camel@edumazet-glaptop>
于 2012年08月22日 19:24, Eric Dumazet 写道:
> On Wed, 2012-08-22 at 19:00 +0800, Gao feng wrote:
>
>> Hi Eric
>>
>> I saw your patch and think this patch is clear and doesn't change too much logic.
>>
>> I test your patch, it not fix this problem.
>>
>> In my test case,when moving a net device to another net namespace,
>> Because you patch delete NETDEV_UNREGISTER event from dst_dev_event,
>> we will just put dst entries into the dst garbage list in event
>> NETDEV_DOWN,without call dst_ifdown to change these dst entries' device
>> to the lo device,and now this net device belongs to the new net namespace.
>>
>
> Then fix the "moving a net device to another net namespace", instead
> of slowing down other common operations.
>
okay, I will send a patch to fix this problem after your patch beeing applied.
> dev_change_net_namespace() is probably a better place to put your patch
>
>> After the net device beeing moved to another net namespace, I rmmod this
>> net device's driver,this will trigger the new added event NETDEV_UNREGISTER_FINISH,
>> so in dst_dev_event,we will change these dst entries's device to the new net
>> namespace's lo device,and this will make the referenct count of the new net namespace's
>> lo device incorrect. when we exit the new net namespace,this emg message is still exist.
>>
>> Message from syslogd@Donkey at Aug 22 18:50:13 ...
>> kernel:[ 1161.979036] unregister_netdevice: waiting for lo to become free. Usage count = 1
>>
>> And because net_mutex is locked here,so we can't create new net namespace.
>>
>>> rcu_barrier() at this place will kill some workloads.
>>>
>>
>> I think this will only add some workloads when unregister a net device.
>> Do I miss something?
>
> Yes, rcu_barrier() at this point is killing performance, because we hold
> RTNL.
>
> We worked hard to batch things, your patch is a huge step backward.
>
Get it,thanks for your explanation.
^ permalink raw reply
* Re: [PATCH net-next v2] net: remove delay at device dismantle
From: Eric Dumazet @ 2012-08-23 2:58 UTC (permalink / raw)
To: David Miller; +Cc: gaofeng, netdev, therbert, maheshb, ebiederm
In-Reply-To: <20120822.195111.765545116604962053.davem@davemloft.net>
On Wed, 2012-08-22 at 19:51 -0700, David Miller wrote:
> From: Gao feng <gaofeng@cn.fujitsu.com>
> > Hi Eric
> >
> > I got this warning message with your patch applied.
>
> Ok I won't push this out until this is resolved.
Thanks, I'll send a v2
^ permalink raw reply
* Re: [PATCH net-next v2] net: remove delay at device dismantle
From: David Miller @ 2012-08-23 2:51 UTC (permalink / raw)
To: gaofeng; +Cc: eric.dumazet, netdev, therbert, maheshb, ebiederm
In-Reply-To: <5035947C.8090609@cn.fujitsu.com>
From: Gao feng <gaofeng@cn.fujitsu.com>
Date: Thu, 23 Aug 2012 10:25:00 +0800
> 于 2012年08月11日 13:54, Eric Dumazet 写道:
>> On Fri, 2012-08-10 at 17:42 +0200, Eric Dumazet wrote:
>>> From: Eric Dumazet <edumazet@google.com>
>>>
>>> I noticed extra one second delay in device dismantle, tracked down to
>>> a call to dst_dev_event() while some call_rcu() are still in RCU queues.
>>>
>> ...
>>> Signed-off-by: Eric Dumazet <edumazet@google.com>
>>> Cc: Tom Herbert <therbert@google.com>
>>> Cc: Mahesh Bandewar <maheshb@google.com>
>>> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
>>> ---
>>> v2: NETDEV_UNREGISTER_FINAL called outside of rtnl lock
>>> as its more risky, base this patch on net-next
>>
>> Also I am leaving for a one week vacation with no access to the
>> Internet, so better hold this patch until my return ;)
>>
>
> Hi Eric
>
> I got this warning message with your patch applied.
Ok I won't push this out until this is resolved.
^ 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