* Re: [PATCH] ipv6: Early TCP socket demux
From: David Miller @ 2012-07-26 21:29 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1343298868.2626.11348.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 26 Jul 2012 12:34:28 +0200
> + if (sysctl_ip_early_demux && !skb_dst(skb)) {
You obviously don't build ipv6 modular.
sysctl_ip_early_demux needs to be exported to modules in order
for this to work.
^ permalink raw reply
* [PATCH] ipv4: Fix input route performance regression.
From: David Miller @ 2012-07-26 21:14 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
With the routing cache removal we lost the "noref" code paths on
input, and this can kill some routing workloads.
Reinstate the noref path when we hit a cached route in the FIB
nexthops.
With help from Eric Dumazet.
Reported-by: Alexander Duyck <alexander.duyck@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/route.h b/include/net/route.h
index c29ef27..8c52bc6 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -30,6 +30,7 @@
#include <net/inet_sock.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
+#include <linux/rcupdate.h>
#include <linux/route.h>
#include <linux/ip.h>
#include <linux/cache.h>
@@ -157,8 +158,22 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4
return ip_route_output_key(net, fl4);
}
-extern int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin);
+extern int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
+ u8 tos, struct net_device *devin);
+
+static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
+ u8 tos, struct net_device *devin)
+{
+ int err;
+
+ rcu_read_lock();
+ err = ip_route_input_noref(skb, dst, src, tos, devin);
+ if (!err)
+ skb_dst_force(skb);
+ rcu_read_unlock();
+
+ return err;
+}
extern void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
int oif, u32 mark, u8 protocol, int flow_flags);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index a0124eb..77e87af 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -827,7 +827,7 @@ static int arp_process(struct sk_buff *skb)
}
if (arp->ar_op == htons(ARPOP_REQUEST) &&
- ip_route_input(skb, tip, sip, 0, dev) == 0) {
+ ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {
rt = skb_rtable(skb);
addr_type = rt->rt_type;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e55171f..da0cc2e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -172,9 +172,9 @@ static void free_fib_info_rcu(struct rcu_head *head)
if (nexthop_nh->nh_exceptions)
free_nh_exceptions(nexthop_nh);
if (nexthop_nh->nh_rth_output)
- dst_release(&nexthop_nh->nh_rth_output->dst);
+ dst_free(&nexthop_nh->nh_rth_output->dst);
if (nexthop_nh->nh_rth_input)
- dst_release(&nexthop_nh->nh_rth_input->dst);
+ dst_free(&nexthop_nh->nh_rth_input->dst);
} endfor_nexthops(fi);
release_net(fi->fib_net);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 7ad88e5..8d07c97 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -258,8 +258,8 @@ static void ip_expire(unsigned long arg)
/* skb dst is stale, drop it, and perform route lookup again */
skb_dst_drop(head);
iph = ip_hdr(head);
- err = ip_route_input(head, iph->daddr, iph->saddr,
- iph->tos, head->dev);
+ err = ip_route_input_noref(head, iph->daddr, iph->saddr,
+ iph->tos, head->dev);
if (err)
goto out_rcu_unlock;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 93134b0..bda8cac 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -339,8 +339,8 @@ static int ip_rcv_finish(struct sk_buff *skb)
* how the packet travels inside Linux networking.
*/
if (!skb_dst(skb)) {
- int err = ip_route_input(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev);
+ int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev);
if (unlikely(err)) {
if (err == -EXDEV)
NET_INC_STATS_BH(dev_net(skb->dev),
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3f7bb71..fc1a81c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1199,10 +1199,9 @@ restart:
fnhe->fnhe_stamp = jiffies;
}
-static inline void rt_release_rcu(struct rcu_head *head)
+static inline void rt_free(struct rtable *rt)
{
- struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
- dst_release(dst);
+ call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
}
static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
@@ -1216,9 +1215,15 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
prev = cmpxchg(p, orig, rt);
if (prev == orig) {
- dst_clone(&rt->dst);
if (orig)
- call_rcu_bh(&orig->dst.rcu_head, rt_release_rcu);
+ rt_free(orig);
+ } else {
+ /* Routes we intend to cache in the FIB nexthop have
+ * the DST_NOCACHE bit clear. However, if we are
+ * unsuccessful at storing this route into the cache
+ * we really need to set it.
+ */
+ rt->dst.flags |= DST_NOCACHE;
}
}
@@ -1245,7 +1250,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
#ifdef CONFIG_IP_ROUTE_CLASSID
rt->dst.tclassid = nh->nh_tclassid;
#endif
- if (!(rt->dst.flags & DST_HOST))
+ if (!(rt->dst.flags & DST_NOCACHE))
rt_cache_route(nh, rt);
}
@@ -1261,7 +1266,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev,
bool nopolicy, bool noxfrm, bool will_cache)
{
return dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
- (will_cache ? 0 : DST_HOST) | DST_NOCACHE |
+ (will_cache ? 0 : (DST_HOST | DST_NOCACHE)) |
(nopolicy ? DST_NOPOLICY : 0) |
(noxfrm ? DST_NOXFRM : 0));
}
@@ -1366,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev,
static int __mkroute_input(struct sk_buff *skb,
const struct fib_result *res,
struct in_device *in_dev,
- __be32 daddr, __be32 saddr, u32 tos,
- struct rtable **result)
+ __be32 daddr, __be32 saddr, u32 tos)
{
struct rtable *rth;
int err;
@@ -1418,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb,
if (!itag) {
rth = FIB_RES_NH(*res).nh_rth_input;
if (rt_cache_valid(rth)) {
- dst_hold(&rth->dst);
+ skb_dst_set_noref(skb, &rth->dst);
goto out;
}
do_cache = true;
@@ -1445,8 +1449,8 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.output = ip_output;
rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
+ skb_dst_set(skb, &rth->dst);
out:
- *result = rth;
err = 0;
cleanup:
return err;
@@ -1458,21 +1462,13 @@ static int ip_mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
- struct rtable *rth = NULL;
- int err;
-
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
fib_select_multipath(res);
#endif
/* create a routing cache entry */
- err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
- if (err)
- return err;
-
- skb_dst_set(skb, &rth->dst);
- return 0;
+ return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
}
/*
@@ -1588,8 +1584,9 @@ local_input:
if (!itag) {
rth = FIB_RES_NH(res).nh_rth_input;
if (rt_cache_valid(rth)) {
- dst_hold(&rth->dst);
- goto set_and_out;
+ skb_dst_set_noref(skb, &rth->dst);
+ err = 0;
+ goto out;
}
do_cache = true;
}
@@ -1620,7 +1617,6 @@ local_input:
}
if (do_cache)
rt_cache_route(&FIB_RES_NH(res), rth);
-set_and_out:
skb_dst_set(skb, &rth->dst);
err = 0;
goto out;
@@ -1658,8 +1654,8 @@ martian_source_keep_err:
goto out;
}
-int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- u8 tos, struct net_device *dev)
+int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev)
{
int res;
@@ -1702,7 +1698,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rcu_read_unlock();
return res;
}
-EXPORT_SYMBOL(ip_route_input);
+EXPORT_SYMBOL(ip_route_input_noref);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 58d23a5..06814b6 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
if (skb_dst(skb) == NULL) {
const struct iphdr *iph = ip_hdr(skb);
- if (ip_route_input(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev))
+ if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev))
goto drop;
}
return dst_input(skb);
^ permalink raw reply related
* Re: open sockets preventing unregister_netdevice from completing in linux-next (next-20120724)
From: David Miller @ 2012-07-26 21:10 UTC (permalink / raw)
To: eric.dumazet; +Cc: bjorn, netdev
In-Reply-To: <1343322928.2626.11764.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 26 Jul 2012 19:15:28 +0200
> On Wed, 2012-07-25 at 15:17 -0700, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Wed, 25 Jul 2012 16:38:48 +0200
>>
>> > Yes, we miss what was done with rt_cache_flush() : find all cached
>> > routes and release all dev references...
>>
>> We can fix this with a two-pronged approach:
>>
>> 1) Walk the FIB info nexthops and invalidate.
>>
>> 2) Entries not cached in the FIB info nexthops go into a
>> per-netns list which is scanned as well.
>>
>> I'll try to work on this if nobody beats me to it.
>
> With your latest patch, I can "rmmod tg3" while sockets are active.
>
> Not sure we need all this now ?
>
> (the trick is probably in fib_semantics.c, when you changed
> dst_release() to dst_free())
That's not the problem. Not all routes are cached in the FIB nexthop.
Any route that doesn't resolve to a FIB info (255.255.255.255, etc.)
or uses special features (tclassid, etc.) doesn't get cached.
Therefore if a socket gets that kind of route, and then becomes
inactive, we can hold onto the device references forever. The entity
with the route has to call dst_ops->check() to see that the route has
become invalid, but if the application is inactive, that will never
happen.
We have to put such non-cached routes into a special list or table of
some kind, so that we can zap a netdevice if it wants to go down or
unload before the final dst_release() happens.
^ permalink raw reply
* Re: [PATCH] bcma: fix regression in pmu workaround reg masks
From: Linus Torvalds @ 2012-07-26 21:07 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linville, davem, brcm80211-dev-list, linux-wireless, netdev,
linux-kernel, seth.forshee, pieterpg, brudley, Arend van Spriel,
Rafał Miłecki
In-Reply-To: <1343294151-5691-1-git-send-email-hauke@hauke-m.de>
Oops. For some reason I didn't see this email this morning, and grew
impatient and committed the patch without the sign-off and with a
different changelog.
My bad. Too much email.
Anyway, this is commit 1f03bf06e4e3 in my tree.
Linus
On Thu, Jul 26, 2012 at 2:15 AM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> This fixes a regression introduced in:
> commit b9562545ef0b13c0440ccd8d6dd4111fb77cb17a
...
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-26 21:06 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <CAKgT0UfZmK=gSSn+1Z8=KpW9ckVAJJgQg1+5NdO9SKfWv8GiCg@mail.gmail.com>
From: Alexander Duyck <alexander.duyck@gmail.com>
Date: Thu, 26 Jul 2012 11:26:26 -0700
> The previous results were with a slight modifications to your earlier
> patch. With this patch applied I am seeing 10.4Mpps with 8 queues,
> reaching a maximum of 11.6Mpps with 9 queues.
For fun you might want to see what this patch does for your tests,
it should cut the number of fib_table_lookup() calls roughly in half.
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index b64a19c..fc7eade 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -204,9 +204,7 @@ static inline struct fib_table *fib_get_table(struct net *net, u32 id)
{
struct hlist_head *ptr;
- ptr = id == RT_TABLE_LOCAL ?
- &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
- &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
+ ptr = &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
return hlist_entry(ptr->first, struct fib_table, tb_hlist);
}
@@ -220,10 +218,6 @@ static inline int fib_lookup(struct net *net, const struct flowi4 *flp,
{
struct fib_table *table;
- table = fib_get_table(net, RT_TABLE_LOCAL);
- if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
- return 0;
-
table = fib_get_table(net, RT_TABLE_MAIN);
if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
return 0;
@@ -245,10 +239,6 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp,
{
if (!net->ipv4.fib_has_custom_rules) {
res->tclassid = 0;
- if (net->ipv4.fib_local &&
- !fib_table_lookup(net->ipv4.fib_local, flp, res,
- FIB_LOOKUP_NOREF))
- return 0;
if (net->ipv4.fib_main &&
!fib_table_lookup(net->ipv4.fib_main, flp, res,
FIB_LOOKUP_NOREF))
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 44bf82e..bdc0231 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -160,7 +160,7 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
/* Fallback to FIB local table so that communication
* over loopback subnets work.
*/
- local = fib_get_table(net, RT_TABLE_LOCAL);
+ local = fib_get_table(net, RT_TABLE_MAIN);
if (local &&
!fib_table_lookup(local, &fl4, &res, FIB_LOOKUP_NOREF) &&
res.type == RTN_LOCAL)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index c1fde53..ddfe398 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -52,16 +52,10 @@ static int __net_init fib4_rules_init(struct net *net)
{
struct fib_table *local_table, *main_table;
- local_table = fib_trie_table(RT_TABLE_LOCAL);
- if (local_table == NULL)
- return -ENOMEM;
-
main_table = fib_trie_table(RT_TABLE_MAIN);
if (main_table == NULL)
goto fail;
- hlist_add_head_rcu(&local_table->tb_hlist,
- &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX]);
hlist_add_head_rcu(&main_table->tb_hlist,
&net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]);
return 0;
@@ -169,7 +163,7 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
if (ipv4_is_multicast(addr))
return RTN_MULTICAST;
- local_table = fib_get_table(net, RT_TABLE_LOCAL);
+ local_table = fib_get_table(net, RT_TABLE_MAIN);
if (local_table) {
ret = RTN_UNICAST;
rcu_read_lock();
@@ -712,11 +706,7 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
},
};
- if (type == RTN_UNICAST)
- tb = fib_new_table(net, RT_TABLE_MAIN);
- else
- tb = fib_new_table(net, RT_TABLE_LOCAL);
-
+ tb = fib_new_table(net, RT_TABLE_MAIN);
if (tb == NULL)
return;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index a83d74e..65135dd 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -284,9 +284,6 @@ static int fib_default_rules_init(struct fib_rules_ops *ops)
{
int err;
- err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0);
- if (err < 0)
- return err;
err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
if (err < 0)
return err;
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-26 21:00 UTC (permalink / raw)
To: eric.dumazet; +Cc: alexander.duyck, netdev
In-Reply-To: <1343324633.2626.11801.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 26 Jul 2012 19:43:53 +0200
> On Thu, 2012-07-26 at 19:36 +0200, Eric Dumazet wrote:
>> On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
>> > On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
>> >
>> > > I tested this patch and it looks like it runs, but still has the same
>> > > performance issue. I did some digging into the annotation for
>> > > ip_route_intput_noref and it seems like the issue is that I am hitting
>> > > the dst_hold call in __mkroute_input.
>> >
>> > David suggested a percpu cache.
>> >
>> > nh_rth_input would be allocated by alloc_percpu(struct dst *)
>> >
>> > I can work on this.
>>
>> Wait a minute, on input we should use the noref trick too.
>>
>
> Something like : (on top of latest David patch)
Grrr, I only got the local routes didn't I? :-)
That would explain everything.
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-26 20:59 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <CAKgT0UfYEBYQOAoZ77rtwctbwau=2kx4rYdTyeaPaipeMUP9aw@mail.gmail.com>
From: Alexander Duyck <alexander.duyck@gmail.com>
Date: Thu, 26 Jul 2012 10:18:03 -0700
> I did some digging into the annotation for ip_route_intput_noref and
> it seems like the issue is that I am hitting the dst_hold call in
> __mkroute_input.
We shouldn't be building any routes in __mkroute_input except for the
very first packet, we should be instead using the cached route in the
FIB info nexthop.
Something's not right.
^ permalink raw reply
* Re: r8169, 3.5.0, does't work at all
From: Denys Fedoryshchenko @ 2012-07-26 20:44 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20120726195658.GA14668@electric-eye.fr.zoreil.com>
On 2012-07-26 22:56, Francois Romieu wrote:
> Denys Fedoryshchenko <denys@visp.net.lb> :
>> Just pushed new kernel to test cluster and got this:
> [...]
>> [ 1.606212] r8169 0000:03:00.0: eth1: RTL8168b/8111b at
>> 0xf8606000, 00:08:54:57:7a:33, XID 18000000 IRQ 44
>> [ 1.606366] r8169 0000:03:00.0: eth1: jumbo features [frames:
>> 4080 bytes, tx checksumming: ko]
>> ....
>> [ 20.406090] input device check on
>> [ 20.406177] Actions configured
>> [ 21.526836] r8169 0000:02:00.0: eth0: link up
>> [ 28.038386] ------------[ cut here ]------------
>> [ 28.038438] WARNING: at net/sched/sch_generic.c:255
>> dev_watchdog+0xd6/0x12a()
>> [ 28.038489] Hardware name:
>> [ 28.038534] NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed
>
> Right at startup.
>
> Which kernel did you previously use ?
>
> This is exactly the primary device I use to access my test computer.
>
> .config and .dmesg will be welcome as well.
http://www.nuclearcat.com/dmesg.txt
http://www.nuclearcat.com/config.txt
There ifplugd also running, and udhcpc, both from busybox.
Now machine are deployed to production , working fine with 3.4.6
kernel. I can do limited tests on it,
and i can search for more machines with similar cards.
---
Denys Fedoryshchenko, Network Engineer, Virtual ISP S.A.L.
^ permalink raw reply
* Re: r8169, 3.5.0, does't work at all
From: Francois Romieu @ 2012-07-26 19:56 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <88f2e8e7f795239ec4bc759dcda61665@visp.net.lb>
Denys Fedoryshchenko <denys@visp.net.lb> :
> Just pushed new kernel to test cluster and got this:
[...]
> [ 1.606212] r8169 0000:03:00.0: eth1: RTL8168b/8111b at
> 0xf8606000, 00:08:54:57:7a:33, XID 18000000 IRQ 44
> [ 1.606366] r8169 0000:03:00.0: eth1: jumbo features [frames:
> 4080 bytes, tx checksumming: ko]
> ....
> [ 20.406090] input device check on
> [ 20.406177] Actions configured
> [ 21.526836] r8169 0000:02:00.0: eth0: link up
> [ 28.038386] ------------[ cut here ]------------
> [ 28.038438] WARNING: at net/sched/sch_generic.c:255
> dev_watchdog+0xd6/0x12a()
> [ 28.038489] Hardware name:
> [ 28.038534] NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed
Right at startup.
Which kernel did you previously use ?
This is exactly the primary device I use to access my test computer.
.config and .dmesg will be welcome as well.
--
Ueimor
^ permalink raw reply
* Re: [PATCH] vxge: Declare MODULE_FIRMWARE usage
From: Jon Mason @ 2012-07-26 19:55 UTC (permalink / raw)
To: Tim Gardner
Cc: linux-kernel, David S. Miller, Joe Perches, Jiri Pirko,
Stephen Hemminger, Paul Gortmaker, netdev
In-Reply-To: <1343329710-96747-1-git-send-email-tim.gardner@canonical.com>
On Thu, Jul 26, 2012 at 12:08 PM, Tim Gardner <tim.gardner@canonical.com> wrote:
> Cc: Jon Mason <jdmason@kudzu.us>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Joe Perches <joe@perches.com>
> Cc: Jiri Pirko <jpirko@redhat.com>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
> Cc: netdev@vger.kernel.org
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
> drivers/net/ethernet/neterion/vxge/vxge-main.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
> index de21904..d4832b2 100644
> --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
> +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
> @@ -4203,6 +4203,9 @@ out:
> return ret;
> }
>
> +#define VXGE_PXE_FIRMWARE "vxge/X3fw-pxe.ncf"
> +#define VXGE_FIRMWARE "vxge/X3fw.ncf"
> +
> static int vxge_probe_fw_update(struct vxgedev *vdev)
> {
> u32 maj, min, bld;
> @@ -4245,9 +4248,9 @@ static int vxge_probe_fw_update(struct vxgedev *vdev)
> }
> }
> if (gpxe)
> - fw_name = "vxge/X3fw-pxe.ncf";
> + fw_name = VXGE_PXE_FIRMWARE;
> else
> - fw_name = "vxge/X3fw.ncf";
> + fw_name = VXGE_FIRMWARE;
>
> ret = vxge_fw_upgrade(vdev, fw_name, 0);
> /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on
> @@ -4855,3 +4858,5 @@ vxge_closer(void)
> }
> module_init(vxge_starter);
> module_exit(vxge_closer);
> +MODULE_FIRMWARE(VXGE_PXE_FIRMWARE);
> +MODULE_FIRMWARE(VXGE_FIRMWARE);
IIUC, MODULE_FIRMWARE is only necessary for devices that need firmware
to operate. vxge hardware has an image in flash on the nic, and the
modified code is used to update the firmware image on the adapter.
So, this change isn't doing what you want it to do.
Also, wasn't this already discussed (https://lkml.org/lkml/2012/4/12/401)?
Thanks,
Jon
> --
> 1.7.9.5
>
^ permalink raw reply
* [PATCH] vxge: Declare MODULE_FIRMWARE usage
From: Tim Gardner @ 2012-07-26 19:08 UTC (permalink / raw)
To: linux-kernel
Cc: Tim Gardner, Jon Mason, David S. Miller, Joe Perches, Jiri Pirko,
Stephen Hemminger, Paul Gortmaker, netdev
Cc: Jon Mason <jdmason@kudzu.us>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Joe Perches <joe@perches.com>
Cc: Jiri Pirko <jpirko@redhat.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
drivers/net/ethernet/neterion/vxge/vxge-main.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index de21904..d4832b2 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -4203,6 +4203,9 @@ out:
return ret;
}
+#define VXGE_PXE_FIRMWARE "vxge/X3fw-pxe.ncf"
+#define VXGE_FIRMWARE "vxge/X3fw.ncf"
+
static int vxge_probe_fw_update(struct vxgedev *vdev)
{
u32 maj, min, bld;
@@ -4245,9 +4248,9 @@ static int vxge_probe_fw_update(struct vxgedev *vdev)
}
}
if (gpxe)
- fw_name = "vxge/X3fw-pxe.ncf";
+ fw_name = VXGE_PXE_FIRMWARE;
else
- fw_name = "vxge/X3fw.ncf";
+ fw_name = VXGE_FIRMWARE;
ret = vxge_fw_upgrade(vdev, fw_name, 0);
/* -EINVAL and -ENOENT are not fatal errors for flashing firmware on
@@ -4855,3 +4858,5 @@ vxge_closer(void)
}
module_init(vxge_starter);
module_exit(vxge_closer);
+MODULE_FIRMWARE(VXGE_PXE_FIRMWARE);
+MODULE_FIRMWARE(VXGE_FIRMWARE);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Alexander Duyck @ 2012-07-26 18:26 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1343324896.2626.11808.camel@edumazet-glaptop>
On Thu, Jul 26, 2012 at 10:48 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2012-07-26 at 19:43 +0200, Eric Dumazet wrote:
>> On Thu, 2012-07-26 at 19:36 +0200, Eric Dumazet wrote:
>> > On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
>> > > On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
>> > >
>> > > > I tested this patch and it looks like it runs, but still has the same
>> > > > performance issue. I did some digging into the annotation for
>> > > > ip_route_intput_noref and it seems like the issue is that I am hitting
>> > > > the dst_hold call in __mkroute_input.
>> > >
>> > > David suggested a percpu cache.
>> > >
>> > > nh_rth_input would be allocated by alloc_percpu(struct dst *)
>> > >
>> > > I can work on this.
>> >
>> > Wait a minute, on input we should use the noref trick too.
>> >
>>
>> Something like : (on top of latest David patch)
>
> Sorry updated patch : (missing skb_dst_set() before 'out' label)
The previous results were with a slight modifications to your earlier
patch. With this patch applied I am seeing 10.4Mpps with 8 queues,
reaching a maximum of 11.6Mpps with 9 queues.
When we have a final version for this patch let me know and I will
give it a quick run and throw in my tested by.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Alexander Duyck @ 2012-07-26 18:06 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1343324633.2626.11801.camel@edumazet-glaptop>
On Thu, Jul 26, 2012 at 10:43 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2012-07-26 at 19:36 +0200, Eric Dumazet wrote:
>> On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
>> > On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
>> >
>> > > I tested this patch and it looks like it runs, but still has the same
>> > > performance issue. I did some digging into the annotation for
>> > > ip_route_intput_noref and it seems like the issue is that I am hitting
>> > > the dst_hold call in __mkroute_input.
>> >
>> > David suggested a percpu cache.
>> >
>> > nh_rth_input would be allocated by alloc_percpu(struct dst *)
>> >
>> > I can work on this.
>>
>> Wait a minute, on input we should use the noref trick too.
>>
>
> Something like : (on top of latest David patch)
>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 7a591aa..d5d2ad1 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -1371,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev,
> static int __mkroute_input(struct sk_buff *skb,
> const struct fib_result *res,
> struct in_device *in_dev,
> - __be32 daddr, __be32 saddr, u32 tos,
> - struct rtable **result)
> + __be32 daddr, __be32 saddr, u32 tos)
> {
> struct rtable *rth;
> int err;
> @@ -1423,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb,
> if (!itag) {
> rth = FIB_RES_NH(*res).nh_rth_input;
> if (rt_cache_valid(rth)) {
> - dst_hold(&rth->dst);
> + skb_dst_set_noref(skb, &rth->dst);
> goto out;
> }
> do_cache = true;
> @@ -1451,7 +1450,6 @@ static int __mkroute_input(struct sk_buff *skb,
>
> rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
> out:
> - *result = rth;
> err = 0;
> cleanup:
> return err;
> @@ -1463,21 +1461,13 @@ static int ip_mkroute_input(struct sk_buff *skb,
> struct in_device *in_dev,
> __be32 daddr, __be32 saddr, u32 tos)
> {
> - struct rtable *rth = NULL;
> - int err;
> -
> #ifdef CONFIG_IP_ROUTE_MULTIPATH
> if (res->fi && res->fi->fib_nhs > 1)
> fib_select_multipath(res);
> #endif
>
> /* create a routing cache entry */
> - err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
> - if (err)
> - return err;
> -
> - skb_dst_set(skb, &rth->dst);
> - return 0;
> + return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
> }
>
> /*
>
With your changes in place I see an increase from 7.5Mpps to 9.9Mpps
for 8 queues, and increasing the queues to 9 gets me up to 11Mpps even
if the 9th queue is on another node. This is a HUGE improvement over
what we had before.
The only remaining overhead that has been introduced with the recent
changes appears to be the fib_table_lookup which doesn't have any hot
spots that jump out at me. The performance is in-line with what I was
seeing when I was randomly generating source IPs from a fairly large
set so I suspect this is just the expected behaviour without a routing
cache in place.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-26 17:48 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev
In-Reply-To: <1343324633.2626.11801.camel@edumazet-glaptop>
On Thu, 2012-07-26 at 19:43 +0200, Eric Dumazet wrote:
> On Thu, 2012-07-26 at 19:36 +0200, Eric Dumazet wrote:
> > On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
> > > On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
> > >
> > > > I tested this patch and it looks like it runs, but still has the same
> > > > performance issue. I did some digging into the annotation for
> > > > ip_route_intput_noref and it seems like the issue is that I am hitting
> > > > the dst_hold call in __mkroute_input.
> > >
> > > David suggested a percpu cache.
> > >
> > > nh_rth_input would be allocated by alloc_percpu(struct dst *)
> > >
> > > I can work on this.
> >
> > Wait a minute, on input we should use the noref trick too.
> >
>
> Something like : (on top of latest David patch)
Sorry updated patch : (missing skb_dst_set() before 'out' label)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 7a591aa..fc1a81c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1371,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev,
static int __mkroute_input(struct sk_buff *skb,
const struct fib_result *res,
struct in_device *in_dev,
- __be32 daddr, __be32 saddr, u32 tos,
- struct rtable **result)
+ __be32 daddr, __be32 saddr, u32 tos)
{
struct rtable *rth;
int err;
@@ -1423,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb,
if (!itag) {
rth = FIB_RES_NH(*res).nh_rth_input;
if (rt_cache_valid(rth)) {
- dst_hold(&rth->dst);
+ skb_dst_set_noref(skb, &rth->dst);
goto out;
}
do_cache = true;
@@ -1450,8 +1449,8 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.output = ip_output;
rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
+ skb_dst_set(skb, &rth->dst);
out:
- *result = rth;
err = 0;
cleanup:
return err;
@@ -1463,21 +1462,13 @@ static int ip_mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
- struct rtable *rth = NULL;
- int err;
-
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
fib_select_multipath(res);
#endif
/* create a routing cache entry */
- err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
- if (err)
- return err;
-
- skb_dst_set(skb, &rth->dst);
- return 0;
+ return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
}
/*
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-26 17:43 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev
In-Reply-To: <1343324175.2626.11790.camel@edumazet-glaptop>
On Thu, 2012-07-26 at 19:36 +0200, Eric Dumazet wrote:
> On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
> > On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
> >
> > > I tested this patch and it looks like it runs, but still has the same
> > > performance issue. I did some digging into the annotation for
> > > ip_route_intput_noref and it seems like the issue is that I am hitting
> > > the dst_hold call in __mkroute_input.
> >
> > David suggested a percpu cache.
> >
> > nh_rth_input would be allocated by alloc_percpu(struct dst *)
> >
> > I can work on this.
>
> Wait a minute, on input we should use the noref trick too.
>
Something like : (on top of latest David patch)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 7a591aa..d5d2ad1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1371,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev,
static int __mkroute_input(struct sk_buff *skb,
const struct fib_result *res,
struct in_device *in_dev,
- __be32 daddr, __be32 saddr, u32 tos,
- struct rtable **result)
+ __be32 daddr, __be32 saddr, u32 tos)
{
struct rtable *rth;
int err;
@@ -1423,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb,
if (!itag) {
rth = FIB_RES_NH(*res).nh_rth_input;
if (rt_cache_valid(rth)) {
- dst_hold(&rth->dst);
+ skb_dst_set_noref(skb, &rth->dst);
goto out;
}
do_cache = true;
@@ -1451,7 +1450,6 @@ static int __mkroute_input(struct sk_buff *skb,
rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
out:
- *result = rth;
err = 0;
cleanup:
return err;
@@ -1463,21 +1461,13 @@ static int ip_mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
- struct rtable *rth = NULL;
- int err;
-
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
fib_select_multipath(res);
#endif
/* create a routing cache entry */
- err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
- if (err)
- return err;
-
- skb_dst_set(skb, &rth->dst);
- return 0;
+ return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
}
/*
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-26 17:36 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev
In-Reply-To: <1343323858.2626.11783.camel@edumazet-glaptop>
On Thu, 2012-07-26 at 19:31 +0200, Eric Dumazet wrote:
> On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
>
> > I tested this patch and it looks like it runs, but still has the same
> > performance issue. I did some digging into the annotation for
> > ip_route_intput_noref and it seems like the issue is that I am hitting
> > the dst_hold call in __mkroute_input.
>
> David suggested a percpu cache.
>
> nh_rth_input would be allocated by alloc_percpu(struct dst *)
>
> I can work on this.
Wait a minute, on input we should use the noref trick too.
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-26 17:30 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev
In-Reply-To: <CAKgT0UfYEBYQOAoZ77rtwctbwau=2kx4rYdTyeaPaipeMUP9aw@mail.gmail.com>
On Thu, 2012-07-26 at 10:18 -0700, Alexander Duyck wrote:
> I tested this patch and it looks like it runs, but still has the same
> performance issue. I did some digging into the annotation for
> ip_route_intput_noref and it seems like the issue is that I am hitting
> the dst_hold call in __mkroute_input.
David suggested a percpu cache.
nh_rth_input would be allocated by alloc_percpu(struct dst *)
I can work on this.
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Alexander Duyck @ 2012-07-26 17:18 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
In-Reply-To: <20120726.014736.1066206957795563053.davem@davemloft.net>
On Thu, Jul 26, 2012 at 1:47 AM, David Miller <davem@davemloft.net> wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Thu, 26 Jul 2012 10:27:58 +0200
>
>> But isnt DST_NOCACHE intent reverted then ?
>>
>> like you meant :
>>
>> + } else {
>> + /* Routes we intend to cache in the FIB nexthop have
>> + * the DST_NOCACHE bit unset. However, if we are
>> + * unsuccessful at storing this route into the cache
>> + * we really need to set that bit.
>> + */
>> + rt->dst.flags |= DST_NOCACHE;
>> }
>
> Indeed, thanks for catching this bug.
>
> Here's a new version of the patch, as I found another error. In
> fib_semantics.c, we have to change dst_release() to dst_free() for the
> liberation the nexthop cached routes.
I tested this patch and it looks like it runs, but still has the same
performance issue. I did some digging into the annotation for
ip_route_intput_noref and it seems like the issue is that I am hitting
the dst_hold call in __mkroute_input.
You were correct about the ARP entry. It looks like I had messed up
my test script and it wasn't putting the static ARP entry back in.
I'm amazed it was even working since my SmartBits system doesn't
normally even reply to ARPs.
Thanks,
Alex
^ permalink raw reply
* Re: open sockets preventing unregister_netdevice from completing in linux-next (next-20120724)
From: Eric Dumazet @ 2012-07-26 17:15 UTC (permalink / raw)
To: David Miller; +Cc: bjorn, netdev
In-Reply-To: <20120725.151737.1807149851147342859.davem@davemloft.net>
On Wed, 2012-07-25 at 15:17 -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Wed, 25 Jul 2012 16:38:48 +0200
>
> > Yes, we miss what was done with rt_cache_flush() : find all cached
> > routes and release all dev references...
>
> We can fix this with a two-pronged approach:
>
> 1) Walk the FIB info nexthops and invalidate.
>
> 2) Entries not cached in the FIB info nexthops go into a
> per-netns list which is scanned as well.
>
> I'll try to work on this if nobody beats me to it.
With your latest patch, I can "rmmod tg3" while sockets are active.
Not sure we need all this now ?
(the trick is probably in fib_semantics.c, when you changed
dst_release() to dst_free())
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Eric Dumazet @ 2012-07-26 17:02 UTC (permalink / raw)
To: Paweł Staszewski; +Cc: David Miller, netdev
In-Reply-To: <500D8FEE.7050802@itcare.pl>
On Mon, 2012-07-23 at 19:54 +0200, Paweł Staszewski wrote:
> I make some real life tests with 10Gbit traffic and make some rdos.
> With kernel 3.4.5 when I reach 6M routing cache entries - traffic is not
> forwarded - on my hardware with 64G RAM
>
> With kernel - 3.5.0-rc7-next-20120720 + David M. patches - route cache
> removal + fix
> Traffic is forwarder all the time at speed 8.2Mpps RX from traffic
> generator and 8.2Mpps TX to the sink
>
> Also I see performance improvement.
>
> With kernel 3.4.5 I can reach maximum od 7.5Mpps with my hardware
> And with kernel 3.5.0-rc7-next-20120720 i can reach 8.2Mpps - forwarding
> UDP performance - can be more - but my TX pktgen that use 6 cores can't
> do more.
>
> Really thanks for this :)
In real life, with TCP traffic, make sure you
set /proc/sys/net/ipv4/ip_early_demux to 0
^ permalink raw reply
* Re: [RFC ETHTOOL PATCH 2/2] ethtool: allow setting MDI-X state
From: Ben Hutchings @ 2012-07-26 16:35 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: netdev
In-Reply-To: <20120726163033.GA20122@jbrandeb-snb.jf.intel.com>
On Thu, 2012-07-26 at 09:30 -0700, Jesse Brandeburg wrote:
> On Wed, Jul 25, 2012 at 11:59:02PM +0100, Ben Hutchings wrote:
> > On Wed, 2012-07-25 at 10:53 -0700, Jesse Brandeburg wrote:
> > How about when you have a forced mode but the driver reports eth_tp_mdix
> > = ETH_TP_MDI_INVALID because the link is down? This is going to result
> > in:
> >
> > MDI-X: Unknown (forced)
> >
> > which makes no sense at all. So I think that we have to do something
> > like:
> >
> > if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI) {
> > fprintf(stdout, "off (forced)\n");
> > } else if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_X) {
> > fprintf(stdout, "on (forced)\n");
> > } else {
> > switch (ep->eth_tp_mdix) {
> > ...
> > }
> > if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
> > fprintf(stdout, " (auto)");
> > fprintf(stdout, "\n");
> > }
> >
> > Or else we require that when the mode is forced then drivers report that
> > as the current status even if the link is down.
>
> I tried that and it works swimmingly. How does this look?
[...]
That looks good, thanks.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] iproute: Add route showdump command
From: Stephen Hemminger @ 2012-07-26 16:03 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: Dan Smith, Linux Netdev List
In-Reply-To: <50110593.1070502@parallels.com>
On Thu, 26 Jul 2012 12:53:39 +0400
Pavel Emelyanov <xemul@parallels.com> wrote:
> Some time ago the save+restore commands were added to ip route (git
> id f4ff11e3, Add ip route save/restore). These two save the raw rtnl
> stream into a file and restore one (reading it from stdin).
>
> The problem is that there's no way to get the contents of the dump
> file in a human readable form. How about adding a command that reads
> the rtnl stream from stdin and prints the data in a way the usual
> "ip route list" does?
>
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Being able to decode a dump is great idea.
Are the user's smart enough not to try it out at the command prompt
and get totally lost? Maybe another isatty() check is needed.
Another solution would be to put a small header on the save file with
a magic number that could be checked. This would mean changing save/restore/showdump
and ideally updating the magic file in distributions.
^ permalink raw reply
* [PATCH 3/3] pch_gbe: vlan skb len fix
From: Andy Cress @ 2012-07-26 16:01 UTC (permalink / raw)
To: netdev
pch_gbe_xmit_frame skb->len verification was incorrect in vlan case
causing bogus transfer length errors. One correction could be:
offset = skb->protocol == htons(ETH_P_8021Q) ? 0 : 4;
if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - offset)))
However, this verification is not necessary, so remove it.
Signed-off-by: Andy Cress <andy.cress@us.kontron.com>
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 000ef68..817614c 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2157,13 +2157,6 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
unsigned long flags;
- if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) {
- pr_err("Transfer length Error: skb len: %d > max: %d\n",
- skb->len, adapter->hw.mac.max_frame_size);
- dev_kfree_skb_any(skb);
- adapter->stats.tx_length_errors++;
- return NETDEV_TX_OK;
- }
if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
/* Collision - tell upper layer to requeue */
return NETDEV_TX_LOCKED;
^ permalink raw reply related
* [PATCH 2/3] pch_gbe: add extra clean tx
From: Andy Cress @ 2012-07-26 16:00 UTC (permalink / raw)
To: netdev
This adds extra cleaning to the pch_gbe_clean_tx routine to avoid
transmit timeouts on some BCM PHYs that have different timing.
Also update the DRV_VERSION to 1.01, and show it.
Signed-off-by: Andy Cress <andy.cress@us.kontron.com>
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 8694704..000ef68 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -26,7 +26,7 @@
#include <linux/ptp_classify.h>
#endif
-#define DRV_VERSION "1.00"
+#define DRV_VERSION "1.01"
const char pch_driver_version[] = DRV_VERSION;
#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */
@@ -1579,7 +1579,8 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
struct sk_buff *skb;
unsigned int i;
unsigned int cleaned_count = 0;
- bool cleaned = true;
+ bool cleaned = false;
+ int unused, thresh;
pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
@@ -1588,10 +1589,36 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
pr_debug("gbec_status:0x%04x dma_status:0x%04x\n",
tx_desc->gbec_status, tx_desc->dma_status);
+ unused = PCH_GBE_DESC_UNUSED(tx_ring);
+ thresh = tx_ring->count - PCH_GBE_TX_WEIGHT;
+ if ((tx_desc->gbec_status == DSC_INIT16) && (unused < thresh))
+ { /* current marked clean, tx queue filling up, do extra clean */
+ int j, k;
+ if (unused < 8) { /* tx queue nearly full */
+ pr_debug("clean_tx: transmit queue warning (%x,%x) unused=%d\n",
+ tx_ring->next_to_clean,tx_ring->next_to_use,unused);
+ }
+
+ /* current marked clean, scan for more that need cleaning. */
+ k = i;
+ for (j = 0; j < PCH_GBE_TX_WEIGHT; j++)
+ {
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, k);
+ if (tx_desc->gbec_status != DSC_INIT16) break; /*found*/
+ if (++k >= tx_ring->count) k = 0; /*increment, wrap*/
+ }
+ if (j < PCH_GBE_TX_WEIGHT) {
+ pr_debug("clean_tx: unused=%d loops=%d found tx_desc[%x,%x:%x].gbec_status=%04x\n",
+ unused,j, i,k, tx_ring->next_to_use, tx_desc->gbec_status);
+ i = k; /*found one to clean, usu gbec_status==2000.*/
+ }
+ }
+
while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
buffer_info = &tx_ring->buffer_info[i];
skb = buffer_info->skb;
+ cleaned = true;
if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) {
adapter->stats.tx_aborted_errors++;
@@ -1639,18 +1666,21 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
}
pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
cleaned_count);
- /* Recover from running out of Tx resources in xmit_frame */
- spin_lock(&tx_ring->tx_lock);
- if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {
- netif_wake_queue(adapter->netdev);
- adapter->stats.tx_restart_count++;
- pr_debug("Tx wake queue\n");
- }
+ if (cleaned_count > 0) { /*skip this if nothing cleaned*/
+ /* Recover from running out of Tx resources in xmit_frame */
+ spin_lock(&tx_ring->tx_lock);
+ if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev))))
+ {
+ netif_wake_queue(adapter->netdev);
+ adapter->stats.tx_restart_count++;
+ pr_debug("Tx wake queue\n");
+ }
- tx_ring->next_to_clean = i;
+ tx_ring->next_to_clean = i;
- pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
- spin_unlock(&tx_ring->tx_lock);
+ pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+ spin_unlock(&tx_ring->tx_lock);
+ }
return cleaned;
}
@@ -2387,7 +2417,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
- if (!cleaned)
+ if (cleaned)
work_done = budget;
/* If no Tx and not enough Rx work done,
* exit the polling mode
@@ -2793,6 +2823,7 @@ static int __init pch_gbe_init_module(void)
{
int ret;
+ pr_info("EG20T PCH Gigabit Ethernet Driver - version %s\n",DRV_VERSION);
ret = pci_register_driver(&pch_gbe_driver);
if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) {
if (copybreak == 0) {
^ permalink raw reply related
* [PATCH 1/3] pch_gbe: fix transmit watchdog timeout
From: Andy Cress @ 2012-07-26 15:59 UTC (permalink / raw)
To: netdev
An extended ping test with 6 vlans resulted in a driver oops with a
netdev transmit timeout.
Fix WATCHDOG_TIMEOUT to be more like e1000e at 5 * HZ, to avoid
unnecessary transmit timeouts.
Signed-off-by: Andy Cress <andy.cress@us.kontron.com>
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 4c04843..a746064 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -35,7 +35,7 @@ const char pch_driver_version[] = DRV_VERSION;
#define DSC_INIT16 0xC000
#define PCH_GBE_DMA_ALIGN 0
#define PCH_GBE_DMA_PADDING 2
-#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */
+#define PCH_GBE_WATCHDOG_PERIOD (5 * HZ) /* watchdog time */
#define PCH_GBE_COPYBREAK_DEFAULT 256
#define PCH_GBE_PCI_BAR 1
#define PCH_GBE_RESERVE_MEMORY 0x200000 /* 2MB */
^ 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