* [PATCH 2/3] net: davinci_emac: Get device dm816x MAC address using the cpsw code
From: Tony Lindgren @ 2015-01-28 19:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-omap, Brian Hutchinson, Felipe Balbi
In-Reply-To: <1422473586-18100-1-git-send-email-tony@atomide.com>
At least on dm81xx, we can get the davinci_emac MAC address the same
way as on am33xx cpsw.
Let's also use ether_addr_copy() for davinci_emac while at it.
Cc: Brian Hutchinson <b.hutchman@gmail.com>
Cc: Felipe Balbi <balbi@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
drivers/net/ethernet/ti/davinci_emac.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 5fae435..a716938 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -69,6 +69,7 @@
#include <asm/irq.h>
#include <asm/page.h>
+#include "cpsw.h"
#include "davinci_cpdma.h"
static int debug_level;
@@ -1838,7 +1839,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
if (!is_valid_ether_addr(pdata->mac_addr)) {
mac_addr = of_get_mac_address(np);
if (mac_addr)
- memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
+ ether_addr_copy(pdata->mac_addr, mac_addr);
}
of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
@@ -1879,6 +1880,22 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
return pdata;
}
+static int davinci_emac_try_get_mac(struct platform_device *pdev,
+ int instance, u8 *mac_addr)
+{
+ int error = -EINVAL;
+
+ if (!pdev->dev.of_node)
+ return error;
+
+ if (of_device_is_compatible(pdev->dev.of_node, "ti,dm816-emac"))
+ error = cpsw_am33xx_cm_get_macid(&pdev->dev, 0x30,
+ instance,
+ mac_addr);
+
+ return error;
+}
+
/**
* davinci_emac_probe - EMAC device probe
* @pdev: The DaVinci EMAC device that we are removing
@@ -2009,6 +2026,10 @@ static int davinci_emac_probe(struct platform_device *pdev)
}
ndev->irq = res->start;
+ rc = davinci_emac_try_get_mac(pdev, res_ctrl ? 0 : 1, priv->mac_addr);
+ if (!rc)
+ ether_addr_copy(ndev->dev_addr, priv->mac_addr);
+
if (!is_valid_ether_addr(priv->mac_addr)) {
/* Use random MAC if none passed */
eth_hw_addr_random(ndev);
--
2.1.4
^ permalink raw reply related
* Re: [RFC] net: tcp: null pointer crash in __inet_put_port
From: Eric Dumazet @ 2015-01-28 21:03 UTC (permalink / raw)
To: Harout Hedeshian; +Cc: netdev
In-Reply-To: <1422460613-10782-1-git-send-email-harouth@codeaurora.org>
On Wed, 2015-01-28 at 08:56 -0700, Harout Hedeshian wrote:
> Hello,
>
> We are observing a crash in __inet_put_port() wherein icsk_bind_hash
> is null (stack trace below).
>
> net/ipv4/inet_hashtables.c:
> tb = inet_csk(sk)->icsk_bind_hash;
> __sk_del_bind_node(sk);
> tb->num_owners--; <-- tb is unconditionally dereferenced here
>
> From the RAM dumps: [D:0xFFFFFFC0222FB6F8] icsk_bind_hash = 0x0 = ,
>
> The caller of inet_put_port() in this case is tcp_set_state() which
> already does a null check on this particular field before calling
> inet_put_port().
>
> net/ipv4/tcp.c:
> if (inet_csk(sk)->icsk_bind_hash &&
> !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
> inet_put_port(sk);
>
> It seems that inet_put_port() does some locking by disabling bottom
> halves, but this locking is happening after the null check.
>
> Additionally, I see tcp_v4_destroy_sock() also calling inet_put_port()
> after doing a similar null check. However, I am unsure if it would
> ever be called on the same socket.
>
> Does the proposed solution of locking the bottom halves from
> tcp_set_state() make any sense here? Or use some other locking mechanism
> directly on the socket?
> net/ipv4/tcp.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 3075723..f3b5714 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -1910,9 +1910,11 @@ void tcp_set_state(struct sock *sk, int state)
> TCP_INC_STATS(sock_net(sk), TCP_MIB_ESTABRESETS);
>
> sk->sk_prot->unhash(sk);
> + local_bh_disable();
> if (inet_csk(sk)->icsk_bind_hash &&
> !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
> inet_put_port(sk);
> + local_bh_enable();
> /* fall through */
> default:
> if (oldstate == TCP_ESTABLISHED)
I don't think it makes sense.
tcp_set_state() should only be used on a locked socket.
I believe you are papering over another bug.
bh are disabled in inet_put_port because of the spin_lock() that can be
taken both from process and softirq contexts.
^ permalink raw reply
* [GIT] [3.20] NFC update
From: Samuel Ortiz @ 2015-01-29 0:52 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
Hi David,
This is the first NFC pull request for 3.20.
With this one we have:
- Secure element support for the ST Micro st21nfca driver. This depends
on a few HCI internal changes in order for example to support more
than one secure element per controller.
- ACPI support for NXP's pn544 HCI driver. This controller is found on
many x86 SoCs and is typically enumerated on the ACPI bus there.
- A few st21nfca and st21nfcb fixes. Since they're not critical fixes,
I assumed it's too late for a 3.19 inclusion. Please let me know if
you'd prefer to see them going through a net pull request instead.
The following changes since commit 7aee42c6764bae75d0eb2f674f0874193de90c05:
cxgb3: re-use native hex2bin() (2015-01-25 00:09:41 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next.git tags/nfc-next-3.20-1
for you to fetch changes up to 0a5942c8e1480db4b8ee7a8d643e4945ef2f8fed:
NFC: Add ACPI support for NXP PN544 (2015-01-28 01:09:08 +0100)
----------------------------------------------------------------
Christophe Ricard (23):
NFC: dts: st21nfca: Fix compatible string spelling to follow other drivers
NFC: dts: st21nfcb: Fix compatible string spelling to follow other drivers
NFC: st21nfcb: Fix "WARNING: invalid free of devm_ allocated data"
NFC: st21nfca: Remove unreachable code
NFC: st21nfcb: Avoid use of skb after free
NFC: nfc_enable_se Remove useless blank line at beginning of function
NFC: nfc_disable_se Remove useless blank line at beginning of function
NFC: st21nfca: Remove skb_pipe_list and skb_pipe_info useless allocation
NFC: st21nfca: Remove checkpatch.pl warning Possible unnecessary 'out of memory' message
NFC: st21nfca: Fix some skb memory leaks
NFC: st21nfcb: Fix "NULL pointer dereference" possible error
NFC: st21nfcb: Remove useless include
NFC: st21nfcb: Fix copy/paste error in comment
NFC: hci: Change event_received handler gate parameter to pipe
NFC: hci: Add pipes table to reference them with a tuple {gate, host}
NFC: hci: Change nfc_hci_send_response gate parameter to pipe
NFC: hci: Reference every pipe information according to notification
NFC: hci: Add cmd_received handler
NFC: pn544: Change event_received gate parameter to pipe
NFC: microread: Change event_received gate parameter to pipe
NFC: hci: Remove nfc_hci_pipe2gate function
NFC: st21nfca: Adding support for secure element
NFC: dts: st21nfca: Document ese-present & uicc-present DTS property
Robert Dolca (2):
NFC: PN544: GPIO access that may sleep
NFC: Add ACPI support for NXP PN544
.../devicetree/bindings/net/nfc/st21nfca.txt | 11 +-
.../devicetree/bindings/net/nfc/st21nfcb.txt | 4 +-
drivers/nfc/microread/microread.c | 3 +-
drivers/nfc/pn544/i2c.c | 133 ++++++-
drivers/nfc/pn544/pn544.c | 3 +-
drivers/nfc/st21nfca/Makefile | 2 +-
drivers/nfc/st21nfca/i2c.c | 23 +-
drivers/nfc/st21nfca/st21nfca.c | 186 +++++++---
drivers/nfc/st21nfca/st21nfca.h | 21 +-
drivers/nfc/st21nfca/st21nfca_se.c | 390 +++++++++++++++++++++
drivers/nfc/st21nfca/st21nfca_se.h | 63 ++++
drivers/nfc/st21nfcb/i2c.c | 19 +-
drivers/nfc/st21nfcb/ndlc.c | 3 +-
include/linux/platform_data/st21nfca.h | 2 +
include/linux/platform_data/st21nfcb.h | 4 +-
include/net/nfc/hci.h | 25 +-
net/nfc/core.c | 2 -
net/nfc/hci/command.c | 23 +-
net/nfc/hci/core.c | 97 +++--
net/nfc/hci/hci.h | 10 +-
net/nfc/hci/hcp.c | 11 -
21 files changed, 886 insertions(+), 149 deletions(-)
create mode 100644 drivers/nfc/st21nfca/st21nfca_se.c
create mode 100644 drivers/nfc/st21nfca/st21nfca_se.h
^ permalink raw reply
* Bug in netlink_bind
From: Ivan Delalande @ 2015-01-28 23:46 UTC (permalink / raw)
To: netdev, pablo
Hi,
I’ve been trying to debug some of our tests that began failing when
upgrading to 3.18. Our actual failure is caused by the condition added
in commit 97840cb to nfnetlink_bind but the bug has probably been
introduced by 0329274.
Our tests execute the following code, at some point:
localAddr.nl_groups =
NF_NETLINK_CONNTRACK_NEW
| NF_NETLINK_CONNTRACK_UPDATE
| NF_NETLINK_CONNTRACK_DESTROY;
int ret = bind(sd, (sockaddr*)&localAddr, sizeof(localAddr));
these constants are from include/uapi/linux/netfilter/nfnetlink_compat.h
and used as a bit set:
#define NF_NETLINK_CONNTRACK_NEW 0x00000001
#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002
#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004
but, if I understand correctly, internally, constants from
include/uapi/linux/netfilter/nfnetlink.h are used instead:
enum nfnetlink_groups {
NFNLGRP_NONE,
NFNLGRP_CONNTRACK_NEW,
NFNLGRP_CONNTRACK_UPDATE,
NFNLGRP_CONNTRACK_DESTROY,
...
static const int nfnl_group2type[NFNLGRP_MAX+1] = {
[NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK,
[NFNLGRP_CONNTRACK_UPDATE] = NFNL_SUBSYS_CTNETLINK,
[NFNLGRP_CONNTRACK_DESTROY] = NFNL_SUBSYS_CTNETLINK,
Now in netlink_bind (net/netlink/af_netlink.c), our localAddr.nl_groups
value is assigned to the groups variable and tested with test_bit:
for (group = 0; group < nlk->ngroups; group++) {
if (!test_bit(group, &groups)) {
continue;
}
err = nlk->netlink_bind(group);
In our case, for group = 0, bit 0 is indeed set because nl_groups was
ORed with NF_NETLINK_CONNTRACK_NEW (= 1), so nlk->netlink_bind is called
with 0, that is nfnetlink_bind(0) (net/netfilter/nfnetlink.c):
if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
return -EINVAL;
type = nfnl_group2type[group];
And so, with this condition added by 97840cb, the syscall fails with
EINVAL. But it means that, before this commit, we would have tried to
get nfnl_group2type[0].
In the same way, with NF_NETLINK_CONNTRACK_UPDATE (= 2),
nfnetlink_bind(1) would have been called and fetched nfnl_group2type[1],
which is declared as nfnl_group2type[NFNLGRP_CONNTRACK_NEW] =
NFNL_SUBSYS_CTNETLINK, and so on.
So, am I missing something or are the group values incorrectly
interpreted differently between netlink_bind and nfnetlink_bind, with a
difference of one? I tried a really naive patch and it made this part of
ours tests pass:
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b6bf8e8..d2c65b0 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1479,7 +1479,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
for (group = 0; group < nlk->ngroups; group++) {
if (!test_bit(group, &groups))
continue;
- err = nlk->netlink_bind(group);
+ err = nlk->netlink_bind(group + 1);
if (!err)
continue;
netlink_unbind(group, groups, nlk);
But that was really to test if this would fix my problem, I haven’t
really looked if the value nlk->ngroups was still correct with that or
if there was any other nlk->netlink_bind than netlink_bind that would be
affected.
Thanks,
--
Ivan "Colona" Delalande
Arista Networks
^ permalink raw reply
* Re: [PATCH net] sunvnet: set queue mapping when doing packet copies
From: Sowmini Varadhan @ 2015-01-28 16:48 UTC (permalink / raw)
To: David L Stevens; +Cc: David Miller, netdev
In-Reply-To: <54C90AED.7040404@oracle.com>
On (01/28/15 11:14), David L Stevens wrote:
>
> This patch fixes a bug where vnet_skb_shape() didn't set the already-selected
> queue mapping when a packet copy was required. This results in using the
> wrong queue index for stops/starts, hung tx queues and watchdog timeouts
> under heavy load.
Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
^ permalink raw reply
* Re: [PATCH net-next 1/5] tcp: stretch ACK fixes prep
From: David Miller @ 2015-01-28 23:00 UTC (permalink / raw)
To: ncardwell; +Cc: netdev, ycheng, edumazet
In-Reply-To: <1422390883-15603-2-git-send-email-ncardwell@google.com>
From: Neal Cardwell <ncardwell@google.com>
Date: Tue, 27 Jan 2015 15:34:39 -0500
> -void tcp_slow_start(struct tcp_sock *tp, u32 acked);
...
> +int tcp_slow_start(struct tcp_sock *tp, u32 acked);
...
...
> @@ -360,25 +360,28 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
> * ABC caps N to 2. Slow start exits when cwnd grows over ssthresh and
> * returns the leftover acks to adjust cwnd in congestion avoidance mode.
> */
> -void tcp_slow_start(struct tcp_sock *tp, u32 acked)
> +int tcp_slow_start(struct tcp_sock *tp, u32 acked)
> {
> u32 cwnd = tp->snd_cwnd + acked;
>
> if (cwnd > tp->snd_ssthresh)
> cwnd = tp->snd_ssthresh + 1;
> + acked -= cwnd - tp->snd_cwnd;
> tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
> +
> + return acked;
> }
'acked' is a u32, please have this function return a u32 as well.
In fact in all the call sites the return value gets assigned into a
local u32 variable as well, so I have no idea why you're using 'int'
here.
Thanks.
^ permalink raw reply
* [Patch iproute2] skbedit: print action too
From: Cong Wang @ 2015-01-28 22:52 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, Jamal Hadi Salim, Stephen Hemminger
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
tc/m_skbedit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index 36323a9..c5deee0 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -193,7 +193,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
fprintf(f, " mark %d", *mark);
}
- fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
+ fprintf(f, " %s\n\t index %d ref %d bind %d", action_n2a(p->action, b1, sizeof (b1)), p->index, p->refcnt, p->bindcnt);
if (show_stats) {
if (tb[TCA_SKBEDIT_TM]) {
--
1.8.3.1
^ permalink raw reply related
* [PATCH] net, ethernet, LLVMLinux: Add missing MODULE_DEVICE_TABLE()
From: Behan Webster @ 2015-01-29 1:36 UTC (permalink / raw)
To: sathya.perla
Cc: behanw, ajit.khaparde, linux-kernel, netdev, subbu.seetharaman,
Arnd Bergmann
Missing MODULE_DEVICE_TABLE for pci ids from benet driver found by clang.
Signed-off-by: Behan Webster <behanw@converseincode.com>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/emulex/benet/be_main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index d48806b..709400a 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -26,7 +26,6 @@
#include <net/vxlan.h>
MODULE_VERSION(DRV_VER);
-MODULE_DEVICE_TABLE(pci, be_dev_ids);
MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
MODULE_AUTHOR("Emulex Corporation");
MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 linux-trace 4/8] samples: bpf: simple tracing example in C
From: Arnaldo Carvalho de Melo @ 2015-01-28 16:24 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim, Jiri Olsa,
Masami Hiramatsu, linux-api, netdev, linux-kernel
In-Reply-To: <1422417973-10195-5-git-send-email-ast@plumgrid.com>
Em Tue, Jan 27, 2015 at 08:06:09PM -0800, Alexei Starovoitov escreveu:
> diff --git a/samples/bpf/tracex1_kern.c b/samples/bpf/tracex1_kern.c
> new file mode 100644
> index 000000000000..7849ceb4bce6
> --- /dev/null
> +++ b/samples/bpf/tracex1_kern.c
> @@ -0,0 +1,28 @@
> +#include <linux/skbuff.h>
> +#include <linux/netdevice.h>
> +#include <uapi/linux/bpf.h>
> +#include <trace/bpf_trace.h>
> +#include "bpf_helpers.h"
> +
> +SEC("events/net/netif_receive_skb")
> +int bpf_prog1(struct bpf_context *ctx)
> +{
> + /*
> + * attaches to /sys/kernel/debug/tracing/events/net/netif_receive_skb
> + * prints events for loobpack device only
> + */
> + char devname[] = "lo";
> + struct net_device *dev;
> + struct sk_buff *skb = 0;
> +
> + skb = (struct sk_buff *) ctx->arg1;
> + dev = bpf_fetch_ptr(&skb->dev);
> + if (bpf_memcmp(dev->name, devname, 2) == 0)
I'm only starting to look at all this, so bear with me... But why do we
need to have it as "bpf_memcmp"? Can't we simply use it as "memcmp" and
have it use the right function?
Less typing, perhaps we would need to have a:
#define memcmp bpf_memcmp(s1, s2, n) bpf_memcmp(s1, s2, n)
in bpf_helpers.h to have it work?
- Arnaldo
> + /* print event using default tracepoint format */
> + return 1;
> +
> + /* drop event */
> + return 0;
> +}
^ permalink raw reply
* Re: [PATCH] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: David Miller @ 2015-01-28 7:05 UTC (permalink / raw)
To: roopa; +Cc: netdev, stephen, rami.rosen
In-Reply-To: <1422423984-29743-1-git-send-email-roopa@cumulusnetworks.com>
From: roopa@cumulusnetworks.com
Date: Tue, 27 Jan 2015 21:46:24 -0800
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
>
> This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
> handler does not return any bytes in the skb.
>
> Alternately, the skb->len check can be moved inside rtnl_notify.
>
> For the bridge vlan case described in 92081, there is also a fix needed
> in bridge driver to generate a proper notification. Will fix that in
> subsequent patch.
>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
This doesn't apply to the 'net' tree, is there something I missed?
^ permalink raw reply
* Re: A problem about ICMP packet-too-big message handler
From: Eric Dumazet @ 2015-01-28 12:45 UTC (permalink / raw)
To: Yang Yingliang; +Cc: Martin Lau, netdev, David S. Miller
In-Reply-To: <54C885D3.70808@huawei.com>
On Wed, 2015-01-28 at 14:46 +0800, Yang Yingliang wrote:
> On 2015/1/28 13:19, Martin Lau wrote:
> > On Tue, Jan 27, 2015 at 08:58:53PM +0800, Yang Yingliang wrote:
> >> Hi,
> >>
> >> My kernel is 3.10 LTS.
> >>
> >> I got a problem here about handling ICMP packet-too-big message.
> >>
> >> Before sending a packet-too-big packet :
> > The expires should be set by the host _receiving_ the icmpv6 too-big.
> >
> > Can you spell out some details of the outgoing icmpv6 too-big packet?
> > like, the src/dst ip of the icmpv6 and the original ip packet that triggered the
> > too-big.
> >
>
> I don't send too-big packet to trigger the err handling.
>
> I just only send a ICMPv6 packet which type is ICMPV6_PKT_TOOBIG.
You meant : you received an ICMPv6 packet, or you send it ?
^ permalink raw reply
* [PATCH] cxgb4: Remove preprocessor check for CONFIG_CXGB4_DCB
From: Hariprasad Shenai @ 2015-01-28 16:19 UTC (permalink / raw)
To: netdev; +Cc: davem, leedom, anish, nirranjan, praveenm, Hariprasad Shenai
In commit dc9daab226aa ("cxgb4: Added support in debugfs to dump
sge_qinfo") a preprocessor check for CONFIG_CXGB4_DCB got added, which should
have been CONFIG_CHELSIO_T4_DCB.
Reported-by: Paul Bolle <pebolle@tiscal.nl>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 24 +++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 47c0869..61c000a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1229,6 +1229,28 @@ static const struct file_operations rss_vf_config_debugfs_fops = {
.release = seq_release_private
};
+/**
+ * ethqset2pinfo - return port_info of an Ethernet Queue Set
+ * @adap: the adapter
+ * @qset: Ethernet Queue Set
+ */
+static inline struct port_info *ethqset2pinfo(struct adapter *adap, int qset)
+{
+ int pidx;
+
+ for_each_port(adap, pidx) {
+ struct port_info *pi = adap2pinfo(adap, pidx);
+
+ if (qset >= pi->first_qset &&
+ qset < pi->first_qset + pi->nqsets)
+ return pi;
+ }
+
+ /* should never happen! */
+ BUG_ON(1);
+ return NULL;
+}
+
static int sge_qinfo_show(struct seq_file *seq, void *v)
{
struct adapter *adap = seq->private;
@@ -1272,7 +1294,7 @@ do { \
T("TxQ inuse:", q.in_use);
T("TxQ CIDX:", q.cidx);
T("TxQ PIDX:", q.pidx);
-#ifdef CONFIG_CXGB4_DCB
+#ifdef CONFIG_CHELSIO_T4_DCB
T("DCB Prio:", dcb_prio);
S3("u", "DCB PGID:",
(ethqset2pinfo(adap, base_qset + i)->dcb.pgid >>
--
1.7.1
^ permalink raw reply related
* [PATCH 3/3] net: davinci_emac: Get device MAC on 3517
From: Tony Lindgren @ 2015-01-28 19:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-omap
In-Reply-To: <1422473586-18100-1-git-send-email-tony@atomide.com>
Looks like on 3517 davinci_emac MAC address registers have a
different layout compared to dm816x and am33xx.
Let's add a function to get the 3517 MAC address.
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/boot/dts/am3517.dtsi | 1 +
drivers/net/ethernet/ti/davinci_emac.c | 35 +++++++++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
index 5a452fd..c90724b 100644
--- a/arch/arm/boot/dts/am3517.dtsi
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -31,6 +31,7 @@
status = "disabled";
reg = <0x5c000000 0x30000>;
interrupts = <67 68 69 70>;
+ syscon = <&omap3_scm_general>;
ti,davinci-ctrl-reg-offset = <0x10000>;
ti,davinci-ctrl-mod-reg-offset = <0>;
ti,davinci-ctrl-ram-offset = <0x20000>;
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index a716938..aeebc0a 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -52,6 +52,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/semaphore.h>
#include <linux/phy.h>
#include <linux/bitops.h>
@@ -65,6 +66,7 @@
#include <linux/of_mdio.h>
#include <linux/of_irq.h>
#include <linux/of_net.h>
+#include <linux/mfd/syscon.h>
#include <asm/irq.h>
#include <asm/page.h>
@@ -1880,6 +1882,33 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
return pdata;
}
+static int davinci_emac_3517_get_macid(struct device *dev, u16 offset,
+ int slave, u8 *mac_addr)
+{
+ u32 macid_lsb;
+ u32 macid_msb;
+ struct regmap *syscon;
+
+ syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
+ if (IS_ERR(syscon)) {
+ if (PTR_ERR(syscon) == -ENODEV)
+ return 0;
+ return PTR_ERR(syscon);
+ }
+
+ regmap_read(syscon, offset, &macid_lsb);
+ regmap_read(syscon, offset + 4, &macid_msb);
+
+ mac_addr[0] = (macid_msb >> 16) & 0xff;
+ mac_addr[1] = (macid_msb >> 8) & 0xff;
+ mac_addr[2] = macid_msb & 0xff;
+ mac_addr[3] = (macid_lsb >> 16) & 0xff;
+ mac_addr[4] = (macid_lsb >> 8) & 0xff;
+ mac_addr[5] = macid_lsb & 0xff;
+
+ return 0;
+}
+
static int davinci_emac_try_get_mac(struct platform_device *pdev,
int instance, u8 *mac_addr)
{
@@ -1888,7 +1917,11 @@ static int davinci_emac_try_get_mac(struct platform_device *pdev,
if (!pdev->dev.of_node)
return error;
- if (of_device_is_compatible(pdev->dev.of_node, "ti,dm816-emac"))
+ if (of_device_is_compatible(pdev->dev.of_node, "ti,am3517-emac"))
+ error = davinci_emac_3517_get_macid(&pdev->dev, 0x110,
+ 0, mac_addr);
+ else if (of_device_is_compatible(pdev->dev.of_node,
+ "ti,dm816-emac"))
error = cpsw_am33xx_cm_get_macid(&pdev->dev, 0x30,
instance,
mac_addr);
--
2.1.4
^ permalink raw reply related
* Re: [patch net-next] hisilicon: add some missing curly braces
From: Ding Tianhong @ 2015-01-29 2:50 UTC (permalink / raw)
To: Dan Carpenter
Cc: Zhangfei Gao, David S. Miller, Arnd Bergmann, netdev,
kernel-janitors
In-Reply-To: <20150128185833.GA10259@mwanda>
On 2015/1/29 2:58, Dan Carpenter wrote:
> The if block was supposed to have curly braces. In the current code we
> complain about dropped rx packets when we shouldn't.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
Acked-by: Ding Tianhong <dingtianhong@huawei.com>
Good catch. thanks;
Hi David, this patch looks good to me, and I was preparing a series patches for hip04,
I could add this patch to the series or you could apply this alone as your wish.:)
Ding
> diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
> index 525214e..c02b81b 100644
> --- a/drivers/net/ethernet/hisilicon/hip04_eth.c
> +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
> @@ -567,10 +567,11 @@ static irqreturn_t hip04_mac_interrupt(int irq, void *dev_id)
> writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT);
>
> if (unlikely(ists & DEF_INT_ERR)) {
> - if (ists & (RCV_NOBUF | RCV_DROP))
> + if (ists & (RCV_NOBUF | RCV_DROP)) {
> stats->rx_errors++;
> stats->rx_dropped++;
> netdev_err(ndev, "rx drop\n");
> + }
> if (ists & TX_DROP) {
> stats->tx_dropped++;
> netdev_err(ndev, "tx drop\n");
>
>
^ permalink raw reply
* Re: [PATCH] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: roopa @ 2015-01-28 14:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stephen, rami.rosen
In-Reply-To: <54C8E62C.5040603@cumulusnetworks.com>
On 1/28/15, 5:37 AM, roopa wrote:
> On 1/27/15, 11:05 PM, David Miller wrote:
>> From: roopa@cumulusnetworks.com
>> Date: Tue, 27 Jan 2015 21:46:24 -0800
>>
>>> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>>
>>> Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
>>>
>>> This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
>>> handler does not return any bytes in the skb.
>>>
>>> Alternately, the skb->len check can be moved inside rtnl_notify.
>>>
>>> For the bridge vlan case described in 92081, there is also a fix needed
>>> in bridge driver to generate a proper notification. Will fix that in
>>> subsequent patch.
>>>
>>> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>> This doesn't apply to the 'net' tree, is there something I missed?
> sorry, that's me. This should be net-next. Resubmitting with net-next
> in the PATCH line.
>
A few more details ...
....This bug exists in 'net' tree (and I believe previous releases) as
well.
However my patch was generated on net-next, And there are other changes
in the related area in net-next tree hence the patch will not apply on
'net'.
Looks like its better for me to regenerate and submit against 'net'.
will do.
Thanks,
Roopa
^ permalink raw reply
* [PATCH net] ppp: deflate: never return len larger than output buffer
From: Florian Westphal @ 2015-01-28 9:56 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
When we've run out of space in the output buffer to store more data, we
will call zlib_deflate with a NULL output buffer until we've consumed
remaining input.
When this happens, olen contains the size the output buffer would have
consumed iff we'd have had enough room.
This can later cause skb_over_panic when ppp_generic skb_put()s
the returned length.
Reported-by: Iain Douglas <centos@1n6.org.uk>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c
index 602c625..b5edc7f 100644
--- a/drivers/net/ppp/ppp_deflate.c
+++ b/drivers/net/ppp/ppp_deflate.c
@@ -246,7 +246,7 @@ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
/*
* See if we managed to reduce the size of the packet.
*/
- if (olen < isize) {
+ if (olen < isize && olen <= osize) {
state->stats.comp_bytes += olen;
state->stats.comp_packets++;
} else {
--
2.0.5
^ permalink raw reply related
* Re: A problem about ICMP packet-too-big message handler
From: Yang Yingliang @ 2015-01-29 3:16 UTC (permalink / raw)
To: Steffen Klassert; +Cc: netdev, David S. Miller
In-Reply-To: <20150128121026.GM13046@secunet.com>
On 2015/1/28 20:10, Steffen Klassert wrote:
> On Tue, Jan 27, 2015 at 08:58:53PM +0800, Yang Yingliang wrote:
>> Hi,
>>
>> My kernel is 3.10 LTS.
>>
>> I got a problem here about handling ICMP packet-too-big message.
>>
>> Before sending a packet-too-big packet :
>>
>> # ip -6 route list table local
>> local ::1 dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80::1 dev lo metric 0 //It does not have expire value
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:2 dev lo metric 0
>> local fe80::5054:ff:fe12:3456 dev lo metric 0
>>
>>
>> After sending a packet-too-big packet
>>
>> ip -6 route list table local
>> local ::1 dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80::1 dev lo metric 0 expires _597_ //It has expire value
>
> Is this route still present after the expiration time is elapsed?
>
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:2 dev lo metric 0
>> local fe80::5054:ff:fe12:3456 dev lo metric 0
>>
>> When time is up, I can't ping fe80::1 .
>> Is it ok or a bug ?
>
> This looks pretty similar to a bug I discovered recently.
> In my case, a ipv6 host route dissapeared 10 minutes after
> a PMTU event. As a result, this host was not reachable
> anymore.
>
> This happens because we don't clone host routes before
> we use them. If a PMTU event happens, the original route
> is marked with an expire value. After the expiration time
> is elapsed, the original route is deleted and we loose
> conectivity to the host.
>
> I'm currently testing patches to fix this. With these
> patches the ipv6 host routes are cloned if they are
> gateway routes, i.e. if PMTU events can happen.
>
> I fear it will not fix your case because PMTU events are
> not expected to happen at local fe80 routes.
I found current kernel will do ip6_update_pmtu() anyway after
receiving an ICMPV6_PKT_TOOBIG type packet in icmpv6_err().
Does it need some more condition ? Like this:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index a5e95199585e..7c0a28add109 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -89,8 +89,10 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
/* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
struct net *net = dev_net(skb->dev);
+ const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
- if (type == ICMPV6_PKT_TOOBIG)
+ if (type == ICMPV6_PKT_TOOBIG &&
+ !(ipv6_addr_type(&iph->daddr) & IPV6_ADDR_LINKLOCAL))
ip6_update_pmtu(skb, net, info, 0, 0);
else if (type == NDISC_REDIRECT)
ip6_redirect(skb, net, skb->dev->ifindex, 0);
Regards,
Yang
^ permalink raw reply related
* RE: [PATCHv3 ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: David Laight @ 2015-01-28 9:53 UTC (permalink / raw)
To: 'David Miller'
Cc: fan.du@intel.com, steffen.klassert@secunet.com,
herbert@gondor.apana.org.au, netdev@vger.kernel.org,
fengyuleidian0615@gmail.com
In-Reply-To: <20150127.112406.159033030097516231.davem@davemloft.net>
From: David Miller
> From: David Laight <David.Laight@ACULAB.COM>
> Date: Tue, 27 Jan 2015 09:46:21 +0000
>
> > From: Fan Du
> >> structure like xfrm_usersa_info or xfrm_userpolicy_info
> >> has different sizeof when compiled as 32bits and 64bits
> >> due to not appending pack attribute in their definition.
> >
> > Don't 'pack' the structure, just ensure that all the fields
> > are fixed sized and on their natural boundary.
>
> This horse went out of the door more than a decade ago, we can't
> change the layout of any of these structures and must at some point
> add code to translate instead.
>From the other mail it might just be tail-padding.
So any adaption code is easy.
David
^ permalink raw reply
* Re: [Patch iproute2] skbedit: print action too
From: Dennis Chen @ 2015-01-29 3:49 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, Jamal Hadi Salim, Stephen Hemminger
In-Reply-To: <1422485562-15572-1-git-send-email-xiyou.wangcong@gmail.com>
On Thu, Jan 29, 2015 at 6:52 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
> ---
> tc/m_skbedit.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
> index 36323a9..c5deee0 100644
> --- a/tc/m_skbedit.c
> +++ b/tc/m_skbedit.c
> @@ -193,7 +193,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
> fprintf(f, " mark %d", *mark);
> }
>
> - fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
> + fprintf(f, " %s\n\t index %d ref %d bind %d", action_n2a(p->action, b1, sizeof (b1)), p->index, p->refcnt, p->bindcnt);
>
> if (show_stats) {
> if (tb[TCA_SKBEDIT_TM]) {
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello cong, seems no big benifit I can see for the patch...
--
Den
^ permalink raw reply
* Re: [Patch iproute2] skbedit: print action too
From: Cong Wang @ 2015-01-29 3:51 UTC (permalink / raw)
To: Dennis Chen; +Cc: netdev, Jamal Hadi Salim, Stephen Hemminger
In-Reply-To: <CA+U0gViQrppOQXsKwDHWOF5oWs61j6Hbck5o2LnMXMectm64xw@mail.gmail.com>
On Wed, Jan 28, 2015 at 7:49 PM, Dennis Chen <kernel.org.gnu@gmail.com> wrote:
>
> Hello cong, seems no big benifit I can see for the patch...
>
You need to understand skbedit action.
^ permalink raw reply
* [PATCH net-next] pkt_sched: fq: remove useless TIME_WAIT check
From: Eric Dumazet @ 2015-01-28 14:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
TIME_WAIT sockets are not owning any skb.
ip_send_unicast_reply() and tcp_v6_send_response() both use
regular sockets.
We can safely remove a test in sch_fq and save one cache line miss,
as sk_state is far away from sk_pacing_rate.
Tested at Google for about one year.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_fq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 9b05924cc386ecc2cdb9816be27e439637fb37b3..2a50f5c62070a81ae37d871aac2626555128fd38 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -1,7 +1,7 @@
/*
* net/sched/sch_fq.c Fair Queue Packet Scheduler (per flow pacing)
*
- * Copyright (C) 2013 Eric Dumazet <edumazet@google.com>
+ * Copyright (C) 2013-2015 Eric Dumazet <edumazet@google.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -471,7 +471,7 @@ begin:
goto out;
rate = q->flow_max_rate;
- if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT)
+ if (skb->sk)
rate = min(skb->sk->sk_pacing_rate, rate);
if (rate != ~0U) {
^ permalink raw reply related
* [PATCH] net: ipv6: Make address flushing on ifdown optional - v2
From: David Ahern @ 2015-01-29 4:01 UTC (permalink / raw)
To: netdev; +Cc: David Ahern, Hannes Frederic Sowa
Currently, all ipv6 addresses are flushed when the interface is configured
down, even static address:
[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global tentative
valid_lft forever preferred_lft forever
[root@f20 ~]# ip link set dev eth1 up
[root@f20 ~]# ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
Add a new sysctl to make this behavior optional. The new setting defaults to
flush all addresses to maintain backwards compatibility. When the setting is
reset static addresses are not flushed:
[root@f20 ~]# echo 0 > /proc/sys/net/ipv6/conf/eth1/flush_addr_on_down
[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global tentative
valid_lft forever preferred_lft forever
[root@f20 ~]# ip link set dev eth1 up
[root@f20 ~]# ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::4:11ff:fe22:3301/64 scope link
valid_lft forever preferred_lft forever
v2:
- only keep static addresses as suggested by Hannes
- added new managed flag to track configured addresses
- on ifdown do not remove from configured address from inet6_addr_lst
- on ifdown reset the TENTATIVE flag and set state to DAD so that DAD is
redone when link is brought up again
Suggested-by: Hannes Frederic Sowa <hannes@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Hannes Frederic Sowa <hannes@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/linux/ipv6.h | 1 +
include/net/if_inet6.h | 1 +
include/uapi/linux/ipv6.h | 1 +
net/ipv6/addrconf.c | 55 ++++++++++++++++++++++++++++++++++++++---------
4 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 2805062c013f..b91b7c8be023 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -53,6 +53,7 @@ struct ipv6_devconf {
__s32 ndisc_notify;
__s32 suppress_frag_ndisc;
__s32 accept_ra_mtu;
+ __s32 flush_addr_on_down;
void *sysctl;
};
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 98e5f9578f86..3b6323111f77 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -72,6 +72,7 @@ struct inet6_ifaddr {
int regen_count;
bool tokenized;
+ bool managed;
struct rcu_head rcu;
struct in6_addr peer_addr;
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 437a6a4b125a..ed10d4ba8340 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -170,6 +170,7 @@ enum {
DEVCONF_ACCEPT_RA_FROM_LOCAL,
DEVCONF_USE_OPTIMISTIC,
DEVCONF_ACCEPT_RA_MTU,
+ DEVCONF_FLUSH_ON_DOWN,
DEVCONF_MAX
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7dcc065e2160..e0e82aad2116 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.accept_dad = 1,
.suppress_frag_ndisc = 1,
.accept_ra_mtu = 1,
+ .flush_addr_on_down = 1,
};
static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -240,6 +241,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.accept_dad = 1,
.suppress_frag_ndisc = 1,
.accept_ra_mtu = 1,
+ .flush_addr_on_down = 1,
};
/* Check if a valid qdisc is available */
@@ -870,6 +872,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
ifa->prefered_lft = prefered_lft;
ifa->cstamp = ifa->tstamp = jiffies;
ifa->tokenized = false;
+ ifa->managed = false;
ifa->rt = rt;
@@ -2510,6 +2513,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
valid_lft, prefered_lft);
if (!IS_ERR(ifp)) {
+ ifp->managed = true;
+
if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) {
addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
expires, flags);
@@ -3032,8 +3037,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
{
struct net *net = dev_net(dev);
struct inet6_dev *idev;
- struct inet6_ifaddr *ifa;
+ struct inet6_ifaddr *ifa, *tmp;
int state, i;
+ struct list_head del_list;
ASSERT_RTNL();
@@ -3067,9 +3073,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
restart:
hlist_for_each_entry_rcu(ifa, h, addr_lst) {
if (ifa->idev == idev) {
- hlist_del_init_rcu(&ifa->addr_lst);
addrconf_del_dad_work(ifa);
- goto restart;
+ if (how || idev->cnf.flush_addr_on_down ||
+ !ifa->managed) {
+ hlist_del_init_rcu(&ifa->addr_lst);
+ goto restart;
+ }
}
}
spin_unlock_bh(&addrconf_hash_lock);
@@ -3103,14 +3112,35 @@ restart:
write_lock_bh(&idev->lock);
}
- while (!list_empty(&idev->addr_list)) {
- ifa = list_first_entry(&idev->addr_list,
+ INIT_LIST_HEAD(&del_list);
+ list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
+ /*
+ * on NETDEV_DOWN events do not flush managed (user configured)
+ * addresses unless configured to do so. If the address is not
+ * deleted reset flags and state such that DAD is re-done on a
+ * subsequent link up.
+ */
+ if (!how && !idev->cnf.flush_addr_on_down && ifa->managed) {
+ if (!(ifa->flags & IFA_F_NODAD)) {
+ ifa->flags |= IFA_F_TENTATIVE;
+ ifa->state = INET6_IFADDR_STATE_DAD;
+ }
+ } else {
+ list_del(&ifa->if_list);
+ list_add(&ifa->if_list, &del_list);
+ }
+ }
+
+ write_unlock_bh(&idev->lock);
+
+ while (!list_empty(&del_list)) {
+ ifa = list_first_entry(&del_list,
struct inet6_ifaddr, if_list);
+
addrconf_del_dad_work(ifa);
list_del(&ifa->if_list);
- write_unlock_bh(&idev->lock);
spin_lock_bh(&ifa->state_lock);
state = ifa->state;
@@ -3122,12 +3152,8 @@ restart:
inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
}
in6_ifa_put(ifa);
-
- write_lock_bh(&idev->lock);
}
- write_unlock_bh(&idev->lock);
-
/* Step 5: Discard anycast and multicast list */
if (how) {
ipv6_ac_destroy_dev(idev);
@@ -4383,6 +4409,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local;
array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu;
+ array[DEVCONF_FLUSH_ON_DOWN] = cnf->flush_addr_on_down;
}
static inline size_t inet6_ifla6_size(void)
@@ -5269,6 +5296,14 @@ static struct addrconf_sysctl_table
.proc_handler = proc_dointvec,
},
{
+ .procname = "flush_addr_on_down",
+ .data = &ipv6_devconf.flush_addr_on_down,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+
+ },
+ {
/* sentinel */
}
},
--
1.9.3
^ permalink raw reply related
* [PATCH] Repair soft lockup with monitor mode of ath9k_htc card
From: zhengyuwei @ 2015-01-29 4:09 UTC (permalink / raw)
To: linux-kernel, ath9k-devel, linux-wireless, kvalo, ath9k-devel
Cc: netdev, Yuwei Zheng
From: Yuwei Zheng <zhengyuwei@360.cn>
In the environment with heavy wifi traffic, set the ar9271 into monitor mode, will
trigger a deadloop panic.
The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
[59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
[kworker/0:0:30609]
[59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
[59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
[59013.858522] Kernel panic - not syncing: softlockup: hung tasks
[59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
[59014.046834] bc20: de57b950 60000113
[59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
[59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
[59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
[59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
[59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
[59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
[59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
[59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
[59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
[59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
This bug can be see with low performance board, such as uniprocessor beagle bone board.
Signed-off-by: Yuwei Zheng <zhengyuwei@360.cn>
---
drivers/net/wireless/ath/ath9k/hif_usb.c | 53 ++++++++++++++++++++++----
drivers/net/wireless/ath/ath9k/hif_usb.h | 5 +++
drivers/net/wireless/ath/ath9k/htc.h | 13 +++++++
drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 49 ++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 26 +++++++++++++
5 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 8e7153b..febea5e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -658,7 +658,6 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
default:
goto resubmit;
}
-
if (likely(urb->actual_length != 0)) {
skb_put(skb, urb->actual_length);
ath9k_hif_usb_rx_stream(hif_dev, skb);
@@ -667,12 +666,18 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
resubmit:
skb_reset_tail_pointer(skb);
skb_trim(skb, 0);
-
- usb_anchor_urb(urb, &hif_dev->rx_submitted);
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret) {
- usb_unanchor_urb(urb);
- goto free;
+ if (atomic_read(&hif_dev->rx_urb_submit_delay) > 0) {
+ usb_anchor_urb(urb, &hif_dev->rx_delayed_submitted);
+ ret = tasklet_hrtimer_start(&hif_dev->rx_submit_timer,
+ ktime_set(0, atomic_read(&hif_dev->rx_urb_submit_delay)*1000),
+ HRTIMER_MODE_REL);
+ } else {
+ usb_anchor_urb(urb, &hif_dev->rx_submitted);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret) {
+ usb_unanchor_urb(urb);
+ goto free;
+ }
}
return;
@@ -818,9 +823,37 @@ err:
return -ENOMEM;
}
+static enum hrtimer_restart rx_urb_submit_timer_handler(struct hrtimer *me)
+{
+ struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);
+ struct hif_device_usb *hif_dev = container_of(thr, struct hif_device_usb, rx_submit_timer);
+ struct urb *urb = NULL;
+ struct sk_buff *skb = NULL;
+ int ret;
+
+ while (true) {
+ urb = usb_get_from_anchor(&hif_dev->rx_delayed_submitted);
+ if (urb != NULL) {
+ skb = (struct sk_buff *)urb->context;
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret != -EBUSY) {
+ usb_unanchor_urb(urb);
+ dev_kfree_skb_any(skb);
+ urb->context = NULL;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return HRTIMER_NORESTART;
+}
+
static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
{
usb_kill_anchored_urbs(&hif_dev->rx_submitted);
+ usb_kill_anchored_urbs(&hif_dev->rx_delayed_submitted);
+ tasklet_hrtimer_cancel(&hif_dev->rx_submit_timer);
}
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
@@ -830,6 +863,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
int i, ret;
init_usb_anchor(&hif_dev->rx_submitted);
+ init_usb_anchor(&hif_dev->rx_delayed_submitted);
+
spin_lock_init(&hif_dev->rx_lock);
for (i = 0; i < MAX_RX_URB_NUM; i++) {
@@ -871,6 +906,10 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
usb_free_urb(urb);
}
+ /* add for flow control*/
+ atomic_set(&hif_dev->rx_urb_submit_delay, 0);
+ tasklet_hrtimer_init(&hif_dev->rx_submit_timer, rx_urb_submit_timer_handler, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+
return 0;
err_submit:
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 51496e7..56d6be8 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -98,9 +98,14 @@ struct hif_device_usb {
struct hif_usb_tx tx;
struct usb_anchor regout_submitted;
struct usb_anchor rx_submitted;
+ struct usb_anchor rx_delayed_submitted; /* delayed submit anchor */
struct usb_anchor reg_in_submitted;
struct usb_anchor mgmt_submitted;
struct sk_buff *remain_skb;
+
+ struct tasklet_hrtimer rx_submit_timer;/* delayed submit hrtimer */
+ atomic_t rx_urb_submit_delay; /*us*/
+
const char *fw_name;
int rx_remain_len;
int rx_pkt_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 9dde265..453d0a8 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -331,6 +331,10 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+#define TASKLETRX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c++)
+#define TASKLETRX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c += a)
+#define TASKLETRX_STAT_SET(c, a) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c = a)
+
void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
struct ath_rx_status *rs);
@@ -352,11 +356,20 @@ struct ath_skbrx_stats {
u32 skb_dropped;
};
+struct ath_taskletrx_stats {
+ u32 taskletrx_looptimes;
+ u32 taskletrx_highwater;
+ u32 taskletrx_lowwater;
+ u32 taskletrx_watermark_triggered;
+ u32 taskletrx_urb_submit_delay;
+};
+
struct ath9k_debug {
struct dentry *debugfs_phy;
struct ath_tx_stats tx_stats;
struct ath_rx_stats rx_stats;
struct ath_skbrx_stats skbrx_stats;
+ struct ath_taskletrx_stats taskletrx_stats;
};
void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index 8cef1ed..7c8322e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -286,6 +286,51 @@ static const struct file_operations fops_skb_rx = {
.llseek = default_llseek,
};
+static ssize_t read_file_tasklet_rx(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ char *buf;
+ unsigned int len = 0, size = 1500;
+ ssize_t retval = 0;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "Loop times",
+ priv->debug.taskletrx_stats.taskletrx_looptimes);
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "High watermark",
+ priv->debug.taskletrx_stats.taskletrx_highwater);
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "Low watermark",
+ priv->debug.taskletrx_stats.taskletrx_lowwater);
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "WM triggered",
+ priv->debug.taskletrx_stats.taskletrx_watermark_triggered);
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "URB delay",
+ priv->debug.taskletrx_stats.taskletrx_urb_submit_delay);
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static const struct file_operations fops_tasklet_rx = {
+ .read = read_file_tasklet_rx,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
static ssize_t read_file_slot(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -518,7 +563,11 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_skb_rx);
+ debugfs_create_file("tasklet_rx", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_tasklet_rx);
+
ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
+
ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index a0f58e2..f5e6217 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1061,7 +1061,28 @@ void ath9k_rx_tasklet(unsigned long data)
unsigned long flags;
struct ieee80211_hdr *hdr;
+ /* add for adaptive flow control*/
+ int looptimes = 0;
+ int highwatermark = ATH9K_HTC_RXBUF*3/4;
+ int lowwatermark = ATH9K_HTC_RXBUF/4;
+ unsigned int delay = 0;
+
+ struct htc_target *htc = priv->htc;
+ struct hif_device_usb *hif_dev = htc->hif_dev;
+
+ TASKLETRX_STAT_SET(taskletrx_highwater, highwatermark);
+ TASKLETRX_STAT_SET(taskletrx_lowwater, lowwatermark);
+
do {
+ looptimes++;
+ TASKLETRX_STAT_SET(taskletrx_looptimes, looptimes);
+ if (looptimes > highwatermark) {
+ delay = looptimes*10;
+ atomic_set(&hif_dev->rx_urb_submit_delay, delay);
+ TASKLETRX_STAT_INC(taskletrx_watermark_triggered);
+ TASKLETRX_STAT_SET(taskletrx_urb_submit_delay, delay);
+ }
+
spin_lock_irqsave(&priv->rx.rxbuflock, flags);
list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
if (tmp_buf->in_process) {
@@ -1072,6 +1093,11 @@ void ath9k_rx_tasklet(unsigned long data)
if (rxbuf == NULL) {
spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
+ if (looptimes < lowwatermark) {
+ atomic_set(&hif_dev->rx_urb_submit_delay, 0);
+ TASKLETRX_STAT_SET(taskletrx_urb_submit_delay, 0);
+ }
+
break;
}
--
1.9.1
^ permalink raw reply related
* [PATCH net v2] net: ipv6: allow explicitly choosing optimistic addresses
From: Erik Kline @ 2015-01-28 12:03 UTC (permalink / raw)
To: netdev; +Cc: hannes, Erik Kline
RFC 4429 ("Optimistic DAD") states that optimistic addresses
should be treated as deprecated addresses. From section 2.1:
Unless noted otherwise, components of the IPv6 protocol stack
should treat addresses in the Optimistic state equivalently to
those in the Deprecated state, indicating that the address is
available for use but should not be used if another suitable
address is available.
Optimistic addresses are indeed avoided when other addresses are
available (i.e. at source address selection time), but they have
not heretofore been available for things like explicit bind() and
sendmsg() with struct in6_pktinfo, etc.
This change makes optimistic addresses treated more like
deprecated addresses than tentative ones.
Signed-off-by: Erik Kline <ek@google.com>
---
include/net/addrconf.h | 3 +++
net/ipv6/addrconf.c | 13 +++++++++++--
net/ipv6/ndisc.c | 4 +++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index d13573b..80456f7 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -62,6 +62,9 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg);
int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, int strict);
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
+ const struct net_device *dev, int strict,
+ u32 banned_flags);
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f7c8bbe..943da83 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1519,6 +1519,14 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, int strict)
{
+ return ipv6_chk_addr_and_flags(net, addr, dev, strict, IFA_F_TENTATIVE);
+}
+EXPORT_SYMBOL(ipv6_chk_addr);
+
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
+ const struct net_device *dev, int strict,
+ u32 banned_flags)
+{
struct inet6_ifaddr *ifp;
unsigned int hash = inet6_addr_hash(addr);
@@ -1527,7 +1535,8 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
if (!net_eq(dev_net(ifp->idev->dev), net))
continue;
if (ipv6_addr_equal(&ifp->addr, addr) &&
- !(ifp->flags&IFA_F_TENTATIVE) &&
+ (!(ifp->flags&banned_flags) ||
+ ifp->flags&IFA_F_OPTIMISTIC&~banned_flags) &&
(dev == NULL || ifp->idev->dev == dev ||
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
rcu_read_unlock_bh();
@@ -1538,7 +1547,7 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
rcu_read_unlock_bh();
return 0;
}
-EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
struct net_device *dev)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 6828667..113fc6c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -655,7 +655,9 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
int probes = atomic_read(&neigh->probes);
- if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
+ if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
+ dev, 1,
+ IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
saddr = &ipv6_hdr(skb)->saddr;
probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
if (probes < 0) {
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [PATCH v2 linux-trace 4/8] samples: bpf: simple tracing example in C
From: Alexei Starovoitov @ 2015-01-29 4:19 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim, Jiri Olsa,
Masami Hiramatsu, Linux API, Network Development, LKML
On Wed, Jan 28, 2015 at 12:44 PM, Arnaldo Carvalho de Melo
<acme-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
>> > #define memcmp(s1, s2, n) bpf_memcmp(s1, s2, n)
>
>> >> in bpf_helpers.h to have it work?
>
>> yes, that will work just fine.
>> Since it's an example I made it explicit that bpf_memcmp()
>> has memcmp() semantics, but little bit different:
>> int bpf_memcmp(void *unsafe_ptr, void *safe_ptr, int size)
>
> Not knowing about the safe/unsafe pointers (at this point in my
> conceptual eBPF learning process), I would think that it would be easier
> to understand if it would reuse another well known idiom:
>
> #define memcmp_from_user(kernel, user, n) bpf_memcmp(user, kernel, n)
that actually won't be right. It's not reading from user.
'unsafe' means that pointer is not known to be safe
within the program. So far, bpf verifier recognizes pointer
to context, stack and maps. Everything else is unsafe.
Therefore all pointer walking of unknown data structures
need to use bpf_fetch_*() helpers to access memory.
Similarly bpf_memcmp() is used to do memcmp() of
two memory regions: one known to be safe and one
unknown.
> I don't reuse anything I've learned before trying to understand eBPF,
> not I see any well known marker (__user) that would help me understand
> that that pointer needs special treatment/belongs to a different "domain".
I tried to do exactly that actually :)
bpf_fetch_*() helpers suppose to match existing fetch*()
primitives used to do the same pointer walking for kprobes.
Maybe bpf_probe_memcmp() would be a better name?
Hard to tell.
>> bpf_fetch_*() helpers are also explicit in examples.
>> If one need to do a lot of pointer walking, then macro like
>> #define D(P) ((typeof(P))bpf_fetch_ptr(&P))
>> would be easier to use: p = D(D(skb->dev)->ifalias)
>> multiple pointer derefs would look more natural...
>
> And if possible, i.e. if the eBPF compiler would take care of that
> somehow, would indeed be preferred as it looks more natural :-)
yes, on the user space side we have all the freedom.
Note, these examples are using user's bpf_helpers.h
which defines it as:
static int (*bpf_memcmp)(void *unsafe_ptr, void *safe_ptr, int size) =
(void *) BPF_FUNC_memcmp;
so whether we want to call the function bpf_memcmp() or
bpf_probe_memcmp() is up to user space.
The BPF_FUNC_memcmp name is what matters which
is defined in uapi/linux/bpf.h
I'll try to come up with more explicit name...
^ 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