* [PATCH] ipv4: fix error handling in icmp_protocol.
From: Li Wei @ 2013-02-22 8:18 UTC (permalink / raw)
To: davem; +Cc: netdev, lw
Now we handle icmp errors in each transport protocol's err_handler,
for icmp protocols, that is ping_err. Since this handler only care
of those icmp errors triggered by echo request, errors triggered
by echo reply(which sent by kernel) are sliently ignored.
So wrap ping_err() with icmp_err() to deal with those icmp errors.
Signed-off-by: Li Wei <lw@cn.fujitsu.com>
---
include/net/icmp.h | 1 +
net/ipv4/af_inet.c | 2 +-
net/ipv4/icmp.c | 23 +++++++++++++++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 9ac2524..081439f 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -41,6 +41,7 @@ struct net;
extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
extern int icmp_rcv(struct sk_buff *skb);
+extern void icmp_err(struct sk_buff *, u32 info);
extern int icmp_init(void);
extern void icmp_out_count(struct net *net, unsigned char type);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e225a4e..334b461 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1572,7 +1572,7 @@ static const struct net_offload udp_offload = {
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
- .err_handler = ping_err,
+ .err_handler = icmp_err,
.no_policy = 1,
.netns_ok = 1,
};
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 17ff9fd..3ac5dff 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -934,6 +934,29 @@ error:
goto drop;
}
+void icmp_err(struct sk_buff *skb, u32 info)
+{
+ struct iphdr *iph = (struct iphdr *)skb->data;
+ struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
+ int type = icmp_hdr(skb)->type;
+ int code = icmp_hdr(skb)->code;
+ struct net *net = dev_net(skb->dev);
+
+ /*
+ * Use ping_err to handle all icmp errors except those
+ * triggered by ICMP_ECHOREPLY which sent from kernel.
+ */
+ if (icmph->type != ICMP_ECHOREPLY) {
+ ping_err(skb, info);
+ return;
+ }
+
+ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
+ ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0);
+ else if (type == ICMP_REDIRECT)
+ ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0);
+}
+
/*
* This table is the definition of how we handle ICMP.
*/
--
1.8.0.2
^ permalink raw reply related
* Re: Softirqs without captured packets
From: Javier Domingo @ 2013-02-22 9:32 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <CALZVapm1evE6rOgNkJapu9VboA6OojKGJ-UhRhZ26J0A+k4nmw@mail.gmail.com>
Which is the reason for that in the poll function, not only some
drivers have that tx completion (I suppose it is to free resources),
but also to send packets in that routine?
In e1000e, I have found that it frees resources used in tx, with the
e1000_clean_tx_irq, and also, although the tx completion is first, it
executes the rx routine.
On the other hand, tg3 driver not only does the tx resources free but
also sends packets in that time, and may return from the poll thought
it might not have done rx work in the net_rx_action routine.
Why is this like that? I mean, why all the tx is done *before* the rx
thread, thought it may not do any rx work (in tg3) ?
I hope you can help me to understand the reasons,
Javier Domingo
^ permalink raw reply
* [PATCH 1/2] openvswitch: fix the calculation of checksum for vlan header
From: Cong Wang @ 2013-02-22 9:32 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Jesse Gross, Cong Wang
From: Cong Wang <amwang@redhat.com>
In vlan_insert_tag(), we insert a 4-byte VLAN header _after_
mac header:
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
...
veth->h_vlan_proto = htons(ETH_P_8021Q);
...
veth->h_vlan_TCI = htons(vlan_tci);
so after it, we should recompute the checksum to include these 4 bytes.
skb->data still points to the mac header, therefore VLAN header is at
(2 * ETH_ALEN = 12) bytes after it, not (ETH_HLEN = 14) bytes.
This can also be observed via tcpdump:
0x0000: ffff ffff ffff 5254 005d 6f6e 8100 000a
0x0010: 0806 0001 0800 0604 0001 5254 005d 6f6e
0x0020: c0a8 026e 0000 0000 0000 c0a8 0282
Similar for __pop_vlan_tci(), the vlan header we remove is the one
overwritten in:
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
Therefore the VLAN_HLEN = 4 bytes after 2 * ETH_ALEN is the part
we want to sub from checksum.
Cc: David S. Miller <davem@davemloft.net>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/openvswitch/actions.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index ac2defe..d4d5363 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -58,7 +58,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
- + ETH_HLEN, VLAN_HLEN, 0));
+ + (2 * ETH_ALEN), VLAN_HLEN, 0));
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
*current_tci = vhdr->h_vlan_TCI;
@@ -115,7 +115,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_add(skb->csum, csum_partial(skb->data
- + ETH_HLEN, VLAN_HLEN, 0));
+ + (2 * ETH_ALEN), VLAN_HLEN, 0));
}
__vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
--
1.7.7.6
^ permalink raw reply related
* [PATCH 2/2] vlan: adjust vlan_set_encap_proto() for its callers
From: Cong Wang @ 2013-02-22 9:32 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Jesse Gross, Cong Wang
In-Reply-To: <1361525547-21808-1-git-send-email-amwang@redhat.com>
From: Cong Wang <amwang@redhat.com>
There are two places to call vlan_set_encap_proto():
vlan_untag() and __pop_vlan_tci().
vlan_untag() assumes skb->data points after mac addr, otherwise
the following code
vhdr = (struct vlan_hdr *) skb->data;
vlan_tci = ntohs(vhdr->h_vlan_TCI);
__vlan_hwaccel_put_tag(skb, vlan_tci);
skb_pull_rcsum(skb, VLAN_HLEN);
won't be correct. But __pop_vlan_tci() assumes points _before_
mac addr.
In vlan_set_encap_proto(), it looks for some magic L2 value
after mac addr:
rawp = skb->data;
if (*(unsigned short *) rawp == 0xFFFF)
...
Therefore __pop_vlan_tci() is obviously wrong.
A quick fix is avoiding using skb->data in vlan_set_encap_proto(),
use 'vhdr+1' is always correct in both cases.
Cc: David S. Miller <davem@davemloft.net>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/linux/if_vlan.h | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index d06cc5c..218a3b6 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -331,7 +331,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
struct vlan_hdr *vhdr)
{
__be16 proto;
- unsigned char *rawp;
+ unsigned short *rawp;
/*
* Was a VLAN packet, grab the encapsulated protocol, which the layer
@@ -344,8 +344,8 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
return;
}
- rawp = skb->data;
- if (*(unsigned short *) rawp == 0xFFFF)
+ rawp = (unsigned short *)(vhdr + 1);
+ if (*rawp == 0xFFFF)
/*
* This is a magic hack to spot IPX packets. Older Novell
* breaks the protocol design and runs IPX over 802.3 without
--
1.7.7.6
^ permalink raw reply related
* Re: Kernel 3.7.2 strange warning and short system hang
From: Urban Loesch @ 2013-02-22 9:49 UTC (permalink / raw)
To: Eric Dumazet; +Cc: linux-kernel, netdev
In-Reply-To: <1361379176.19353.187.camel@edumazet-glaptop>
Hi,
thanks for your help. I patched my kernel yesterday. Now I have to wait some days.
The error occurs not periodically. If it occurs again I let you now.
many thanks
Urban
On 20.02.2013 17:52, Eric Dumazet wrote:
> On Wed, 2013-02-20 at 17:10 +0100, Urban Loesch wrote:
>> Hi,
>>
>> today I had a strange system hang on one of our new Dell PER620 machines.
>> I'm running a self compiled kernel, version 3.7.2 with linux vserver patch included.
>>
>> uname -a
>> Linux dbhost04 3.7.2-vs2.3.5.5-rol-em64t #4 SMP Sun Feb 3 14:08:37 CET 2013 x86_64 GNU/Linux
>>
>> 15min. systemload between 1-3.
>>
>>
>> Today the system hangs for some seconds and I got the folling errors in syslog multiple times within one second:
>>
>> ...
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196338] WARNING: at net/core/skbuff.c:573 skb_release_head_state+0xed/0x100()
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196338] Hardware name: PowerEdge R620
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196352] Modules linked in: lru_cache netconsole configfs act_police cls_basic cls_flow cls_fw cls_u32
>> sch_tbf sch_prio sch_hfsc sch_htb sch_ingress sch_sfq xt_statistic xt_CT xt_realm xt_LOG xt_c
>> onnlimit iptable_raw xt_comment xt_nat xt_recent ipt_ULOG ipt_REJECT ipt_MASQUERADE ipt_ECN ipt_CLUSTERIP ipt_ah nf_nat_tftp nf_nat_sip nf_nat_pptp
>> nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda nf_conntrack_tftp nf_con
>> ntrack_sane nf_conntrack_sip nf_conntrack_proto_udplite nf_conntrack_proto_sctp nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink
>> nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_irc ts_kmp nf_conntrack_h323 nf_con
>> ntrack_amanda nf_conntrack_ftp xt_TPROXY xt_time nf_tproxy_core xt_TCPMSS xt_tcpmss xt_sctp xt_policy xt_pkttype xt_NFLOG nfnetlink_log xt_physdev
>> xt_owner xt_NFQUEUE xt_multiport xt_mark xt_mac xt_limit xt_length xt_iprange xt_helper xt
>> _hashlimit xt_DSCP xt_dscp xt_dccp xt_connmark xt_CLASSIFY iptable_nat nf_nat_ipv
>> Feb 20 15:58:04 dbhost04 kernel: 4 nf_nat ip6t_REJECT nf_conntrack_ipv4 xt_tcpudp nf_defrag_ipv4 xt_state nf_conntrack_ipv6 nf_defrag_ipv6
>> xt_conntrack nf_conntrack iptable_mangle ip6table_raw ip6table_mangle nfnetlink ip6table_filter ip
>> 6_tables iptable_filter ip_tables x_tables ipmi_devintf ipmi_si ipmi_msghandler coretemp kvm_intel kvm ghash_clmulni_intel aesni_intel xts aes_x86_64
>> lrw gf128mul ablk_helper cryptd iTCO_wdt iTCO_vendor_support dcdbas microcode pcspkr jo
>> ydev lpc_ich shpchp hed evbug hid_generic usbhid hid ahci libahci megaraid_sas tg3 [last unloaded: drbd]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196368] Pid: 10942, comm: mysqld Tainted: G W 3.7.2-vs2.3.5.5-rol-em64t #4
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196368] Call Trace:
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196370] <IRQ> [<ffffffff81053bff>] warn_slowpath_common+0x7f/0xc0
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196371] [<ffffffff81594c52>] ? skb_release_data+0xf2/0x110
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196372] [<ffffffff81053c5a>] warn_slowpath_null+0x1a/0x20
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196373] [<ffffffff81594e9d>] skb_release_head_state+0xed/0x100
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196374] [<ffffffff81594c86>] __kfree_skb+0x16/0xa0
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196375] [<ffffffff8159521c>] consume_skb+0x2c/0x80
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196379] [<ffffffffa000b0af>] tg3_poll_work+0x5ef/0xdb0 [tg3]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196384] [<ffffffffa000b055>] ? tg3_poll_work+0x595/0xdb0 [tg3]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196388] [<ffffffffa00145cf>] tg3_poll+0x7f/0x390 [tg3]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196392] [<ffffffffa000b927>] ? tg3_poll_msix+0xb7/0x140 [tg3]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196394] [<ffffffff815b9622>] netpoll_poll_dev+0x162/0x580
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196395] [<ffffffff815b9bcc>] netpoll_send_skb_on_dev+0x18c/0x3a0
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196398] [<ffffffff815ba0f7>] netpoll_send_udp+0x277/0x290
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196400] [<ffffffffa03ae91f>] write_msg+0xaf/0x100 [netconsole]
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196401] [<ffffffff81054959>] call_console_drivers.constprop.16+0x99/0x100
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196403] [<ffffffff810553b9>] console_unlock+0x3d9/0x420
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196404] [<ffffffff81055ca5>] vprintk_emit+0x255/0x510
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196406] [<ffffffff8169f0b9>] printk+0x61/0x63
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196407] [<ffffffff81031e8e>] therm_throt_process+0x13e/0x180
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196408] [<ffffffff81032066>] intel_thermal_interrupt+0x196/0x1a0
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196410] [<ffffffff810320c1>] smp_thermal_interrupt+0x21/0x40
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196411] [<ffffffff816b1a1a>] thermal_interrupt+0x6a/0x70
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196413] <EOI> [<ffffffff816b0e19>] ? system_call_fastpath+0x16/0x1b
>> Feb 20 15:58:04 dbhost04 kernel: [1463997.196414] ---[ end trace e3ec69533a534ff5 ]---
>> ...
>>
>> After the last message I got this entries in syslog, too:
>> Feb 20 15:58:04 dbhost04 kernel: [1464001.755218] CPU18: Core power limit normal
>> Feb 20 15:58:04 dbhost04 kernel: [1464001.760038] Clocksource tsc unstable (delta = 299966106527 ns)
>> Feb 20 15:58:04 dbhost04 kernel: [1464001.769627] Switching to clocksource hpet
>>
>> I searched the archives for this error, but I can't find any solution.
>> And my second PER620 doesn't show this error until now.
>>
>> Have you any idea what this problem could be?
>>
>> I'm not subscribed to lkml, if you need more information please contact me directly by email.
>>
>> Many thanks for your help.
>> Urban
>
> CC netdev
>
> I guess tg3 needs to call dev_kfree_skb_any()
>
> diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
> index bdb0869..22d9e44 100644
> --- a/drivers/net/ethernet/broadcom/tg3.c
> +++ b/drivers/net/ethernet/broadcom/tg3.c
> @@ -5942,7 +5942,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
> pkts_compl++;
> bytes_compl += skb->len;
>
> - dev_kfree_skb(skb);
> + dev_kfree_skb_any(skb);
>
> if (unlikely(tx_bug)) {
> tg3_tx_recover(tp);
>
>
>
^ permalink raw reply
* Re: [Patch] openvswitch: fix the calculation of checksum for vlan header
From: Cong Wang @ 2013-02-22 9:29 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Jesse Gross
In-Reply-To: <1361510722-27831-1-git-send-email-amwang@redhat.com>
On Fri, 2013-02-22 at 13:25 +0800, Cong Wang wrote:
> @@ -115,7 +115,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla
>
> if (skb->ip_summed == CHECKSUM_COMPLETE)
> skb->csum = csum_add(skb->csum, csum_partial(skb->data
> - + ETH_HLEN, VLAN_HLEN, 0));
> + + (2 * ETH_ALEN), VLAN_HLEN, 0));
>
> }
> __vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
__pop_vlan_tci() has same problem...
I will resend this patch.
^ permalink raw reply
* [PATCH ipsec-next v2] xfrm: allow to avoid copying DSCP during encapsulation
From: Nicolas Dichtel @ 2013-02-22 9:54 UTC (permalink / raw)
To: steffen.klassert, herbert, davem; +Cc: netdev, Nicolas Dichtel
In-Reply-To: <20130222060644.GH17794@secunet.com>
By default, DSCP is copying during encapsulation.
Copying the DSCP in IPsec tunneling may be a bit dangerous because packets with
different DSCP may get reordered relative to each other in the network and then
dropped by the remote IPsec GW if the reordering becomes too big compared to the
replay window.
It is possible to avoid this copy with netfilter rules, but it's very convenient
to be able to configure it for each SA directly.
This patch adds a toogle for this purpose. By default, it's not set to maintain
backward compatibility.
Field flags in struct xfrm_usersa_info is full, hence I add a new attribute.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
v2: rename DONT_ENCAP flag to have a shorter name
ensure to copy extra_flags in xfrm_state_clone() and ipcomp_tunnel_create()
Note that I will be off next week, so I will answer to comments only the week
after.
include/net/xfrm.h | 1 +
include/uapi/linux/xfrm.h | 3 +++
net/ipv4/ipcomp.c | 1 +
net/ipv4/xfrm4_mode_tunnel.c | 8 ++++++--
net/ipv6/xfrm6_mode_tunnel.c | 7 +++++--
net/xfrm/xfrm_state.c | 1 +
net/xfrm/xfrm_user.c | 13 +++++++++++++
7 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 24c8886..ae16531 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -162,6 +162,7 @@ struct xfrm_state {
xfrm_address_t saddr;
int header_len;
int trailer_len;
+ u32 extra_flags;
} props;
struct xfrm_lifetime_cfg lft;
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 28e493b..a8cd6a4 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -297,6 +297,7 @@ enum xfrm_attr_type_t {
XFRMA_MARK, /* struct xfrm_mark */
XFRMA_TFCPAD, /* __u32 */
XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */
+ XFRMA_SA_EXTRA_FLAGS, /* __u32 */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -367,6 +368,8 @@ struct xfrm_usersa_info {
#define XFRM_STATE_ESN 128
};
+#define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
+
struct xfrm_usersa_id {
xfrm_address_t daddr;
__be32 spi;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index f01d1b1..59cb8c7 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -75,6 +75,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.mode = x->props.mode;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
+ t->props.extra_flags = x->props.extra_flags;
memcpy(&t->mark, &x->mark, sizeof(t->mark));
if (xfrm_init_state(t))
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index fe5189e..eb1dd4d 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -103,8 +103,12 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family);
- /* DS disclosed */
- top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
+ /* DS disclosing depends on XFRM_SA_XFLAG_DONT_ENCAP_DSCP */
+ if (x->props.extra_flags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP)
+ top_iph->tos = 0;
+ else
+ top_iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
+ top_iph->tos = INET_ECN_encapsulate(top_iph->tos,
XFRM_MODE_SKB_CB(skb)->tos);
flags = x->props.flags;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 9bf6a74..4770d51 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -49,8 +49,11 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
sizeof(top_iph->flow_lbl));
top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family);
- dsfield = XFRM_MODE_SKB_CB(skb)->tos;
- dsfield = INET_ECN_encapsulate(dsfield, dsfield);
+ if (x->props.extra_flags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP)
+ dsfield = 0;
+ else
+ dsfield = XFRM_MODE_SKB_CB(skb)->tos;
+ dsfield = INET_ECN_encapsulate(dsfield, XFRM_MODE_SKB_CB(skb)->tos);
if (x->props.flags & XFRM_STATE_NOECN)
dsfield &= ~INET_ECN_MASK;
ipv6_change_dsfield(top_iph, 0, dsfield);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ae01bdb..2a34167 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1195,6 +1195,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
goto error;
x->props.flags = orig->props.flags;
+ x->props.extra_flags = orig->props.extra_flags;
x->curlft.add_time = orig->curlft.add_time;
x->km.state = orig->km.state;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fbd9e6c..204cba1 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -515,6 +515,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
copy_from_user_state(x, p);
+ if (attrs[XFRMA_SA_EXTRA_FLAGS])
+ x->props.extra_flags = nla_get_u32(attrs[XFRMA_SA_EXTRA_FLAGS]);
+
if ((err = attach_aead(&x->aead, &x->props.ealgo,
attrs[XFRMA_ALG_AEAD])))
goto error;
@@ -779,6 +782,13 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
copy_to_user_state(x, p);
+ if (x->props.extra_flags) {
+ ret = nla_put_u32(skb, XFRMA_SA_EXTRA_FLAGS,
+ x->props.extra_flags);
+ if (ret)
+ goto out;
+ }
+
if (x->coaddr) {
ret = nla_put(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
if (ret)
@@ -2302,6 +2312,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
[XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) },
[XFRMA_TFCPAD] = { .type = NLA_U32 },
[XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) },
+ [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 },
};
static struct xfrm_link {
@@ -2495,6 +2506,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
x->security->ctx_len);
if (x->coaddr)
l += nla_total_size(sizeof(*x->coaddr));
+ if (x->props.extra_flags)
+ l += nla_total_size(sizeof(x->props.extra_flags));
/* Must count x->lastused as it may become non-zero behind our back. */
l += nla_total_size(sizeof(u64));
--
1.8.0.1
^ permalink raw reply related
* Re: [PATCH net-next 2/3] tipc: byte-based overload control on socket receive queue
From: Jon Maloy @ 2013-02-22 11:18 UTC (permalink / raw)
To: Neil Horman; +Cc: Jon Maloy, Paul Gortmaker, David Miller, netdev, Ying Xue
In-Reply-To: <20130221213528.GA32764@hmsreliant.think-freely.org>
On 02/21/2013 10:35 PM, Neil Horman wrote:
> On Thu, Feb 21, 2013 at 10:05:37PM +0100, Jon Maloy wrote:
>> On 02/21/2013 07:16 PM, Neil Horman wrote:
>>> On Thu, Feb 21, 2013 at 05:54:12PM +0100, Jon Maloy wrote:
>>>> On 02/21/2013 04:07 PM, Neil Horman wrote:
>>>>> On Thu, Feb 21, 2013 at 11:24:19AM +0100, Jon Maloy wrote:
>>>>>> On 02/19/2013 10:44 PM, Neil Horman wrote:
>>>>>>> On Tue, Feb 19, 2013 at 09:16:40PM +0100, Jon Maloy wrote:
>>>>>>>> On 02/19/2013 08:18 PM, Neil Horman wrote:
>>>>>>>>> On Tue, Feb 19, 2013 at 06:54:14PM +0100, Jon Maloy wrote:
>>>>>>>>>> On 02/19/2013 03:26 PM, Neil Horman wrote:
>>>>>>>>>>> On Tue, Feb 19, 2013 at 09:07:54AM +0100, Jon Maloy wrote:
>>>>>>>>>>>> On 02/18/2013 09:47 AM, Neil Horman wrote:
>>>>>>>>>>>>> On Fri, Feb 15, 2013 at 05:57:46PM -0500, Paul Gortmaker wrote:
>>>>>>>>>>>>>> From: Ying Xue <ying.xue@windriver.com>
>>>>>>>> <snip>
>>>> I wouldn't call it a bug, because it doesn't cause deadlock in the current code,
>>>> but it is clearly a design that can be improved.
>>> I don't understand this - Above you said you could demonstrate how my proposal
>>> (which was to drop packets when they surpassed the sk_rcvbuf limit), would cause
>>> deadlock - if that happens, you have a locking bug. If the only reason this
>>> does not happen currently is because you allow for a large overrun of your
>>> set sk_rcvbuf, then ostensibly a lockup can still be triggered if you have a
>>> misbehaving sender that is willing to send frames past its congestion window.
>>> So I think the root question here is: Does the code currently deadlock if you
>>> drop frames in the receive path?
>> No. We can drop as as many as we want, the retransmission protocol will
>> take hand of that, and that part is pretty robust by now.
>> But it *would* deadlock if we tried to read fields in the sock structure, with
>> the necessary grabbing of locks that involves, from within the scope of
>> tipc_recv_msg, which is at a completely different level in the stack.
>>
>> Since we don't do that in the current code, there is no deadlock problem.
>>
> Theres tons of protocols that read socket structures that low in the receive
> path, in fact (with the exception of TIPC) they all do, specifically for the
> purpose of being able to check, among other things, the socket buffer recieve
> limit. See sctp_rcv, tcp_v4_rcv, tcp_v6_rcv, _udp4_lib_rcv, etc for examples.
All those examples are trivial in this respect, because they either have
no retransmission layer at all, or the retransmission is bound to the socket
name space itself. If you first have to lookup the socket even to perform the
most basic protocol check it goes without saying that you can first take a
quick look into sk_rcvbuf before going on. Besides, it doesn't cost any
performance with this approach.
There are, or have been, other protocols, TIPC, LINX, HDLC, LAPB, MTP2 etc.
where reliability is ensured at a logical data link layer (L2.5), and where
this kind of early endpoint access is less obvious, but not impossible.
TIPC is the only one of these present in the Linux kernel and sporting
a socket API, though; that's why we are having this discussion.
> Looking at tipc_recv_msg, it looks to me like you need to grab the
> tipc_port_lock for a short critical section to get the tipc_port struct, from
> which (as we previously discussed, you can get the socket). Presuming you've
> done appropriate reference counting on your socket, thats it. One lock, that
> you take and release in several other places in the same call path.
Ok. Currently it looks like this:
Outgoing data path:
------------------
grab socket lock
grab net lock
grab node_lock
<send packet(s)>
release node lock
release net lock
release socket lock
Incoming data path:
-------------------
grab net lock (read mode)
<do some packet sanity check>
grab node lock
<perform link level protocol check>
release node lock'
release net lock
grab port lock
grab socket lock
<check sk_rcvbuf>
<deliver or reject>
release socket lock
release port lock
As I interpreted your suggestion, incoming data path
would become as follows:
-----------------------
grab net lock (read mode)
<do some packet sanity check>
grab node lock
--> grab port lock
grab socket lock
<check sk_rcvbuf>
release socket lock
--> release port lock
<perform link level protocol check>
release node lock
release net lock
grab port lock
grab socket lock
<check sk_rcvbuf>
<deliver or reject>
release socket lock
release port lock
I.e., deadlock would occur almost immediately.
Now, having slept on it, I see we could also do:
-----------------------------------------------
grab port lock
grab socket lock
check sk_rcvbuf>
release socket lock
release port lock
grab net lock (read mode)
<do some packet sanity check>
grab node lock
<perform link level protocol check>
release node lock'
release net lock'
grab port lock
grab socket lock
<check sk_rcvbuf>
<deliver or reject>
release socket lock
release port lock
If this is what you meant, then you are right.
It would work, although it would severely impact performance.
But the fact that it works technically doesn't mean it is the
right thing to do, because of the way it would mess up the
overall packet flow.
This is not a good solution!
And I think there are better ways...
If we really want to improve the solution we agreed on
yesterday we should rather go for a scheme adding back-pressure
to the sender socket, even for connectionless datagram messages,
not only connections as we do now. We have some ideas there, and
you are welcome to participate in the discussions.
Maybe another thread at tipc-discussion?
Regards
///jon
>
> Neil
>
>> ///jon
>>
>> [...]
>>>
>>>>>>
>>>>
>>
>>
^ permalink raw reply
* [Patch] openvswitch: remove some useless comments
From: Cong Wang @ 2013-02-22 11:41 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Jesse Gross, Cong Wang
From: Cong Wang <amwang@redhat.com>
These comments are useless in upstream kernel.
Cc: David S. Miller <davem@davemloft.net>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 670cbc3..2130d61 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -43,8 +43,7 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
/* Make our own copy of the packet. Otherwise we will mangle the
* packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
- * (No one comes after us, since we tell handle_bridge() that we took
- * the packet.) */
+ */
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
return;
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 70af0be..6255e48 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -326,8 +326,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
* @skb: skb that was received
*
* Must be called with rcu_read_lock. The packet cannot be shared and
- * skb->data should point to the Ethernet header. The caller must have already
- * called compute_ip_summed() to initialize the checksumming fields.
+ * skb->data should point to the Ethernet header.
*/
void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)
{
^ permalink raw reply related
* RE: [PATCH net-next 2/3] tipc: byte-based overload control on socket receive queue
From: David Laight @ 2013-02-22 11:54 UTC (permalink / raw)
To: Jon Maloy, Neil Horman
Cc: Jon Maloy, Paul Gortmaker, David Miller, netdev, Ying Xue
In-Reply-To: <5127541C.9070306@ericsson.com>
> grab net lock (read mode)
> <do some packet sanity check>
> grab node lock
> --> grab port lock
> grab socket lock
> <check sk_rcvbuf>
> release socket lock
> --> release port lock
> <perform link level protocol check>
> release node lock
> release net lock
> grab port lock
> grab socket lock
> <check sk_rcvbuf>
> <deliver or reject>
> release socket lock
> release port lock
You probably don't need to grab the socket lock itself, you
only need to be able to read a 'receive buffer full' marker.
That could (probably) be done with some careful coding in the
socket create/delete paths.
Another option is to remember that the socket became full
the previous time, and only do the early check of the
receive buffer state when it had previously been full.
David
^ permalink raw reply
* Re: [PATCH net-next 2/3] tipc: byte-based overload control on socket receive queue
From: Neil Horman @ 2013-02-22 12:08 UTC (permalink / raw)
To: Jon Maloy; +Cc: Jon Maloy, Paul Gortmaker, David Miller, netdev, Ying Xue
In-Reply-To: <5127541C.9070306@ericsson.com>
On Fri, Feb 22, 2013 at 12:18:52PM +0100, Jon Maloy wrote:
> On 02/21/2013 10:35 PM, Neil Horman wrote:
> > On Thu, Feb 21, 2013 at 10:05:37PM +0100, Jon Maloy wrote:
> >> On 02/21/2013 07:16 PM, Neil Horman wrote:
> >>> On Thu, Feb 21, 2013 at 05:54:12PM +0100, Jon Maloy wrote:
> >>>> On 02/21/2013 04:07 PM, Neil Horman wrote:
> >>>>> On Thu, Feb 21, 2013 at 11:24:19AM +0100, Jon Maloy wrote:
> >>>>>> On 02/19/2013 10:44 PM, Neil Horman wrote:
> >>>>>>> On Tue, Feb 19, 2013 at 09:16:40PM +0100, Jon Maloy wrote:
> >>>>>>>> On 02/19/2013 08:18 PM, Neil Horman wrote:
> >>>>>>>>> On Tue, Feb 19, 2013 at 06:54:14PM +0100, Jon Maloy wrote:
> >>>>>>>>>> On 02/19/2013 03:26 PM, Neil Horman wrote:
> >>>>>>>>>>> On Tue, Feb 19, 2013 at 09:07:54AM +0100, Jon Maloy wrote:
> >>>>>>>>>>>> On 02/18/2013 09:47 AM, Neil Horman wrote:
> >>>>>>>>>>>>> On Fri, Feb 15, 2013 at 05:57:46PM -0500, Paul Gortmaker wrote:
> >>>>>>>>>>>>>> From: Ying Xue <ying.xue@windriver.com>
> >>>>>>>> <snip>
><snip>
>
> grab net lock (read mode)
> <do some packet sanity check>
> grab node lock
> --> grab port lock
> grab socket lock
> <check sk_rcvbuf>
> release socket lock
> --> release port lock
> <perform link level protocol check>
> release node lock
> release net lock
> grab port lock
> grab socket lock
> <check sk_rcvbuf>
> <deliver or reject>
> release socket lock
> release port lock
>
> I.e., deadlock would occur almost immediately.
>
>
> Now, having slept on it, I see we could also do:
> -----------------------------------------------
>
> grab port lock
> grab socket lock
> check sk_rcvbuf>
> release socket lock
> release port lock
> grab net lock (read mode)
> <do some packet sanity check>
> grab node lock
> <perform link level protocol check>
> release node lock'
> release net lock'
> grab port lock
> grab socket lock
> <check sk_rcvbuf>
> <deliver or reject>
> release socket lock
> release port lock
>
> If this is what you meant, then you are right.
Yes, this is one of the options I had meant. Another one would be to pass a
reference of b_ptr up to the dispatch function (as everthing else is discernable
from the message buffer), and send the ack from there.
> It would work, although it would severely impact performance.
>
> But the fact that it works technically doesn't mean it is the
> right thing to do, because of the way it would mess up the
> overall packet flow.
> This is not a good solution!
>
How many times have we gone over this?
A) Impacting performance isn't an excuse for being able to overwhelm a system by
flooding it with traffic
B) I'm not advocating that you lower you receive buffer limit by default, only
that if someone chooses to, they be able to do so (and accept the performance
consequences thereof).
> And I think there are better ways...
> If we really want to improve the solution we agreed on
> yesterday we should rather go for a scheme adding back-pressure
> to the sender socket, even for connectionless datagram messages,
As long as you drop frames when you supercede the limits set by the user on your
socket buffer, sure.
> not only connections as we do now. We have some ideas there, and
> you are welcome to participate in the discussions.
> Maybe another thread at tipc-discussion?
>
Sure
> Regards
> ///jon
>
>
>
>
> >
> > Neil
> >
> >> ///jon
> >>
> >> [...]
> >>>
> >>>>>>
> >>>>
> >>
> >>
>
>
^ permalink raw reply
* Re: [PATCH 1/1] net: fec: fix miss init spinlock
From: Jim Baxter @ 2013-02-22 12:25 UTC (permalink / raw)
To: netdev
In-Reply-To: <CAHrpEqR9u5t8fZOYRq4k_vTsEORVsNwa2C_rLaxesmusY5e9-Q@mail.gmail.com>
> > On 2/6/2013 1:50 AM, Frank Li wrote:
> >>
> >>
> >> It is not easy to fix. Need put tx to NAPI poll function.
> >> I will work on that after China New year holiday
Hi Frank,
Have you had time to have a look at this issues again?
Jim
^ permalink raw reply
* [PATCH 0/3] usbnet: smsc95xx: fix smsc95xx_suspend
From: Ming Lei @ 2013-02-22 13:05 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
Hi,
The 1st two patches fix smsc95xx_suspend, and the 1st one should
be backported to 3.8.
The last one is to rename the misleading FEATURE_AUTOSUSPEND.
Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/3] usbnet: smsc95xx: fix suspend failure
From: Ming Lei @ 2013-02-22 13:05 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, netdev, linux-usb, Ming Lei, Steve Glendinning
In-Reply-To: <1361538305-28418-1-git-send-email-ming.lei@canonical.com>
The three below functions:
smsc95xx_enter_suspend0()
smsc95xx_enter_suspend1()
smsc95xx_enter_suspend2()
return > 0 in case of success, so they will cause smsc95xx_suspend()
to return > 0 and cause suspend failure.
The bug is introduced in commit 3b9f7d(smsc95xx: fix error handling
in suspend failure case).
Cc: <stable@vger.kernel.org> [3.8]
Cc: Steve Glendinning <steve.glendinning@shawell.net>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
drivers/net/usb/smsc95xx.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index ff4fa37..b2721bc 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1247,10 +1247,12 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev)
/* read back PM_CTRL */
ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
+ if (ret < 0)
+ return ret;
pdata->suspend_flags |= SUSPEND_SUSPEND0;
- return ret;
+ return 0;
}
static int smsc95xx_enter_suspend1(struct usbnet *dev)
@@ -1293,10 +1295,12 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev)
val |= (PM_CTL_WUPS_ED_ | PM_CTL_ED_EN_);
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
+ if (ret < 0)
+ return ret;
pdata->suspend_flags |= SUSPEND_SUSPEND1;
- return ret;
+ return 0;
}
static int smsc95xx_enter_suspend2(struct usbnet *dev)
@@ -1313,10 +1317,12 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev)
val |= PM_CTL_SUS_MODE_2;
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
+ if (ret < 0)
+ return ret;
pdata->suspend_flags |= SUSPEND_SUSPEND2;
- return ret;
+ return 0;
}
static int smsc95xx_enter_suspend3(struct usbnet *dev)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/3] usbnet: smsc95xx: fix broken runtime suspend
From: Ming Lei @ 2013-02-22 13:05 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, netdev, linux-usb, Ming Lei, Steve Glendinning
In-Reply-To: <1361538305-28418-1-git-send-email-ming.lei@canonical.com>
Commit b2d4b150(smsc95xx: enable dynamic autosuspend) implements
autosuspend, but breaks current runtime suspend, such as:
when the interface becomes down, the usb device can't be put into
runtime suspend any more.
This patch fixes the broken runtime suspend.
Cc: Steve Glendinning <steve.glendinning@shawell.net>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
drivers/net/usb/smsc95xx.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index b2721bc..7fa9622 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1418,15 +1418,6 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
u32 val, link_up;
int ret;
- /* TODO: don't indicate this feature to usb framework if
- * our current hardware doesn't have the capability
- */
- if ((message.event == PM_EVENT_AUTO_SUSPEND) &&
- (!(pdata->features & FEATURE_AUTOSUSPEND))) {
- netdev_warn(dev->net, "autosuspend not supported\n");
- return -EBUSY;
- }
-
ret = usbnet_suspend(intf, message);
if (ret < 0) {
netdev_warn(dev->net, "usbnet_suspend error\n");
@@ -1441,7 +1432,8 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
/* determine if link is up using only _nopm functions */
link_up = smsc95xx_link_ok_nopm(dev);
- if (message.event == PM_EVENT_AUTO_SUSPEND) {
+ if (message.event == PM_EVENT_AUTO_SUSPEND &&
+ (pdata->features & FEATURE_AUTOSUSPEND)) {
ret = smsc95xx_autosuspend(dev, link_up);
goto done;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/3] usbnet: smsc95xx: rename FEATURE_AUTOSUSPEND
From: Ming Lei @ 2013-02-22 13:05 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: Oliver Neukum, netdev, linux-usb, Ming Lei, Steve Glendinning
In-Reply-To: <1361538305-28418-1-git-send-email-ming.lei@canonical.com>
The name of FEATURE_AUTOSUSPEND is very misleading and the actual
meaning is remote wakeup, but a device incapable of remote wakeup
still can support USB autosuspend under some situations, so rename
it to avoid misunderstanding.
Cc: Steve Glendinning <steve.glendinning@shawell.net>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
drivers/net/usb/smsc95xx.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 7fa9622..e6d2dea 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -53,7 +53,7 @@
#define FEATURE_8_WAKEUP_FILTERS (0x01)
#define FEATURE_PHY_NLP_CROSSOVER (0x02)
-#define FEATURE_AUTOSUSPEND (0x04)
+#define FEATURE_REMOTE_WAKEUP (0x04)
#define SUSPEND_SUSPEND0 (0x01)
#define SUSPEND_SUSPEND1 (0x02)
@@ -1146,7 +1146,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
(val == ID_REV_CHIP_ID_89530_) || (val == ID_REV_CHIP_ID_9730_))
pdata->features = (FEATURE_8_WAKEUP_FILTERS |
FEATURE_PHY_NLP_CROSSOVER |
- FEATURE_AUTOSUSPEND);
+ FEATURE_REMOTE_WAKEUP);
else if (val == ID_REV_CHIP_ID_9512_)
pdata->features = FEATURE_8_WAKEUP_FILTERS;
@@ -1378,7 +1378,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
if (!link_up) {
/* link is down so enter EDPD mode, but only if device can
* reliably resume from it. This check should be redundant
- * as current FEATURE_AUTOSUSPEND parts also support
+ * as current FEATURE_REMOTE_WAKEUP parts also support
* FEATURE_PHY_NLP_CROSSOVER but it's included for clarity */
if (!(pdata->features & FEATURE_PHY_NLP_CROSSOVER)) {
netdev_warn(dev->net, "EDPD not supported\n");
@@ -1433,7 +1433,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
link_up = smsc95xx_link_ok_nopm(dev);
if (message.event == PM_EVENT_AUTO_SUSPEND &&
- (pdata->features & FEATURE_AUTOSUSPEND)) {
+ (pdata->features & FEATURE_REMOTE_WAKEUP)) {
ret = smsc95xx_autosuspend(dev, link_up);
goto done;
}
@@ -1870,11 +1870,11 @@ static int smsc95xx_manage_power(struct usbnet *dev, int on)
dev->intf->needs_remote_wakeup = on;
- if (pdata->features & FEATURE_AUTOSUSPEND)
+ if (pdata->features & FEATURE_REMOTE_WAKEUP)
return 0;
- /* this chip revision doesn't support autosuspend */
- netdev_info(dev->net, "hardware doesn't support USB autosuspend\n");
+ /* this chip revision isn't capable of remote wakeup */
+ netdev_info(dev->net, "hardware isn't capable of remote wakeup\n");
if (on)
usb_autopm_get_interface_no_resume(dev->intf);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH net-next 1/3] net: stmmac: add gmac autoneg set for SGMII, TBI, and RTBI
From: Giuseppe CAVALLARO @ 2013-02-22 13:17 UTC (permalink / raw)
To: Byungho An
Cc: netdev, linux-kernel, davem, jeffrey.t.kirsher, kgene.kim, cpgs
In-Reply-To: <013e01cdfb47$8f5d2b30$ae178190$@samsung.com>
[-- Attachment #1: Type: text/plain, Size: 6873 bytes --]
Hello Byungho
sorry for my late reply. I'm attaching two patches built for net-next
as we had clarified. I had written the first patch long time ago
and on top of it I have added some part of your code below with some
fixes (see also the comments inline below).
This work is not yet completed but I do hope these two patches will
help you to complete all. Unfortunately, I cannot do any tests
because I have no HW that supports PCS. :-(
In the second patch, take a look at the comment that reports
the missing parts. For example, ethtool, SGMII etc.
I wonder if you could review/test the two patches on your side.
Also I hope you can improve all adding the missing features (that is
what you were already doing).
If you agree, you could also re-send *all* to the mailing list to
be finally reviewed.
On 1/25/2013 11:01 PM, Byungho An wrote:
>
> On 1/23/2013 1:43 PM, Giuseppe CAVALLARO write:
[snip]
>>
> I modified this part like below
>
> @@ -1044,12 +1046,8 @@ static int stmmac_open(struct net_device *dev)
> priv->hw->mac->core_init(priv->ioaddr);
>
> /* Enable auto-negotiation for SGMII, TBI or RTBI */
> - if (interface == PHY_INTERFACE_MODE_SGMII ||
> - interface == PHY_INTERFACE_MODE_TBI ||
> - interface == PHY_INTERFACE_MODE_RTBI) {
> - if (priv->phydev->autoneg)
> - priv->hw->mac->set_autoneg(priv->ioaddr);
> - }
> + if (priv->dma_cap.pcs)
> + priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
>
> /* Request the IRQ lines */
> ret = request_irq(dev->irq, stmmac_interrupt,
>
> As you may know, auto-negotiation is essential for SGMII, TBI, or RTBI
> interface.
>
good, add it on top of the second patch.
> And ctrl_ane funciont is like that
>
> @@ -311,6 +317,18 @@ static void dwmac1000_set_autoneg(void __iomem *ioaddr)
> writel(value, ioaddr + GMAC_AN_CTRL);
> }
>
> +static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart)
> +{
> + u32 value;
> +
> + value = readl(ioaddr + GMAC_AN_CTRL);
> + /* auto negotiation enable and External Loopback enable */
> + value = GMAC_AN_CTRL__ANE | GMAC_AN_CTRL__ELE;
> +
> + if (restart)
> + value |= GMAC_AN_CTRL_RAN;
> +
> + writel(value, ioaddr + GMAC_AN_CTRL);
> +}
>
> static const struct stmmac_ops dwmac1000_ops = {
> .core_init = dwmac1000_core_init,
well done and added in the second patch.
[snip]
> I've changed restart AN like below.
>
> @@ -610,6 +607,27 @@ static int stmmac_set_coalesce(struct net_device *dev,
> return 0;
> }
>
> +static int
> +stmmac_nway_reset(struct net_device *netdev)
> +{
> + struct stmmac_priv *priv = netdev_priv(netdev);
> + struct phy_device *phy = priv->phydev;
> + int ret = 0;
> +
> + spin_lock(&priv->lock);
> +
> + if (netif_running(netdev)) {
> + phy_stop(phy);
> + phy_start(phy);
> + ret = phy_start_aneg(phy);
> + if (priv->dma_cap.pcs)
> + priv->hw->mac->ctrl_ane(priv->ioaddr, true);
> + }
> +
> + spin_unlock(&priv->lock);
> + return ret;
> +}
> +
> static const struct ethtool_ops stmmac_ethtool_ops = {
> .begin = stmmac_check_if_running,
> .get_drvinfo = stmmac_ethtool_getdrvinfo,
>
>
we have to review this. I expect to have a new patch that includes the
ethtool support but, at first glance, the stmmac_nway_reset should only
call the ctrl_ane.
pay attention that also some other ethtool functions have to be fixed
for this support.
[snip]
> I think whenever link is changed, phy->state is changed and call
> stmmac_adjust_link. It would update gmac's link.
> I can get autonegotiation complete and link change irqs if we need something
> we can add code in the handler but I'm not sure which one is need yet.
> As of now I just added phy_state = PHY_CHANGELINK as a test code in the link
> change irq handler.
>
> @@ -1624,8 +1629,43 @@ static irqreturn_t stmmac_interrupt(int irq, void
> *dev_id)
> priv->xstats.mmc_rx_csum_offload_irq_n++;
> if (status & core_irq_receive_pmt_irq)
> priv->xstats.irq_receive_pmt_irq_n++;
> + if (status & core_irq_pcs_autoneg_complete)
> + priv->core_pcs_an = true;
> + if (status & core_irq_pcs_link_status_change) {
> + priv->core_pcs_link_change = true;
> + status = readl(priv->ioaddr +
> GMAC_AN_STATUS);
> + if (status & GMAC_AN_STATUS_LS)
> + if ((priv->speed != phy->speed) ||
> (priv->oldduplex != phy->duplex))
> + phy->state = PHY_CHANGELINK; /* for
> test */
> + }
>
> /* For LPI we need to save the tx status */
> if (status & core_irq_tx_path_in_lpi_mode) {
>
> I have a question, how to hand over phy's irq number, as I analyzed
> phydev->irq is irqlist and irqlist is like below but I can not find a way to
> set phy's irq number.
> How to register or set priv->mii_irq or mdio_bus_data->irqs.
>
> if (mdio_bus_data->irqs)
> irqlist = mdio_bus_data->irqs;
> else
> irqlist = priv->mii_irq;
I had added something in my first patch that should be ok.
> I added some defines for AN like below
> @@ -97,6 +97,20 @@ enum power_event {
> #define GMAC_TBI 0x000000d4 /* TBI extend status */
> #define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
>
> +/* AN Configuration defines */
> +#define GMAC_AN_CTRL_RAN 0x00000200 /* Restart Auto-Negotiation
> */
> +#define GMAC_AN_CTRL_ANE 0x00001000 /* Auto-Negotiation Enable
> */
> +#define GMAC_AN_CTRL_ELE 0x00004000 /* External Loopback Enable
> */
> +#define GMAC_AN_CTRL_ECD 0x00010000 /* Enable Comma Detect */
> +#define GMAC_AN_CTRL_LR 0x00020000 /* Lock to Reference */
> +#define GMAC_AN_CTRL_SGMRAL 0x00040000 /* SGMII RAL Control */
> +
> +/* AN Status defines */
> +#define GMAC_AN_STATUS_LS 0x00000004 /* Link Status 0:down 1:up
> */
> +#define GMAC_AN_STATUS_ANA 0x00000008 /* Auto-Negotiation Ability
> */
> +#define GMAC_AN_STATUS_ANC 0x00000020 /* Auto-Negotiation Complete
> */
> +#define GMAC_AN_STATUS_ES 0x00000100 /* Extended Status */
> +
> /* GMAC Configuration defines */
> #define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in
> RGMII/SGMII */
> #define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on
> receive */
ok, these are in the second patch
[-- Attachment #2: 0001-stmmac-start-adding-pcs-and-rgmii-core-irq.patch --]
[-- Type: text/x-patch, Size: 9625 bytes --]
>From 13a4be74f7a4a7d180cae25f4528dc0a78bf5d7c Mon Sep 17 00:00:00 2001
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Mon, 17 Dec 2012 07:22:18 +0100
Subject: [net-next.git 1/2] stmmac: start adding pcs and rgmii core irq
This patch starts adding in the main ISR the management of the PCS and
RGMII/SGMII core interrupts. This is to help further development
on this area. Currently the core irq handler only clears the
PCS and S-R_MII interrupts and reports the event in the ethtool stats.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Udit Kumar <udit-dlh.kumar@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 25 ++++++-----
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 5 +-
.../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 44 ++++++++++++-------
.../net/ethernet/stmicro/stmmac/dwmac100_core.c | 3 +-
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 3 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 24 ++---------
6 files changed, 54 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 186d148..1db761c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -117,6 +117,10 @@ struct stmmac_extra_stats {
unsigned long irq_rx_path_in_lpi_mode_n;
unsigned long irq_rx_path_exit_lpi_mode_n;
unsigned long phy_eee_wakeup_error_n;
+ /* PCS */
+ unsigned long irq_pcs_ane_n;
+ unsigned long irq_pcs_link_n;
+ unsigned long irq_rgmii_n;
};
/* CSR Frequency Access Defines*/
@@ -194,16 +198,14 @@ enum dma_irq_status {
handle_tx = 0x8,
};
-enum core_specific_irq_mask {
- core_mmc_tx_irq = 1,
- core_mmc_rx_irq = 2,
- core_mmc_rx_csum_offload_irq = 4,
- core_irq_receive_pmt_irq = 8,
- core_irq_tx_path_in_lpi_mode = 16,
- core_irq_tx_path_exit_lpi_mode = 32,
- core_irq_rx_path_in_lpi_mode = 64,
- core_irq_rx_path_exit_lpi_mode = 128,
-};
+#define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 1)
+#define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 2)
+#define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 3)
+#define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 4)
+
+#define CORE_PCS_ANE_COMPLETE (1 << 5)
+#define CORE_PCS_LINK_STATUS (1 << 6)
+#define CORE_RGMII_IRQ (1 << 7)
/* DMA HW capabilities */
struct dma_features {
@@ -327,7 +329,8 @@ struct stmmac_ops {
/* Dump MAC registers */
void (*dump_regs) (void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
- int (*host_irq_status) (void __iomem *ioaddr);
+ int (*host_irq_status) (void __iomem *ioaddr,
+ struct stmmac_extra_stats *x);
/* Multicast filter setting */
void (*set_filter) (struct net_device *dev, int id);
/* Flow control setting */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 7ad56af..8a8c39f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -89,13 +89,14 @@ enum power_event {
(reg * 8))
#define GMAC_MAX_PERFECT_ADDRESSES 32
+/* PCS registers (AN/TBI/SGMII/RGMII) offset */
#define GMAC_AN_CTRL 0x000000c0 /* AN control */
#define GMAC_AN_STATUS 0x000000c4 /* AN status */
#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
-#define GMAC_ANE_LINK 0x000000cc /* Auto-Neg. link partener ability */
+#define GMAC_ANE_LPA 0x000000cc /* Auto-Neg. link partener ability */
#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
#define GMAC_TBI 0x000000d4 /* TBI extend status */
-#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
+#define GMAC_S_R_GMII 0x000000d8 /* SGMII RGMII status */
/* GMAC Configuration defines */
#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index bfe0226..ff4c79e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -194,58 +194,70 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
}
-static int dwmac1000_irq_status(void __iomem *ioaddr)
+static int dwmac1000_irq_status(void __iomem *ioaddr,
+ struct stmmac_extra_stats *x)
{
u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
- int status = 0;
+ int ret = 0;
/* Not used events (e.g. MMC interrupts) are not handled. */
if ((intr_status & mmc_tx_irq)) {
CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n",
readl(ioaddr + GMAC_MMC_TX_INTR));
- status |= core_mmc_tx_irq;
+ x->mmc_tx_irq_n++;
}
if (unlikely(intr_status & mmc_rx_irq)) {
CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n",
readl(ioaddr + GMAC_MMC_RX_INTR));
- status |= core_mmc_rx_irq;
+ x->mmc_rx_irq_n++;
}
if (unlikely(intr_status & mmc_rx_csum_offload_irq)) {
CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n",
readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
- status |= core_mmc_rx_csum_offload_irq;
+ x->mmc_rx_csum_offload_irq_n++;
}
if (unlikely(intr_status & pmt_irq)) {
CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n");
/* clear the PMT bits 5 and 6 by reading the PMT
* status register. */
readl(ioaddr + GMAC_PMT);
- status |= core_irq_receive_pmt_irq;
+ x->irq_receive_pmt_irq_n++;
}
/* MAC trx/rx EEE LPI entry/exit interrupts */
if (intr_status & lpiis_irq) {
/* Clean LPI interrupt by reading the Reg 12 */
- u32 lpi_status = readl(ioaddr + LPI_CTRL_STATUS);
+ ret = readl(ioaddr + LPI_CTRL_STATUS);
- if (lpi_status & LPI_CTRL_STATUS_TLPIEN) {
+ if (ret & LPI_CTRL_STATUS_TLPIEN) {
CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n");
- status |= core_irq_tx_path_in_lpi_mode;
+ x->irq_tx_path_in_lpi_mode_n++;
}
- if (lpi_status & LPI_CTRL_STATUS_TLPIEX) {
+ if (ret & LPI_CTRL_STATUS_TLPIEX) {
CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n");
- status |= core_irq_tx_path_exit_lpi_mode;
+ x->irq_tx_path_exit_lpi_mode_n++;
}
- if (lpi_status & LPI_CTRL_STATUS_RLPIEN) {
+ if (ret & LPI_CTRL_STATUS_RLPIEN) {
CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n");
- status |= core_irq_rx_path_in_lpi_mode;
+ x->irq_rx_path_in_lpi_mode_n++;
}
- if (lpi_status & LPI_CTRL_STATUS_RLPIEX) {
+ if (ret & LPI_CTRL_STATUS_RLPIEX) {
CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n");
- status |= core_irq_rx_path_exit_lpi_mode;
+ x->irq_rx_path_exit_lpi_mode_n++;
}
}
- return status;
+ if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
+ CHIP_DBG(KERN_INFO "GMAC PCS ANE IRQ\n");
+ readl(ioaddr + GMAC_AN_STATUS);
+ x->irq_pcs_ane_n++;
+ }
+ if (intr_status & rgmii_irq) {
+ CHIP_DBG(KERN_INFO "GMAC RGMII IRQ status\n");
+ readl(ioaddr + GMAC_S_R_GMII);
+ x->irq_rgmii_n++;
+ }
+
+ return ret;
}
static void dwmac1000_set_eee_mode(void __iomem *ioaddr)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index f83210e..cb86a58 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -72,7 +72,8 @@ static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
return 0;
}
-static int dwmac100_irq_status(void __iomem *ioaddr)
+static int dwmac100_irq_status(void __iomem *ioaddr,
+ struct stmmac_extra_stats *x)
{
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d1ac39c..e15004f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -108,6 +108,9 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
STMMAC_STAT(irq_rx_path_in_lpi_mode_n),
STMMAC_STAT(irq_rx_path_exit_lpi_mode_n),
STMMAC_STAT(phy_eee_wakeup_error_n),
+ /* PCS */
+ STMMAC_STAT(irq_pcs_ane_n),
+ STMMAC_STAT(irq_rgmii_n),
};
#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 39c6c55..1f2f349 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1604,30 +1604,14 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
/* To handle GMAC own interrupts */
if (priv->plat->has_gmac) {
int status = priv->hw->mac->host_irq_status((void __iomem *)
- dev->base_addr);
+ dev->base_addr,
+ &priv->xstats);
if (unlikely(status)) {
- if (status & core_mmc_tx_irq)
- priv->xstats.mmc_tx_irq_n++;
- if (status & core_mmc_rx_irq)
- priv->xstats.mmc_rx_irq_n++;
- if (status & core_mmc_rx_csum_offload_irq)
- priv->xstats.mmc_rx_csum_offload_irq_n++;
- if (status & core_irq_receive_pmt_irq)
- priv->xstats.irq_receive_pmt_irq_n++;
-
/* For LPI we need to save the tx status */
- if (status & core_irq_tx_path_in_lpi_mode) {
- priv->xstats.irq_tx_path_in_lpi_mode_n++;
+ if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)
priv->tx_path_in_lpi_mode = true;
- }
- if (status & core_irq_tx_path_exit_lpi_mode) {
- priv->xstats.irq_tx_path_exit_lpi_mode_n++;
+ if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE)
priv->tx_path_in_lpi_mode = false;
- }
- if (status & core_irq_rx_path_in_lpi_mode)
- priv->xstats.irq_rx_path_in_lpi_mode_n++;
- if (status & core_irq_rx_path_exit_lpi_mode)
- priv->xstats.irq_rx_path_exit_lpi_mode_n++;
}
}
--
1.7.4.4
[-- Attachment #3: 0002-stmmac-start-managing-pcs-RGMII-modes-and-restart-AN.patch --]
[-- Type: text/x-patch, Size: 9695 bytes --]
>From 952f89212446f3f346d2ade62aada1d7c06842b0 Mon Sep 17 00:00:00 2001
From: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Date: Fri, 22 Feb 2013 12:24:00 +0100
Subject: [net-next.git 2/2] stmmac: start managing pcs RGMII modes and
restart ANE
This patch adds the minimal support to manage the PCS
modes (RGMII) and restart the ANE when the interface is
opened.
Currently the following main things are missing:
o SGMII/TBI support
o manage the advertisement register (e.g. reg 50)
o manage pause via ADV.
o manage the Auto-Nogotiation Ability Register (51)
o improve the ethtool.
Thanks to Byungho that wrote some part of this code.
Signed-off-by: Byungho An <bh74.an@samsung.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 7 +++
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 20 +++++++
.../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 15 +++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 13 +++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 55 +++++++++++++++----
6 files changed, 99 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1db761c..04134ad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -142,6 +142,12 @@ struct stmmac_extra_stats {
#define FLOW_TX 2
#define FLOW_AUTO (FLOW_TX | FLOW_RX)
+/* PCS defines */
+#define STMMAC_PCS_RGMII (1<<0)
+#define STMMAC_PCS_SGMII (1<<1)
+#define STMMAC_PCS_TBI (1<<2)
+#define STMMAC_PCS_RTBI (1<<1)
+
#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
/* DAM HW feature register fields */
@@ -347,6 +353,7 @@ struct stmmac_ops {
void (*reset_eee_mode) (void __iomem *ioaddr);
void (*set_eee_timer) (void __iomem *ioaddr, int ls, int tw);
void (*set_eee_pls) (void __iomem *ioaddr, int link);
+ void (*ctrl_ane) (void __iomem *ioaddr, bool restart);
};
struct mac_link {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 8a8c39f..5cfd4d2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -98,6 +98,24 @@ enum power_event {
#define GMAC_TBI 0x000000d4 /* TBI extend status */
#define GMAC_S_R_GMII 0x000000d8 /* SGMII RGMII status */
+/* AN Configuration defines */
+#define GMAC_AN_CTRL_RAN 0x00000200 /* Restart Auto-Negotiation */
+#define GMAC_AN_CTRL_ANE 0x00001000 /* Auto-Negotiation Enable */
+#define GMAC_AN_CTRL_ELE 0x00004000 /* External Loopback Enable */
+#define GMAC_AN_CTRL_ECD 0x00010000 /* Enable Comma Detect */
+#define GMAC_AN_CTRL_LR 0x00020000 /* Lock to Reference */
+#define GMAC_AN_CTRL_SGMRAL 0x00040000 /* SGMII RAL Control */
+
+/* AN Status defines */
+#define GMAC_AN_STATUS_LS 0x00000004 /* Link Status 0:down 1:up */
+#define GMAC_AN_STATUS_ANA 0x00000008 /* Auto-Negotiation Ability */
+#define GMAC_AN_STATUS_ANC 0x00000020 /* Auto-Negotiation Complete */
+#define GMAC_AN_STATUS_ES 0x00000100 /* Extended Status */
+
+ /* GMAC Configuration defines */
+#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
+#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
+
/* GMAC Configuration defines */
#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
@@ -231,5 +249,7 @@ enum rtc_control {
#define GMAC_MMC_TX_INTR 0x108
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
+
+
extern const struct stmmac_dma_ops dwmac1000_dma_ops;
#endif /* __DWMAC1000_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index ff4c79e..f59366d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -309,6 +309,20 @@ static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw)
writel(value, ioaddr + LPI_TIMER_CTRL);
}
+static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart)
+{
+ u32 value;
+
+ value = readl(ioaddr + GMAC_AN_CTRL);
+ /* auto negotiation enable and External Loopback enable */
+ value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
+
+ if (restart)
+ value |= GMAC_AN_CTRL_RAN;
+
+ writel(value, ioaddr + GMAC_AN_CTRL);
+}
+
static const struct stmmac_ops dwmac1000_ops = {
.core_init = dwmac1000_core_init,
.rx_ipc = dwmac1000_rx_ipc_enable,
@@ -323,6 +337,7 @@ static const struct stmmac_ops dwmac1000_ops = {
.reset_eee_mode = dwmac1000_reset_eee_mode,
.set_eee_timer = dwmac1000_set_eee_timer,
.set_eee_pls = dwmac1000_set_eee_pls,
+ .ctrl_ane = dwmac1000_ctrl_ane,
};
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b05df89..197497c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -93,6 +93,7 @@ struct stmmac_priv {
u32 tx_coal_timer;
int use_riwt;
u32 rx_riwt;
+ int pcs;
};
extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index e15004f..71b58ea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -222,6 +222,10 @@ static int stmmac_ethtool_getsettings(struct net_device *dev,
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phy = priv->phydev;
int rc;
+
+ if (priv->pcs) /* FIXME */
+ return -EOPNOTSUPP;
+
if (phy == NULL) {
pr_err("%s: %s: PHY is not registered\n",
__func__, dev->name);
@@ -246,6 +250,9 @@ static int stmmac_ethtool_setsettings(struct net_device *dev,
struct phy_device *phy = priv->phydev;
int rc;
+ if (priv->pcs) /* FIXME */
+ return -EOPNOTSUPP;
+
spin_lock(&priv->lock);
rc = phy_ethtool_sset(phy, cmd);
spin_unlock(&priv->lock);
@@ -317,6 +324,9 @@ stmmac_get_pauseparam(struct net_device *netdev,
spin_lock(&priv->lock);
+ if (priv->pcs)
+ return -EOPNOTSUPP;
+
pause->rx_pause = 0;
pause->tx_pause = 0;
pause->autoneg = priv->phydev->autoneg;
@@ -338,6 +348,9 @@ stmmac_set_pauseparam(struct net_device *netdev,
int new_pause = FLOW_OFF;
int ret = 0;
+ if (priv->pcs)
+ return -EOPNOTSUPP;
+
spin_lock(&priv->lock);
if (pause->rx_pause)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1f2f349..6366266 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -398,6 +398,21 @@ static void stmmac_adjust_link(struct net_device *dev)
DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
}
+static void stmmac_check_pcs_mode(struct stmmac_priv *priv)
+{
+ int interface = priv->plat->interface;
+
+ if (priv->dma_cap.pcs) {
+ if ((interface & PHY_INTERFACE_MODE_RGMII) ||
+ (interface & PHY_INTERFACE_MODE_RGMII_ID) ||
+ (interface & PHY_INTERFACE_MODE_RGMII_RXID) ||
+ (interface & PHY_INTERFACE_MODE_RGMII_TXID)) {
+ pr_debug("STMMAC: PCS RGMII support enable\n");
+ priv->pcs = STMMAC_PCS_RGMII;
+ }
+ }
+}
+
/**
* stmmac_init_phy - PHY initialization
* @dev: net device structure
@@ -1012,10 +1027,13 @@ static int stmmac_open(struct net_device *dev)
stmmac_check_ether_addr(priv);
- ret = stmmac_init_phy(dev);
- if (unlikely(ret)) {
- pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
- goto open_error;
+ if (!priv->pcs) {
+ ret = stmmac_init_phy(dev);
+ if (unlikely(ret)) {
+ pr_err("%s: Cannot attach to PHY (error: %d)\n",
+ __func__, ret);
+ goto open_error;
+ }
}
/* Create and initialize the TX/RX descriptors chains. */
@@ -1104,7 +1122,12 @@ static int stmmac_open(struct net_device *dev)
phy_start(priv->phydev);
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
- priv->eee_enabled = stmmac_eee_init(priv);
+
+ /* Using PCS we cannot dial with the phy registers at this stage
+ * so we do not support extra feature like EEE.
+ */
+ if (!priv->pcs)
+ priv->eee_enabled = stmmac_eee_init(priv);
stmmac_init_tx_coalesce(priv);
@@ -1113,6 +1136,9 @@ static int stmmac_open(struct net_device *dev)
priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
}
+ if (priv->pcs && priv->hw->mac->ctrl_ane)
+ priv->hw->mac->ctrl_ane(priv->ioaddr, 1);
+
napi_enable(&priv->napi);
netif_start_queue(dev);
@@ -2028,12 +2054,16 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
else
priv->clk_csr = priv->plat->clk_csr;
- /* MDIO bus Registration */
- ret = stmmac_mdio_register(ndev);
- if (ret < 0) {
- pr_debug("%s: MDIO bus (id: %d) registration failed",
- __func__, priv->plat->bus_id);
- goto error_mdio_register;
+ stmmac_check_pcs_mode(priv);
+
+ if (!priv->pcs) {
+ /* MDIO bus Registration */
+ ret = stmmac_mdio_register(ndev);
+ if (ret < 0) {
+ pr_debug("%s: MDIO bus (id: %d) registration failed",
+ __func__, priv->plat->bus_id);
+ goto error_mdio_register;
+ }
}
return priv;
@@ -2065,7 +2095,8 @@ int stmmac_dvr_remove(struct net_device *ndev)
priv->hw->dma->stop_tx(priv->ioaddr);
stmmac_set_mac(priv->ioaddr, false);
- stmmac_mdio_unregister(ndev);
+ if (!priv->pcs)
+ stmmac_mdio_unregister(ndev);
netif_carrier_off(ndev);
unregister_netdev(ndev);
free_netdev(ndev);
--
1.7.4.4
^ permalink raw reply related
* Re: Softirqs without captured packets
From: Eric Dumazet @ 2013-02-22 14:11 UTC (permalink / raw)
To: Javier Domingo; +Cc: David Miller, netdev
In-Reply-To: <CALZVapmKbqcamTYTEhoerRUPpjsaLJqoTo84Fqmz+aUWWTmh2g@mail.gmail.com>
On Fri, 2013-02-22 at 10:32 +0100, Javier Domingo wrote:
> Which is the reason for that in the poll function, not only some
> drivers have that tx completion (I suppose it is to free resources),
> but also to send packets in that routine?
>
> In e1000e, I have found that it frees resources used in tx, with the
> e1000_clean_tx_irq, and also, although the tx completion is first, it
> executes the rx routine.
>
> On the other hand, tg3 driver not only does the tx resources free but
> also sends packets in that time, and may return from the poll thought
> it might not have done rx work in the net_rx_action routine.
>
> Why is this like that? I mean, why all the tx is done *before* the rx
> thread, thought it may not do any rx work (in tg3) ?
To free memory, so that rx handler gets more chance to be able to
allocate memory, and reuse memory already hot in cpu caches.
^ permalink raw reply
* Re: Problem with Reaktek 8168
From: Ralf Friedl @ 2013-02-22 14:55 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20130221224543.GA11240@electric-eye.fr.zoreil.com>
Francois Romieu wrote:
> I have not noticed 8168f specific problems as of late. It could be worth
> giving stock 3.8 a try though: its load of changes includes some post
> 3.4.x branch 8168f bits.
>
Thank you very much.
I just installed the OpenSuse kernel 3.8.0-2.1 and transferred my
collection of Linux install images, about 145G, to and from another
computer, without a single problem.
So whatever was changed fixed the issue.
I have one warning in the syslog, but I hope it is not serious.
WARNING: at net/sched/sch_generic.c:254 dev_watchdog+0x239/0x250()
NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
Call Trace:
<IRQ> [<ffffffff810355c9>] ? warn_slowpath_common+0x79/0xc0
[<ffffffff810356c5>] ? warn_slowpath_fmt+0x45/0x50
[<ffffffff813096c9>] ? dev_watchdog+0x239/0x250
[<ffffffff81309490>] ? pfifo_fast_dequeue+0xd0/0xd0
[<ffffffff810415ba>] ? call_timer_fn.isra.32+0x2a/0x90
[<ffffffff8104177e>] ? run_timer_softirq+0x15e/0x1f0
[<ffffffff811ce4c9>] ? timerqueue_add+0x59/0xa0
[<ffffffff8103c314>] ? __do_softirq+0xa4/0x150
[<ffffffff810733df>] ? clockevents_program_event+0x6f/0x110
[<ffffffff8138bf4c>] ? call_softirq+0x1c/0x30
[<ffffffff8100464d>] ? do_softirq+0x4d/0x80
[<ffffffff8103c4e6>] ? irq_exit+0x86/0xa0
[<ffffffff810221e8>] ? smp_apic_timer_interrupt+0x68/0xa0
[<ffffffff8138b94a>] ? apic_timer_interrupt+0x6a/0x70
<EOI> [<ffffffff81042074>] ? get_next_timer_interrupt+0x1d4/0x270
[<ffffffff812c2a71>] ? cpuidle_wrap_enter+0x41/0x80
[<ffffffff812c2a6d>] ? cpuidle_wrap_enter+0x3d/0x80
[<ffffffff812c2838>] ? cpuidle_idle_call+0x78/0x100
[<ffffffff8100b22f>] ? cpu_idle+0x5f/0xd0
Ralf
^ permalink raw reply
* Disable IPv4-mapped - enforce IPV6_V6ONLY
From: Alexander Holler @ 2013-02-22 15:21 UTC (permalink / raw)
To: netdev
Hello,
I'm searching for a way to either enforce IPV6_V6ONLY or to block
IPv4-mapped addresses on ipv6-sockets (e.g. by using iptables) system-wide.
E.g. net.ipv6.bindv6only doesn't help if something calls
int v6on = 0;
setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6on, sizeof(v6on))
In such a case I still want to disable or block IPv4-mapped addresses on
that socket, even if the program thinks it nows it better.
Until now I haven't found a solution.
Regards,
Alexander
^ permalink raw reply
* Re: [PATCH] net: fec: Ensure that initialization is done prior to request_irq()
From: Fabio Estevam @ 2013-02-22 16:22 UTC (permalink / raw)
To: Jim Baxter; +Cc: netdev
In-Reply-To: <loom.20130222T020618-678@post.gmane.org>
On Thu, Feb 21, 2013 at 10:13 PM, Jim Baxter <jim_baxter@mentor.com> wrote:
> There is a divide by zero error.
>
> If I enable these 3 kernel hacking options;
> CONFIG_DEBUG_SPINLOCK: -- Spinlock and rw-lock debugging: basic checks
> CONFIG_DEBUG_LOCK_ALLOC: -- Lock debugging: detect incorrect freeing of live
> locks
> CONFIG_PROVE_LOCKING: -- Lock debugging: prove locking correctness
Thanks for reporting this issue, Jim.
I was testing under mx53, which did not show this problem.
I have a fix for this and I have tested it on both mx6q and mx53. Will
submit it shortly.
^ permalink raw reply
* [PATCH] net: Fix locking bug in netif_set_xps_queue
From: Alexander Duyck @ 2013-02-22 16:38 UTC (permalink / raw)
To: netdev; +Cc: fengguang.wu, davem, dan.carpenter, jeffrey.t.kirsher
Smatch found a locking bug in netif_set_xps_queue in which we were not
releasing the lock in the case of an allocation failure.
This change corrects that so that we release the xps_map_mutex before
returning -ENOMEM in the case of an allocation failure.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
net/core/dev.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 17bc535..18d8b5a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1882,8 +1882,10 @@ int netif_set_xps_queue(struct net_device *dev, struct cpumask *mask, u16 index)
if (!new_dev_maps)
new_dev_maps = kzalloc(maps_sz, GFP_KERNEL);
- if (!new_dev_maps)
+ if (!new_dev_maps) {
+ mutex_unlock(&xps_map_mutex);
return -ENOMEM;
+ }
map = dev_maps ? xmap_dereference(dev_maps->cpu_map[cpu]) :
NULL;
^ permalink raw reply related
* [PATCH] net: fec: Fix division by zero
From: Fabio Estevam @ 2013-02-22 16:40 UTC (permalink / raw)
To: davem; +Cc: Frank.Li, s.hauer, jim_baxter, netdev, Fabio Estevam
commit 7f7d6c282 (net: fec: Ensure that initialization is done prior to
request_irq()) placed fec_ptp_init() into a point that ptp clock was not
available, which causes a division by zero in fec_ptp_start_cyclecounter():
[ 17.895723] Division by zero in kernel.
[ 17.899571] Backtrace:
[ 17.902094] [<80012564>] (dump_backtrace+0x0/0x10c) from [<8056deec>]
(dump_stack+0x18/0x1c)
[ 17.910539] r6:bfba8500 r5:8075c950 r4:bfba8000 r3:bfbd0000
[ 17.916284] [<8056ded4>] (dump_stack+0x0/0x1c) from [<80012688>]
(__div0+0x18/0x20)
[ 17.923968] [<80012670>] (__div0+0x0/0x20) from [<802829c4>] (Ldiv0+0x8/0x10)
[ 17.931140] [<80398534>] (fec_ptp_start_cyclecounter+0x0/0x110) from
[<80394f64>] (fec_restart+0x6c8/0x754)
[ 17.940898] [<8039489c>] (fec_restart+0x0/0x754) from [<803969a0>]
(fec_enet_adjust_link+0xdc/0x108)
[ 17.950046] [<803968c4>] (fec_enet_adjust_link+0x0/0x108) from [<80390bc4>]
(phy_state_machine+0x178/0x534)
...
Fix this by rearraging the code so that fec_ptp_init() is called only after
the clocks have been properly acquired.
Tested on both mx53 and mx6 platforms.
Reported-by: Jim Baxter <jim_baxter@mentor.com>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
drivers/net/ethernet/freescale/fec.c | 68 +++++++++++++++++-----------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 2dbb36c..fccc3bf 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1782,33 +1782,6 @@ fec_probe(struct platform_device *pdev)
fep->phy_interface = ret;
}
- fep->bufdesc_ex =
- pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
- if (fep->bufdesc_ex)
- fec_ptp_init(ndev, pdev);
-
- ret = fec_enet_init(ndev);
- if (ret)
- goto failed_init;
-
- for (i = 0; i < FEC_IRQ_NUM; i++) {
- irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- if (i)
- break;
- ret = irq;
- goto failed_irq;
- }
- ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
- if (ret) {
- while (--i >= 0) {
- irq = platform_get_irq(pdev, i);
- free_irq(irq, ndev);
- }
- goto failed_irq;
- }
- }
-
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
@@ -1828,6 +1801,8 @@ fec_probe(struct platform_device *pdev)
}
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
+ fep->bufdesc_ex =
+ pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
if (IS_ERR(fep->clk_ptp)) {
ret = PTR_ERR(fep->clk_ptp);
fep->bufdesc_ex = 0;
@@ -1850,6 +1825,31 @@ fec_probe(struct platform_device *pdev)
fec_reset_phy(pdev);
+ if (fep->bufdesc_ex)
+ fec_ptp_init(ndev, pdev);
+
+ ret = fec_enet_init(ndev);
+ if (ret)
+ goto failed_init;
+
+ for (i = 0; i < FEC_IRQ_NUM; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0) {
+ if (i)
+ break;
+ ret = irq;
+ goto failed_irq;
+ }
+ ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
+ if (ret) {
+ while (--i >= 0) {
+ irq = platform_get_irq(pdev, i);
+ free_irq(irq, ndev);
+ }
+ goto failed_irq;
+ }
+ }
+
ret = fec_enet_mii_init(pdev);
if (ret)
goto failed_mii_init;
@@ -1866,6 +1866,13 @@ fec_probe(struct platform_device *pdev)
failed_register:
fec_enet_mii_remove(fep);
failed_mii_init:
+failed_init:
+ for (i = 0; i < FEC_IRQ_NUM; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq > 0)
+ free_irq(irq, ndev);
+ }
+failed_irq:
failed_regulator:
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
@@ -1873,14 +1880,7 @@ failed_regulator:
clk_disable_unprepare(fep->clk_ptp);
failed_pin:
failed_clk:
- for (i = 0; i < FEC_IRQ_NUM; i++) {
- irq = platform_get_irq(pdev, i);
- if (irq > 0)
- free_irq(irq, ndev);
- }
-failed_irq:
iounmap(fep->hwp);
-failed_init:
failed_ioremap:
free_netdev(ndev);
failed_alloc_etherdev:
--
1.7.9.5
^ permalink raw reply related
* batman-adv: gpf in batadv_slide_own_bcast_window
From: Sasha Levin @ 2013-02-22 16:54 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli
Cc: David S. Miller, b.a.t.m.a.n, netdev,
linux-kernel@vger.kernel.org, Dave Jones
Hi all,
While fuzzing with trinity inside a KVM tools guest running latest -next kernel
I've stumbled on the following:
[ 3148.615130] batman_adv: <98>\<AE><A4><C7>^?: Removing interface: eth0
[ 3148.991938] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 3148.993736] Dumping ftrace buffer:
[ 3148.997554] (ftrace buffer empty)
[ 3148.998426] Modules linked in:
[ 3148.999135] CPU 3
[ 3148.999606] Pid: 6, comm: kworker/u:0 Tainted: G W 3.8.0-next-20130222-sasha-00038-gba27e20-dirty #11
[ 3149.001223] RIP: 0010:[<ffffffff83d217d8>] [<ffffffff83d217d8>] batadv_slide_own_bcast_window+0xb8/0x2b0
[ 3149.001223] RSP: 0018:ffff8800b9f4fc58 EFLAGS: 00010246
[ 3149.001223] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001
[ 3149.001223] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001
[ 3149.001223] RBP: ffff8800b9f4fcb8 R08: 0000000000000002 R09: ffff8800b9f63950
[ 3149.001223] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800abad2238
[ 3149.001223] R13: 6b6b6b6b6b6b865b R14: ffff88004c13cda0 R15: 0000000000000001
[ 3149.001223] FS: 0000000000000000(0000) GS:ffff8800bbc00000(0000) knlGS:0000000000000000
[ 3149.001223] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3149.001223] CR2: 00007f006711f1d0 CR3: 000000008258e000 CR4: 00000000000406e0
[ 3149.001223] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 3149.001223] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 3149.001223] Process kworker/u:0 (pid: 6, threadinfo ffff8800b9f4e000, task ffff8800b9f63000)
[ 3149.001223] Stack:
[ 3149.001223] ffffffff83d21760 ffff8800b9f63000 ffff8800abad2238 0000000000000000
[ 3149.001223] ffff880068f6c438 0000035e00000001 ffff8800b9f4fc98 0000000000000000
[ 3149.001223] ffff8800abad2238 ffff88004c13c2a0 ffff88004c13cda0 0000000000000001
[ 3149.001223] Call Trace:
[ 3149.001223] [<ffffffff83d21760>] ? batadv_slide_own_bcast_window+0x40/0x2b0
[ 3149.001223] [<ffffffff83d10ee4>] batadv_iv_ogm_schedule+0x254/0x300
[ 3149.001223] [<ffffffff83d10c90>] ? batadv_iv_ogm_queue_add+0x710/0x710
[ 3149.001223] [<ffffffff811178bf>] ? local_bh_enable_ip+0xef/0x150
[ 3149.001223] [<ffffffff83d25a15>] batadv_send_outstanding_bat_ogm_packet+0xc5/0xf0
[ 3149.001223] [<ffffffff81133ce6>] process_one_work+0x366/0x6a0
[ 3149.001223] [<ffffffff81133ba8>] ? process_one_work+0x228/0x6a0
[ 3149.001223] [<ffffffff811345a8>] worker_thread+0x238/0x370
[ 3149.001223] [<ffffffff81134370>] ? rescuer_thread+0x310/0x310
[ 3149.001223] [<ffffffff8113eb73>] kthread+0xe3/0xf0
[ 3149.001223] [<ffffffff8113ea90>] ? flush_kthread_work+0x1f0/0x1f0
[ 3149.001223] [<ffffffff83dc203c>] ret_from_fork+0x7c/0xb0
[ 3149.001223] [<ffffffff8113ea90>] ? flush_kthread_work+0x1f0/0x1f0
[ 3149.001223] Code: 31 4b fd 85 c0 74 24 48 c7 c2 50 cd bd 84 be 02 03 00 00 48 c7 c7 b4 da bd 84 c6 05 14 ab 16 02 01 e8 ed 16
46 fd 0f 1f 44 00 00 <49> 8b 55 00 48 89 55 b8 e8 0b 55 41 fd 85 c0 74 37 80 3d ee aa
[ 3149.001223] RIP [<ffffffff83d217d8>] batadv_slide_own_bcast_window+0xb8/0x2b0
[ 3149.001223] RSP <ffff8800b9f4fc58>
[ 3149.105631] ---[ end trace ba69e369627c73e7 ]---
Rip points to:
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) { <--- here
spin_lock_bh(&orig_node->ogm_cnt_lock);
word_index = hard_iface->if_num * BATADV_NUM_WORDS;
word = &(orig_node->bcast_own[word_index]);
Thanks,
Sasha
^ permalink raw reply
* Re: batman-adv: gpf in batadv_slide_own_bcast_window
From: Antonio Quartulli @ 2013-02-22 17:06 UTC (permalink / raw)
To: Sasha Levin
Cc: Marek Lindner, Simon Wunderlich, David S. Miller, b.a.t.m.a.n,
netdev, linux-kernel@vger.kernel.org, Dave Jones
In-Reply-To: <5127A2AF.9030502@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 4570 bytes --]
Hi Sasha and thank you very much for reporting this issue.
IIRC this is similar to a bug you already reported in the past.
This bug should be the result of a race condition batman-adv has in the
hard-interface handling code (this is why it has been triggered while removing
eth0).
Now that the rtnl-deadlock has been solved I think we can try to further
investigate on this bug and try to find a solution..though it will not be easy
as it probably requires another lock to protect the hard-interface during this
operations.
If you have any fix proposal feel free to contribute!
Cheers,
On Fri, Feb 22, 2013 at 11:54:07AM -0500, Sasha Levin wrote:
> Hi all,
>
> While fuzzing with trinity inside a KVM tools guest running latest -next kernel
> I've stumbled on the following:
>
> [ 3148.615130] batman_adv: <98>\<AE><A4><C7>^?: Removing interface: eth0
> [ 3148.991938] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
> [ 3148.993736] Dumping ftrace buffer:
> [ 3148.997554] (ftrace buffer empty)
> [ 3148.998426] Modules linked in:
> [ 3148.999135] CPU 3
> [ 3148.999606] Pid: 6, comm: kworker/u:0 Tainted: G W 3.8.0-next-20130222-sasha-00038-gba27e20-dirty #11
> [ 3149.001223] RIP: 0010:[<ffffffff83d217d8>] [<ffffffff83d217d8>] batadv_slide_own_bcast_window+0xb8/0x2b0
> [ 3149.001223] RSP: 0018:ffff8800b9f4fc58 EFLAGS: 00010246
> [ 3149.001223] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001
> [ 3149.001223] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001
> [ 3149.001223] RBP: ffff8800b9f4fcb8 R08: 0000000000000002 R09: ffff8800b9f63950
> [ 3149.001223] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800abad2238
> [ 3149.001223] R13: 6b6b6b6b6b6b865b R14: ffff88004c13cda0 R15: 0000000000000001
> [ 3149.001223] FS: 0000000000000000(0000) GS:ffff8800bbc00000(0000) knlGS:0000000000000000
> [ 3149.001223] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 3149.001223] CR2: 00007f006711f1d0 CR3: 000000008258e000 CR4: 00000000000406e0
> [ 3149.001223] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 3149.001223] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 3149.001223] Process kworker/u:0 (pid: 6, threadinfo ffff8800b9f4e000, task ffff8800b9f63000)
> [ 3149.001223] Stack:
> [ 3149.001223] ffffffff83d21760 ffff8800b9f63000 ffff8800abad2238 0000000000000000
> [ 3149.001223] ffff880068f6c438 0000035e00000001 ffff8800b9f4fc98 0000000000000000
> [ 3149.001223] ffff8800abad2238 ffff88004c13c2a0 ffff88004c13cda0 0000000000000001
> [ 3149.001223] Call Trace:
> [ 3149.001223] [<ffffffff83d21760>] ? batadv_slide_own_bcast_window+0x40/0x2b0
> [ 3149.001223] [<ffffffff83d10ee4>] batadv_iv_ogm_schedule+0x254/0x300
> [ 3149.001223] [<ffffffff83d10c90>] ? batadv_iv_ogm_queue_add+0x710/0x710
> [ 3149.001223] [<ffffffff811178bf>] ? local_bh_enable_ip+0xef/0x150
> [ 3149.001223] [<ffffffff83d25a15>] batadv_send_outstanding_bat_ogm_packet+0xc5/0xf0
> [ 3149.001223] [<ffffffff81133ce6>] process_one_work+0x366/0x6a0
> [ 3149.001223] [<ffffffff81133ba8>] ? process_one_work+0x228/0x6a0
> [ 3149.001223] [<ffffffff811345a8>] worker_thread+0x238/0x370
> [ 3149.001223] [<ffffffff81134370>] ? rescuer_thread+0x310/0x310
> [ 3149.001223] [<ffffffff8113eb73>] kthread+0xe3/0xf0
> [ 3149.001223] [<ffffffff8113ea90>] ? flush_kthread_work+0x1f0/0x1f0
> [ 3149.001223] [<ffffffff83dc203c>] ret_from_fork+0x7c/0xb0
> [ 3149.001223] [<ffffffff8113ea90>] ? flush_kthread_work+0x1f0/0x1f0
> [ 3149.001223] Code: 31 4b fd 85 c0 74 24 48 c7 c2 50 cd bd 84 be 02 03 00 00 48 c7 c7 b4 da bd 84 c6 05 14 ab 16 02 01 e8 ed 16
> 46 fd 0f 1f 44 00 00 <49> 8b 55 00 48 89 55 b8 e8 0b 55 41 fd 85 c0 74 37 80 3d ee aa
> [ 3149.001223] RIP [<ffffffff83d217d8>] batadv_slide_own_bcast_window+0xb8/0x2b0
> [ 3149.001223] RSP <ffff8800b9f4fc58>
> [ 3149.105631] ---[ end trace ba69e369627c73e7 ]---
>
> Rip points to:
>
> for (i = 0; i < hash->size; i++) {
> head = &hash->table[i];
>
> rcu_read_lock();
> hlist_for_each_entry_rcu(orig_node, head, hash_entry) { <--- here
> spin_lock_bh(&orig_node->ogm_cnt_lock);
> word_index = hard_iface->if_num * BATADV_NUM_WORDS;
> word = &(orig_node->bcast_own[word_index]);
>
>
> Thanks,
> Sasha
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox