* Re: [net-next 00/13][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2011-10-07 16:38 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, gospo, sassmann
In-Reply-To: <1317971926-23145-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Fri, 7 Oct 2011 00:18:32 -0700
> The following series contains updates to e1000, e1000e, igb and ixgbe. Here
> is a quick summary:
> - e1000: 3 conversions (timers->threads, mdelay->msleep, mutex->rtnl)
> - e1000e: fix jumbo frames on 82579
> - igb: several cleanups to reduce stack space and improve performance
> - ixgbe: bump driver ver
>
> The following are changes since commit e878d78b9a7403fabc89ecc93c56928b74d14f01:
> virtio-net: Verify page list size before fitting into skb
> and are available in the git repository at
> git://github.com/Jkirsher/net-next.git
Pulled, thanks Jeff.
^ permalink raw reply
* Re: [PATCH net-next] Add ethtool -g support to 8139cp
From: Rick Jones @ 2011-10-07 16:38 UTC (permalink / raw)
To: David Miller; +Cc: bhutchings, netdev
In-Reply-To: <20111005.175329.2143609207723954863.davem@davemloft.net>
On 10/05/2011 02:53 PM, David Miller wrote:
> From: Ben Hutchings<bhutchings@solarflare.com>
> Date: Wed, 05 Oct 2011 19:50:48 +0100
>
>> You generally don't need to set fields to zero in ethtool 'get'
>> operations, as the ethtool core will initialise the entire structure to
>> zero.
>
> Rick, please remove the explicit zero initializations and resubmit,
> thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Ben/Dave
Thanks for the feedback. I'll tweak and resend under separate cover.
rick
simply copying what he saw in e1000_get_ringparm :)
^ permalink raw reply
* Re: [PATCH] dev: use name hash for dev_seq_ops.
From: Stephen Hemminger @ 2011-10-07 16:24 UTC (permalink / raw)
To: Mihai Maruseac
Cc: davem, eric.dumazet, mirq-linux, therbert, jpirko, netdev,
linux-kernel, dbaluta, Mihai Maruseac
In-Reply-To: <1318000849-2531-1-git-send-email-mmaruseac@ixiacom.com>
On Fri, 7 Oct 2011 18:20:49 +0300
Mihai Maruseac <mihai.maruseac@gmail.com> wrote:
> Instead of using the dev->next chain and trying to resync at each call to
> dev_seq_start, use this hash and store bucket number and bucket offset in
> seq->private field.
>
> Tests revealed the following results for ifconfig > /dev/null
> * 1000 interfaces:
> * 0.114s without patch
> * 0.020s with patch
> * 3000 interfaces:
> * 0.489s without patch
> * 0.048s with patch
> * 5000 interfaces:
> * 1.363s without patch
> * 0.131s with patch
>
> As one can notice the improvement is of 1 order of magnitude.
Good idea,
This will change the ordering of entries in /proc which may upset
some program, not a critical flaw but worth noting.
Rather than recording the bucket and offset of last entry, another
alternative would be to just record the ifindex.
Also ifconfig is considered deprecated and replaced by ip commands
for general use.
^ permalink raw reply
* e1000e might_sleep warnings (3.1-rc9)
From: Dave Jones @ 2011-10-07 16:14 UTC (permalink / raw)
To: netdev
Just had this reported..
> [20734.109233] Call Trace:
> [20734.109242] [<ffffffff8104f6b5>] __might_sleep+0x103/0x108
> [20734.109249] [<ffffffff8150363e>] mutex_lock_nested+0x25/0x45
> [20734.109260] [<ffffffffa023b8f7>] e1000_acquire_swflag_ich8lan+0x26/0x136 [e1000e]
> [20734.109271] [<ffffffffa024a3af>] e1000e_update_stats+0x156/0x73e [e1000e]
> [20734.109275] [<ffffffff81504561>] ? _raw_spin_lock+0x71/0x79
> [20734.109285] [<ffffffffa024e658>] ? e1000_watchdog_task+0x3b1/0x5de [e1000e]
> [20734.109294] [<ffffffffa024e660>] e1000_watchdog_task+0x3b9/0x5de [e1000e]
> [20734.109303] [<ffffffffa024e2a7>] ? e1000_update_mng_vlan+0x68/0x68 [e1000e]
> [20734.109307] [<ffffffff81075b21>] process_one_work+0x205/0x3e7
> [20734.109310] [<ffffffff81075a69>] ? process_one_work+0x14d/0x3e7
> [20734.109315] [<ffffffff8108cf0f>] ? lock_acquired+0x210/0x243
> [20734.109320] [<ffffffff810767cf>] worker_thread+0xda/0x15d
> [20734.109323] [<ffffffff810766f5>] ? manage_workers+0x176/0x176
> [20734.109327] [<ffffffff8107a195>] kthread+0xa8/0xb0
> [20734.109332] [<ffffffff8150dec4>] kernel_thread_helper+0x4/0x10
> [20734.109336] [<ffffffff81505334>] ? retint_restore_args+0x13/0x13
> [20734.109340] [<ffffffff8107a0ed>] ? __init_kthread_worker+0x5a/0x5a
> [20734.109344] [<ffffffff8150dec0>] ? gs_change+0x13/0x13
> [20736.106653] BUG: sleeping function called from invalid context at kernel/mutex.c:271
> [20736.106658] in_atomic(): 1, irqs_disabled(): 0, pid: 18071, name: kworker/0:1
> [20736.106661] INFO: lockdep is turned off.
> [20736.106664] Pid: 18071, comm: kworker/0:1 Not tainted 3.1.0-0.rc9.git0.0.fc17.x86_64 #1
> [20736.106667] Call Trace:
> [20736.106675] [<ffffffff8104f6b5>] __might_sleep+0x103/0x108
> [20736.106682] [<ffffffff8150363e>] mutex_lock_nested+0x25/0x45
> [20736.106693] [<ffffffffa023b8f7>] e1000_acquire_swflag_ich8lan+0x26/0x136 [e1000e]
> [20736.106705] [<ffffffffa024a3af>] e1000e_update_stats+0x156/0x73e [e1000e]
> [20736.106709] [<ffffffff81504561>] ? _raw_spin_lock+0x71/0x79
> [20736.106719] [<ffffffffa024e658>] ? e1000_watchdog_task+0x3b1/0x5de [e1000e]
> [20736.106728] [<ffffffffa024e660>] e1000_watchdog_task+0x3b9/0x5de [e1000e]
> [20736.106737] [<ffffffffa024e2a7>] ? e1000_update_mng_vlan+0x68/0x68 [e1000e]
> [20736.106741] [<ffffffff81075b21>] process_one_work+0x205/0x3e7
> [20736.106744] [<ffffffff81075a69>] ? process_one_work+0x14d/0x3e7
> [20736.106749] [<ffffffff8108cf0f>] ? lock_acquired+0x210/0x243
> [20736.106754] [<ffffffff810767cf>] worker_thread+0xda/0x15d
> [20736.106757] [<ffffffff810766f5>] ? manage_workers+0x176/0x176
> [20736.106761] [<ffffffff8107a195>] kthread+0xa8/0xb0
> [20736.106767] [<ffffffff8150dec4>] kernel_thread_helper+0x4/0x10
> [20736.106771] [<ffffffff81505334>] ? retint_restore_args+0x13/0x13
> [20736.106775] [<ffffffff8107a0ed>] ? __init_kthread_worker+0x5a/0x5a
> [20736.106779] [<ffffffff8150dec0>] ? gs_change+0x13/0x13
> [20738.104064] BUG: sleeping function called from invalid context at kernel/mutex.c:271
> [20738.104070] in_atomic(): 1, irqs_disabled(): 0, pid: 18071, name: kworker/0:1
> [20738.104073] INFO: lockdep is turned off.
> [20738.104077] Pid: 18071, comm: kworker/0:1 Not tainted 3.1.0-0.rc9.git0.0.fc17.x86_64 #1
> [20738.104079] Call Trace:
> [20738.104088] [<ffffffff8104f6b5>] __might_sleep+0x103/0x108
> [20738.104096] [<ffffffff8150363e>] mutex_lock_nested+0x25/0x45
> [20738.104107] [<ffffffffa023b8f7>] e1000_acquire_swflag_ich8lan+0x26/0x136 [e1000e]
> [20738.104118] [<ffffffffa024a3af>] e1000e_update_stats+0x156/0x73e [e1000e]
> [20738.104123] [<ffffffff81504561>] ? _raw_spin_lock+0x71/0x79
> [20738.104133] [<ffffffffa024e658>] ? e1000_watchdog_task+0x3b1/0x5de [e1000e]
> [20738.104142] [<ffffffffa024e660>] e1000_watchdog_task+0x3b9/0x5de [e1000e]
> [20738.104151] [<ffffffffa024e2a7>] ? e1000_update_mng_vlan+0x68/0x68 [e1000e]
> [20738.104155] [<ffffffff81075b21>] process_one_work+0x205/0x3e7
> [20738.104158] [<ffffffff81075a69>] ? process_one_work+0x14d/0x3e7
> [20738.104162] [<ffffffff8108cf0f>] ? lock_acquired+0x210/0x243
> [20738.104167] [<ffffffff810767cf>] worker_thread+0xda/0x15d
> [20738.104170] [<ffffffff810766f5>] ? manage_workers+0x176/0x176
> [20738.104175] [<ffffffff8107a195>] kthread+0xa8/0xb0
> [20738.104180] [<ffffffff8150dec4>] kernel_thread_helper+0x4/0x10
> [20738.104184] [<ffffffff81505334>] ? retint_restore_args+0x13/0x13
> [20738.104188] [<ffffffff8107a0ed>] ? __init_kthread_worker+0x5a/0x5a
> [20738.104192] [<ffffffff8150dec0>] ? gs_change+0x13/0x13
>
>
>
> On my x220 ThinnkPad.
^ permalink raw reply
* [PATCH net-next] l2tp: give proper headroom in pppol2tp_xmit()
From: Eric Dumazet @ 2011-10-07 15:45 UTC (permalink / raw)
To: David Miller; +Cc: netdev
pppol2tp_xmit() calls skb_cow_head(skb, 2) before calling
l2tp_xmit_skb()
Then l2tp_xmit_skb() calls again skb_cow_head(skb, large_headroom)
This patchs changes the first skb_cow_head() call to supply the needed
headroom to make sure at most one (expensive) pskb_expand_head() is
done.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
Maybe we should add a counter to help diagnose too many
pskb_expand_head() calls...
net/l2tp/l2tp_ppp.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index f42cd09..8a90d75 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -395,6 +395,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
struct pppol2tp_session *ps;
int old_headroom;
int new_headroom;
+ int uhlen, headroom;
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
goto abort;
@@ -413,7 +414,13 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
goto abort_put_sess;
old_headroom = skb_headroom(skb);
- if (skb_cow_head(skb, sizeof(ppph)))
+ uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
+ headroom = NET_SKB_PAD +
+ sizeof(struct iphdr) + /* IP header */
+ uhlen + /* UDP header (if L2TP_ENCAPTYPE_UDP) */
+ session->hdr_len + /* L2TP header */
+ sizeof(ppph); /* PPP header */
+ if (skb_cow_head(skb, headroom))
goto abort_put_sess_tun;
new_headroom = skb_headroom(skb);
^ permalink raw reply related
* [PATCH] l2tp: fix a potential skb leak in l2tp_xmit_skb()
From: Eric Dumazet @ 2011-10-07 15:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
l2tp_xmit_skb() can leak one skb if skb_cow_head() returns an error.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/l2tp/l2tp_core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index ad4ac26..34b2dde 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
headroom = NET_SKB_PAD + sizeof(struct iphdr) +
uhlen + hdr_len;
old_headroom = skb_headroom(skb);
- if (skb_cow_head(skb, headroom))
+ if (skb_cow_head(skb, headroom)) {
+ dev_kfree_skb(skb);
goto abort;
+ }
new_headroom = skb_headroom(skb);
skb_orphan(skb);
^ permalink raw reply related
* [PATCH] dev: use name hash for dev_seq_ops.
From: Mihai Maruseac @ 2011-10-07 15:20 UTC (permalink / raw)
To: davem
Cc: eric.dumazet, mirq-linux, therbert, jpirko, netdev, linux-kernel,
dbaluta, Mihai Maruseac
Instead of using the dev->next chain and trying to resync at each call to
dev_seq_start, use this hash and store bucket number and bucket offset in
seq->private field.
Tests revealed the following results for ifconfig > /dev/null
* 1000 interfaces:
* 0.114s without patch
* 0.020s with patch
* 3000 interfaces:
* 0.489s without patch
* 0.048s with patch
* 5000 interfaces:
* 1.363s without patch
* 0.131s with patch
As one can notice the improvement is of 1 order of magnitude.
Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
---
net/core/dev.c | 73 +++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index bf49a47..2d0f126 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4034,6 +4034,51 @@ static int dev_ifconf(struct net *net, char __user *arg)
}
#ifdef CONFIG_PROC_FS
+
+struct dev_iter_state {
+ struct seq_net_private p;
+ int bucket;
+ int offset;
+};
+
+static inline struct net_device *dev_from_same_bucket(struct seq_file *seq)
+{
+ struct net_device *dev = NULL;
+ struct net *net = seq_file_net(seq);
+ struct dev_iter_state *state = seq->private;
+ struct hlist_node *p;
+ struct hlist_head *h;
+ int count;
+
+ h = &net->dev_name_head[state->bucket];
+ count = 0;
+ hlist_for_each_entry_rcu(dev, p, h, name_hlist) {
+ if (count++ == state->offset) {
+ state->offset = count;
+ return dev;
+ }
+ }
+
+ return NULL;
+}
+
+static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
+{
+ struct dev_iter_state *state = seq->private;
+ struct net_device *dev = NULL;
+
+ while (state->bucket < NETDEV_HASHENTRIES) {
+ dev = dev_from_same_bucket(seq);
+ if (dev)
+ return dev;
+
+ state->bucket++;
+ state->offset = 0;
+ }
+
+ return NULL;
+}
+
/*
* This is invoked by the /proc filesystem handler to display a device
* in detail.
@@ -4041,33 +4086,27 @@ static int dev_ifconf(struct net *net, char __user *arg)
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
{
- struct net *net = seq_file_net(seq);
- loff_t off;
- struct net_device *dev;
-
rcu_read_lock();
if (!*pos)
return SEQ_START_TOKEN;
- off = 1;
- for_each_netdev_rcu(net, dev)
- if (off++ == *pos)
- return dev;
-
- return NULL;
+ return dev_from_new_bucket(seq);
}
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct net_device *dev = v;
+ struct net_device *dev = NULL;
+
+ ++*pos;
if (v == SEQ_START_TOKEN)
- dev = first_net_device_rcu(seq_file_net(seq));
- else
- dev = next_net_device_rcu(dev);
+ return dev_from_new_bucket(seq);
- ++*pos;
- return dev;
+ dev = dev_from_same_bucket(seq);
+ if (dev)
+ return dev;
+
+ return dev_from_new_bucket(seq);
}
void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4166,7 +4205,7 @@ static const struct seq_operations dev_seq_ops = {
static int dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dev_seq_ops,
- sizeof(struct seq_net_private));
+ sizeof(struct dev_iter_state));
}
static const struct file_operations dev_seq_fops = {
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH] net: use sock_valbool_flag to set/clear SOCK_RXQ_OVFL
From: Neil Horman @ 2011-10-07 13:40 UTC (permalink / raw)
To: Johannes Berg; +Cc: netdev
In-Reply-To: <1317994221.3988.12.camel@jlt3.sipsolutions.net>
On Fri, Oct 07, 2011 at 03:30:20PM +0200, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> There's no point in open-coding sock_valbool_flag().
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> net/core/sock.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> --- a/net/core/sock.c 2011-10-07 15:26:30.000000000 +0200
> +++ b/net/core/sock.c 2011-10-07 15:27:46.000000000 +0200
> @@ -738,10 +738,7 @@ set_rcvbuf:
> /* We implement the SO_SNDLOWAT etc to
> not be settable (1003.1g 5.3) */
> case SO_RXQ_OVFL:
> - if (valbool)
> - sock_set_flag(sk, SOCK_RXQ_OVFL);
> - else
> - sock_reset_flag(sk, SOCK_RXQ_OVFL);
> + sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
> break;
> default:
> ret = -ENOPROTOOPT;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Looks good, thanks Johannes!
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [RFC PATCH net 2/2] [BUGFIX] bonding: use flush_delayed_work_sync in bond_close
From: Américo Wang @ 2011-10-07 13:34 UTC (permalink / raw)
To: Mitsuo Hayasaka
Cc: Jay Vosburgh, Andy Gospodarek, netdev, linux-kernel,
yrl.pp-manager.tt
In-Reply-To: <20111007125006.7089.9539.stgit@ltc219.sdl.hitachi.co.jp>
On Fri, Oct 7, 2011 at 8:50 PM, Mitsuo Hayasaka
<mitsuo.hayasaka.hu@hitachi.com> wrote:
> The bond_close() calls cancel_delayed_work() to cancel delayed works.
> It, however, cannot cancel works that were already queued in workqueue.
> The bond_open() initializes work->data, and proccess_one_work() refers
> get_work_cwq(work)->wq->flags. The get_work_cwq() returns NULL when
> work->data has been initialized. Thus, a panic occurs.
>
> This patch uses flush_delayed_work_sync() instead of cancel_delayed_work()
> in bond_close(). It cancels delayed timer and waits for work to finish
> execution. So, it can avoid the null pointer dereference due to the
> parallel executions of proccess_one_work() and initializing proccess
> of bond_open().
>
> Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
> Cc: Jay Vosburgh <fubar@us.ibm.com>
> Cc: Andy Gospodarek <andy@greyhouse.net>
Makes sense,
Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>
Thanks!
^ permalink raw reply
* Old Mobile-IP code and modern Linux
From: Joerg Pommnitz @ 2011-10-07 13:27 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hello all,
I'm trying to run the old dynamics Mobile IP implementation (see http://dynamics.sourceforge.net/) on a modern Linux kernel (Fedora 15 2.6.40 aka 3.0).
There seems to be a problem in the communication between a mobile node and the foreign agent. The mobile node sends UDP packets with a source address from its own home network to the discovered address of the FA. Unfortunately the FA never sees these packets. It seems that packets with an unexpected source address will be discarded (ingress filtering?). Is there a way to disable this behavior? What is the right way to implement MobileIP on a recent Linux kernel?
Thanks in advance
Joerg
^ permalink raw reply
* [PATCH] net: use sock_valbool_flag to set/clear SOCK_RXQ_OVFL
From: Johannes Berg @ 2011-10-07 13:30 UTC (permalink / raw)
To: netdev
From: Johannes Berg <johannes.berg@intel.com>
There's no point in open-coding sock_valbool_flag().
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/core/sock.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/net/core/sock.c 2011-10-07 15:26:30.000000000 +0200
+++ b/net/core/sock.c 2011-10-07 15:27:46.000000000 +0200
@@ -738,10 +738,7 @@ set_rcvbuf:
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
case SO_RXQ_OVFL:
- if (valbool)
- sock_set_flag(sk, SOCK_RXQ_OVFL);
- else
- sock_reset_flag(sk, SOCK_RXQ_OVFL);
+ sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
break;
default:
ret = -ENOPROTOOPT;
^ permalink raw reply
* Re: [RFC PATCH net 1/2] [BUGFIX] bonding: use local function pointer of bond->recv_probe in bond_handle_frame
From: Américo Wang @ 2011-10-07 13:24 UTC (permalink / raw)
To: Mitsuo Hayasaka
Cc: Jay Vosburgh, Andy Gospodarek, netdev, linux-kernel,
yrl.pp-manager.tt
In-Reply-To: <20111007124954.7089.9776.stgit@ltc219.sdl.hitachi.co.jp>
On Fri, Oct 7, 2011 at 8:49 PM, Mitsuo Hayasaka
<mitsuo.hayasaka.hu@hitachi.com> wrote:
> The bond->recv_probe is called in bond_handle_frame() when
> a packet is received, but bond_close() sets it to NULL. So,
> a panic occurs when both functions work in parallel.
>
> Why this happen:
> After null pointer check of bond->recv_probe, an sk_buff is
> duplicated and bond->recv_probe is called in bond_handle_frame.
> So, a panic occurs when bond_close() is called between the
> check and call of bond->recv_probe.
>
> Patch:
> This patch uses a local function pointer of bond->recv_probe
> in bond_handle_frame(). So, it can avoid the null pointer
> dereference.
>
Hmm, I don't doubt it can fix the problem, I am wondering if
bond->recv_probe should be protected by bond->lock...
^ permalink raw reply
* [RFC PATCH net 2/2] [BUGFIX] bonding: use flush_delayed_work_sync in bond_close
From: Mitsuo Hayasaka @ 2011-10-07 12:50 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek
Cc: netdev, linux-kernel, yrl.pp-manager.tt, Mitsuo Hayasaka,
Jay Vosburgh, Andy Gospodarek
In-Reply-To: <20111007124925.7089.27260.stgit@ltc219.sdl.hitachi.co.jp>
The bond_close() calls cancel_delayed_work() to cancel delayed works.
It, however, cannot cancel works that were already queued in workqueue.
The bond_open() initializes work->data, and proccess_one_work() refers
get_work_cwq(work)->wq->flags. The get_work_cwq() returns NULL when
work->data has been initialized. Thus, a panic occurs.
This patch uses flush_delayed_work_sync() instead of cancel_delayed_work()
in bond_close(). It cancels delayed timer and waits for work to finish
execution. So, it can avoid the null pointer dereference due to the
parallel executions of proccess_one_work() and initializing proccess
of bond_open().
Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
---
drivers/net/bonding/bond_main.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f1baec5..cd490b7 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3504,27 +3504,27 @@ static int bond_close(struct net_device *bond_dev)
write_unlock_bh(&bond->lock);
if (bond->params.miimon) { /* link check interval, in milliseconds. */
- cancel_delayed_work(&bond->mii_work);
+ flush_delayed_work_sync(&bond->mii_work);
}
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- cancel_delayed_work(&bond->arp_work);
+ flush_delayed_work_sync(&bond->arp_work);
}
switch (bond->params.mode) {
case BOND_MODE_8023AD:
- cancel_delayed_work(&bond->ad_work);
+ flush_delayed_work_sync(&bond->ad_work);
break;
case BOND_MODE_TLB:
case BOND_MODE_ALB:
- cancel_delayed_work(&bond->alb_work);
+ flush_delayed_work_sync(&bond->alb_work);
break;
default:
break;
}
if (delayed_work_pending(&bond->mcast_work))
- cancel_delayed_work(&bond->mcast_work);
+ flush_delayed_work_sync(&bond->mcast_work);
if (bond_is_lb(bond)) {
/* Must be called only after all
^ permalink raw reply related
* [RFC PATCH net 1/2] [BUGFIX] bonding: use local function pointer of bond->recv_probe in bond_handle_frame
From: Mitsuo Hayasaka @ 2011-10-07 12:49 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek
Cc: netdev, linux-kernel, yrl.pp-manager.tt, Mitsuo Hayasaka,
Jay Vosburgh, Andy Gospodarek
In-Reply-To: <20111007124925.7089.27260.stgit@ltc219.sdl.hitachi.co.jp>
The bond->recv_probe is called in bond_handle_frame() when
a packet is received, but bond_close() sets it to NULL. So,
a panic occurs when both functions work in parallel.
Why this happen:
After null pointer check of bond->recv_probe, an sk_buff is
duplicated and bond->recv_probe is called in bond_handle_frame.
So, a panic occurs when bond_close() is called between the
check and call of bond->recv_probe.
Patch:
This patch uses a local function pointer of bond->recv_probe
in bond_handle_frame(). So, it can avoid the null pointer
dereference.
Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
---
drivers/net/bonding/bond_main.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6d79b78..f1baec5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1435,6 +1435,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
+ void (*recv_probe)(struct sk_buff *, struct bonding *,
+ struct slave *);
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
@@ -1448,11 +1450,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
- if (bond->recv_probe) {
+ recv_probe = bond->recv_probe;
+ if (recv_probe) {
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
if (likely(nskb)) {
- bond->recv_probe(nskb, bond, slave);
+ recv_probe(nskb, bond, slave);
dev_kfree_skb(nskb);
}
}
^ permalink raw reply related
* [RFC PATCH net 0/2] bonding: fix panics for making bonding device up and down repeatedly
From: Mitsuo Hayasaka @ 2011-10-07 12:49 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek; +Cc: netdev, linux-kernel, yrl.pp-manager.tt
Hi,
I hit a kernel BUG when I made a bonding interface up and down
repeatedly, as below.
# while true; do ifconfig bond0 down; done &
# while true; do ifconfig bond0 up; done &
(panic messages are bottom of this mail)
I investigated it and found the below commit tries to address
this kind of parallel up&down problem.
a0db2dad0935e798973bb79676e722b82f177206 "bonding: properly stop
queuing work when requested"
However, above fix is not enough. I've found two different BUG
patterns.
They happens as follows:
(1) NULL pointer dereference in bond_handle_frame()
1. bond_close() sets bond->recv_probe to NULL.
2. bond_handle_frame() calls bond->recv_probe.
3. a panic happens when running bond_close() in parallel
with bond_handle_frame().
(2) NULL pointer dereference in proccess_one_work()
1. bond_close() calls cancel_delayed_work() but its last works
are not cancelled because they were already queued in workqueue.
2. bond_open() initializes work->data.
3. process_one_work() refers get_work_cwq(work)->wq->flags in
workqueue.c:1850, but get_work_cwq() returns NULL when work->data
has been initialized.
4. a panic happens when running process_one_work() in parallel with
bond_open().
Each log is shown below.
The following two patches addresses these panics in detail:
[PATCH 1/2] use local function pointer of bond->recv_probe
in bond_handle_frame
[PATCH 2/2] use flush_delayed_work_sync in bond_close
Thanks,
============== log for a panic in bond_handle_frame=========
# while true; do ifconfig bond0 down; done &
[1] 1441
# while true; do ifconfig bond0 up; done &
[2] 3383
# [ 296.794817] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 296.795761] IP: [< (null)>] (null)
[ 296.795761] PGD 79515067 PUD 375e9067 PMD 0
[ 296.795761] Oops: 0010 [#1] SMP
[ 296.795761] CPU 0
[ 296.795761] Modules linked in: nfs lockd fscache auth_rpcgss nfs_acl sunrpc bonding snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm pcspkr virtio_balloon microcode i2c_piix4 joydev snd_timer snd virtio_net i2c_core soundcore snd_page_alloc ipv6 xfs exportfs virtio_blk [last unloaded: speedstep_lib]
[ 296.795761]
[ 296.795761] Pid: 0, comm: swapper Not tainted 3.1.0-rc9+ #4 Bochs Bochs
[ 296.795761] RIP: 0010:[<0000000000000000>] [< (null)>] (null)
[ 296.795761] RSP: 0018:ffff88007fc03d28 EFLAGS: 00010286
[ 296.795761] RAX: ffff88007b1e6500 RBX: ffff88007b1e6a00 RCX: 0000000000000000
[ 296.795761] RDX: ffff880037670e00 RSI: ffff88007b522740 RDI: ffff88007b1e6500
[ 296.795761] RBP: ffff88007fc03d50 R08: 0000000000000000 R09: 0000000180100001
[ 296.795761] R10: ffffffff81a01fd8 R11: ffffffff81a01fd8 R12: ffff88007b522740
[ 296.795761] R13: ffff880037670e00 R14: ffff88007b1e6500 R15: ffffe8ffffc02578
[ 296.795761] FS: 0000000000000000(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
[ 296.795761] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 296.795761] CR2: 0000000000000000 CR3: 00000000794f9000 CR4: 00000000000006f0
[ 296.795761] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 296.795761] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 296.795761] Process swapper (pid: 0, threadinfo ffffffff81a00000, task ffffffff81a0d020)
[ 296.795761] Stack:
[ 296.795761] ffffffffa00b64d0 ffffffffa00b642e 0000000000000001 ffff880037a3f000
[ 296.795761] 0000000000000000 ffff88007fc03db0 ffffffff813e2996 000000000000002e
[ 296.795761] ffff88007b1e6a00 ffff88007fc03d90 ffffffff81b5be40 ffff88007b1e6a00
[ 296.795761] Call Trace:
[ 296.795761] <IRQ>
[ 296.795761] [<ffffffffa00b64d0>] ? bond_handle_frame+0xa2/0x160 [bonding]
[ 296.795761] [<ffffffffa00b642e>] ? skb_cow_head+0x70/0x70 [bonding]
[ 296.795761] [<ffffffff813e2996>] __netif_receive_skb+0x2c5/0x417
[ 296.795761] [<ffffffff813e5c22>] netif_receive_skb+0x6c/0x73
[ 296.795761] [<ffffffffa0155360>] virtnet_poll+0x49a/0x562 [virtio_net]
[ 296.795761] [<ffffffff813e623b>] net_rx_action+0xa9/0x1b8
[ 296.795761] [<ffffffff8105c61b>] __do_softirq+0xc9/0x1b5
[ 296.795761] [<ffffffff81014fa0>] ? sched_clock+0x9/0xd
[ 296.795761] [<ffffffff814b8c2c>] call_softirq+0x1c/0x30
[ 296.795761] [<ffffffff81010af9>] do_softirq+0x46/0x81
[ 296.795761] [<ffffffff8105c8e3>] irq_exit+0x57/0xb1
[ 296.795761] [<ffffffff814b950e>] do_IRQ+0x8e/0xa5
[ 296.795761] [<ffffffff814b062e>] common_interrupt+0x6e/0x6e
[ 296.795761] <EOI>
[ 296.795761] [<ffffffff810b27c3>] ? rcu_needs_cpu+0x11a/0x1cb
[ 296.795761] [<ffffffff8102f2f1>] ? native_safe_halt+0xb/0xd
[ 296.795761] [<ffffffff81015b32>] default_idle+0x4e/0x86
[ 296.795761] [<ffffffff8100e2ed>] cpu_idle+0xae/0xe8
[ 296.795761] [<ffffffff8148cd6e>] rest_init+0x72/0x74
[ 296.795761] [<ffffffff81b74b7d>] start_kernel+0x3ab/0x3b6
[ 296.795761] [<ffffffff81b742c4>] x86_64_start_reservations+0xaf/0xb3
[ 296.795761] [<ffffffff81b74140>] ? early_idt_handlers+0x140/0x140
[ 296.795761] [<ffffffff81b743ca>] x86_64_start_kernel+0x102/0x111
[ 296.795761] Code: Bad RIP value.
[ 296.795761] RIP [< (null)>] (null)
[ 296.795761] RSP <ffff88007fc03d28>
[ 296.795761] CR2: 0000000000000000
[ 296.846940] ---[ end trace 2d2403022cca4fe1 ]---
[ 296.847691] Kernel panic - not syncing: Fatal exception in interrupt
[ 296.848701] Pid: 0, comm: swapper Tainted: G D 3.1.0-rc9+ #4
[ 296.849717] Call Trace:
[ 296.850122] <IRQ> [<ffffffff814a6f2b>] panic+0x91/0x1a5
[ 296.851080] [<ffffffff814b13e6>] oops_end+0xb4/0xc5
[ 296.851856] [<ffffffff814a67d5>] no_context+0x203/0x212
[ 296.852710] [<ffffffff813e7601>] ? dev_queue_xmit+0x44b/0x472
[ 296.853641] [<ffffffff814a69af>] __bad_area_nosemaphore+0x1cb/0x1ec
[ 296.854654] [<ffffffffa00bc52c>] ? bond_3ad_xmit_xor+0x130/0x156 [bonding]
[ 296.855747] [<ffffffff814a69e3>] bad_area_nosemaphore+0x13/0x15
[ 296.856705] [<ffffffff814b33a3>] do_page_fault+0x1b8/0x37e
[ 296.857602] [<ffffffff811131d5>] ? virt_to_head_page+0xe/0x31
[ 296.858533] [<ffffffff81114f7a>] ? __cmpxchg_double_slab+0x2c/0x9e
[ 296.859538] [<ffffffff814a9d74>] ? __slab_alloc+0x39f/0x3b4
[ 296.860453] [<ffffffff813dcde0>] ? skb_clone+0x77/0x97
[ 296.861277] [<ffffffff8102fdbd>] ? pvclock_clocksource_read+0x48/0xb4
[ 296.862325] [<ffffffff814b08f5>] page_fault+0x25/0x30
[ 296.863148] [<ffffffffa00b64d0>] ? bond_handle_frame+0xa2/0x160 [bonding]
[ 296.864235] [<ffffffffa00b642e>] ? skb_cow_head+0x70/0x70 [bonding]
[ 296.865242] [<ffffffff813e2996>] __netif_receive_skb+0x2c5/0x417
[ 296.866218] [<ffffffff813e5c22>] netif_receive_skb+0x6c/0x73
[ 296.867134] [<ffffffffa0155360>] virtnet_poll+0x49a/0x562 [virtio_net]
[ 296.868166] [<ffffffff813e623b>] net_rx_action+0xa9/0x1b8
[ 296.869037] [<ffffffff8105c61b>] __do_softirq+0xc9/0x1b5
[ 296.869888] [<ffffffff81014fa0>] ? sched_clock+0x9/0xd
[ 296.870726] [<ffffffff814b8c2c>] call_softirq+0x1c/0x30
[ 296.871584] [<ffffffff81010af9>] do_softirq+0x46/0x81
[ 296.872402] [<ffffffff8105c8e3>] irq_exit+0x57/0xb1
[ 296.873192] [<ffffffff814b950e>] do_IRQ+0x8e/0xa5
[ 296.873940] [<ffffffff814b062e>] common_interrupt+0x6e/0x6e
[ 296.874846] <EOI> [<ffffffff810b27c3>] ? rcu_needs_cpu+0x11a/0x1cb
[ 296.875881] [<ffffffff8102f2f1>] ? native_safe_halt+0xb/0xd
[ 296.876771] [<ffffffff81015b32>] default_idle+0x4e/0x86
[ 296.877615] [<ffffffff8100e2ed>] cpu_idle+0xae/0xe8
[ 296.878412] [<ffffffff8148cd6e>] rest_init+0x72/0x74
[ 296.879215] [<ffffffff81b74b7d>] start_kernel+0x3ab/0x3b6
[ 296.880096] [<ffffffff81b742c4>] x86_64_start_reservations+0xaf/0xb3
[ 296.881189] [<ffffffff81b74140>] ? early_idt_handlers+0x140/0x140
[ 296.882169] [<ffffffff81b743ca>] x86_64_start_kernel+0x102/0x111
============== log for a panic in proccess_one_work=========
# while true; do ifconfig bond0 down; done &
[1] 1463
# while true; do ifconfig bond0 up; done &
[2] 7093
# [ 734.859163] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[ 734.862624] IP: [<ffffffff8106da2e>] process_one_work+0x104/0x2a9
[ 734.862624] PGD 0
[ 734.862624] Oops: 0000 [#1] SMP
[ 734.862624] CPU 3
[ 734.862624] Modules linked in: fuse nfs lockd fscache auth_rpcgss nfs_acl sunrpc bonding snd_hda_intel snd_hda_codec snd_hwdep joydev snd_seq snd_seq_device snd_pcm pcspkr microcode virtio_net virtio_balloon snd_timer snd soundcore snd_page_alloc i2c_piix4 i2c_core ipv6 xfs exportfs virtio_blk [last unloaded: speedstep_lib]
[ 734.862624]
[ 734.862624] Pid: 47, comm: kworker/u:1 Not tainted 3.1.0-rc9+ #4 Bochs Bochs
[ 734.862624] RIP: 0010:[<ffffffff8106da2e>] [<ffffffff8106da2e>] process_one_work+0x104/0x2a9
[ 734.862624] RSP: 0018:ffff880078f95e50 EFLAGS: 00010046
[ 734.862624] RAX: 0000000000000000 RBX: ffff880078f5af00 RCX: 0000000000010000
[ 734.862624] RDX: 0000000000010000 RSI: ffff88007bcada50 RDI: ffff88007bcad8f8
[ 734.862624] RBP: ffff880078f95ea0 R08: ffff88007bcad900 R09: ffff880076c1bf00
[ 734.862624] R10: ffff880076c1bf00 R11: ffff88007fd92e40 R12: ffffffff81cc3dc0
[ 734.862624] R13: ffff88007a81f600 R14: ffffffffa00b8759 R15: ffff88007a81f607
[ 734.862624] FS: 0000000000000000(0000) GS:ffff88007fd80000(0000) knlGS:0000000000000000
[ 734.862624] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 734.862624] CR2: 0000000000000008 CR3: 0000000001a05000 CR4: 00000000000006e0
[ 734.862624] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 734.862624] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 734.862624] Process kworker/u:1 (pid: 47, threadinfo ffff880078f94000, task ffff880078f3ae40)
[ 734.862624] Stack:
[ 734.862624] ffffffff81cc3dc8 ffff88007bcad900 0000009a7bc54a70 ffff88007bcad8f8
[ 734.862624] ffffffff81cc3dc0 ffff880078f5af00 ffffffff81cc3dc0 ffff880078f5af20
[ 734.862624] ffff880078f3ae40 ffff880078f5af20 ffff880078f95ee0 ffffffff8106e5aa
[ 734.862624] Call Trace:
[ 734.862624] [<ffffffff8106e5aa>] worker_thread+0xda/0x15d
[ 734.862624] [<ffffffff8106e4d0>] ? manage_workers+0x176/0x176
[ 734.862624] [<ffffffff810719f7>] kthread+0x84/0x8c
[ 734.862624] [<ffffffff814b8b34>] kernel_thread_helper+0x4/0x10
[ 734.862624] [<ffffffff81071973>] ? kthread_worker_fn+0x148/0x148
[ 734.862624] [<ffffffff814b8b30>] ? gs_change+0x13/0x13
[ 734.862624] Code: 8b 55 c8 48 89 42 08 48 89 42 10 41 f6 44 24 1c 10 74 31 49 8b 7c 24 08 49 8d 44 24 08 48 39 c7 74 1c 48 83 ef 08 e8 6a e0 ff ff
[ 734.862624] 8b 40 08 f6 00 10 74 0a 4c 89 e7 e8 85 e4 ff ff eb 06 41 83
[ 734.862624] RIP [<ffffffff8106da2e>] process_one_work+0x104/0x2a9
[ 734.862624] RSP <ffff880078f95e50>
[ 734.862624] CR2: 0000000000000008
[ 734.862624] ---[ end trace 7cf0d13647b8711b ]---
[ 734.997227] BUG: unable to handle kernel paging request at fffffffffffffff8
Mess[age fr om734.998114] IP:
---
Mitsuo Hayasaka (2):
[BUGFIX] bonding: use flush_delayed_work_sync in bond_close
[BUGFIX] bonding: use local function pointer of bond->recv_probe in bond_handle_frame
drivers/net/bonding/bond_main.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
--
Mitsuo Hayasaka (mitsuo.hayasaka.hu@hitachi.com)
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Eric Dumazet @ 2011-10-07 12:23 UTC (permalink / raw)
To: Josh Boyer; +Cc: Joel Sing, Julian Anastasov, netdev
In-Reply-To: <1317989073.3207.10.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Le vendredi 07 octobre 2011 à 14:04 +0200, Eric Dumazet a écrit :
> Its a completely different problem IMHO : You describe a tftp server
> bug.
>
> Say your tftp server is multihomed with 3 different IPS :
>
> 192.168.20.21, 192.168.20.22, 192.168.20.23
>
> And tftp server listens to any address (UDP port 69) : 0.0.0.0:69
>
> When receiving a request on 192.168.20.22, it should use same source
> address, not let the system chose a "random or whatever policy" one.
>
>
>
> So I would suggest to check/fix if TFTP server uses the correct socket
> API to get both the client IP and its own IP in each UDP datagram
>
> -> setsockopt(fd, IPPROTO_IP, &on, sizeof(on))
> This permits tftp server to use the same "struct in_pktinfo" for replies, forcing a correct source address.
>
By the way, there is no need for tftp change :
Just launch several tftpd instances, and bind each them to one
particular IP.
If started from xinetd.d :
$ cat /etc/xinetd.d/tftp1
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
bind = 192.168.20.21
per_source = 11
cps = 100 2
flags = IPv4
}
$ cat /etc/xinetd.d/tftp2
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
bind = 192.168.20.22
per_source = 11
cps = 100 2
flags = IPv4
}
$ cat /etc/xinetd.d/tftp3
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
bind = 192.168.20.23
per_source = 11
cps = 100 2
flags = IPv4
}
^ permalink raw reply
* Re: [PATCH 1/2 net-next] r6040: invoke phy_{start,stop} when appropriate
From: Florian Fainelli @ 2011-10-07 12:13 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev
In-Reply-To: <1317983087.3207.1.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Friday 07 October 2011 12:24:47 Eric Dumazet wrote:
> Le vendredi 07 octobre 2011 à 11:36 +0200, Florian Fainelli a écrit :
> > Joe reported to me that right after a bring up of a r6040 interface
> > the ethtool output had no consistent output with respect to link duplex
> > and speed. Fix this by adding a missing phy_start call in r6040_up and
> > conversely a phy_stop call in r6040_down to properly initialize phy
> > states.
> >
> > Reported-by: Joe Chou <Joe.Chou@rdc.com.tw>
> > Signed-off-by: Florian Fainelli <florian@openwrt.org>
> > ---
> > diff --git a/drivers/net/ethernet/rdc/r6040.c
> > b/drivers/net/ethernet/rdc/r6040.c index 2bbadc0..a128c3d 100644
> > --- a/drivers/net/ethernet/rdc/r6040.c
> > +++ b/drivers/net/ethernet/rdc/r6040.c
> > @@ -470,6 +470,8 @@ static void r6040_down(struct net_device *dev)
> >
> > iowrite16(adrp[0], ioaddr + MID_0L);
> > iowrite16(adrp[1], ioaddr + MID_0M);
> > iowrite16(adrp[2], ioaddr + MID_0H);
> >
> > +
> > + phy_stop(lp->phydev);
> >
> > }
> >
> > static int r6040_close(struct net_device *dev)
> >
> > @@ -727,6 +729,8 @@ static int r6040_up(struct net_device *dev)
> >
> > /* Initialize all MAC registers */
> > r6040_init_mac_regs(dev);
> >
> > + phy_start(lp->phydev);
> > +
> >
> > return 0;
> >
> > }
>
> You dont need to submit your patches twice (net and net-next)
>
> If its a bug fix, base your patch against net tree
>
> If its a new feature, against net-next
Allright, thanks for the tip. I just thought that would make it easier for
David to get this applied (especially after the drivers reorganization).
--
Florian
^ permalink raw reply
* [PATCH 1/1] ethtool: add ETHTOOL_{G,S}CHANNEL support.
From: Sucheta Chakraborty @ 2011-10-07 11:58 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, Dept_NX_Linux_NIC_Driver
In-Reply-To: <1317988730-4197-1-git-send-email-sucheta.chakraborty@qlogic.com>
Used to configure number of tx/ rx/ other channels.
Reqd. man page changes are included.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
---
ethtool.8.in | 29 ++++++++++++++
ethtool.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index efc6098..f9d3633 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -307,6 +307,16 @@ ethtool \- query or control network driver and hardware settings
.BN action
.BN loc
.RB ]
+.HP
+.B ethtool \-l|\-\-show\-channels
+.I ethX
+.HP
+.B ethtool \-L|\-\-set\-channels
+.I ethX
+.BN rx
+.BN tx
+.BN other
+.BN combined
.
.\" Adjust lines (i.e. full justification) and hyphenate.
.ad
@@ -754,6 +764,25 @@ lB l.
Specify the location/ID to insert the rule. This will overwrite
any rule present in that location and will not go through any
of the rule ordering process.
+.TP
+.B \-l \-\-show\-channels
+Queries the specified network device for the numbers of channels it has.
+A channel is an IRQ and the set of queues that can trigger that IRQ.
+.TP
+.B \-L \-\-set\-channels
+Changes the numbers of channels of the specified network device.
+.TP
+.BI rx \ N
+Changes the number of channels with only receive queues.
+.TP
+.BI tx \ N
+Changes the number of channels with only transmit queues.
+.TP
+.BI other \ N
+Changes the number of channels used only for other purposes e.g. link interrupts or SR-IOV co-ordination.
+.TP
+.BI combined \ N
+Changes the number of multi-purpose channels.
.SH BUGS
Not supported (in part or whole) on all network drivers.
.SH AUTHOR
diff --git a/ethtool.c b/ethtool.c
index d7d2d58..c533a48 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -80,6 +80,8 @@ static int do_gpause(int fd, struct ifreq *ifr);
static int do_spause(int fd, struct ifreq *ifr);
static int do_gring(int fd, struct ifreq *ifr);
static int do_sring(int fd, struct ifreq *ifr);
+static int do_schannels(int fd, struct ifreq *ifr);
+static int do_gchannels(int fd, struct ifreq *ifr);
static int do_gcoalesce(int fd, struct ifreq *ifr);
static int do_scoalesce(int fd, struct ifreq *ifr);
static int do_goffload(int fd, struct ifreq *ifr);
@@ -133,6 +135,8 @@ static enum {
MODE_PERMADDR,
MODE_SET_DUMP,
MODE_GET_DUMP,
+ MODE_GCHANNELS,
+ MODE_SCHANNELS
} mode = MODE_GSET;
static struct option {
@@ -266,6 +270,12 @@ static struct option {
{ "-W", "--set-dump", MODE_SET_DUMP,
"Set dump flag of the device",
" N\n"},
+ { "-l", "--show-channels", MODE_GCHANNELS, "Query Channels" },
+ { "-L", "--set-channels", MODE_SCHANNELS, "Set Channels",
+ " [ rx N ]\n"
+ " [ tx N ]\n"
+ " [ other N ]\n"
+ " [ combined N ]\n" },
{ "-h", "--help", MODE_HELP, "Show this help" },
{ NULL, "--version", MODE_VERSION, "Show version number" },
{}
@@ -331,6 +341,13 @@ static s32 ring_rx_mini_wanted = -1;
static s32 ring_rx_jumbo_wanted = -1;
static s32 ring_tx_wanted = -1;
+static struct ethtool_channels echannels;
+static int gchannels_changed;
+static s32 channels_rx_wanted = -1;
+static s32 channels_tx_wanted = -1;
+static s32 channels_other_wanted = -1;
+static s32 channels_combined_wanted = -1;
+
static struct ethtool_coalesce ecoal;
static int gcoalesce_changed = 0;
static s32 coal_stats_wanted = -1;
@@ -495,6 +512,13 @@ static struct cmdline_info cmdline_ring[] = {
{ "tx", CMDL_S32, &ring_tx_wanted, &ering.tx_pending },
};
+static struct cmdline_info cmdline_channels[] = {
+ { "rx", CMDL_S32, &channels_rx_wanted, &echannels.rx_count },
+ { "tx", CMDL_S32, &channels_tx_wanted, &echannels.tx_count },
+ { "other", CMDL_S32, &channels_other_wanted, &echannels.other_count },
+ { "combined", CMDL_S32, &channels_combined_wanted, &echannels.combined_count },
+};
+
static struct cmdline_info cmdline_coalesce[] = {
{ "adaptive-rx", CMDL_BOOL, &coal_adaptive_rx_wanted, &ecoal.use_adaptive_rx_coalesce },
{ "adaptive-tx", CMDL_BOOL, &coal_adaptive_tx_wanted, &ecoal.use_adaptive_tx_coalesce },
@@ -787,6 +811,8 @@ static void parse_cmdline(int argc, char **argp)
(mode == MODE_GCOALESCE) ||
(mode == MODE_SCOALESCE) ||
(mode == MODE_GRING) ||
+ (mode == MODE_GCHANNELS) ||
+ (mode == MODE_SCHANNELS) ||
(mode == MODE_SRING) ||
(mode == MODE_GOFFLOAD) ||
(mode == MODE_SOFFLOAD) ||
@@ -871,6 +897,14 @@ static void parse_cmdline(int argc, char **argp)
i = argc;
break;
}
+ if (mode == MODE_SCHANNELS) {
+ parse_generic_cmdline(argc, argp, i,
+ &gchannels_changed,
+ cmdline_channels,
+ ARRAY_SIZE(cmdline_ring));
+ i = argc;
+ break;
+ }
if (mode == MODE_SCOALESCE) {
parse_generic_cmdline(argc, argp, i,
&gcoalesce_changed,
@@ -1751,6 +1785,32 @@ static int dump_ring(void)
return 0;
}
+static int dump_channels(void)
+{
+ fprintf(stdout,
+ "Pre-set maximums:\n"
+ "RX: %u\n"
+ "TX: %u\n"
+ "Other: %u\n"
+ "Combined: %u\n",
+ echannels.max_rx, echannels.max_tx,
+ echannels.max_other,
+ echannels.max_combined);
+
+ fprintf(stdout,
+ "Current hardware settings:\n"
+ "RX: %u\n"
+ "TX: %u\n"
+ "Other: %u\n"
+ "Combined: %u\n",
+ echannels.rx_count, echannels.tx_count,
+ echannels.other_count,
+ echannels.combined_count);
+
+ fprintf(stdout, "\n");
+ return 0;
+}
+
static int dump_coalesce(void)
{
fprintf(stdout, "Adaptive RX: %s TX: %s\n",
@@ -1937,6 +1997,10 @@ static int doit(void)
return do_gring(fd, &ifr);
} else if (mode == MODE_SRING) {
return do_sring(fd, &ifr);
+ } else if (mode == MODE_GCHANNELS) {
+ return do_gchannels(fd, &ifr);
+ } else if (mode == MODE_SCHANNELS) {
+ return do_schannels(fd, &ifr);
} else if (mode == MODE_GOFFLOAD) {
return do_goffload(fd, &ifr);
} else if (mode == MODE_SOFFLOAD) {
@@ -2114,6 +2178,62 @@ static int do_gring(int fd, struct ifreq *ifr)
return 0;
}
+static int do_schannels(int fd, struct ifreq *ifr)
+{
+ int err, changed = 0;
+
+ echannels.cmd = ETHTOOL_GCHANNELS;
+ ifr->ifr_data = (caddr_t)&echannels;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ perror("Cannot get device channel parameters");
+ return 1;
+ }
+
+ do_generic_set(cmdline_channels, ARRAY_SIZE(cmdline_channels),
+ &changed);
+
+ if (!changed) {
+ fprintf(stderr, "no channel parameters changed, aborting\n");
+ fprintf(stderr, "current values: tx %u rx %u other %u"
+ "combined %u\n", echannels.rx_count,
+ echannels.tx_count, echannels.other_count,
+ echannels.combined_count);
+ return 1;
+ }
+
+ echannels.cmd = ETHTOOL_SCHANNELS;
+ ifr->ifr_data = (caddr_t)&echannels;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ perror("Cannot set device channel parameters");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int do_gchannels(int fd, struct ifreq *ifr)
+{
+ int err;
+
+ fprintf(stdout, "Channel parameters for %s:\n", devname);
+
+ echannels.cmd = ETHTOOL_GCHANNELS;
+ ifr->ifr_data = (caddr_t)&echannels;
+ err = send_ioctl(fd, ifr);
+ if (err == 0) {
+ err = dump_channels();
+ if (err)
+ return err;
+ } else {
+ perror("Cannot get device channel parameters\n");
+ return 1;
+ }
+ return 0;
+
+}
+
static int do_gcoalesce(int fd, struct ifreq *ifr)
{
int err;
--
1.7.3.3
^ permalink raw reply related
* [PATCH 0/1] ethtool: {G, S}-CHANNEL support added
From: Sucheta Chakraborty @ 2011-10-07 11:58 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, Dept_NX_Linux_NIC_Driver
Thanks Ben for reviewing and applying the patches.
I have incorporated all the changes suggested by you for this patch.
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Eric Dumazet @ 2011-10-07 12:04 UTC (permalink / raw)
To: Josh Boyer; +Cc: Joel Sing, Julian Anastasov, netdev
In-Reply-To: <20111007114017.GA1165@zod.bos.redhat.com>
Le vendredi 07 octobre 2011 à 07:40 -0400, Josh Boyer a écrit :
> The original bug reporter explained the loopback testcase is simply a
> trivial example to illustrate the problem. The real setup seems to be:
>
> "I have a hardware (Dell PC) booting over the network with PXE, this
> hardware try to load it system from a tftp server. If I used the real
> ip of the tftp server I have no problem, if I used an alias I have the
> problem (I have to use an alias, because I have a Cluster).
>
> What I think, the bios tftp client talk to the server with the IP alias
> but the server reply with the real IP and the client reject the reply."
>
> So in this case, because the alias is being used in a cluster, should he
> also setup the local routing table as you suggested?
>
> I apologize for my lack of depth here. I'm at the moment somewhat of a
> go-between. I do greatly appreciate the help!
Its a completely different problem IMHO : You describe a tftp server
bug.
Say your tftp server is multihomed with 3 different IPS :
192.168.20.21, 192.168.20.22, 192.168.20.23
And tftp server listens to any address (UDP port 69) : 0.0.0.0:69
When receiving a request on 192.168.20.22, it should use same source
address, not let the system chose a "random or whatever policy" one.
So I would suggest to check/fix if TFTP server uses the correct socket
API to get both the client IP and its own IP in each UDP datagram
-> setsockopt(fd, IPPROTO_IP, &on, sizeof(on))
IP_PKTINFO
Pass an IP_PKTINFO ancillary message that contains a pktinfo structure that supplies some
information about the incoming packet. This only works for datagram oriented sockets. The
argument is a flag that tells the socket whether the IP_PKTINFO message should be passed or
not. The message itself can only be sent/retrieved as control message with a packet using
recvmsg(2) or sendmsg(2).
struct in_pktinfo {
unsigned int ipi_ifindex; /* Interface index */
struct in_addr ipi_spec_dst; /* Local address */
struct in_addr ipi_addr; /* Header Destination
address */
};
ipi_ifindex is the unique index of the interface the packet was received on. ipi_spec_dst
is the local address of the packet and ipi_addr is the destination address in the packet
header. If IP_PKTINFO is passed to sendmsg(2) and ipi_spec_dst is not zero, then it is used
as the local source address for the routing table lookup and for setting up IP source route
options. When ipi_ifindex is not zero, the primary local address of the interface specified
by the index overwrites ipi_spec_dst for the routing table lookup.
This permits tftp server to use the same "struct in_pktinfo" for replies, forcing a correct source address.
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Josh Boyer @ 2011-10-07 11:40 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Joel Sing, Julian Anastasov, netdev
In-Reply-To: <1317972573.3457.55.camel@edumazet-laptop>
On Fri, Oct 07, 2011 at 09:29:33AM +0200, Eric Dumazet wrote:
> Le vendredi 07 octobre 2011 à 18:02 +1100, Joel Sing a écrit :
> > > > > We've had a report [1] of a change in behavior when trying to use an IP
> > > > > alias to tftp from a loopback device. Apparently the steps outlined in
> > > > > [1] https://bugzilla.redhat.com/show_bug.cgi?id=739534
> > >
> > > Yep. That is exactly what my git bisect said too.
> > >
> > > So now we have a change in behavior since that commit for the usecase
> > > described in the bug above, but I'm unsure if that usecase was ever
> > > really valid or if the commit had unintentional side effects.
> > >
> > > Joel (or anyone else) can you take a look and comment?
> >
> > Prior to this commit the src address in the local routing table was
> > completely ignored, so connecting to a local address always used the
> > same source and destination addresses. However, this is not what was
> > configured in the local routing table:
> >
> > $ ifconfig lo:0 127.0.0.2
> > $ ip route show table local | grep 127.0.0.2
> > local 127.0.0.2 dev lo proto kernel scope host src 127.0.0.1
> >
> > When an interface has an alias configured, the source address
> > installed in the local routing table is always the primary address for
> > the interface. The tftp use case you've described now breaks due to
> > the way that in.tftpd is determining the reply address (as documented
> > in the in.tftpd manual page). This means that it is now responding
> > from 127.0.0.1 even though the client connected to 127.0.0.2. Binding
> > inetd to a specific address will avoid this issue.
> >
> > I have not yet looked to see if there is a specific reason for the
> > source address selection, however one way of restoring the previous
> > behaviour (whilst still respecting the configured source address)
> > would be to use a default source address which matches the configured
> > address (as is done for primary addresses). I cannot immediately think
> > of a reason not to do this, but I've not gone looking at the code.
> >
> > Worst case scenario if you specifically need the original behaviour
> > then the source address can be changed in the local routing table:
> >
> > $ ip route change table local local 127.0.0.2 dev lo:0 proto kernel
> > scope host src 127.0.0.2
> > $ ip route show table local | grep 127.0.0.2
> > local 127.0.0.2 dev lo proto kernel scope host src 127.0.0.2
>
> Agreed.
>
> The "table local" bit is really the key, because following naive setup
> doesnt work.
>
> # ip addr add 127.0.0.11/8 dev lo
> # ip route add 127.0.0.11 dev lo src 127.0.0.11
>
> since 127.0.0.1 will still be the src address selected for connections.
>
> # ip ro show table local | grep 127.0.0.11
> local 127.0.0.11 dev lo proto kernel scope host src 127.0.0.1
The original bug reporter explained the loopback testcase is simply a
trivial example to illustrate the problem. The real setup seems to be:
"I have a hardware (Dell PC) booting over the network with PXE, this
hardware try to load it system from a tftp server. If I used the real
ip of the tftp server I have no problem, if I used an alias I have the
problem (I have to use an alias, because I have a Cluster).
What I think, the bios tftp client talk to the server with the IP alias
but the server reply with the real IP and the client reject the reply."
So in this case, because the alias is being used in a cluster, should he
also setup the local routing table as you suggested?
I apologize for my lack of depth here. I'm at the moment somewhat of a
go-between. I do greatly appreciate the help!
josh
^ permalink raw reply
* Re: [PATCH] IPv6: DAD from bonding iface is treated as dup address from others
From: Neil Horman @ 2011-10-07 11:10 UTC (permalink / raw)
To: Yinglin Sun
Cc: Jay Vosburgh, David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, netdev
In-Reply-To: <CAN17JHUkeCarKf3U-0EMEyL+RJvZGV3GSQWG7+TZFy7ZvD8jYA@mail.gmail.com>
On Thu, Oct 06, 2011 at 06:24:36PM -0700, Yinglin Sun wrote:
> On Thu, Oct 6, 2011 at 5:59 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
> > Yinglin Sun <Yinglin.Sun@emc.com> wrote:
> >
> >>On Thu, Oct 6, 2011 at 3:17 PM, Yinglin Sun <Yinglin.Sun@emc.com> wrote:
> >>>
> >>> On Thu, Oct 6, 2011 at 12:05 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
> >>> >
> >>> > Neil Horman <nhorman@tuxdriver.com> wrote:
> >>> >
> >>> > >On Wed, Oct 05, 2011 at 08:59:10PM -0700, Yinglin Sun wrote:
> >>> > >> Steps to reproduce this issue:
> >>> > >> 1. create bond0 over eth0 and eth1, set the mode to balance-xor
> >>> > >> 2. add an IPv6 address to bond0
> >>> > >> 3. DAD packet is sent out from one slave and then is looped back from
> >>> > >> the other slave. Therefore, it is treated as a duplicate address and
> >>> > >> stays tentative afterwards:
> >>> > >> kern.info:
> >>> > >> Oct 5 11:50:18 testvm1 kernel: [ 129.224353] bond0: IPv6 duplicate address 1234::1 detected!
> >
> > [...]
> >
> >>> > >Nack, This seems like it will just completely break DAD. What if theres another
> >>> > >system out there with the same mac address. A response from that system would
> >>> > >get dropped by this filter, instead of causing The local system to stop using
> >>> > >the address. What you really want to do is modify
> >>> > >bond_should_deliver_exact_match to detect this frame on the inactive slave or
> >>> > >some such, and drop the frame there.
> >>> >
> >>> > Also NACK; and adding a bit of information. The balance-xor
> >>> > mode is nominally expecting to interact with a switch whose ports are
> >>> > set for etherchannel ("static link aggregation"), in which case the
> >>> > switch will not loop the packet back around.
> >>> >
> >>> > If your switch can do etherchannel, then enable it and the
> >>> > problem should go away. If your switch cannot do this, then you may
> >>> > have other issues, because all of the multicast or broadcast packets
> >>> > going out any bonding slave will loop around to another slave. You
> >>> > could also use 802.3ad / LACP if you switch supports that.
> >>> >
> >>> > For balance-xor (or balance-rr, for that matter) mode to a
> >>> > non-etherchannel switch, it's going to be difficult, if not impossible,
> >>> > to modify bond_should_deliver_exact_match, because there are no inactive
> >>> > slaves. In this mode, bonding is expecting the switch to balance
> >>> > incoming traffic across the ports, and not deliver looped back packets
> >>> > or duplicates. There are no restrictions on what type of traffic
> >>> > (mcast, bcast, ucast) may arrive on any given port.
> >>> >
> >>> > I can't think of a way to make the non-etherchannel case work
> >>> > for balance-xor (or balance-rr) without breaking the DAD functionality
> >>> > in the case of an actual duplicate. I'm not aware of a way to
> >>> > distinguish a looped back DAD probe from an actual duplicate address
> >>> > probe elsewhere on the network.
> >>> >
> >>>
> >>> Hi Neil & Jay,
> >>>
> >>> Thanks a lot for the comments.
> >>>
> >>> The use case is to add IPv6 address on the bonding interface first,
> >>> and then set up port channel on switch. We'll hit this issue and the
> >>> new address will stay tentative and unusable after port channel is set
> >>> up on switch. This patch is for this valid use case.
> >>>
> >>> Except failover mode, all slaves are active on receiving packets, so
> >>> we are receiving such looped back DAD and the bonding driver cannot
> >>> ignore them. I cannot think of a way to distinguish if a DAD is looped
> >>> back or from someone else having the same mac address. They look the
> >>> same to the host. If there is another machine having the same mac
> >>> address, this code path gets executed if both are doing DAD at the
> >>> same time for the same IPv6 address. Maybe we should find out what the
> >>> specification defines for this case?
> >>>
> >>
> >>RFC4862 has a discussion about this issue:
> >>http://tools.ietf.org/html/rfc4862#appendix-A
> >>The better solution could be to record the number of DAD sent out. If
> >>we received more DAD packets than we sent out, there is someone else
> >>on the network who has the same mac address and sent DAD for the same
> >>IPv6 address. However, this solution doesn't work with bonding
> >>interface, since all other active slaves but the one sending out DAD
> >>will receive packet looped back. It doesn't seem there is a simple
> >>solution for this issue.
> >
> > Why are you setting up the port channel after configuring the
> > bond?
> >
> > As a possible workaround, if you have control over the setup
> > process (perhaps it's some sort of manual process), adding one slave to
> > the bond, leaving the other soon-to-be slaves down, then setting up the
> > switch, and finally adding the remaining slaves should work around the
> > issue, since if the bond has only one slave it won't see any looped
> > packets.
> >
> > Or you could bring the bond up as active-backup, then change the
> > mode to balance-xor once the switch is configured.
> >
> > Ultimately, though, the problem stems from the settings mismatch
> > between the switch and the bonding system; balance-xor is meant to
> > interoperate with etherchannel, and when the switch is not configured
> > properly, correct behavior is difficult to guarantee.
> >
>
> Jay,
>
> Thanks a lot for the suggestion.
>
> It's mainly about usability. We would like to provide customers with
> consistent IPv6 configuration procedures as IPv4. Such workarounds
> could be confusing and generate customer calls.
>
Its not a workaround, its the way it has to be done. You can't just drop dad
packets because you can't tell the difference between those that are looped back
and those that are legitimaely from other hosts, so you need to do something
like what Jay is suggesting.
> Yinglin
>
^ permalink raw reply
* Re: [PATCH 1/2 net-next] r6040: invoke phy_{start,stop} when appropriate
From: Eric Dumazet @ 2011-10-07 10:24 UTC (permalink / raw)
To: Florian Fainelli; +Cc: davem, netdev
In-Reply-To: <201110071136.22107.florian@openwrt.org>
Le vendredi 07 octobre 2011 à 11:36 +0200, Florian Fainelli a écrit :
> Joe reported to me that right after a bring up of a r6040 interface
> the ethtool output had no consistent output with respect to link duplex
> and speed. Fix this by adding a missing phy_start call in r6040_up and
> conversely a phy_stop call in r6040_down to properly initialize phy states.
>
> Reported-by: Joe Chou <Joe.Chou@rdc.com.tw>
> Signed-off-by: Florian Fainelli <florian@openwrt.org>
> ---
> diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
> index 2bbadc0..a128c3d 100644
> --- a/drivers/net/ethernet/rdc/r6040.c
> +++ b/drivers/net/ethernet/rdc/r6040.c
> @@ -470,6 +470,8 @@ static void r6040_down(struct net_device *dev)
> iowrite16(adrp[0], ioaddr + MID_0L);
> iowrite16(adrp[1], ioaddr + MID_0M);
> iowrite16(adrp[2], ioaddr + MID_0H);
> +
> + phy_stop(lp->phydev);
> }
>
> static int r6040_close(struct net_device *dev)
> @@ -727,6 +729,8 @@ static int r6040_up(struct net_device *dev)
> /* Initialize all MAC registers */
> r6040_init_mac_regs(dev);
>
> + phy_start(lp->phydev);
> +
> return 0;
> }
>
You dont need to submit your patches twice (net and net-next)
If its a bug fix, base your patch against net tree
If its a new feature, against net-next
^ permalink raw reply
* [PATCH 2/2 net] r6040: bump version to 0.28 and date to 07Oct2011.
From: Florian Fainelli @ 2011-10-07 9:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stable
Signed-off-by: Florian Fainelli <florian@openwrt.org>
CC: stable@kernel.org # 2.6.38+
---
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index ab59538..6b21565 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.27"
-#define DRV_RELDATE "23Feb2011"
+#define DRV_VERSION "0.28"
+#define DRV_RELDATE "07Oct2011"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
--
1.7.4.1
^ permalink raw reply related
* [PATCH 1/2 net] r6040: invoke phy_{start,stop} when appropriate
From: Florian Fainelli @ 2011-10-07 9:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stable
Joe reported to me that right after a bring up of a r6040 interface
the ethtool output had no consistent output with respect to link duplex
and speed. Fix this by adding a missing phy_start call in r6040_up and
conversely a phy_stop call in r6040_down to properly initialize phy states.
Reported-by: Joe Chou <Joe.Chou@rdc.com.tw>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
CC: stable@kernel.org # 2.6.38+
---
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index b64fcee..ab59538 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -470,6 +470,8 @@ static void r6040_down(struct net_device *dev)
iowrite16(adrp[0], ioaddr + MID_0L);
iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H);
+
+ phy_stop(lp->phydev);
}
static int r6040_close(struct net_device *dev)
@@ -727,6 +729,8 @@ static int r6040_up(struct net_device *dev)
/* Initialize all MAC registers */
r6040_init_mac_regs(dev);
+ phy_start(lp->phydev);
+
return 0;
}
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox