* Re: [PATCH] sctp: Make "Invalid Stream Identifier" ERROR follows SACK when bundling
From: Xufeng Zhang @ 2012-07-26 1:30 UTC (permalink / raw)
To: Vlad Yasevich
Cc: Neil Horman, xufeng zhang, sri, davem, linux-sctp, netdev,
linux-kernel
In-Reply-To: <50100A29.8010705@gmail.com>
On 7/25/12, Vlad Yasevich <vyasevich@gmail.com> wrote:
>> And after take a moment to look into the relative codes, I think we
>> can implement it
>> by below way:
>> 1). Add a flag(isi_err_needed) in the embedded struct peer of struct
>> struct sctp_association
>> just like sack_needed flag.
>> 2). When "invalid stream identifier" ERROR happens in sctp_eat_data()
>> function, we just
>> set isi_err_needed flag and don't create ERROR chunk and also don't
>> insert SCTP_CMD_REPLY command.
>> 3). In sctp_gen_sack() function, we create ERROR chunk and also insert
>> SCTP_CMD_REPLY command if isi_err_needed flag is set.
>>
>> Is this way proper?
>>
>
> So, I looked at the code, and it looks very simple to do. We already
> return a specific status from sctp_eat_data() when the error was
> generated. All you have to do is take the code that generates the error
> and adds it to the command list and give it its own small function that
> you can then call if SCTP_IERROR_BAD_STREAM error was returned.
No, it will still has the same problem by just doing this.
SCTP_CMD_GEN_SACK command actually don't enqueue SACK to outqueue,
sctp_gen_sack() do this things when processing SCTP_CMD_GEN_SACK command
in sctp_cmd_interpreter().
So it's not enough if we just insert SCTP_ERROR_INV_STRM command after
sctp_eat_data() return SCTP_IERROR_BAD_STREAM in sctp_sf_eat_data_6_2().
Thanks,
Xufeng Zhang
>
> -vlad
>
>>
>> Thanks,
>> Xufeng Zhang
>>>
>>>
>>>
>>> Thanks,
>>> Xufeng Zhang
>>>>
>>>> -vlad
>>>>>
>>>>> Thanks,
>>>>> Xufeng Zhang
>>>>>>
>>>>>> -vlad
>>>>
>>>>
>>>> --
>>>> Sent from my Android phone with SkitMail. Please excuse my brevity.
>>>>
>>>
>
>
>
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-26 0:54 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <20120725.163939.581743307449189972.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 25 Jul 2012 16:39:39 -0700 (PDT)
> From: David Miller <davem@davemloft.net>
> Date: Wed, 25 Jul 2012 16:17:32 -0700 (PDT)
>
>> From: Alexander Duyck <alexander.duyck@gmail.com>
>> Date: Wed, 25 Jul 2012 16:02:45 -0700
>>
>>> Since your patches are in I have started to re-run my tests. I am
>>> seeing a significant drop in throughput with 8 flows which I expected,
>>> however it looks like one of the biggest issues I am seeing is that
>>> the dst_hold and dst_release calls seem to be causing some serious
>>> cache thrash. I was at 12.5Mpps w/ 8 flows before the patches, after
>>> your patches it drops to 8.3Mpps.
>>
>> Yes, this is something we knew would start happening.
>>
>> One idea is to make cached dsts be per-cpu in the nexthops.
>
> Actually I think what really kills your case is the removal of the
> noref path for route lookups. I'll work on a patch to restore that
> in the case where we use cached routes from the FIB nexthops.
Alex, here is something I tossed together, does it help with the
dst_hold()/dst_release() overhead at all?
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/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..68887e3 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 set. However, if we are
+ * unsuccessful at storing this route into the cache
+ * we really need to clear that bit.
+ */
+ 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));
}
@@ -1588,8 +1593,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 +1626,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 +1663,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 +1707,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: [PATCH] dynamic_debug: Restore dev_dbg/netdev_dbg functionality, reduce stack use
From: David Miller @ 2012-07-26 0:17 UTC (permalink / raw)
To: joe; +Cc: gregkh, jbaron, kay, jim.cromie, akpm, linux-kernel, netdev
In-Reply-To: <403af268697d3d117114b12000b20c74aafa5bac.1343261030.git.joe@perches.com>
From: Joe Perches <joe@perches.com>
Date: Wed, 25 Jul 2012 17:10:00 -0700
> commit c4e00daaa9 ("driver-core: extend dev_printk() to pass structured data")
> changed __dev_printk and broke dynamic-debug's ability to control the
> dynamic prefix of dev_dbg(dev,..).
>
> dynamic_emit_prefix() adds "[tid] module:func:line:" to the output and
> those additions got lost.
>
> In addition, the current dynamic debug code uses up to 3 recursion
> levels via %pV. This can consume quite a bit of stack. Directly
> call printk_emit to reduce the recursion by one depth.
>
> These changes include:
>
> o Remove KERN_DEBUG from dynamic_emit_prefix
> o Create and use function create_syslog_header to format the syslog
> header for printk_emit uses.
> o Call create_syslog_header and neaten __dev_printk
> o Call create_syslog_header and printk_emit from dynamic_dev_dbg
> o Call create_syslog_header and printk_emit from dynamic_netdev_dbg
> o Make __dev_printk and __netdev_printk static not global
> o Remove include header declarations of __dev_printk and __netdev_printk
> o Remove now unused EXPORT_SYMBOL()s of __dev_printk and __netdev_printk
> o Whitespace neatening
>
> Signed-off-by: Joe Perches <joe@perches.com>
For networking parts:
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* [PATCH] dynamic_debug: Restore dev_dbg/netdev_dbg functionality, reduce stack use
From: Joe Perches @ 2012-07-26 0:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, David S. Miller, Jason Baron
Cc: Kay Sievers, Jim Cromie, Andrew Morton, linux-kernel, netdev
commit c4e00daaa9 ("driver-core: extend dev_printk() to pass structured data")
changed __dev_printk and broke dynamic-debug's ability to control the
dynamic prefix of dev_dbg(dev,..).
dynamic_emit_prefix() adds "[tid] module:func:line:" to the output and
those additions got lost.
In addition, the current dynamic debug code uses up to 3 recursion
levels via %pV. This can consume quite a bit of stack. Directly
call printk_emit to reduce the recursion by one depth.
These changes include:
o Remove KERN_DEBUG from dynamic_emit_prefix
o Create and use function create_syslog_header to format the syslog
header for printk_emit uses.
o Call create_syslog_header and neaten __dev_printk
o Call create_syslog_header and printk_emit from dynamic_dev_dbg
o Call create_syslog_header and printk_emit from dynamic_netdev_dbg
o Make __dev_printk and __netdev_printk static not global
o Remove include header declarations of __dev_printk and __netdev_printk
o Remove now unused EXPORT_SYMBOL()s of __dev_printk and __netdev_printk
o Whitespace neatening
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/base/core.c | 57 ++++++++++++++++++++++++-----------------
include/linux/device.h | 11 +++-----
include/linux/netdevice.h | 3 --
lib/dynamic_debug.c | 61 ++++++++++++++++++++++++++++++++++++---------
net/core/dev.c | 5 ++-
5 files changed, 89 insertions(+), 48 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 346be8b..320a32c 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1844,25 +1844,19 @@ void device_shutdown(void)
*/
#ifdef CONFIG_PRINTK
-int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf)
+int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
{
- char dict[128];
- size_t dictlen = 0;
const char *subsys;
-
- if (!dev)
- return printk("%s(NULL device *): %pV", level, vaf);
+ size_t pos = 0;
if (dev->class)
subsys = dev->class->name;
else if (dev->bus)
subsys = dev->bus->name;
else
- goto skip;
+ return 0;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "SUBSYSTEM=%s", subsys);
+ pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys);
/*
* Add device identifier DEVICE=:
@@ -1878,28 +1872,41 @@ int __dev_printk(const char *level, const struct device *dev,
c = 'b';
else
c = 'c';
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=%c%u:%u",
- c, MAJOR(dev->devt), MINOR(dev->devt));
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=%c%u:%u",
+ c, MAJOR(dev->devt), MINOR(dev->devt));
} else if (strcmp(subsys, "net") == 0) {
struct net_device *net = to_net_dev(dev);
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=n%u", net->ifindex);
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=n%u", net->ifindex);
} else {
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=+%s:%s", subsys, dev_name(dev));
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=+%s:%s", subsys, dev_name(dev));
}
-skip:
- return printk_emit(0, level[1] - '0',
- dictlen ? dict : NULL, dictlen,
+
+ return pos;
+}
+EXPORT_SYMBOL(create_syslog_header);
+
+static int __dev_printk(const char *level, const struct device *dev,
+ struct va_format *vaf)
+{
+ char hdr[128];
+ size_t hdrlen;
+
+ if (!dev)
+ return printk("%s(NULL device *): %pV", level, vaf);
+
+ hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
+
+ return printk_emit(0, level[1] - '0', hdrlen ? hdr : NULL, hdrlen,
"%s %s: %pV",
dev_driver_string(dev), dev_name(dev), vaf);
}
-EXPORT_SYMBOL(__dev_printk);
int dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
@@ -1914,6 +1921,7 @@ int dev_printk(const char *level, const struct device *dev,
vaf.va = &args;
r = __dev_printk(level, dev, &vaf);
+
va_end(args);
return r;
@@ -1933,6 +1941,7 @@ int func(const struct device *dev, const char *fmt, ...) \
vaf.va = &args; \
\
r = __dev_printk(kern_level, dev, &vaf); \
+ \
va_end(args); \
\
return r; \
diff --git a/include/linux/device.h b/include/linux/device.h
index 5083bcc..bd9701d 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -886,12 +886,12 @@ extern const char *dev_driver_string(const struct device *dev);
#ifdef CONFIG_PRINTK
-extern int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf);
+extern int create_syslog_header(const struct device *dev,
+ char *hdr, size_t hdrlen);
+
extern __printf(3, 4)
int dev_printk(const char *level, const struct device *dev,
- const char *fmt, ...)
- ;
+ const char *fmt, ...);
extern __printf(2, 3)
int dev_emerg(const struct device *dev, const char *fmt, ...);
extern __printf(2, 3)
@@ -909,9 +909,6 @@ int _dev_info(const struct device *dev, const char *fmt, ...);
#else
-static inline int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf)
-{ return 0; }
static inline __printf(3, 4)
int dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index eb06e58..291e0ee 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2715,9 +2715,6 @@ static inline const char *netdev_name(const struct net_device *dev)
return dev->name;
}
-extern int __netdev_printk(const char *level, const struct net_device *dev,
- struct va_format *vaf);
-
extern __printf(3, 4)
int netdev_printk(const char *level, const struct net_device *dev,
const char *format, ...);
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 7ca29a0..6507d11 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -521,25 +521,23 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
int pos_after_tid;
int pos = 0;
- pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG);
if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
- pos += snprintf(buf + pos, remaining(pos), "%s ",
- "<intr>");
+ pos += snprintf(buf + pos, remaining(pos), "<intr> ");
else
pos += snprintf(buf + pos, remaining(pos), "[%d] ",
- task_pid_vnr(current));
+ task_pid_vnr(current));
}
pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->modname);
+ desc->modname);
if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->function);
+ desc->function);
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
- desc->lineno);
+ desc->lineno);
if (pos - pos_after_tid)
pos += snprintf(buf + pos, remaining(pos), " ");
if (pos >= PREFIX_SIZE)
@@ -559,9 +557,13 @@ int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
+
+ res = printk(KERN_DEBUG "%s%pV",
+ dynamic_emit_prefix(descriptor, buf), &vaf);
+
va_end(args);
return res;
@@ -580,9 +582,24 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+
+ if (!dev) {
+ res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
+ } else {
+ char dict[128];
+ size_t dictlen;
+
+ dictlen = create_syslog_header(dev, dict, sizeof(dict));
+
+ res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
+ "%s%s %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev), dev_name(dev), &vaf);
+ }
+
va_end(args);
return res;
@@ -592,20 +609,40 @@ EXPORT_SYMBOL(__dynamic_dev_dbg);
#ifdef CONFIG_NET
int __dynamic_netdev_dbg(struct _ddebug *descriptor,
- const struct net_device *dev, const char *fmt, ...)
+ const struct net_device *dev, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
int res;
- char buf[PREFIX_SIZE];
BUG_ON(!descriptor);
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+
+ if (dev && dev->dev.parent) {
+ char buf[PREFIX_SIZE];
+ char dict[128];
+ size_t dictlen;
+
+ dictlen = create_syslog_header(dev->dev.parent,
+ dict, sizeof(dict));
+
+ res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
+ "%s%s %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev->dev.parent),
+ netdev_name(dev), &vaf);
+
+ } else if (dev) {
+ res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
+ } else {
+ res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
+ }
+
va_end(args);
return res;
diff --git a/net/core/dev.c b/net/core/dev.c
index 0ebaea1..f6ebe92 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6358,7 +6358,7 @@ const char *netdev_drivername(const struct net_device *dev)
return empty;
}
-int __netdev_printk(const char *level, const struct net_device *dev,
+static int __netdev_printk(const char *level, const struct net_device *dev,
struct va_format *vaf)
{
int r;
@@ -6373,7 +6373,6 @@ int __netdev_printk(const char *level, const struct net_device *dev,
return r;
}
-EXPORT_SYMBOL(__netdev_printk);
int netdev_printk(const char *level, const struct net_device *dev,
const char *format, ...)
@@ -6388,6 +6387,7 @@ int netdev_printk(const char *level, const struct net_device *dev,
vaf.va = &args;
r = __netdev_printk(level, dev, &vaf);
+
va_end(args);
return r;
@@ -6407,6 +6407,7 @@ int func(const struct net_device *dev, const char *fmt, ...) \
vaf.va = &args; \
\
r = __netdev_printk(level, dev, &vaf); \
+ \
va_end(args); \
\
return r; \
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-25 23:39 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <20120725.161732.91008692477078715.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 25 Jul 2012 16:17:32 -0700 (PDT)
> From: Alexander Duyck <alexander.duyck@gmail.com>
> Date: Wed, 25 Jul 2012 16:02:45 -0700
>
>> Since your patches are in I have started to re-run my tests. I am
>> seeing a significant drop in throughput with 8 flows which I expected,
>> however it looks like one of the biggest issues I am seeing is that
>> the dst_hold and dst_release calls seem to be causing some serious
>> cache thrash. I was at 12.5Mpps w/ 8 flows before the patches, after
>> your patches it drops to 8.3Mpps.
>
> Yes, this is something we knew would start happening.
>
> One idea is to make cached dsts be per-cpu in the nexthops.
Actually I think what really kills your case is the removal of the
noref path for route lookups. I'll work on a patch to restore that
in the case where we use cached routes from the FIB nexthops.
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: David Miller @ 2012-07-25 23:17 UTC (permalink / raw)
To: alexander.duyck; +Cc: eric.dumazet, netdev
In-Reply-To: <CAKgT0UdcqE52WFCT-t2om0SN3Yq5GqiwN+JbwCcnBv4LDOB6BQ@mail.gmail.com>
From: Alexander Duyck <alexander.duyck@gmail.com>
Date: Wed, 25 Jul 2012 16:02:45 -0700
> Since your patches are in I have started to re-run my tests. I am
> seeing a significant drop in throughput with 8 flows which I expected,
> however it looks like one of the biggest issues I am seeing is that
> the dst_hold and dst_release calls seem to be causing some serious
> cache thrash. I was at 12.5Mpps w/ 8 flows before the patches, after
> your patches it drops to 8.3Mpps.
Yes, this is something we knew would start happening.
One idea is to make cached dsts be per-cpu in the nexthops.
> I am also seeing routing fail periodically.
Every 30 seconds by chance? :-)
> I will be moving at rates listed above and suddenly drop to single
> digits packets per second. When this occurs the trace completely
> changes and __write_lock_failed jumps to over 90% of the CPU cycles.
It's probably happening when the nexthop ARP entry expires.
^ permalink raw reply
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Alexander Duyck @ 2012-07-25 23:02 UTC (permalink / raw)
To: David Miller, Eric Dumazet; +Cc: netdev
In-Reply-To: <20120720.142502.1144557295933737451.davem@davemloft.net>
On Fri, Jul 20, 2012 at 2:25 PM, David Miller <davem@davemloft.net> wrote:
>
> [ Ok I'm going to be a little bit cranky, and I think I deserve it.
>
> I'm basically not going to go through the multi-hour rebase and
> retest process again, as it's hit the point of diminishing returns
> as NOBODY is giving me test results but I can guarentee that
> EVERYONE will bitch and complain when I push this into net-next and
> it breaks their favorite feature. If you can't be bothered to test
> these changes, I'm honestly going to tell people to take a hike and
> fix it themselves. I simply don't care if you don't care enough to
> test changes of this magnitude to make sure your favorite setup
> still works.
>
> To say that I'm disappointed with the amount of testing feedback
> after posting more than a dozen iterations of this delicate patch
> set would be an understatement. I can think of only one person who
> actually tested one iteration of these patches and gave feedback.
>
> And meanwhile I've personally reviewed, tested, and signed off on
> everyone else's work WITHOUT DELAY during this entire process.
>
> I've pulled 25 hour long hacking shifts to make that a reality, so
> that my routing cache removal work absolutely would not impact or
> delay the patch submissions of any other networking developer. And
> I can't even get a handful of testers with some feedback? You
> really have to be kidding me.. ]
Sorry for not responding sooner but I have been on vacation for the
last few days.
I had been testing the patches over the last couple of weeks but I
didn't really feel like I could provide any input of value since I
don't have a strong understanding of the routing stack internals, and
because my test case tends to focus on small packet routing with a
very artificial work flow. I saw an overall drop in performance. I
had attributed to the fact that with so few flows I was exploiting the
routing cache to it's maximum potential, and had not explored it much
further.
My test consists of a SmartBits w/ a 10Gb/s port connected back to
back with one port on an 82599 adapter. I have the SmartBits
generating up to 16 64byte packet flows, each flow is filtered through
an ntuple filter to a specific queue, and each queue is pinned to a
specific CPU. The flows all have a unique source address but the same
destination address. The port doing the routing has two subnets. We
receive packets on the first subnet and then transmit them back out on
the second. I have set-up a static ARP entry for the destination
address in order to avoid the need for ARP address translation since
we are sending such a heavy packet load. My kernel config is stripped
down and does not include netfilter support.
Since your patches are in I have started to re-run my tests. I am
seeing a significant drop in throughput with 8 flows which I expected,
however it looks like one of the biggest issues I am seeing is that
the dst_hold and dst_release calls seem to be causing some serious
cache thrash. I was at 12.5Mpps w/ 8 flows before the patches, after
your patches it drops to 8.3Mpps. If I increase the number of queues
I am using to 16 the throughput drops off to something like 3.3Mpps.
Prior to your patches being applied the top 3 CPU consumers were
ixgbe_poll at around 10%, ixgbe_xmit_frame_ring at around 5%, and
__netif_receive_skb at around 5%. Below is the latest perf results
for 8 flows/queues after your patches:
14.52% [k] __write_lock_failed
10.68% [k] ip_route_input (75% of hits on dst_hold call)
10.18% [k] fib_table_lookup
6.04% [k] ixgbe_poll
5.80% [k] dst_release
4.14% [k] __netif_receive_skb
3.55% [k] _raw_spin_lock
2.84% [k] ip_forward
2.58% [k] ixgbe_xmit_frame_ring
I am also seeing routing fail periodically. I will be moving at rates
listed above and suddenly drop to single digits packets per second.
When this occurs the trace completely changes and __write_lock_failed
jumps to over 90% of the CPU cycles. It seems to occur more often if
I increase the number of CPUs in use while routing. Below is the call
graph I recorded for the function from perf to show the function calls
that are leading to the issue:
14.52% [k] __write_lock_failed
|
|--99.92%-- _raw_write_lock_bh
| __neigh_event_send
| neigh_resolve_output
| ip_finish_output
| ip_output
| ip_forward
| ip_rcv
| __netif_receive_skb
| netif_receive_skb
| napi_skb_finish
| napi_gro_receive
| ixgbe_poll
| net_rx_action
| __do_softirq
| run_ksoftirqd
| kthread
| kernel_thread_helper
--0.08%-- [...]
I am trying to figure out what can be done, but as I said I am not
that familiar with the internals of the IP routing stack itself. If
you need more data let me know and I can see about performing whatever
test, or altering my configuration as needed.
Thanks,
Alex
^ permalink raw reply
* Re: [RFC ETHTOOL PATCH 2/2] ethtool: allow setting MDI-X state
From: Ben Hutchings @ 2012-07-25 22:59 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: netdev
In-Reply-To: <20120725175308.9839.50343.stgit@jbrandeb-snb.jf.intel.com>
On Wed, 2012-07-25 at 10:53 -0700, Jesse Brandeburg wrote:
> A bit ago ethtool added support for reading MDI-X state, this
> patch finishes the implementation, adding the complementary write
> command.
>
> Add support to ethtool for controlling the MDI-X (crossover)
> state of a network port. Most adapters correctly negotiate
> MDI-X, but some ill-behaved switches have trouble and end up
> picking the wrong MDI setting, which results in complete loss of
> link. Usually this error condition can be observed when multiple
> ethtool -r ethX are required before link is achieved.
>
> This patch allows the user to override the normal "auto" setting
> and force the crossover state to on or off.
>
> The set will fail if the driver doesn't support the get, as
> suggested by Ben Hutchings.
>
> # ./ethtool -s p1p1 mdix off
> setting MDI not supported
>
> In addition the do_gset output was changed slightly to report the
> value set by the user (when the driver supports the set)
>
> old:
> MDI-X: on
>
> new:
> MDI-X: on (auto)
> or
> MDI-X: on (forced)
>
> usage is ethtool -s eth0 mdix [auto|on|off]
[...]
> --- a/ethtool.c
> +++ b/ethtool.c
> @@ -18,6 +18,8 @@
> * Rx Network Flow Control configuration support <santwona.behera@sun.com>
> * Various features by Ben Hutchings <bhutchings@solarflare.com>;
> * Copyright 2009, 2010 Solarflare Communications
> + * MDI-X set support by Jesse Brandeburg <jesse.brandeburg@intel.com>
> + * Copyright 2012 Intel Corporation
> *
> * TODO:
> * * show settings for all devices
> @@ -559,13 +561,29 @@ static int dump_ecmd(struct ethtool_cmd *ep)
> fprintf(stdout, " MDI-X: ");
> switch (ep->eth_tp_mdix) {
> case ETH_TP_MDI:
> - fprintf(stdout, "off\n");
> + fprintf(stdout, "off");
> break;
> case ETH_TP_MDI_X:
> - fprintf(stdout, "on\n");
> + fprintf(stdout, "on");
> break;
> default:
> - fprintf(stdout, "Unknown\n");
> + fprintf(stdout, "Unknown");
> + break;
> + }
> + switch (ep->eth_tp_mdix_ctrl) {
> + case ETH_TP_MDI:
> + case ETH_TP_MDI_X:
> + /* forced via sset */
> + fprintf(stdout, " (forced)\n");
[...]
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.
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 net-next,2/2] hyperv: Add error handling to rndis_filter_device_add()
From: David Miller @ 2012-07-25 22:49 UTC (permalink / raw)
To: haiyangz; +Cc: netdev, olaf, linux-kernel, devel
In-Reply-To: <1343239722-21328-2-git-send-email-haiyangz@microsoft.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
Date: Wed, 25 Jul 2012 11:08:42 -0700
> Reported-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next,1/2] hyperv: Add a check for ring_size value
From: David Miller @ 2012-07-25 22:48 UTC (permalink / raw)
To: haiyangz; +Cc: netdev, kys, olaf, linux-kernel, devel
In-Reply-To: <1343239722-21328-1-git-send-email-haiyangz@microsoft.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
Date: Wed, 25 Jul 2012 11:08:41 -0700
> It prevents ring_size being set to a too small value.
>
> Reported-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Applied.
^ permalink raw reply
* Re: [RFC NET-NEXT PATCH 0/6] implement MDI-X set support in Intel drivers
From: Ben Hutchings @ 2012-07-25 22:48 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: netdev
In-Reply-To: <20120725175430.9995.11370.stgit@jbrandeb-snb.jf.intel.com>
On Wed, 2012-07-25 at 10:59 -0700, Jesse Brandeburg wrote:
> This is an update (v2) to the patches sent previously.
>
> This series implements MDI-X set support in the Intel gigabit ethernet
> drivers. It specifically allows a user to control the MDI state,
> in order for them to work around issues with broken switches.
>
> The only change to this series is updated descriptions and an
> addition of reporting the current mdix_ctrl value in the
> "get_settings" functions, which allows the new extended reporting
> in the ethtool app's MDI-X: line
>
> sent as RFC for now to get feedback while internal testing
> completes. (and net-next is closed)
[...]
This all looks sane.
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: [RFC NET-NEXT PATCH 5/6] e1000e: implement MDI/MDI-X control
From: Ben Hutchings @ 2012-07-25 22:43 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: netdev
In-Reply-To: <20120725180025.9995.5613.stgit@jbrandeb-snb.jf.intel.com>
On Wed, 2012-07-25 at 11:00 -0700, Jesse Brandeburg wrote:
> some users report issues with link failing when connected to certain
> switches. This gives the user the ability to control the MDI state
> from the driver, allowing users to work around some improperly
> behaving switches.
>
> forcing in this driver is for now only allowed when auto-neg is
> enabled.
[...]
> --- a/drivers/net/ethernet/intel/e1000e/ethtool.c
> +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
[...]
> @@ -241,6 +246,10 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
> default:
> goto err_inval;
> }
> +
> + /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
> + adapter->hw.phy.mdix = AUTO_ALL_MODES;
> +
[...]
I have the same question about this assignment as in e1000.
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: [RFC NET-NEXT PATCH 4/6] e1000: configure and read MDI settings
From: Ben Hutchings @ 2012-07-25 22:41 UTC (permalink / raw)
To: Jesse Brandeburg; +Cc: netdev
In-Reply-To: <20120725180020.9995.32923.stgit@jbrandeb-snb.jf.intel.com>
On Wed, 2012-07-25 at 11:00 -0700, Jesse Brandeburg wrote:
> this is the implementation in e1000 to allow ethtool to force
> MDI state, allowing users to work around some improperly
> behaving switches.
>
> forcing in this driver is for now only allowed when auto-neg is enabled.
>
> to use must have the matching version of ethtool app that supports
> this functionality.
[...]
> --- a/drivers/net/ethernet/intel/e1000/e1000_main.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
> @@ -4939,6 +4939,10 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
> default:
> goto err_inval;
> }
> +
> + /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
> + hw->mdix = AUTO_ALL_MODES;
You will translate AUTO_ALL_MODES to ETH_TP_MDI_AUTO in
e1000_get_settings, and then treat that as an error in
e1000_set_settings if hw->media_type != e1000_media_type_copper. So,
does this assignment need to be conditional on hw->media_type ==
e1000_media_type_copper?
Ben.
> return 0;
>
> err_inval:
>
--
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 RESEND net] net/mlx4_en: Limit the RFS filter IDs to be < RPS_NO_FILTER
From: Ben Hutchings @ 2012-07-25 22:29 UTC (permalink / raw)
To: David Miller; +Cc: ogerlitz, netdev, oren, amirv
In-Reply-To: <20120725.152337.155627167530086828.davem@davemloft.net>
On Wed, 2012-07-25 at 15:23 -0700, David Miller wrote:
> From: Or Gerlitz <ogerlitz@mellanox.com>
> Date: Wed, 25 Jul 2012 18:04:35 +0300
>
> > On 25/07/2012 17:57, Ben Hutchings wrote:
> >>> @@ -77,12 +77,8 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv,
> >>> struct mlx4_en_cq *cq,
> >>> struct mlx4_en_dev *mdev = priv->mdev;
> >>> int err = 0;
> >>> char name[25];
> >>> - struct cpu_rmap *rmap =
> >>> -#ifdef CONFIG_RFS_ACCEL
> >>> - priv->dev->rx_cpu_rmap;
> >>> -#else
> >>> - NULL;
> >>> -#endif
> >>> + struct cpu_rmap *rmap = IS_ENABLED(CONFIG_RFS_ACCEL) ?
> >>> + priv->dev->rx_cpu_rmap : NULL;
> >>
> >> This is a separate change.
> >
> > OK, will send two patches
>
> This change breaks the build.
>
> You can't do this check at run-time, because the reason you need to
> check CONFIG_RFS_ACCEL is because if that's disabled then the netdev
> structure doesn't even have the ->rx_cpu_rmap member.
Yes, sorry for suggesting that, Or.
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] ipv4: rt_cache_valid must check expired routes
From: David Miller @ 2012-07-25 22:25 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1343229083.2626.11177.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 25 Jul 2012 17:11:23 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> commit d2d68ba9fe8 (ipv4: Cache input routes in fib_info nexthops.)
> introduced rt_cache_valid() helper. It unfortunately doesn't check if
> route is expired before caching it.
>
> I noticed sk_setup_caps() was constantly called on a tcp workload.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks.
> ---
> This patch is bringed by an European guy, but its still July after
> all ;)
:-)
^ permalink raw reply
* Re: [PATCH v0 net-next 1/1] net/pch_gpe: Cannot disable ethernet autonegation
From: David Miller @ 2012-07-25 22:25 UTC (permalink / raw)
To: w90p710; +Cc: netdev
In-Reply-To: <1343218439-5403-1-git-send-email-w90p710@gmail.com>
From: w90p710@gmail.com
Date: Wed, 25 Jul 2012 20:13:59 +0800
> From: Wei Yang <w90p710@gmail.com>
>
> When attempting to disable ethernet autonegation via ethtool,
> the pch_gpe driver will set software reset bit of PHY chip, But
> control register of PHY chip of FRI2 will reenable ethernet autonegation.
>
> Signed-off-by: Wei Yang <w90p710@gmail.com>
Applied.
^ permalink raw reply
* Re: [patch 0/3] s390: bug fixes for net
From: David Miller @ 2012-07-25 22:24 UTC (permalink / raw)
To: frank.blaschka; +Cc: netdev, linux-s390
In-Reply-To: <20120725083426.704834478@de.ibm.com>
From: frank.blaschka@de.ibm.com
Date: Wed, 25 Jul 2012 10:34:26 +0200
> here are some bug fixes for net.
All applied, thanks.
^ permalink raw reply
* Re: [PATCH] be2net: Missing byteswap in be_get_fw_log_level causes oops on PowerPC
From: David Miller @ 2012-07-25 22:24 UTC (permalink / raw)
To: anton; +Cc: sathya.perla, subbu.seetharaman, ajit.khaparde, netdev
In-Reply-To: <20120725110525.0468f754@kryten>
From: Anton Blanchard <anton@samba.org>
Date: Wed, 25 Jul 2012 11:05:25 +1000
>
> We are seeing an oops in be_get_fw_log_level on ppc64 where we walk
> off the end of memory.
>
> commit 941a77d582c8 (be2net: Fix to allow get/set of debug levels in
> the firmware.) requires byteswapping of num_modes and num_modules.
>
> Cc: stable@vger.kernel.org # 3.5+
> Signed-off-by: Anton Blanchard <anton@samba.org>
Applied.
^ permalink raw reply
* Re: [PATCH RESEND net] net/mlx4_en: Limit the RFS filter IDs to be < RPS_NO_FILTER
From: David Miller @ 2012-07-25 22:23 UTC (permalink / raw)
To: ogerlitz; +Cc: bhutchings, netdev, oren, amirv
In-Reply-To: <50100B03.2020205@mellanox.com>
From: Or Gerlitz <ogerlitz@mellanox.com>
Date: Wed, 25 Jul 2012 18:04:35 +0300
> On 25/07/2012 17:57, Ben Hutchings wrote:
>>> @@ -77,12 +77,8 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv,
>>> struct mlx4_en_cq *cq,
>>> struct mlx4_en_dev *mdev = priv->mdev;
>>> int err = 0;
>>> char name[25];
>>> - struct cpu_rmap *rmap =
>>> -#ifdef CONFIG_RFS_ACCEL
>>> - priv->dev->rx_cpu_rmap;
>>> -#else
>>> - NULL;
>>> -#endif
>>> + struct cpu_rmap *rmap = IS_ENABLED(CONFIG_RFS_ACCEL) ?
>>> + priv->dev->rx_cpu_rmap : NULL;
>>
>> This is a separate change.
>
> OK, will send two patches
This change breaks the build.
You can't do this check at run-time, because the reason you need to
check CONFIG_RFS_ACCEL is because if that's disabled then the netdev
structure doesn't even have the ->rx_cpu_rmap member.
^ permalink raw reply
* Re: [PATCH] mlx4: Add support for EEH error recovery
From: David Miller @ 2012-07-25 22:19 UTC (permalink / raw)
To: shlomop
Cc: or.gerlitz, klebers, netdev, jackm, yevgenyp, ogerlitz, cascardo,
brking
In-Reply-To: <5010070B.5040405@mellanox.com>
From: Shlomo Pongartz <shlomop@mellanox.com>
Date: Wed, 25 Jul 2012 17:47:39 +0300
> Acked-by: Shlomo Pongratz <shlomop@mellanox.com
> <mailto:shlomop@mellanox.com>>
This really isn't how an Acked-by: tag should look, there should
simply be a closing ">" at the end of the first line, but it's somehow
been replaced with a newline and that "<mailto:shlomop@mellanox.com>"
URL instead.
I'll fix it up this time, but in the future I will not and your
ACK will simply get lost.
^ permalink raw reply
* Re: open sockets preventing unregister_netdevice from completing in linux-next (next-20120724)
From: David Miller @ 2012-07-25 22:17 UTC (permalink / raw)
To: eric.dumazet; +Cc: bjorn, netdev
In-Reply-To: <1343227128.2626.11157.camel@edumazet-glaptop>
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.
^ permalink raw reply
* orphan process is causing deadlock in __kernel_vsyscall ()
From: Sri Ram Vemulpali @ 2012-07-25 21:14 UTC (permalink / raw)
To: linux-kernel-mail, linux-newbie, linux-netdev
Hello All,
I am debugging a problem which I do not know how to solve. I know what
is happening, but cannot find solution to it. If anyone has any
suggestions or solution that would be really grateful and I appreciate
it.
Here is the description.
I have a thread which spawns a child process using fork() and in child
context it execv to shell and parent thread waits on waitpid(). This
child process is nothing but a shell /bin/sh, so that from program I
can create shell and run some commands.
In this shell instance, I run tshark for capturing network traffic. I
have really high traffic going, so system is really busy. All is good
so far, but when I send SIGKILL to child process (shell) from another
thread from same application,
child process (shell) gets terminated and tshark is assigned to
init(1) process as orphan. The parent thread which spawned the child
process unblocks from waitpid() after cleaning child instance and
continues it execution.
Here is the problem:
Once the parent thread resumes from waitpid(), it hits fprintf to
print message "exiting from shell" to console. In here the main thread
gets blocked in __kernel_vsyscall () entered from fprintf. Following
is my stack trace from gdb.
But after some more debugging and found that, if I kill from another
shell "tshark" process which is assigned to init(1) as child, the
parent thread unblocks from __kernel_vsyscall ().
Can anyone tell what is going on, is this related to futex spinning
problem where lock is been held by tshark. How would I approach this
problem?
Or is there a way to kill all child process of a process without
making them orphan. Because when a child process is running at the
time parent is exiting, that child process is assigned to init(1) as
orphan process.
Can this behavior be modified. Please let me know any suggestions and
thoughts. Thanks in advance.
--
Regards,
Sri.
(gdb) backtrace
#0 0xffffe424 in __kernel_vsyscall ()
#1 0xb7e6396b in write () from /lib/libc.so.6
#2 0xb7e0c2ef in _IO_new_file_write () from /lib/libc.so.6
#3 0xb7e0bf93 in new_do_write () from /lib/libc.so.6
#4 0xb7e0c296 in _IO_new_do_write () from /lib/libc.so.6
#5 0xb7e0ce20 in _IO_new_file_overflow () from /lib/libc.so.6
#6 0xb7e0c0cd in _IO_new_file_xsputn () from /lib/libc.so.6
#7 0xb7de3634 in vfprintf () from /lib/libc.so.6
#8 0x09ad62a2 in acme_fprintf (stream=0xb7ee2560,
format=0x9f17694 "shell exited. returning to acli\n")
at /home/svemulpali/cc/svemulpali_SCOTTY_main/linux/private/common/src/coutOverride.cpp:42
#9 0x094a9345 in vxShellCmdStartWait (syscmd=0x0)
at /home/svemulpali/cc/svemulpali_SCOTTY_main/linux/private/lib/stub/vxShellLib.cpp:210
^ permalink raw reply
* [RFC NET-NEXT PATCH 6/6] igb: update to allow reading/setting MDI state
From: Jesse Brandeburg @ 2012-07-25 18:00 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, jesse.brandeburg
In-Reply-To: <20120725175430.9995.11370.stgit@jbrandeb-snb.jf.intel.com>
This is the implementation for igb to allow forcing MDI state
via ethtool, allowing users to work around some improperly
behaving switches.
forcing in this driver is for now only allowed when auto-neg is
enabled.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Carolyn Wyborny <carolyn.wyborny@intel.com>
---
drivers/net/ethernet/intel/igb/igb_ethtool.c | 42 ++++++++++++++++++++++++++
drivers/net/ethernet/intel/igb/igb_main.c | 4 ++
2 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index a19c84c..cf0e9fb 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -198,6 +198,19 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
}
ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+ /* MDI-X => 2; MDI =>1; Invalid =>0 */
+ if (hw->phy.media_type == e1000_media_type_copper)
+ ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
+ ETH_TP_MDI;
+ else
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+
+ if (hw->phy.mdix == AUTO_ALL_MODES)
+ ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
+ else
+ ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
+
return 0;
}
@@ -214,6 +227,22 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
return -EINVAL;
}
+ /*
+ * MDI setting is only allowed when autoneg enabled because
+ * some hardware doesn't allow MDI setting when speed or
+ * duplex is forced.
+ */
+ if (ecmd->eth_tp_mdix_ctrl) {
+ if (hw->phy.media_type != e1000_media_type_copper)
+ return -EOPNOTSUPP;
+
+ if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
+ (ecmd->autoneg != AUTONEG_ENABLE)) {
+ dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
+ return -EINVAL;
+ }
+ }
+
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
msleep(1);
@@ -227,12 +256,25 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
hw->fc.requested_mode = e1000_fc_default;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
+ /* calling this overrides forced MDI setting */
if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__IGB_RESETTING, &adapter->state);
return -EINVAL;
}
}
+ /* MDI-X => 2; MDI => 1; Auto => 3 */
+ if (ecmd->eth_tp_mdix_ctrl) {
+ /*
+ * fix up the value for auto (3 => 0) as zero is mapped
+ * internally to auto
+ */
+ if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
+ hw->phy.mdix = AUTO_ALL_MODES;
+ else
+ hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
+ }
+
/* reset the link */
if (netif_running(adapter->netdev)) {
igb_down(adapter);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 1050411..447e131 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6676,6 +6676,10 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
default:
goto err_inval;
}
+
+ /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
+ adapter->hw.phy.mdix = AUTO_ALL_MODES;
+
return 0;
err_inval:
^ permalink raw reply related
* [RFC ETHTOOL PATCH 2/2] ethtool: allow setting MDI-X state
From: Jesse Brandeburg @ 2012-07-25 17:53 UTC (permalink / raw)
To: netdev, bhutchings; +Cc: jesse.brandeburg
In-Reply-To: <20120725174351.9839.132.stgit@jbrandeb-snb.jf.intel.com>
A bit ago ethtool added support for reading MDI-X state, this
patch finishes the implementation, adding the complementary write
command.
Add support to ethtool for controlling the MDI-X (crossover)
state of a network port. Most adapters correctly negotiate
MDI-X, but some ill-behaved switches have trouble and end up
picking the wrong MDI setting, which results in complete loss of
link. Usually this error condition can be observed when multiple
ethtool -r ethX are required before link is achieved.
This patch allows the user to override the normal "auto" setting
and force the crossover state to on or off.
The set will fail if the driver doesn't support the get, as
suggested by Ben Hutchings.
# ./ethtool -s p1p1 mdix off
setting MDI not supported
In addition the do_gset output was changed slightly to report the
value set by the user (when the driver supports the set)
old:
MDI-X: on
new:
MDI-X: on (auto)
or
MDI-X: on (forced)
usage is ethtool -s eth0 mdix [auto|on|off]
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 8 ++++++++
ethtool.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 523b737..fbfb252 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -239,6 +239,7 @@ ethtool \- query or control network driver and hardware settings
.BI speed \ N
.B2 duplex half full
.B4 port tp aui bnc mii fibre
+.B3 mdix auto on off
.B2 autoneg on off
.BN advertise
.BN phyad
@@ -518,6 +519,13 @@ Sets full or half duplex mode.
.A4 port tp aui bnc mii fibre
Selects device port.
.TP
+.A3 mdix auto on off
+Selects MDI-X mode for port. May be used to override the automatic detection
+feature of most adapters. Auto means automatic detection of MDI status, on
+forces MDI-X (crossover) mode, while off means MDI (straight through) mode.
+The driver should guarantee that this command takes effect immediately, and
+if necessary may reset the link to cause the change to take effect.
+.TP
.A2 autoneg on off
Specifies whether autonegotiation should be enabled. Autonegotiation
is enabled by default, but in some network devices may have trouble
diff --git a/ethtool.c b/ethtool.c
index f18f611..7b60895 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -18,6 +18,8 @@
* Rx Network Flow Control configuration support <santwona.behera@sun.com>
* Various features by Ben Hutchings <bhutchings@solarflare.com>;
* Copyright 2009, 2010 Solarflare Communications
+ * MDI-X set support by Jesse Brandeburg <jesse.brandeburg@intel.com>
+ * Copyright 2012 Intel Corporation
*
* TODO:
* * show settings for all devices
@@ -559,13 +561,29 @@ static int dump_ecmd(struct ethtool_cmd *ep)
fprintf(stdout, " MDI-X: ");
switch (ep->eth_tp_mdix) {
case ETH_TP_MDI:
- fprintf(stdout, "off\n");
+ fprintf(stdout, "off");
break;
case ETH_TP_MDI_X:
- fprintf(stdout, "on\n");
+ fprintf(stdout, "on");
break;
default:
- fprintf(stdout, "Unknown\n");
+ fprintf(stdout, "Unknown");
+ break;
+ }
+ switch (ep->eth_tp_mdix_ctrl) {
+ case ETH_TP_MDI:
+ case ETH_TP_MDI_X:
+ /* forced via sset */
+ fprintf(stdout, " (forced)\n");
+ break;
+ case ETH_TP_MDI_AUTO:
+ /* not forced */
+ fprintf(stdout, " (auto)\n");
+ break;
+ case ETH_TP_MDI_INVALID:
+ default:
+ /* this interface doesn't support gset MDI-X */
+ fprintf(stdout, "\n");
break;
}
}
@@ -1939,6 +1957,7 @@ static int do_sset(struct cmd_context *ctx)
int speed_wanted = -1;
int duplex_wanted = -1;
int port_wanted = -1;
+ int mdix_wanted = -1;
int autoneg_wanted = -1;
int phyad_wanted = -1;
int xcvr_wanted = -1;
@@ -1999,6 +2018,19 @@ static int do_sset(struct cmd_context *ctx)
port_wanted = PORT_FIBRE;
else
exit_bad_args();
+ } else if (!strcmp(argp[i], "mdix")) {
+ gset_changed = 1;
+ i += 1;
+ if (i >= argc)
+ exit_bad_args();
+ if (!strcmp(argp[i], "auto"))
+ mdix_wanted = ETH_TP_MDI_AUTO;
+ else if (!strcmp(argp[i], "on"))
+ mdix_wanted = ETH_TP_MDI_X;
+ else if (!strcmp(argp[i], "off"))
+ mdix_wanted = ETH_TP_MDI;
+ else
+ exit_bad_args();
} else if (!strcmp(argp[i], "autoneg")) {
i += 1;
if (i >= argc)
@@ -2120,6 +2152,13 @@ static int do_sset(struct cmd_context *ctx)
ecmd.duplex = duplex_wanted;
if (port_wanted != -1)
ecmd.port = port_wanted;
+ if (mdix_wanted != -1) {
+ /* check driver supports MDI-X */
+ if (ecmd.eth_tp_mdix_ctrl != ETH_TP_MDI_INVALID)
+ ecmd.eth_tp_mdix_ctrl = mdix_wanted;
+ else
+ fprintf(stderr, "setting MDI not supported\n");
+ }
if (autoneg_wanted != -1)
ecmd.autoneg = autoneg_wanted;
if (phyad_wanted != -1)
@@ -2179,6 +2218,8 @@ static int do_sset(struct cmd_context *ctx)
fprintf(stderr, " not setting phy_address\n");
if (xcvr_wanted != -1)
fprintf(stderr, " not setting transceiver\n");
+ if (mdix_wanted != -1)
+ fprintf(stderr, " not setting mdix\n");
}
}
@@ -3285,6 +3326,7 @@ static const struct option {
" [ speed %d ]\n"
" [ duplex half|full ]\n"
" [ port tp|aui|bnc|mii|fibre ]\n"
+ " [ mdix auto|on|off ]\n"
" [ autoneg on|off ]\n"
" [ advertise %x ]\n"
" [ phyad %d ]\n"
^ permalink raw reply related
* [RFC NET-NEXT PATCH 4/6] e1000: configure and read MDI settings
From: Jesse Brandeburg @ 2012-07-25 18:00 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, jesse.brandeburg
In-Reply-To: <20120725175430.9995.11370.stgit@jbrandeb-snb.jf.intel.com>
this is the implementation in e1000 to allow ethtool to force
MDI state, allowing users to work around some improperly
behaving switches.
forcing in this driver is for now only allowed when auto-neg is enabled.
to use must have the matching version of ethtool app that supports
this functionality.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Tushar Dave <tushar.n.dave@intel.com>
---
drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 39 ++++++++++++++++++++++
drivers/net/ethernet/intel/e1000/e1000_main.c | 4 ++
2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index 736a7d9..9089d00 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -174,6 +174,20 @@ static int e1000_get_settings(struct net_device *netdev,
ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+ /* MDI-X => 1; MDI => 0 */
+ if ((hw->media_type == e1000_media_type_copper) &&
+ netif_carrier_ok(netdev))
+ ecmd->eth_tp_mdix = (!!adapter->phy_info.mdix_mode ?
+ ETH_TP_MDI_X :
+ ETH_TP_MDI);
+ else
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+
+ if (hw->mdix == AUTO_ALL_MODES)
+ ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
+ else
+ ecmd->eth_tp_mdix_ctrl = hw->mdix;
return 0;
}
@@ -183,6 +197,22 @@ static int e1000_set_settings(struct net_device *netdev,
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ /*
+ * MDI setting is only allowed when autoneg enabled because
+ * some hardware doesn't allow MDI setting when speed or
+ * duplex is forced.
+ */
+ if (ecmd->eth_tp_mdix_ctrl) {
+ if (hw->media_type != e1000_media_type_copper)
+ return -EOPNOTSUPP;
+
+ if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
+ (ecmd->autoneg != AUTONEG_ENABLE)) {
+ e_err(drv, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
+ return -EINVAL;
+ }
+ }
+
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1);
@@ -199,12 +229,21 @@ static int e1000_set_settings(struct net_device *netdev,
ecmd->advertising = hw->autoneg_advertised;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
+ /* calling this overrides forced MDI setting */
if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->flags);
return -EINVAL;
}
}
+ /* MDI-X => 2; MDI => 1; Auto => 3 */
+ if (ecmd->eth_tp_mdix_ctrl) {
+ if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
+ hw->mdix = AUTO_ALL_MODES;
+ else
+ hw->mdix = ecmd->eth_tp_mdix_ctrl;
+ }
+
/* reset the link */
if (netif_running(adapter->netdev)) {
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 3bfbb8d..0ae2fcf 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -4939,6 +4939,10 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
default:
goto err_inval;
}
+
+ /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
+ hw->mdix = AUTO_ALL_MODES;
+
return 0;
err_inval:
^ 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