* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 7:39 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337757862.14538.199.camel@ymzhang.sh.intel.com>
On Wed, 2012-05-23 at 15:24 +0800, Yanmin Zhang wrote:
> On Wed, 2012-05-23 at 09:13 +0200, Eric Dumazet wrote:
> > On Wed, 2012-05-23 at 08:55 +0200, Eric Dumazet wrote:
> >
> > > Please hold on, I'll send a v2
> >
> > I believe your patch should be fine, if you move back the
> > fib_info_cnt--;
> >
> > So only do the dev_put() in free_fib_info_rcu().
> We would do so in a new patch.
>
> >
> > No need to clear nh_dev to NULL since we are freeing fi at the end of
> > function.
> David suggests to reset it to NULL to detect other potential
> race conditions.
>
Yes but no.
Users are in a RCU read lock and we should not change nh_dev to NULL
while they are running.
Thats what I tried to do (David message gave me this wrong hint) but it
came to a dead issue.
Only after a grace period we can :
dev_put() all involved net_devices
kfree(fi)
> Besides above suggestions, how do you think about:
>
> fib_create_info=>fib_find_info, but fib_find_info is not protected by
> fib_info_lock. See the codes:
>
> fib_create_info()
> {
> ...
> link_it:
> ofi = fib_find_info(fi);
> if (ofi) {
> fi->fib_dead = 1;
> free_fib_info(fi);
> ofi->fib_treeref++;
> return ofi;
> }
> fi->fib_treeref++;
> atomic_inc(&fi->fib_clntref);
> spin_lock_bh(&fib_info_lock);
>
> ...
> }
>
> I plan to change it to hold fib_info_lock before calling fib_find_info. Is
> it ok for you?
Its not needed we hold RTNL mutex.
spinlock is needed mainly because of ip_fib_check_default(), but this
could be changed to use RCU as well.
(readers use RCU, writers already hold RTNL -> no more fib_info_lock )
^ permalink raw reply
* Re: [PATCH 1/4] stmmac: remove two useless initialisation
From: Giuseppe CAVALLARO @ 2012-05-23 7:38 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120523.024211.816676351593259308.davem@davemloft.net>
On 5/23/2012 8:42 AM, David Miller wrote:
>
> You really need to post your patches properly.
>
> In particular, you need to indicate, either in an initial "[PATCH 0/N]"
> posting, or in the subject lines of that patch, exactly what tree
> you are targetting.
>
> And if this is meant for net-next, I told you specifically that net-next
> is not open right now and you need to submit this later when I make
> the announcement here that it is open.
>
> We are in the middle of the merge window, and therefore you should only
> be submitting bug fixes against the 'net' tree.
Previous ones were for net-next and in fact in the subject I indeed used:
[net-next X/N] stmmac: ....
After your comment I re-sent them for net.git (pls see my previous email
where I clarified that).
I have always posted all my patches for net-next adding its suffix in
the subject.
For all the patches for net.git I've never added the suffix but I'll do
that.
I agree with you that the suffix should be added and I had understood
(and always used and fixed in my subjectprefix) that these were the
format of the patches in this mailing list
[PATCH] ... =>>> for net.git
[PATCH net-next] =>>> for net-next.git
So I'll use starting from now:
[PATCH (net.git)] =>>> for net.git
[PATCH (net-next)] =>>> for net-next.git
> It is extremely irritating that, when I go out of my way to make
> announcements here on this list, multiple times, about what kind of
> patches are appropriate and what kinds are not, and yet people still
> do not listen and they still submit any old crap they feel like
> submitting.
>
> People need to stop this, now.
>
> Pay attention to the development state, and follow the rules,
> otherwise you'll royally piss me off and I'll ignore your patches
> completely.
>
> Thanks.
>
>
>
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Yanmin Zhang @ 2012-05-23 7:24 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337757238.3361.1965.camel@edumazet-glaptop>
On Wed, 2012-05-23 at 09:13 +0200, Eric Dumazet wrote:
> On Wed, 2012-05-23 at 08:55 +0200, Eric Dumazet wrote:
>
> > Please hold on, I'll send a v2
>
> I believe your patch should be fine, if you move back the
> fib_info_cnt--;
>
> So only do the dev_put() in free_fib_info_rcu().
We would do so in a new patch.
>
> No need to clear nh_dev to NULL since we are freeing fi at the end of
> function.
David suggests to reset it to NULL to detect other potential
race conditions.
Besides above suggestions, how do you think about:
fib_create_info=>fib_find_info, but fib_find_info is not protected by
fib_info_lock. See the codes:
fib_create_info()
{
...
link_it:
ofi = fib_find_info(fi);
if (ofi) {
fi->fib_dead = 1;
free_fib_info(fi);
ofi->fib_treeref++;
return ofi;
}
fi->fib_treeref++;
atomic_inc(&fi->fib_clntref);
spin_lock_bh(&fib_info_lock);
...
}
I plan to change it to hold fib_info_lock before calling fib_find_info. Is
it ok for you?
Thanks for the direct speaking.
Yanmin
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 7:13 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337756138.3361.1922.camel@edumazet-glaptop>
On Wed, 2012-05-23 at 08:55 +0200, Eric Dumazet wrote:
> Please hold on, I'll send a v2
I believe your patch should be fine, if you move back the
fib_info_cnt--;
So only do the dev_put() in free_fib_info_rcu().
No need to clear nh_dev to NULL since we are freeing fi at the end of
function.
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 6:55 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337755623.14538.194.camel@ymzhang.sh.intel.com>
On Wed, 2012-05-23 at 14:47 +0800, Yanmin Zhang wrote:
> On Wed, 2012-05-23 at 08:27 +0200, Eric Dumazet wrote:
> > On Wed, 2012-05-23 at 14:15 +0800, Yanmin Zhang wrote:
> >
> > >
> > > Besides fi->fib_dev here, we need check fi->fib_hash, fi->fib_lhash,
> > > and nexthop_nh->nh_hash.
> >
> > No, its not needed.
> I am checking it now.
> fib_create_info=>fib_find_info, but fib_find_info is not protected by
> fib_info_lock. See the codes:
>
>
> link_it:
> ofi = fib_find_info(fi);
> if (ofi) {
> fi->fib_dead = 1;
> free_fib_info(fi);
> ofi->fib_treeref++;
> return ofi;
> }
>
> >
> > I am sending a patch, because I feel this area is too complex for non
> > netdev guys.
> Indeed, it's complicated. I will test your patches.
Please hold on, I'll send a v2
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Yanmin Zhang @ 2012-05-23 6:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337754459.3361.1850.camel@edumazet-glaptop>
On Wed, 2012-05-23 at 08:27 +0200, Eric Dumazet wrote:
> On Wed, 2012-05-23 at 14:15 +0800, Yanmin Zhang wrote:
>
> >
> > Besides fi->fib_dev here, we need check fi->fib_hash, fi->fib_lhash,
> > and nexthop_nh->nh_hash.
>
> No, its not needed.
I am checking it now.
fib_create_info=>fib_find_info, but fib_find_info is not protected by
fib_info_lock. See the codes:
link_it:
ofi = fib_find_info(fi);
if (ofi) {
fi->fib_dead = 1;
free_fib_info(fi);
ofi->fib_treeref++;
return ofi;
}
>
> I am sending a patch, because I feel this area is too complex for non
> netdev guys.
Indeed, it's complicated. I will test your patches.
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 6:43 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337755038.3361.1878.camel@edumazet-glaptop>
On Wed, 2012-05-23 at 08:37 +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index ffcb3b0..b56b91e 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2127,7 +2127,7 @@ static int __mkroute_input(struct sk_buff *skb,
> u32 itag;
>
> /* get a working reference to the output device */
> - out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res));
> + out_dev = __in_dev_get_rcu(rcu_dereference(FIB_RES_DEV(*res)));
This part might need additional fix (if FIB_RES_DEV(*res) is NULL),
because __in_dev_get_rcu() could crash dereferencing NULL pointer.
^ permalink raw reply
* Re: [PATCH 1/4] stmmac: remove two useless initialisation
From: David Miller @ 2012-05-23 6:42 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1337754964-21754-1-git-send-email-peppe.cavallaro@st.com>
You really need to post your patches properly.
In particular, you need to indicate, either in an initial "[PATCH 0/N]"
posting, or in the subject lines of that patch, exactly what tree
you are targetting.
And if this is meant for net-next, I told you specifically that net-next
is not open right now and you need to submit this later when I make
the announcement here that it is open.
We are in the middle of the merge window, and therefore you should only
be submitting bug fixes against the 'net' tree.
It is extremely irritating that, when I go out of my way to make
announcements here on this list, multiple times, about what kind of
patches are appropriate and what kinds are not, and yet people still
do not listen and they still submit any old crap they feel like
submitting.
People need to stop this, now.
Pay attention to the development state, and follow the rules,
otherwise you'll royally piss me off and I'll ignore your patches
completely.
Thanks.
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 6:37 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337749339.3361.1655.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
I am testing following patch, could you test it too ?
Thanks
[PATCH] ipv4: nh_dev should be rcu protected
Yanmin Zhang reported an OOPS and provided a patch.
<3>[23898.789643] BUG: sleeping function called from invalid context at
/data/buildbot/workdir/ics/hardware/intel/linux-2.6/arch/x86/mm/fault.c:1103
<3>[23898.862215] in_atomic(): 0, irqs_disabled(): 0, pid: 10526, name:
Thread-6683
<4>[23898.967805] HSU serial 0000:00:05.1: 0000:00:05.2:HSU serial
prevented me
to suspend...
<4>[23899.258526] Pid: 10526, comm: Thread-6683 Tainted: G W
3.0.8-137685-ge7742f9 #1
<4>[23899.357404] HSU serial 0000:00:05.1: 0000:00:05.2:HSU serial
prevented me
to suspend...
<4>[23899.904225] Call Trace:
<4>[23899.989209] [<c1227f50>] ? pgtable_bad+0x130/0x130
<4>[23900.000416] [<c1238c2a>] __might_sleep+0x10a/0x110
<4>[23900.007357] [<c1228021>] do_page_fault+0xd1/0x3c0
<4>[23900.013764] [<c18e9ba9>] ? restore_all+0xf/0xf
<4>[23900.024024] [<c17c007b>] ? napi_complete+0x8b/0x690
<4>[23900.029297] [<c1227f50>] ? pgtable_bad+0x130/0x130
<4>[23900.123739] [<c1227f50>] ? pgtable_bad+0x130/0x130
<4>[23900.128955] [<c18ea0c3>] error_code+0x5f/0x64
<4>[23900.133466] [<c1227f50>] ? pgtable_bad+0x130/0x130
<4>[23900.138450] [<c17f6298>] ? __ip_route_output_key+0x698/0x7c0
<4>[23900.144312] [<c17f5f8d>] ? __ip_route_output_key+0x38d/0x7c0
<4>[23900.150730] [<c17f63df>] ip_route_output_flow+0x1f/0x60
<4>[23900.156261] [<c181de58>] ip4_datagram_connect+0x188/0x2b0
<4>[23900.161960] [<c18e981f>] ? _raw_spin_unlock_bh+0x1f/0x30
<4>[23900.167834] [<c18298d6>] inet_dgram_connect+0x36/0x80
<4>[23900.173224] [<c14f9e88>] ? _copy_from_user+0x48/0x140
<4>[23900.178817] [<c17ab9da>] sys_connect+0x9a/0xd0
<4>[23900.183538] [<c132e93c>] ? alloc_file+0xdc/0x240
<4>[23900.189111] [<c123925d>] ? sub_preempt_count+0x3d/0x50
But real fix is to provide appropriate RCU protection to nh_dev/fib_dev,
with appropriate __rcu annotation.
tested with CONFIG_PROVE_RCU and CONFIG_SPARSE_RCU_POINTER
Reported-by: Yanmin Zhang <yanmin_zhang@linux.intel.com>
Reported-by: Kun Jiang <kunx.jiang@intel.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/inetdevice.h | 8 ++-
include/net/ip_fib.h | 2
net/ipv4/devinet.c | 11 ++--
net/ipv4/fib_frontend.c | 6 +-
net/ipv4/fib_semantics.c | 66 ++++++++++++++++++----------
net/ipv4/fib_trie.c | 11 ++--
net/ipv4/netfilter/ipt_rpfilter.c | 4 -
net/ipv4/route.c | 4 -
8 files changed, 71 insertions(+), 41 deletions(-)
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 597f4a9..8cfa569 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -172,7 +172,13 @@ extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
extern void devinet_init(void);
extern struct in_device *inetdev_by_index(struct net *, int);
-extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
+
+extern __be32 __inet_select_addr(struct net *net,
+ const struct net_device *dev,
+ __be32 dst, int scope);
+#define inet_select_addr(dev, dst, scope) \
+ __inet_select_addr(dev_net(dev), (dev), (dst), (scope))
+
extern __be32 inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope);
extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 78df0866..9d49426 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -46,7 +46,7 @@ struct fib_config {
struct fib_info;
struct fib_nh {
- struct net_device *nh_dev;
+ struct net_device __rcu *nh_dev;
struct hlist_node nh_hash;
struct fib_info *nh_parent;
unsigned int nh_flags;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 10e15a1..be1e75c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -164,7 +164,7 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
if (local &&
!fib_table_lookup(local, &fl4, &res, FIB_LOOKUP_NOREF) &&
res.type == RTN_LOCAL)
- result = FIB_RES_DEV(res);
+ result = rcu_dereference(FIB_RES_DEV(res));
}
if (result && devref)
dev_hold(result);
@@ -960,14 +960,15 @@ out:
return done;
}
-__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
+__be32 __inet_select_addr(struct net *net,
+ const struct net_device *dev,
+ __be32 dst, int scope)
{
__be32 addr = 0;
struct in_device *in_dev;
- struct net *net = dev_net(dev);
rcu_read_lock();
- in_dev = __in_dev_get_rcu(dev);
+ in_dev = dev ? __in_dev_get_rcu(dev) : NULL;
if (!in_dev)
goto no_in_dev;
@@ -1007,7 +1008,7 @@ out_unlock:
rcu_read_unlock();
return addr;
}
-EXPORT_SYMBOL(inet_select_addr);
+EXPORT_SYMBOL(__inet_select_addr);
static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
__be32 local, int scope)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 3854411..2479884 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -159,7 +159,7 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
ret = RTN_UNICAST;
rcu_read_lock();
if (!fib_table_lookup(local_table, &fl4, &res, FIB_LOOKUP_NOREF)) {
- if (!dev || dev == res.fi->fib_dev)
+ if (!dev || dev == rcu_dereference(res.fi->fib_dev))
ret = res.type;
}
rcu_read_unlock();
@@ -237,13 +237,13 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
for (ret = 0; ret < res.fi->fib_nhs; ret++) {
struct fib_nh *nh = &res.fi->fib_nh[ret];
- if (nh->nh_dev == dev) {
+ if (rcu_dereference(nh->nh_dev) == dev) {
dev_match = true;
break;
}
}
#else
- if (FIB_RES_DEV(res) == dev)
+ if (rcu_dereference(FIB_RES_DEV(res)) == dev)
dev_match = true;
#endif
if (dev_match) {
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index a8bdf74..a09f055 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -157,9 +157,13 @@ void free_fib_info(struct fib_info *fi)
return;
}
change_nexthops(fi) {
- if (nexthop_nh->nh_dev)
- dev_put(nexthop_nh->nh_dev);
- nexthop_nh->nh_dev = NULL;
+ struct net_device *ndev;
+
+ ndev = rtnl_dereference(nexthop_nh->nh_dev);
+ if (ndev) {
+ dev_put(ndev);
+ RCU_INIT_POINTER(nexthop_nh->nh_dev, NULL);
+ }
} endfor_nexthops(fi);
fib_info_cnt--;
release_net(fi->fib_net);
@@ -273,7 +277,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)
hash = fib_devindex_hashfn(dev->ifindex);
head = &fib_info_devhash[hash];
hlist_for_each_entry(nh, node, head, nh_hash) {
- if (nh->nh_dev == dev &&
+ if (rcu_access_pointer(nh->nh_dev) == dev &&
nh->nh_gw == gw &&
!(nh->nh_flags & RTNH_F_DEAD)) {
spin_unlock(&fib_info_lock);
@@ -360,13 +364,17 @@ struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
return NULL;
}
+/* called in rcu_read_lock() section */
int fib_detect_death(struct fib_info *fi, int order,
struct fib_info **last_resort, int *last_idx, int dflt)
{
- struct neighbour *n;
+ struct neighbour *n = NULL;
int state = NUD_NONE;
+ struct net_device *ndev = rcu_dereference(fi->fib_dev);
+
+ if (ndev)
+ n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, ndev);
- n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
if (n) {
state = n->nud_state;
neigh_release(n);
@@ -551,7 +559,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
return -ENODEV;
if (!(dev->flags & IFF_UP))
return -ENETDOWN;
- nh->nh_dev = dev;
+ rcu_assign_pointer(nh->nh_dev, dev);
dev_hold(dev);
nh->nh_scope = RT_SCOPE_LINK;
return 0;
@@ -578,7 +586,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
goto out;
nh->nh_scope = res.scope;
nh->nh_oif = FIB_RES_OIF(res);
- nh->nh_dev = dev = FIB_RES_DEV(res);
+ dev = rcu_dereference(FIB_RES_DEV(res));
+ rcu_assign_pointer(nh->nh_dev, dev);
if (!dev)
goto out;
dev_hold(dev);
@@ -597,8 +606,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
err = -ENETDOWN;
if (!(in_dev->dev->flags & IFF_UP))
goto out;
- nh->nh_dev = in_dev->dev;
- dev_hold(nh->nh_dev);
+ rcu_assign_pointer(nh->nh_dev, in_dev->dev);
+ dev_hold(in_dev->dev);
nh->nh_scope = RT_SCOPE_HOST;
err = 0;
}
@@ -695,9 +704,14 @@ static void fib_info_hash_move(struct hlist_head *new_info_hash,
__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
{
- nh->nh_saddr = inet_select_addr(nh->nh_dev,
- nh->nh_gw,
- nh->nh_parent->fib_scope);
+ struct net_device *ndev;
+
+ rcu_read_lock();
+ ndev = rcu_dereference(nh->nh_dev);
+ nh->nh_saddr = __inet_select_addr(net, ndev,
+ nh->nh_gw,
+ nh->nh_parent->fib_scope);
+ rcu_read_unlock();
nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
return nh->nh_saddr;
@@ -843,7 +857,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
if (nhs != 1 || nh->nh_gw)
goto err_inval;
nh->nh_scope = RT_SCOPE_NOWHERE;
- nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
+ RCU_INIT_POINTER(nh->nh_dev,
+ dev_get_by_index(net, fi->fib_nh->nh_oif));
err = -ENODEV;
if (nh->nh_dev == NULL)
goto failure;
@@ -889,10 +904,11 @@ link_it:
change_nexthops(fi) {
struct hlist_head *head;
unsigned int hash;
+ struct net_device *ndev = rtnl_dereference(nexthop_nh->nh_dev);
- if (!nexthop_nh->nh_dev)
+ if (!ndev)
continue;
- hash = fib_devindex_hashfn(nexthop_nh->nh_dev->ifindex);
+ hash = fib_devindex_hashfn(ndev->ifindex);
head = &fib_info_devhash[hash];
hlist_add_head(&nexthop_nh->nh_hash, head);
} endfor_nexthops(fi)
@@ -1049,14 +1065,14 @@ int fib_sync_down_dev(struct net_device *dev, int force)
int dead;
BUG_ON(!fi->fib_nhs);
- if (nh->nh_dev != dev || fi == prev_fi)
+ if (rtnl_dereference(nh->nh_dev) != dev || fi == prev_fi)
continue;
prev_fi = fi;
dead = 0;
change_nexthops(fi) {
if (nexthop_nh->nh_flags & RTNH_F_DEAD)
dead++;
- else if (nexthop_nh->nh_dev == dev &&
+ else if (rtnl_dereference(nexthop_nh->nh_dev) == dev &&
nexthop_nh->nh_scope != scope) {
nexthop_nh->nh_flags |= RTNH_F_DEAD;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -1068,7 +1084,8 @@ int fib_sync_down_dev(struct net_device *dev, int force)
dead++;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (force > 1 && nexthop_nh->nh_dev == dev) {
+ if (force > 1 &&
+ rtnl_dereference(nexthop_nh->nh_dev) == dev) {
dead = fi->fib_nhs;
break;
}
@@ -1167,20 +1184,23 @@ int fib_sync_up(struct net_device *dev)
int alive;
BUG_ON(!fi->fib_nhs);
- if (nh->nh_dev != dev || fi == prev_fi)
+ if (rtnl_dereference(nh->nh_dev) != dev || fi == prev_fi)
continue;
prev_fi = fi;
alive = 0;
change_nexthops(fi) {
+ struct net_device *ndev;
+
if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
alive++;
continue;
}
- if (nexthop_nh->nh_dev == NULL ||
- !(nexthop_nh->nh_dev->flags & IFF_UP))
+ ndev = rtnl_dereference(nexthop_nh->nh_dev);
+ if (ndev == NULL ||
+ !(ndev->flags & IFF_UP))
continue;
- if (nexthop_nh->nh_dev != dev ||
+ if (ndev != dev ||
!__in_dev_get_rtnl(dev))
continue;
alive++;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 30b88d7..3861ba0 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -2556,11 +2556,14 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
|| fa->fa_type == RTN_MULTICAST)
continue;
- if (fi)
+ if (fi) {
+ struct net_device *ndev;
+
+ ndev = rcu_dereference(fi->fib_dev);
seq_printf(seq,
"%s\t%08X\t%08X\t%04X\t%d\t%u\t"
"%d\t%08X\t%d\t%u\t%u%n",
- fi->fib_dev ? fi->fib_dev->name : "*",
+ ndev ? ndev->name : "*",
prefix,
fi->fib_nh->nh_gw, flags, 0, 0,
fi->fib_priority,
@@ -2569,13 +2572,13 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
fi->fib_advmss + 40 : 0),
fi->fib_window,
fi->fib_rtt >> 3, &len);
- else
+ } else {
seq_printf(seq,
"*\t%08X\t%08X\t%04X\t%d\t%u\t"
"%d\t%08X\t%d\t%u\t%u%n",
prefix, 0, flags, 0, 0, 0,
mask, 0, 0, 0, &len);
-
+ }
seq_printf(seq, "%*s\n", 127 - len, "");
}
}
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index 31371be..bdc9393 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -52,13 +52,13 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
for (ret = 0; ret < res.fi->fib_nhs; ret++) {
struct fib_nh *nh = &res.fi->fib_nh[ret];
- if (nh->nh_dev == dev) {
+ if (rcu_dereference(nh->nh_dev) == dev) {
dev_match = true;
break;
}
}
#else
- if (FIB_RES_DEV(res) == dev)
+ if (rcu_dereference(FIB_RES_DEV(res)) == dev)
dev_match = true;
#endif
if (dev_match || flags & XT_RPFILTER_LOOSE)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ffcb3b0..b56b91e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2127,7 +2127,7 @@ static int __mkroute_input(struct sk_buff *skb,
u32 itag;
/* get a working reference to the output device */
- out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res));
+ out_dev = __in_dev_get_rcu(rcu_dereference(FIB_RES_DEV(*res)));
if (out_dev == NULL) {
net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n");
return -EINVAL;
@@ -2786,7 +2786,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
if (!fl4->saddr)
fl4->saddr = FIB_RES_PREFSRC(net, res);
- dev_out = FIB_RES_DEV(res);
+ dev_out = rcu_dereference(FIB_RES_DEV(res));
fl4->flowi4_oif = dev_out->ifindex;
^ permalink raw reply related
* [PATCH 4/4] stmmac: update driver's doc
From: Giuseppe CAVALLARO @ 2012-05-23 6:36 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1337754964-21754-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 44 +++++++++++++++++++---------------
1 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index ab1e8d7..5cb9a19 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -10,8 +10,8 @@ Currently this network device driver is for all STM embedded MAC/GMAC
(i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000
FF1152AMT0221 D1215994A VIRTEX FPGA board.
-DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether MAC 10/100
-Universal version 4.0 have been used for developing this driver.
+DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether
+MAC 10/100 Universal version 4.0 have been used for developing this driver.
This driver supports both the platform bus and PCI.
@@ -54,27 +54,27 @@ net_device structure enabling the scatter/gather feature.
When one or more packets are received, an interrupt happens. The interrupts
are not queued so the driver has to scan all the descriptors in the ring during
the receive process.
-This is based on NAPI so the interrupt handler signals only if there is work to be
-done, and it exits.
+This is based on NAPI so the interrupt handler signals only if there is work
+to be done, and it exits.
Then the poll method will be scheduled at some future point.
The incoming packets are stored, by the DMA, in a list of pre-allocated socket
buffers in order to avoid the memcpy (Zero-copy).
4.3) Timer-Driver Interrupt
-Instead of having the device that asynchronously notifies the frame receptions, the
-driver configures a timer to generate an interrupt at regular intervals.
-Based on the granularity of the timer, the frames that are received by the device
-will experience different levels of latency. Some NICs have dedicated timer
-device to perform this task. STMMAC can use either the RTC device or the TMU
-channel 2 on STLinux platforms.
+Instead of having the device that asynchronously notifies the frame receptions,
+the driver configures a timer to generate an interrupt at regular intervals.
+Based on the granularity of the timer, the frames that are received by the
+device will experience different levels of latency. Some NICs have dedicated
+timer device to perform this task. STMMAC can use either the RTC device or the
+TMU channel 2 on STLinux platforms.
The timers frequency can be passed to the driver as parameter; when change it,
take care of both hardware capability and network stability/performance impact.
-Several performance tests on STM platforms showed this optimisation allows to spare
-the CPU while having the maximum throughput.
+Several performance tests on STM platforms showed this optimisation allows to
+spare the CPU while having the maximum throughput.
4.4) WOL
-Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC
-core.
+Wake up on Lan feature through Magic and Unicast frames are supported for the
+GMAC core.
4.5) DMA descriptors
Driver handles both normal and enhanced descriptors. The latter has been only
@@ -106,7 +106,8 @@ Several driver's information can be passed through the platform
These are included in the include/linux/stmmac.h header file
and detailed below as well:
- struct plat_stmmacenet_data {
+struct plat_stmmacenet_data {
+ char *phy_bus_name;
int bus_id;
int phy_addr;
int interface;
@@ -124,19 +125,24 @@ and detailed below as well:
void (*bus_setup)(void __iomem *ioaddr);
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
+ void *custom_cfg;
+ void *custom_data;
void *bsp_priv;
};
Where:
+ o phy_bus_name: phy bus name to attach to the stmmac.
o bus_id: bus identifier.
o phy_addr: the physical address can be passed from the platform.
If it is set to -1 the driver will automatically
detect it at run-time by probing all the 32 addresses.
o interface: PHY device's interface.
o mdio_bus_data: specific platform fields for the MDIO bus.
- o pbl: the Programmable Burst Length is maximum number of beats to
+ o dma_cfg: internal DMA parameters
+ o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
+ o fixed_burst/mixed_burst/burst_len
o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
@@ -160,8 +166,9 @@ Where:
this is sometime necessary on some platforms (e.g. ST boxes)
where the HW needs to have set some PIO lines or system cfg
registers.
- o custom_cfg: this is a custom configuration that can be passed while
- initialising the resources.
+ o custom_cfg/custom_data: this is a custom configuration that can be passed
+ while initialising the resources.
+ o bsp_priv: another private poiter.
For MDIO bus The we have:
@@ -180,7 +187,6 @@ Where:
o irqs: list of IRQs, one per PHY.
o probed_phy_irq: if irqs is NULL, use this for probed PHY.
-
For DMA engine we have the following internal fields that should be
tuned according to the HW capabilities.
--
1.7.4.4
^ permalink raw reply related
* [PATCH 3/4] stmmac: fix driver Kconfig when built as module
From: Giuseppe CAVALLARO @ 2012-05-23 6:36 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro, Rayagond Kokatanur
In-Reply-To: <1337754964-21754-1-git-send-email-peppe.cavallaro@st.com>
This patches fixes the driver when built as dyn module.
In fact the platform part cannot be built and the probe fails
(thanks to Bob Liu that reported this bug).
The patch also makes the selection of Platform and PCI parts
mutually exclusive.
Reported-by: Bob Liu <lliubbo@gmail.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 0364283..3318b32 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -12,10 +12,12 @@ config STMMAC_ETH
if STMMAC_ETH
+choice
+ prompt "STMMAC bus support"
+
config STMMAC_PLATFORM
- tristate "STMMAC platform bus support"
+ bool "Platform bus support"
depends on STMMAC_ETH
- default y
---help---
This selects the platform specific bus support for
the stmmac device driver. This is the driver used
@@ -26,7 +28,7 @@ config STMMAC_PLATFORM
If unsure, say N.
config STMMAC_PCI
- tristate "STMMAC support on PCI bus (EXPERIMENTAL)"
+ bool "PCI bus support (EXPERIMENTAL)"
depends on STMMAC_ETH && PCI && EXPERIMENTAL
---help---
This is to select the Synopsys DWMAC available on PCI devices,
@@ -36,6 +38,7 @@ config STMMAC_PCI
D1215994A VIRTEX FPGA board.
If unsure, say N.
+endchoice
config STMMAC_DEBUG_FS
bool "Enable monitoring via sysFS "
--
1.7.4.4
^ permalink raw reply related
* [PATCH 2/4] stmmac: fix driver's doc when run kernel-doc script
From: Giuseppe CAVALLARO @ 2012-05-23 6:36 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1337754964-21754-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0caae72..18ed878 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -833,8 +833,9 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
/**
* stmmac_selec_desc_mode
- * @dev : device pointer
- * Description: select the Enhanced/Alternate or Normal descriptors */
+ * @priv : private structure
+ * Description: select the Enhanced/Alternate or Normal descriptors
+ */
static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
{
if (priv->plat->enh_desc) {
@@ -1860,6 +1861,8 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
/**
* stmmac_dvr_probe
* @device: device pointer
+ * @plat_dat: platform data pointer
+ * @addr: iobase memory address
* Description: this is the main probe function used to
* call the alloc_etherdev, allocate the priv structure.
*/
--
1.7.4.4
^ permalink raw reply related
* [PATCH 1/4] stmmac: remove two useless initialisation
From: Giuseppe CAVALLARO @ 2012-05-23 6:36 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch removes two useful initialisation in the
stmmac_rx and stmmac_tx function.
In the former, count var was already reset and in the
stmmac_tx we only need to increment the dirty pointer
w/o setting the entry var.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7096633..0caae72 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -677,7 +677,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
priv->hw->desc->release_tx_desc(p);
- entry = (++priv->dirty_tx) % txsize;
+ priv->dirty_tx++;
}
if (unlikely(netif_queue_stopped(priv->dev) &&
stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
@@ -1307,7 +1307,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
display_ring(priv->dma_rx, rxsize);
}
#endif
- count = 0;
while (!priv->hw->desc->get_rx_owner(p)) {
int status;
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Eric Dumazet @ 2012-05-23 6:27 UTC (permalink / raw)
To: Yanmin Zhang; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337753757.14538.190.camel@ymzhang.sh.intel.com>
On Wed, 2012-05-23 at 14:15 +0800, Yanmin Zhang wrote:
>
> Besides fi->fib_dev here, we need check fi->fib_hash, fi->fib_lhash,
> and nexthop_nh->nh_hash.
No, its not needed.
I am sending a patch, because I feel this area is too complex for non
netdev guys.
^ permalink raw reply
* Re: [net-next 1/4] stmmac: modify and improve the bus_setup platform callback
From: Giuseppe CAVALLARO @ 2012-05-23 6:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120523.014359.1912436981409831773.davem@davemloft.net>
Hello David
On 5/23/2012 7:43 AM, David Miller wrote:
>
> As I stated the other day, the net-next tree is closed, therefore only
> bug fixes are appropriate at this time.
Ok, so only these patches shouldbe considered:
stmmac: update driver's doc
stmmac: remove two useless initialisation
stmmac: remove two useless initialisation
and
stmmac: fix driver Kconfig when built as module
This is attached to another thread and under review.
> If there are bug fixes you want integrated in this series, you need
> to seperate them out and submit them only at this time.
Thanks, I'm resending them again for net.git.
> When net-next opens back up you can submit the rest.
I'll only resend the following patch (that should be stay in next repo)
later:
stmmac: modify and improve the bus_setup platform callback
Regards
Peppe
> --
> 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
>
>
^ permalink raw reply
* Re: [PATCH] ipv4: fix the rcu race between free_fib_info and ip_route_output_slow
From: Yanmin Zhang @ 2012-05-23 6:15 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, kunx.jiang, netdev, linux-kernel
In-Reply-To: <1337749339.3361.1655.camel@edumazet-glaptop>
On Wed, 2012-05-23 at 07:02 +0200, Eric Dumazet wrote:
> On Wed, 2012-05-23 at 12:54 +0800, Yanmin Zhang wrote:
>
> > > fi->fib_dev (aka fib_nh[0].nh_dev) need full RCU protection.
> > The new patch posted at https://lkml.org/lkml/2012/5/22/558 does move the
> > resetting to RCU protection.
>
> Its not enough.
>
> We must take care that all users are in a RCU protected region.
>
> They might be already, but a full check is needed.
>
> For example
>
> net/ipv4/fib_trie.c:2563: fi->fib_dev ? fi->fib_dev->name : "*"
>
> looks to be safe (because already in a rcu_read_lock())
>
> But its not.
>
> Right thing would be to do :
>
> struct net_device *ndev = rcu_dereference(fi->fib_dev)
>
> ...
> ndev ? ndev->name : "*"
Thanks for the pointer.
Besides fi->fib_dev here, we need check fi->fib_hash, fi->fib_lhash,
and nexthop_nh->nh_hash.
Yanmin
^ permalink raw reply
* Re: [PATCH] rfkill: Add handling when rfkill's type is RFKILL_TYPE_ALL.
From: Alex Hung @ 2012-05-23 6:12 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <1337712399.4470.5.camel@jlt3.sipsolutions.net>
On 05/23/2012 02:46 AM, Johannes Berg wrote:
> On Mon, 2012-05-21 at 16:37 +0800, Alex Hung wrote:
>> This rfkill type is supposed to be able to toggles the status of all wireless
>> devices; however, no wireless devices will register itself with type
>> RFKILL_TYPE_ALL and thus it was previously ignored in __rfkill_switch_all.
>>
>> Signed-off-by: Alex Hung<alex.hung@canonical.com>
>> ---
>> net/rfkill/core.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/rfkill/core.c b/net/rfkill/core.c
>> index 5be1957..84dd71a 100644
>> --- a/net/rfkill/core.c
>> +++ b/net/rfkill/core.c
>> @@ -324,7 +324,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
>>
>> rfkill_global_states[type].cur = blocked;
>> list_for_each_entry(rfkill,&rfkill_list, node) {
>> - if (rfkill->type != type)
>> + if (rfkill->type != type&& type != RFKILL_TYPE_ALL)
>> continue;
>
> Sorry, I accidentally replied to this in private and then Alex replied
> but it all got lost.
>
> He said he was going to change the eeepc use KEY_RFKILL instead of
> KEY_WLAN to switch all types...
>
> So I guess what this change really does is make __rfkill_switch_all() be
> able to not only switch all devices of a given type, but also be able to
> switch all devices of all types.
>
> Alex, can you please rewrite the commit log to make that clearer?
>
> johannes
>
Thanks for your feedback, I re-wrote the comments to clarify the changes
and re-submitted.
Cheers,
Alex Hung
^ permalink raw reply
* [PATCH] rfkill: Add the capability to switch all devices of all type in __rfkill_switch_all().
From: Alex Hung @ 2012-05-23 6:11 UTC (permalink / raw)
To: linville, johannes, davem, linux-wireless, netdev, linux-kernel,
alex.hung
__rfkill_switch_all() switches the state of devices of a given type; however,
it does not switch devices of all type (RFKILL_TYPE_ALL). As a result, it
ignores the keycode "KEY_RFKILL" from another module, i.e. eeepc-wmi.
This fix is to make __rfkill_switch_all() to be able to switch not only
devices of a given type but also all devices.
Signed-off-by: Alex Hung <alex.hung@canonical.com>
---
net/rfkill/core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 5be1957..84dd71a 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -324,7 +324,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
rfkill_global_states[type].cur = blocked;
list_for_each_entry(rfkill, &rfkill_list, node) {
- if (rfkill->type != type)
+ if (rfkill->type != type && type != RFKILL_TYPE_ALL)
continue;
rfkill_set_block(rfkill, blocked);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 2/3] drivers: net: ethernet: stmmac: fix failure in module test
From: Giuseppe CAVALLARO @ 2012-05-23 6:08 UTC (permalink / raw)
To: Bob Liu; +Cc: davem, francesco.virlinzi, rayagond, sr, netdev,
uclinux-dist-devel
In-Reply-To: <CAA_GA1fNJCT=qfuHDkNrBdeZd8wiR30MPBdtUVuAv+ZY+zMH_g@mail.gmail.com>
On 5/23/2012 7:09 AM, Bob Liu wrote:
> Hi Peppe,
>
> On Tue, May 22, 2012 at 8:51 PM, Giuseppe CAVALLARO
> <peppe.cavallaro@st.com> wrote:
>> On 5/22/2012 9:38 AM, Bob Liu wrote:
>>> Module can't be compiled and installed in current Makefile.
>>
>> I've just seen that I can generate the stmmac.ko on ARM and also on x86
>> with my configuration.
>>
>> Can you post here you build failure?
>>
>> In the meantime I'll test the module on ARM soon.
>
> Yes, stmmac.ko can be generated, but stmmac_platform.c won't be built.
> which cause net device can't be probed.
Yes you are perfectly right!
I've just sent a patch following Ben's advice.
Also not clear if/how to build this as a system which supports both PCI
and platform versions of the driver. So the patch makes them mutually
exclusive.
Thanks a lot
peppe
>
>>
>> peppe
>>
>>>
>>> Signed-off-by: Bob Liu <lliubbo@gmail.com>
>>> ---
>>> drivers/net/ethernet/stmicro/stmmac/Makefile | 12 ++++++------
>>> 1 files changed, 6 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
>>> index bc965ac..4b50922 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
>>> @@ -1,10 +1,10 @@
>>> obj-$(CONFIG_STMMAC_ETH) += stmmac.o
>>> -stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
>>> -stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o
>>> -stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o
>>> -stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
>>> -stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
>>> +stmmac-$(CONFIG_STMMAC_TIMER:m=y) += stmmac_timer.o
>>> +stmmac-$(CONFIG_STMMAC_RING:m=y) += ring_mode.o
>>> +stmmac-$(CONFIG_STMMAC_CHAINED:m=y) += chain_mode.o
>>> +stmmac-$(CONFIG_STMMAC_PLATFORM:m=y) += stmmac_platform.o
>>> +stmmac-$(CONFIG_STMMAC_PCI:m=y) += stmmac_pci.o
>>> stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
>>> dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
>>> dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
>>> - mmc_core.o $(stmmac-y)
>>> + mmc_core.o
>>
>
^ permalink raw reply
* [net] stmmac: fix driver Kconfig when built as module
From: Giuseppe CAVALLARO @ 2012-05-23 6:05 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, lliubbo, Giuseppe Cavallaro, Rayagond Kokatanur
In-Reply-To: <1337672336-7378-2-git-send-email-lliubbo@gmail.com>
This patches fixes the driver when built as dyn module.
In fact the platform part cannot be built and the probe fails
(thanks to Bob Liu that reported this bug).
The patch also makes the selection of Platform and PCI parts
mutually exclusive.
Reported-by: Bob Liu <lliubbo@gmail.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 0364283..3318b32 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -12,10 +12,12 @@ config STMMAC_ETH
if STMMAC_ETH
+choice
+ prompt "STMMAC bus support"
+
config STMMAC_PLATFORM
- tristate "STMMAC platform bus support"
+ bool "Platform bus support"
depends on STMMAC_ETH
- default y
---help---
This selects the platform specific bus support for
the stmmac device driver. This is the driver used
@@ -26,7 +28,7 @@ config STMMAC_PLATFORM
If unsure, say N.
config STMMAC_PCI
- tristate "STMMAC support on PCI bus (EXPERIMENTAL)"
+ bool "PCI bus support (EXPERIMENTAL)"
depends on STMMAC_ETH && PCI && EXPERIMENTAL
---help---
This is to select the Synopsys DWMAC available on PCI devices,
@@ -36,6 +38,7 @@ config STMMAC_PCI
D1215994A VIRTEX FPGA board.
If unsure, say N.
+endchoice
config STMMAC_DEBUG_FS
bool "Enable monitoring via sysFS "
--
1.7.4.4
^ permalink raw reply related
* Re: [net-next 1/4] stmmac: modify and improve the bus_setup platform callback
From: David Miller @ 2012-05-23 5:43 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1337751619-21941-1-git-send-email-peppe.cavallaro@st.com>
As I stated the other day, the net-next tree is closed, therefore only
bug fixes are appropriate at this time.
If there are bug fixes you want integrated in this series, you need
to seperate them out and submit them only at this time.
When net-next opens back up you can submit the rest.
^ permalink raw reply
* [net-next 4/4] stmmac: update driver's doc
From: Giuseppe CAVALLARO @ 2012-05-23 5:40 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1337751619-21941-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 47 ++++++++++++++++++++---------------
1 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 20c01bf..b71f960 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -10,8 +10,8 @@ Currently this network device driver is for all STM embedded MAC/GMAC
(i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000
FF1152AMT0221 D1215994A VIRTEX FPGA board.
-DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether MAC 10/100
-Universal version 4.0 have been used for developing this driver.
+DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether
+MAC 10/100 Universal version 4.0 have been used for developing this driver.
This driver supports both the platform bus and PCI.
@@ -54,27 +54,27 @@ net_device structure enabling the scatter/gather feature.
When one or more packets are received, an interrupt happens. The interrupts
are not queued so the driver has to scan all the descriptors in the ring during
the receive process.
-This is based on NAPI so the interrupt handler signals only if there is work to be
-done, and it exits.
+This is based on NAPI so the interrupt handler signals only if there is work
+to be done, and it exits.
Then the poll method will be scheduled at some future point.
The incoming packets are stored, by the DMA, in a list of pre-allocated socket
buffers in order to avoid the memcpy (Zero-copy).
4.3) Timer-Driver Interrupt
-Instead of having the device that asynchronously notifies the frame receptions, the
-driver configures a timer to generate an interrupt at regular intervals.
-Based on the granularity of the timer, the frames that are received by the device
-will experience different levels of latency. Some NICs have dedicated timer
-device to perform this task. STMMAC can use either the RTC device or the TMU
-channel 2 on STLinux platforms.
+Instead of having the device that asynchronously notifies the frame receptions,
+the driver configures a timer to generate an interrupt at regular intervals.
+Based on the granularity of the timer, the frames that are received by the
+device will experience different levels of latency. Some NICs have dedicated
+timer device to perform this task. STMMAC can use either the RTC device or the
+TMU channel 2 on STLinux platforms.
The timers frequency can be passed to the driver as parameter; when change it,
take care of both hardware capability and network stability/performance impact.
-Several performance tests on STM platforms showed this optimisation allows to spare
-the CPU while having the maximum throughput.
+Several performance tests on STM platforms showed this optimisation allows to
+spare the CPU while having the maximum throughput.
4.4) WOL
-Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC
-core.
+Wake up on Lan feature through Magic and Unicast frames are supported for the
+GMAC core.
4.5) DMA descriptors
Driver handles both normal and enhanced descriptors. The latter has been only
@@ -106,7 +106,8 @@ Several driver's information can be passed through the platform
These are included in the include/linux/stmmac.h header file
and detailed below as well:
- struct plat_stmmacenet_data {
+struct plat_stmmacenet_data {
+ char *phy_bus_name;
int bus_id;
int phy_addr;
int interface;
@@ -122,21 +123,27 @@ and detailed below as well:
int force_sf_dma_mode;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void *(*bus_setup)(void __iomem *ioaddr, struct device *dev, void *d);
+ void *bus_data;
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
+ void *custom_cfg;
+ void *custom_data;
void *bsp_priv;
- };
+};
Where:
+ o phy_bus_name: phy bus name to attach to the stmmac.
o bus_id: bus identifier.
o phy_addr: the physical address can be passed from the platform.
If it is set to -1 the driver will automatically
detect it at run-time by probing all the 32 addresses.
o interface: PHY device's interface.
o mdio_bus_data: specific platform fields for the MDIO bus.
- o pbl: the Programmable Burst Length is maximum number of beats to
+ o dma_cfg: internal DMA parameters
+ o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
+ o fixed_burst/mixed_burst/burst_len
o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
@@ -161,8 +168,9 @@ Where:
this is sometime necessary on some platforms (e.g. ST boxes)
where the HW needs to have set some PIO lines or system cfg
registers.
- o custom_cfg: this is a custom configuration that can be passed while
- initialising the resources.
+ o custom_cfg/custom_data: this is a custom configuration that can be passed
+ while initialising the resources.
+ o bsp_priv: another private poiter.
For MDIO bus The we have:
@@ -181,7 +189,6 @@ Where:
o irqs: list of IRQs, one per PHY.
o probed_phy_irq: if irqs is NULL, use this for probed PHY.
-
For DMA engine we have the following internal fields that should be
tuned according to the HW capabilities.
--
1.7.4.4
^ permalink raw reply related
* [net-next 3/4] stmmac: fix driver's doc when run kernel-doc script
From: Giuseppe CAVALLARO @ 2012-05-23 5:40 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1337751619-21941-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b942ed4..fd8bafc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -833,8 +833,9 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
/**
* stmmac_selec_desc_mode
- * @dev : device pointer
- * Description: select the Enhanced/Alternate or Normal descriptors */
+ * @priv : private structure
+ * Description: select the Enhanced/Alternate or Normal descriptors
+ */
static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
{
if (priv->plat->enh_desc) {
@@ -1856,6 +1857,8 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
/**
* stmmac_dvr_probe
* @device: device pointer
+ * @plat_dat: platform data pointer
+ * @addr: iobase memory address
* Description: this is the main probe function used to
* call the alloc_etherdev, allocate the priv structure.
*/
--
1.7.4.4
^ permalink raw reply related
* [net-next 2/4] stmmac: remove two useless initialisation
From: Giuseppe CAVALLARO @ 2012-05-23 5:40 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
In-Reply-To: <1337751619-21941-1-git-send-email-peppe.cavallaro@st.com>
This patch removes two useful initialisation in the
stmmac_rx and stmmac_tx function.
In the former, count var was already reset and in the
stmmac_tx we only need to increment the dirty pointer
w/o setting the entry var.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2fc5462..b942ed4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -677,7 +677,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
priv->hw->desc->release_tx_desc(p);
- entry = (++priv->dirty_tx) % txsize;
+ priv->dirty_tx++;
}
if (unlikely(netif_queue_stopped(priv->dev) &&
stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
@@ -1303,7 +1303,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
display_ring(priv->dma_rx, rxsize);
}
#endif
- count = 0;
while (!priv->hw->desc->get_rx_owner(p)) {
int status;
--
1.7.4.4
^ permalink raw reply related
* [net-next 1/4] stmmac: modify and improve the bus_setup platform callback
From: Giuseppe CAVALLARO @ 2012-05-23 5:40 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch modifies and improves the bus_setup callback now
by passing extra parameters that can help on more complex
platforms that require more custom settings.
The patch also updates the documentation.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 3 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +++++++++++++++----
include/linux/stmmac.h | 3 ++-
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index ab1e8d7..20c01bf 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -121,7 +121,7 @@ and detailed below as well:
int pmt;
int force_sf_dma_mode;
void (*fix_mac_speed)(void *priv, unsigned int speed);
- void (*bus_setup)(void __iomem *ioaddr);
+ void *(*bus_setup)(void __iomem *ioaddr, struct device *dev, void *d);
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
void *bsp_priv;
@@ -156,6 +156,7 @@ Where:
o bus_setup: perform HW setup of the bus. For example, on some ST platforms
this field is used to configure the AMBA bridge to generate more
efficient STBus traffic.
+ o bus_data: saved custom data for custom bus setting.
o init/exit: callbacks used for calling a custom initialisation;
this is sometime necessary on some platforms (e.g. ST boxes)
where the HW needs to have set some PIO lines or system cfg
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7096633..2fc5462 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -999,10 +999,6 @@ static int stmmac_open(struct net_device *dev)
/* Copy the MAC addr into the HW */
priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
- /* If required, perform hw setup of the bus. */
- if (priv->plat->bus_setup)
- priv->plat->bus_setup(priv->ioaddr);
-
/* Initialize the MAC Core */
priv->hw->mac->core_init(priv->ioaddr);
@@ -1949,6 +1945,15 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
goto error;
}
+ /* On some platforms, is is possible to perform some hw setup of the bus
+ * and this is done by calling the bus_setup (when implemented).
+ * Data from bus_setup can be saved in the patform structure to be
+ * restored when resume for example form standby.
+ */
+ if (priv->plat->bus_setup)
+ priv->plat->bus_data =
+ priv->plat->bus_setup(priv->ioaddr, priv->device,
+ priv->plat->bus_data);
return priv;
error:
@@ -2057,6 +2062,8 @@ int stmmac_resume(struct net_device *ndev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
+ priv->plat->bus_data = priv->plat->bus_setup(priv->ioaddr, priv->device,
+ priv->plat->bus_data);
#ifdef CONFIG_STMMAC_TIMER
if (likely(priv->tm->enable))
priv->tm->timer_start(tmrate);
@@ -2083,9 +2090,13 @@ int stmmac_freeze(struct net_device *ndev)
int stmmac_restore(struct net_device *ndev)
{
+ struct stmmac_priv *priv = netdev_priv(ndev);
+
if (!ndev || !netif_running(ndev))
return 0;
+ priv->plat->bus_data = priv->plat->bus_setup(priv->ioaddr, priv->device,
+ priv->plat->bus_data);
return stmmac_open(ndev);
}
#endif /* CONFIG_PM */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index b69bdb1..cf03968 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -106,7 +106,8 @@ struct plat_stmmacenet_data {
int pmt;
int force_sf_dma_mode;
void (*fix_mac_speed)(void *priv, unsigned int speed);
- void (*bus_setup)(void __iomem *ioaddr);
+ void *(*bus_setup)(void __iomem *ioaddr, struct device *dev, void *d);
+ void *bus_data;
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
void *custom_cfg;
--
1.7.4.4
^ 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