* [PATCH net-next 1/1] forcedeth: remove unnecessary variable
From: Zhu Yanjun @ 2017-12-07 4:15 UTC (permalink / raw)
To: netdev, keescook
Since both tx_ring and first_tx are the head of tx ring, it not
necessary to use two variables. So first_tx is removed.
CC: Srinivas Eeda <srinivas.eeda@oracle.com>
CC: Joe Jin <joe.jin@oracle.com>
CC: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 53614ed..cadea67 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -822,7 +822,7 @@ struct fe_priv {
/*
* tx specific fields.
*/
- union ring_type get_tx, put_tx, first_tx, last_tx;
+ union ring_type get_tx, put_tx, last_tx;
struct nv_skb_map *get_tx_ctx, *put_tx_ctx;
struct nv_skb_map *first_tx_ctx, *last_tx_ctx;
struct nv_skb_map *tx_skb;
@@ -1932,7 +1932,8 @@ static void nv_init_tx(struct net_device *dev)
struct fe_priv *np = netdev_priv(dev);
int i;
- np->get_tx = np->put_tx = np->first_tx = np->tx_ring;
+ np->get_tx = np->tx_ring;
+ np->put_tx = np->tx_ring;
if (!nv_optimized(np))
np->last_tx.orig = &np->tx_ring.orig[np->tx_ring_size-1];
@@ -2248,7 +2249,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
offset += bcnt;
size -= bcnt;
if (unlikely(put_tx++ == np->last_tx.orig))
- put_tx = np->first_tx.orig;
+ put_tx = np->tx_ring.orig;
if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
@@ -2294,13 +2295,13 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
offset += bcnt;
frag_size -= bcnt;
if (unlikely(put_tx++ == np->last_tx.orig))
- put_tx = np->first_tx.orig;
+ put_tx = np->tx_ring.orig;
if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (frag_size);
}
- if (unlikely(put_tx == np->first_tx.orig))
+ if (unlikely(put_tx == np->tx_ring.orig))
prev_tx = np->last_tx.orig;
else
prev_tx = put_tx - 1;
@@ -2406,7 +2407,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
offset += bcnt;
size -= bcnt;
if (unlikely(put_tx++ == np->last_tx.ex))
- put_tx = np->first_tx.ex;
+ put_tx = np->tx_ring.ex;
if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
@@ -2452,13 +2453,13 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
offset += bcnt;
frag_size -= bcnt;
if (unlikely(put_tx++ == np->last_tx.ex))
- put_tx = np->first_tx.ex;
+ put_tx = np->tx_ring.ex;
if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (frag_size);
}
- if (unlikely(put_tx == np->first_tx.ex))
+ if (unlikely(put_tx == np->tx_ring.ex))
prev_tx = np->last_tx.ex;
else
prev_tx = put_tx - 1;
@@ -2597,7 +2598,7 @@ static int nv_tx_done(struct net_device *dev, int limit)
}
}
if (unlikely(np->get_tx.orig++ == np->last_tx.orig))
- np->get_tx.orig = np->first_tx.orig;
+ np->get_tx.orig = np->tx_ring.orig;
if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx))
np->get_tx_ctx = np->first_tx_ctx;
}
@@ -2651,7 +2652,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
}
if (unlikely(np->get_tx.ex++ == np->last_tx.ex))
- np->get_tx.ex = np->first_tx.ex;
+ np->get_tx.ex = np->tx_ring.ex;
if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx))
np->get_tx_ctx = np->first_tx_ctx;
}
--
2.7.4
^ permalink raw reply related
* RE: [PATCH net-next] netdevsim: check return value of debugfs_create_dir
From: Prashant Bhole @ 2017-12-07 4:10 UTC (permalink / raw)
To: 'Jakub Kicinski'; +Cc: 'David S . Miller', netdev
In-Reply-To: <20171206183341.00175b36@cakuba.netronome.com>
> From: Jakub Kicinski [mailto:jakub.kicinski@netronome.com]
>
> On Thu, 7 Dec 2017 10:02:13 +0900, Prashant Bhole wrote:
> > - Handled debugfs_create_dir failure in nsim_init()
> > - Fixed return value of nsim_module_init() when debugfs_create_dir
> > fails
> >
> > Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
>
> Why? Failing to expose the state via DebugFS is not fatal to the driver.
Ok, my intention was to handle the return code properly, which is not needed
as per your comment.
Shall I remove the existing handling in nsim_module_init() in separate
patch? Because it will prevent netdevsim from loading when debugfs is
disabled.
Thanks,
Prashant
^ permalink raw reply
* [PATCH v2 net] netlink: Relax attr validation for fixed length types
From: David Ahern @ 2017-12-07 4:09 UTC (permalink / raw)
To: netdev; +Cc: johannes, David Ahern
Commit 28033ae4e0f5 ("net: netlink: Update attr validation to require
exact length for some types") requires attributes using types NLA_U* and
NLA_S* to have an exact length. This change is exposing bugs in various
userspace commands that are sending attributes with an invalid length
(e.g., attribute has type NLA_U8 and userspace sends NLA_U32). While
the commands are clearly broken and need to be fixed, users are arguing
that the sudden change in enforcement is breaking older commands on
newer kernels for use cases that otherwise "worked".
Relax the validation to print a warning mesage similar to what is done
for messages containing extra bytes after parsing.
Fixes: 28033ae4e0f5 ("net: netlink: Update attr validation to require exact length for some types")
Signed-off-by: David Ahern <dsahern@gmail.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
v2
- updated the comment before nla_attr_len and removed the outdated
comment before use of nla_attr_len
lib/nlattr.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 8bf78b4b78f0..dfa55c873c13 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -15,7 +15,11 @@
#include <linux/types.h>
#include <net/netlink.h>
-/* for these data types attribute length must be exactly given size */
+/* For these data types, attribute length should be exactly the given
+ * size. However, to maintain compatibility with broken commands, if the
+ * attribute length does not match the expected size a warning is emitted
+ * to the user that the command is sending invalid data and needs to be fixed.
+ */
static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {
[NLA_U8] = sizeof(u8),
[NLA_U16] = sizeof(u16),
@@ -28,8 +32,16 @@ static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {
};
static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
+ [NLA_U8] = sizeof(u8),
+ [NLA_U16] = sizeof(u16),
+ [NLA_U32] = sizeof(u32),
+ [NLA_U64] = sizeof(u64),
[NLA_MSECS] = sizeof(u64),
[NLA_NESTED] = NLA_HDRLEN,
+ [NLA_S8] = sizeof(s8),
+ [NLA_S16] = sizeof(s16),
+ [NLA_S32] = sizeof(s32),
+ [NLA_S64] = sizeof(s64),
};
static int validate_nla_bitfield32(const struct nlattr *nla,
@@ -69,11 +81,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
BUG_ON(pt->type > NLA_TYPE_MAX);
- /* for data types NLA_U* and NLA_S* require exact length */
- if (nla_attr_len[pt->type]) {
- if (attrlen != nla_attr_len[pt->type])
- return -ERANGE;
- return 0;
+ if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) {
+ pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",
+ current->comm, type);
}
switch (pt->type) {
--
2.11.0
^ permalink raw reply related
* RE: [PATCH 2/2] net: fec: optimize IRQ handler
From: Andy Duan @ 2017-12-07 3:02 UTC (permalink / raw)
To: Lucas Stach, netdev@vger.kernel.org
Cc: patchwork-lst@pengutronix.de, kernel@pengutronix.de
In-Reply-To: <20171206172459.14059-2-l.stach@pengutronix.de>
From: Lucas Stach <l.stach@pengutronix.de> Sent: Thursday, December 07, 2017 1:25 AM
>fep->work_rx and fep->work_tx are both non-zero, as long as the NAPI
>softirq hasn't finished its work. So if the current IRQ does not signal any RX or
>TX completion, but some unrelated event, the path to schedule the NAPI
>context is still entered.
>
>The handler works correctly as in this case napi_schedule_prep() will reject
>the scheduling attempt, but the flow can still be optimized by not trying to
>schedule if the IRQ doesn't signal RX or TX completion.
>
>Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
>---
> drivers/net/ethernet/freescale/fec_main.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ethernet/freescale/fec_main.c
>b/drivers/net/ethernet/freescale/fec_main.c
>index 0b70c07eb703..2043e140e9bd 100644
>--- a/drivers/net/ethernet/freescale/fec_main.c
>+++ b/drivers/net/ethernet/freescale/fec_main.c
>@@ -1587,14 +1587,14 @@ fec_enet_interrupt(int irq, void *dev_id)
> int_events = readl_relaxed(fep->hwp + FEC_IEVENT) &
> readl_relaxed(fep->hwp + FEC_IMASK);
> writel(int_events, fep->hwp + FEC_IEVENT);
>- fec_enet_collect_events(fep, int_events);
>
>- if ((fep->work_tx || fep->work_rx) && fep->link) {
>+ if ((int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) && fep->link) {
> ret = IRQ_HANDLED;
>
> if (napi_schedule_prep(&fep->napi)) {
> /* Disable the NAPI interrupts */
> writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
>+ fec_enet_collect_events(fep, int_events);
> __napi_schedule(&fep->napi);
> }
> }
>--
>2.11.0
The patch seems fine, and patch#1 is better to cache imask as David's comment.
Thanks.
Acked-by: Fugang Duan <fugang.duan@nxp.com>
^ permalink raw reply
* Re: [PATCH net-next] netdevsim: check return value of debugfs_create_dir
From: Jakub Kicinski @ 2017-12-07 2:33 UTC (permalink / raw)
To: Prashant Bhole; +Cc: David S . Miller, netdev
In-Reply-To: <20171207010213.4792-1-bhole_prashant_q7@lab.ntt.co.jp>
On Thu, 7 Dec 2017 10:02:13 +0900, Prashant Bhole wrote:
> - Handled debugfs_create_dir failure in nsim_init()
> - Fixed return value of nsim_module_init() when debugfs_create_dir fails
>
> Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Why? Failing to expose the state via DebugFS is not fatal to the
driver.
^ permalink raw reply
* Re: [PATCH net v2] adding missing rcu_read_unlock in ipxip6_rcv
From: Alexei Starovoitov @ 2017-12-07 1:54 UTC (permalink / raw)
To: Nikita V. Shirokov
Cc: netdev, ast, vnuorval, Daniel Borkmann, David S. Miller
In-Reply-To: <20171207011543.2877447-1-tehnerd@fb.com>
On Wed, Dec 06, 2017 at 05:15:43PM -0800, Nikita V. Shirokov wrote:
> commit 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
> introduced new exit point in ipxip6_rcv. however rcu_read_unlock is
> missing there. this diff is fixing this
>
> v1->v2:
> instead of doing rcu_read_unlock in place, we are going to "drop"
> section (to prevent skb leakage)
>
> Signed-off-by: Nikita V. Shirokov <tehnerd@fb.com>
thanks for fixing my mess.
Fixes: 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
Acked-by: Alexei Starovoitov <ast@kernel.org>
^ permalink raw reply
* Re: [PATCH net 1/2] bpf/verifier: fix bounds calculation on BPF_RSH
From: Alexei Starovoitov @ 2017-12-07 1:47 UTC (permalink / raw)
To: Edward Cree; +Cc: davem, netdev, Jann Horn, Alexei Starovoitov, Daniel Borkmann
In-Reply-To: <20171205194413.opdsw3muh2b7ujw5@ast-mbp.dhcp.thefacebook.com>
On Tue, Dec 05, 2017 at 11:44:14AM -0800, Alexei Starovoitov wrote:
> On Tue, Dec 05, 2017 at 07:15:18PM +0000, Edward Cree wrote:
> > Incorrect signed bounds were being computed, although this had no effect
> > since the propagation in __reg_deduce_bounds() happened to overwrite them.
> >
> > Fixes: b03c9f9fdc37 ("bpf/verifier: track signed and unsigned min/max values")
> > Reported-by: Jann Horn <jannh@google.com>
> > Signed-off-by: Edward Cree <ecree@solarflare.com>
>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
turned out this one is incomplete fix. The more complete set
from Jann and Ed will be coming.
^ permalink raw reply
* [PATCH net v2] adding missing rcu_read_unlock in ipxip6_rcv
From: Nikita V. Shirokov @ 2017-12-07 1:15 UTC (permalink / raw)
To: netdev; +Cc: ast, vnuorval, Nikita V. Shirokov
commit 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
introduced new exit point in ipxip6_rcv. however rcu_read_unlock is
missing there. this diff is fixing this
v1->v2:
instead of doing rcu_read_unlock in place, we are going to "drop"
section (to prevent skb leakage)
Signed-off-by: Nikita V. Shirokov <tehnerd@fb.com>
---
net/ipv6/ip6_tunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3d3092a..db84f52 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -904,7 +904,7 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
if (t->parms.collect_md) {
tun_dst = ipv6_tun_rx_dst(skb, 0, 0, 0);
if (!tun_dst)
- return 0;
+ goto drop;
}
ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate,
log_ecn_error);
--
2.9.5
^ permalink raw reply related
* [PATCH net-next] netdevsim: check return value of debugfs_create_dir
From: Prashant Bhole @ 2017-12-07 1:02 UTC (permalink / raw)
To: David S . Miller; +Cc: Prashant Bhole, netdev, Jakub Kicinski
- Handled debugfs_create_dir failure in nsim_init()
- Fixed return value of nsim_module_init() when debugfs_create_dir fails
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
---
drivers/net/netdevsim/netdev.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index eb8c679fca9f..6c4e08f46bcb 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -147,10 +147,15 @@ struct device_type nsim_dev_type = {
static int nsim_init(struct net_device *dev)
{
struct netdevsim *ns = netdev_priv(dev);
- int err;
+ int err = -ENOMEM;
ns->netdev = dev;
ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir);
+ if (IS_ERR_OR_NULL(ns->ddir)) {
+ if (ns->ddir)
+ err = PTR_ERR(ns->ddir);
+ goto err;
+ }
err = nsim_bpf_init(ns);
if (err)
@@ -171,6 +176,7 @@ static int nsim_init(struct net_device *dev)
nsim_bpf_uninit(ns);
err_debugfs_destroy:
debugfs_remove_recursive(ns->ddir);
+err:
return err;
}
@@ -466,11 +472,14 @@ struct dentry *nsim_ddir;
static int __init nsim_module_init(void)
{
- int err;
+ int err = -ENOMEM;
nsim_ddir = debugfs_create_dir(DRV_NAME, NULL);
- if (IS_ERR(nsim_ddir))
- return PTR_ERR(nsim_ddir);
+ if (IS_ERR_OR_NULL(nsim_ddir)) {
+ if (nsim_ddir)
+ err = PTR_ERR(nsim_ddir);
+ goto err;
+ }
err = bus_register(&nsim_bus);
if (err)
@@ -486,6 +495,7 @@ static int __init nsim_module_init(void)
bus_unregister(&nsim_bus);
err_debugfs_destroy:
debugfs_remove_recursive(nsim_ddir);
+err:
return err;
}
--
2.13.6
^ permalink raw reply related
* Re: [PATCH net] adding missing rcu_read_unlock in ipxip6_rcv
From: Nikita Shirokov @ 2017-12-07 0:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org, ast@kernel.org, vnuorval@tcs.hut.fi
In-Reply-To: <20171206.155005.2230253778373071462.davem@davemloft.net>
On 12/6/17, 12:50 PM, "David Miller" <davem@davemloft.net> wrote:
From: "Nikita V. Shirokov" <tehnerd@fb.com>
Date: Wed, 6 Dec 2017 10:19:33 -0800
> commit 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
> introduced new exit point in ipxip6_rcv. however rcu_read_unlock is
> missing there. this diff is fixing this
>
> Signed-off-by: Nikita V. Shirokov <tehnerd@fb.com>
...
> @@ -903,8 +903,10 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
> goto drop;
> if (t->parms.collect_md) {
> tun_dst = ipv6_tun_rx_dst(skb, 0, 0, 0);
> - if (!tun_dst)
> + if (!tun_dst) {
> + rcu_read_unlock();
> return 0;
> + }
> }
> ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate,
> log_ecn_error);
Shouldn't it branch to 'drop' otherwise we leak the skb?
Fair point, will rework.
--
Nikita
^ permalink raw reply
* Re: [PATCH net-next] bridge: ebtables: Avoid resetting limit rule state
From: Pablo Neira Ayuso @ 2017-12-07 0:26 UTC (permalink / raw)
To: Linus Lüssing
Cc: netdev, bridge, Florian Westphal, linux-kernel, coreteam,
netfilter-devel, Jozsef Kadlecsik, David S . Miller
In-Reply-To: <20171204045335.GE3307@otheros>
Hi Linus,
On Mon, Dec 04, 2017 at 05:53:35AM +0100, Linus Lüssing wrote:
> Hi Pablo,
>
> Thanks for your reply!
>
> On Tue, Nov 28, 2017 at 12:30:08AM +0100, Pablo Neira Ayuso wrote:
> > [...]
> > > diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
> > > index 61a9f1be1263..f74b48633feb 100644
> > > --- a/net/bridge/netfilter/ebt_limit.c
> > > +++ b/net/bridge/netfilter/ebt_limit.c
> > > @@ -69,6 +69,10 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
> > > {
> > > struct ebt_limit_info *info = par->matchinfo;
> > >
> > > + /* Do not reset state on unrelated table changes */
> > > + if (info->prev)
> > > + return 0;
> >
> > What kernel version are you using? I suspect you don't have this
> > applied?
>
> I'm indeed using a 4.4.102 kernel, as LEDE is still in the process
> of updating to 4.14. So 4.4 with LEDE is where I got the measurement
> results from.
>
> >
> > commit ec23189049651b16dc2ffab35a4371dc1f491aca
> > Author: Willem de Bruijn <willemb@google.com>
> > Date: Mon Jan 2 17:19:46 2017 -0500
> >
> > xtables: extend matches and targets with .usersize
>
> And so, no I do not have this patch. I looked at it now, but it
> does not seem to have any relation with .matchinfo, does it?
>
> I also had a quick look at a 4.15-rc1 kernel in a VM now. I still
> end up in ebt_limit_mt_check() with the variables being reset
> when editing the table somewhere.
My question is if your fix would work with 4.15-rc1.
^ permalink raw reply
* [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal
From: Andrew Lunn @ 2017-12-07 0:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Vivien Didelot, Andrew Lunn
In-Reply-To: <1512605157-6765-1-git-send-email-andrew@lunn.ch>
When removing the interrupt handling code, we should mask the
generation of interrupts. The code however unmasked all
interrupts. This can then cause a new interrupt. We then get into a
deadlock where the interrupt thread is waiting to run, and the code
continues, trying to remove the interrupt handler, which means waiting
for the thread to complete. On a UP machine this deadlocks.
Fix so we really mask interrupts in the hardware. The same error is
made in the error path when install the interrupt handling code.
Fixes: 3460a5770ce9 ("net: dsa: mv88e6xxx: Mask g1 interrupts and free interrupt")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8171055fde7a..70004264f60d 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -339,7 +339,7 @@ static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
u16 mask;
mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
- mask |= GENMASK(chip->g1_irq.nirqs, 0);
+ mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
free_irq(chip->irq, chip);
@@ -395,7 +395,7 @@ static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
return 0;
out_disable:
- mask |= GENMASK(chip->g1_irq.nirqs, 0);
+ mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
out_mapping:
--
2.15.1
^ permalink raw reply related
* [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path
From: Andrew Lunn @ 2017-12-07 0:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Vivien Didelot, Andrew Lunn
In-Reply-To: <1512605157-6765-1-git-send-email-andrew@lunn.ch>
The MDIO busses need to be unregistered before they are freed,
otherwise BUG() is called. Add a call to the unregister code if the
registration fails, since we can have multiple busses, of which some
may correctly register before one fails. This requires moving the code
around a little.
Fixes: a3c53be55c95 ("net: dsa: mv88e6xxx: Support multiple MDIO busses")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 70004264f60d..66d33e97cbc5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2177,6 +2177,19 @@ static const struct of_device_id mv88e6xxx_mdio_external_match[] = {
{ },
};
+static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
+
+{
+ struct mv88e6xxx_mdio_bus *mdio_bus;
+ struct mii_bus *bus;
+
+ list_for_each_entry(mdio_bus, &chip->mdios, list) {
+ bus = mdio_bus->bus;
+
+ mdiobus_unregister(bus);
+ }
+}
+
static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
struct device_node *np)
{
@@ -2201,27 +2214,16 @@ static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
match = of_match_node(mv88e6xxx_mdio_external_match, child);
if (match) {
err = mv88e6xxx_mdio_register(chip, child, true);
- if (err)
+ if (err) {
+ mv88e6xxx_mdios_unregister(chip);
return err;
+ }
}
}
return 0;
}
-static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
-
-{
- struct mv88e6xxx_mdio_bus *mdio_bus;
- struct mii_bus *bus;
-
- list_for_each_entry(mdio_bus, &chip->mdios, list) {
- bus = mdio_bus->bus;
-
- mdiobus_unregister(bus);
- }
-}
-
static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
struct mv88e6xxx_chip *chip = ds->priv;
--
2.15.1
^ permalink raw reply related
* [PATCH net 0/2] mv88e6xxx error patch fixes
From: Andrew Lunn @ 2017-12-07 0:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Vivien Didelot, Andrew Lunn
While trying to bring up a new PHY on a board, i exercised the error
paths a bit, and discovered some bugs. The unwind for interrupt
handling deadlocks, and the MDIO code hits a BUG() when a registered
MDIO device is freed without first being unregistered.
Andrew Lunn (2):
net: dsa: mv88e6xxx: Fix interrupt masking on removal
net: dsa: mv88e6xxx: Unregister MDIO bus on error path
drivers/net/dsa/mv88e6xxx/chip.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
--
2.15.1
^ permalink raw reply
* linux-next: manual merge of the vfs tree with the bpf tree
From: Stephen Rothwell @ 2017-12-07 0:00 UTC (permalink / raw)
To: Al Viro, Daniel Borkmann, Alexei Starovoitov, Networking
Cc: Linux-Next Mailing List, Linux Kernel Mailing List,
Hendrik Brueckner
Hi Al,
Today's linux-next merge of the vfs tree got conflicts in:
arch/alpha/include/uapi/asm/Kbuild
arch/mn10300/include/uapi/asm/Kbuild
arch/score/include/uapi/asm/Kbuild
between commit:
c895f6f703ad ("bpf: correct broken uapi for BPF_PROG_TYPE_PERF_EVENT program type")
from the bpf tree and commit:
d759be8953fe ("switch wrapper poll.h instances to generic-y")
from the vfs tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
I do wonder if those poll.h additions are necessary given that poll.h
is listed in include/uapi/asm-generic/Kbuild.asm ...
--
Cheers,
Stephen Rothwell
diff --cc arch/alpha/include/uapi/asm/Kbuild
index 14a2e9af97e9,574fe90c8b58..000000000000
--- a/arch/alpha/include/uapi/asm/Kbuild
+++ b/arch/alpha/include/uapi/asm/Kbuild
@@@ -1,4 -1,4 +1,5 @@@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+generic-y += bpf_perf_event.h
+ generic-y += poll.h
diff --cc arch/mn10300/include/uapi/asm/Kbuild
index 81271d3af47c,162fbdbb5fd5..000000000000
--- a/arch/mn10300/include/uapi/asm/Kbuild
+++ b/arch/mn10300/include/uapi/asm/Kbuild
@@@ -1,5 -1,5 +1,6 @@@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+generic-y += bpf_perf_event.h
+ generic-y += poll.h
generic-y += siginfo.h
diff --cc arch/score/include/uapi/asm/Kbuild
index 81271d3af47c,162fbdbb5fd5..000000000000
--- a/arch/score/include/uapi/asm/Kbuild
+++ b/arch/score/include/uapi/asm/Kbuild
@@@ -1,5 -1,5 +1,6 @@@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+generic-y += bpf_perf_event.h
+ generic-y += poll.h
generic-y += siginfo.h
^ permalink raw reply
* Re: [PATCHv2 2/2] userns: control capabilities of some user namespaces
From: Serge E. Hallyn @ 2017-12-06 23:59 UTC (permalink / raw)
To: Mahesh Bandewar (महेश बंडेवार)
Cc: Serge E. Hallyn, Mahesh Bandewar, LKML, Netdev, Kernel-hardening,
Linux API, Kees Cook, Eric W . Biederman, Eric Dumazet,
David Miller
In-Reply-To: <CAF2d9jgsSZ6mCE8QwxPpoO7GoO4zeQzNfZuZwM9Gqqdi8uP4fw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Quoting Mahesh Bandewar (महेश बंडेवार) (maheshb-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org):
> On Wed, Nov 29, 2017 at 9:57 AM, Serge E. Hallyn <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> wrote:
> > Quoting Mahesh Bandewar (महेश बंडेवार) (maheshb-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org):
> >> On Tue, Nov 28, 2017 at 3:04 PM, Serge E. Hallyn <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> wrote:
> >> > Quoting Mahesh Bandewar (महेश बंडेवार) (maheshb-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org):
> >> > ...
> >> >> >> diff --git a/security/commoncap.c b/security/commoncap.c
> >> >> >> index fc46f5b85251..89103f16ac37 100644
> >> >> >> --- a/security/commoncap.c
> >> >> >> +++ b/security/commoncap.c
> >> >> >> @@ -73,6 +73,14 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
> >> >> >> {
> >> >> >> struct user_namespace *ns = targ_ns;
> >> >> >>
> >> >> >> + /* If the capability is controlled and user-ns that process
> >> >> >> + * belongs-to is 'controlled' then return EPERM and no need
> >> >> >> + * to check the user-ns hierarchy.
> >> >> >> + */
> >> >> >> + if (is_user_ns_controlled(cred->user_ns) &&
> >> >> >> + is_capability_controlled(cap))
> >> >> >> + return -EPERM;
> >> >> >
> >> >> > I'd be curious to see the performance impact on this on a regular
> >> >> > workload (kernel build?) in a controlled ns.
> >> >> >
> >> >> Should it affect? If at all, it should be +ve since, the recursive
> >> >> user-ns hierarchy lookup is avoided with the above check if the
> >> >> capability is controlled.
> >> >
> >> > Yes but I expect that to be the rare case for normal lxc installs
> >> > (which are of course what I am interested in)
> >> >
> >> >> The additional cost otherwise is this check
> >> >> per cap_capable() call.
> >> >
> >> > And pipeline refetching?
> >> >
> >> > Capability calls also shouldn't be all that frequent, but still I'm
> >> > left wondering...
> >>
> >> Correct, and capability checks are part of the control-path and not
> >> the data-path so shouldn't matter but I guess it doesn't hurt to
> >> find-out the number. Do you have any workload in mind, that we can use
> >> for this test/benchmark?
> >
> > I suppose if you did both (a) a kernel build and (b) a webserve
> > like https://github.com/m3ng9i/ran , being hit for a minute by a
> > heavy load of requests, those two together would be re-assuring.
> >
> Well, I did (a) and (b). Here are the results.
>
> (a0) I used the ubuntu-artful (17.10) vm instance with standard kernel
> to compile the kernel
>
> mahesh@mahesh-vm0-artful:~/Work/Linux$ time make -j4 -s clean
> mahesh@mahesh-vm0-artful:~/Work/Linux$ time make -j4 -s
> real 6m47.525s
> user 22m37.424s
> sys 2m44.745s
>
> (b0) Now in an user-namespce create by an user that does not have
> SYS_ADMIN (just for apples-to-apples comparison)
> mahesh@mahesh-vm0-artful:~$ sysctl -q kernel.controlled_userns_caps_whitelist
> sysctl: cannot stat /proc/sys/kernel/controlled_userns_caps_whitelist:
> No such file or directory
> mahesh@mahesh-vm0-artful:~$ id
> uid=1000(mahesh) gid=1000(mahesh)
> groups=1000(mahesh),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare)
> mahesh@mahesh-vm0-artful:~/Work/Linux$ unshare -Uf -- bash
> nobody@mahesh-vm0-artful:~/Work/Linux$ id
> uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
> nobody@mahesh-vm0-artful:~/Work/Linux$ time make -j4 -s clean
> nobody@mahesh-vm0-artful:~/Work/Linux$ time make -j4 -s
> real 9m10.115s
Got some serious noise in this run?
But the numbers look good - thanks!
^ permalink raw reply
* Re: [PATCH V11 3/5] printk: hash addresses printed with %p
From: Linus Torvalds @ 2017-12-06 23:28 UTC (permalink / raw)
To: Kees Cook
Cc: David Laight, David Miller, geert@linux-m68k.org, me@tobin.cc,
kernel-hardening@lists.openwall.com, Jason@zx2c4.com,
tytso@mit.edu, pbonzini@redhat.com, tycho@tycho.ws,
william.c.roberts@intel.com, tj@kernel.org,
Golden_Miller83@protonmail.ch, gregkh@linuxfoundation.org,
pmladek@suse.com, joe@perches.com, ijc@hellion.org.uk,
"sergey.senozhatsky@gmail.com" <sergey.seno
In-Reply-To: <CAGXu5jLYQypb=-kf9swRy8F4tSFx_R-urE2tREavOMF-OaXD8g@mail.gmail.com>
On Wed, Dec 6, 2017 at 3:21 PM, Kees Cook <keescook@chromium.org> wrote:
> On Wed, Dec 6, 2017 at 2:31 AM, David Laight <David.Laight@aculab.com> wrote:
>>
>> I can also image issues where you want to know whether 2 pointers point
>> into the same structure (like an skb).
>
> This is already retained due to the hashing. i.e. the same pointer
> value will produce the same hash value, so that kind of direct
> comparison still works.
DavidL isn't talking about the _same_ pointer, he's talking about it
being offset from the same base.
But realistically, I don't think we ever hash things like that anyway.
Things like that do show up in register dumps etc during oopses, but
those aren't hashed.
Linus
^ permalink raw reply
* Re: [PATCH v3 net-next 0/1] net: dsa: microchip: Add Microchip KSZ8795 DSA driver
From: Andrew Lunn @ 2017-12-06 23:25 UTC (permalink / raw)
To: Tristram.Ha
Cc: Florian Fainelli, Pavel Machek, Ruediger Schmitt, muvarov,
nathan.leigh.conrad, vivien.didelot, UNGLinuxDriver, netdev
In-Reply-To: <1512524851-16330-1-git-send-email-Tristram.Ha@microchip.com>
On Tue, Dec 05, 2017 at 05:47:30PM -0800, Tristram.Ha@microchip.com wrote:
> From: Tristram Ha <Tristram.Ha@microchip.com>
>
> This patch requires the previous patches for Microchip KSZ9477 DSA driver.
Please don't submit so many patch sets, which all depend on the
previous one. Wait until they get accepted.
I'm not going to review this or the following patchsets, until the
previous ones are accepted.
Andrew
^ permalink raw reply
* Re: [PATCH v3 net-next] net: dsa: Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers
From: Andrew Lunn @ 2017-12-06 23:23 UTC (permalink / raw)
To: Tristram.Ha
Cc: Florian Fainelli, Pavel Machek, Ruediger Schmitt, muvarov,
nathan.leigh.conrad, vivien.didelot, UNGLinuxDriver, netdev
In-Reply-To: <1512524834-16290-1-git-send-email-Tristram.Ha@microchip.com>
On Tue, Dec 05, 2017 at 05:47:14PM -0800, Tristram.Ha@microchip.com wrote:
> +static int ksz9477_get_tag(u8 *tag, int *port)
> +{
> + *port = tag[0] & 7;
> + return KSZ_EGRESS_TAG_LEN;
> +}
> +
> +static void ksz9477_set_tag(void *ptr, u8 *addr, int p)
> +{
> + u16 *tag = (u16 *)ptr;
> +
> + *tag = 1 << p;
> + *tag = cpu_to_be16(*tag);
> +}
Hi Tristram
It would be more normal to create an ops structure
struct ksz_tag_ops {
int (*get_tag)(u8 *tag, int *port);
void (*set_tag)(void *ptr, u8 *addr, int p)
};
static const struct ksz_tag_ops ksz9477_tag_ops = {
.get_tag = ksz9477_get_tag,
.set_tag = ksz9477_set_tag,
}
and then pass this to the functions.
It might even be possible to make this more generic, use it for other
tag drivers.
Andrew
^ permalink raw reply
* Re: [PATCH V11 3/5] printk: hash addresses printed with %p
From: Kees Cook @ 2017-12-06 23:21 UTC (permalink / raw)
To: David Laight
Cc: David Miller, geert@linux-m68k.org, me@tobin.cc,
kernel-hardening@lists.openwall.com,
torvalds@linux-foundation.org, Jason@zx2c4.com, tytso@mit.edu,
pbonzini@redhat.com, tycho@tycho.ws, william.c.roberts@intel.com,
tj@kernel.org, Golden_Miller83@protonmail.ch,
gregkh@linuxfoundation.org, pmladek@suse.com, joe@perches.com,
ijc@hellion.org.uk, "sergey.senozhatsk
In-Reply-To: <e8dd4332196348df8938a1ad8991dc84@AcuMS.aculab.com>
On Wed, Dec 6, 2017 at 2:31 AM, David Laight <David.Laight@aculab.com> wrote:
> From: David Miller
>> Sent: 05 December 2017 20:31
> ...
>> > Would it make sense to keep the 3 lowest bits of the address?
>> >
>> > Currently printed pointers no longer have any correlation with the actual
>> > alignment in memory of the object, which is a typical cause of a class of bugs.
>>
>> Yeah, this is driving people nuts who wonder why pointers are aligned
>> all weird now.
>
> I can also image issues where you want to know whether 2 pointers point
> into the same structure (like an skb).
This is already retained due to the hashing. i.e. the same pointer
value will produce the same hash value, so that kind of direct
comparison still works.
> Useful if you suspect that code is using a stale pointer because the
> skb got reallocated by some internal function.
> I'm not sure such pointers are printed by default though.
I hope not. :) skb used to be exported for INET_DIAG, but that got
fixed a while back.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply
* Re: [PATCH v3 net-next] net: dsa: microchip: Add MIB counter reading support
From: Andrew Lunn @ 2017-12-06 23:13 UTC (permalink / raw)
To: Tristram.Ha
Cc: Florian Fainelli, Pavel Machek, Ruediger Schmitt, muvarov,
nathan.leigh.conrad, vivien.didelot, UNGLinuxDriver, netdev
In-Reply-To: <1512524828-16250-1-git-send-email-Tristram.Ha@microchip.com>
> + for (i = 0; i < dev->mib_port_cnt; i++) {
> + p = &dev->ports[i];
> + if (!p->on)
> + continue;
> + mib = &p->mib;
> + mutex_lock(&mib->cnt_mutex);
> +
> + /* read only dropped counters when link is not up */
> + if (p->link_down)
> + p->link_down = 0;
> + else if (!p->link_up)
> + mib->cnt_ptr = dev->reg_mib_cnt;
So this is the code you were referring to, when i asked if it can be
up and down at the same time.
I'm having a hard time understand this. Please try to implement this
some other way to make it clear what is going on.
Andrew
^ permalink raw reply
* [PATCH] net: ethernet: arc: fix error handling in emac_rockchip_probe
From: Branislav Radocaj @ 2017-12-06 23:07 UTC (permalink / raw)
To: heiko, netdev
Cc: linux-arm-kernel, linux-rockchip, linux-kernel, Branislav Radocaj
If clk_set_rate() fails, we should disable clk before return.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Branislav Radocaj <branislav@radocaj.org>
---
drivers/net/ethernet/arc/emac_rockchip.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c
index e278e3d96ee0..c6163874e4e7 100644
--- a/drivers/net/ethernet/arc/emac_rockchip.c
+++ b/drivers/net/ethernet/arc/emac_rockchip.c
@@ -220,9 +220,11 @@ static int emac_rockchip_probe(struct platform_device *pdev)
/* RMII TX/RX needs always a rate of 25MHz */
err = clk_set_rate(priv->macclk, 25000000);
- if (err)
+ if (err) {
dev_err(dev,
"failed to change mac clock rate (%d)\n", err);
+ goto out_clk_disable_macclk;
+ }
}
err = arc_emac_probe(ndev, interface);
@@ -232,7 +234,8 @@ static int emac_rockchip_probe(struct platform_device *pdev)
}
return 0;
-
+out_clk_disable_macclk:
+ clk_disable_unprepare(priv->macclk);
out_regulator_disable:
if (priv->regulator)
regulator_disable(priv->regulator);
--
2.11.0
^ permalink raw reply related
* [Patch net-next 2/2] netlink: convert netlink tap spinlock to mutex
From: Cong Wang @ 2017-12-06 23:03 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, Daniel Borkmann
In-Reply-To: <20171206230320.22191-1-xiyou.wangcong@gmail.com>
Both netlink_add_tap() and netlink_remove_tap() are
called in process context, no need to bother spinlock.
Note, in fact, currently we always hold RTNL when calling
these two functions, so we don't need any other lock at
all, but keeping this lock doesn't harm anything.
Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
net/netlink/af_netlink.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index de5324cc98d4..f6e6d2278fa9 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -176,7 +176,7 @@ static unsigned int netlink_tap_net_id;
struct netlink_tap_net {
struct list_head netlink_tap_all;
- spinlock_t netlink_tap_lock;
+ struct mutex netlink_tap_lock;
};
int netlink_add_tap(struct netlink_tap *nt)
@@ -187,9 +187,9 @@ int netlink_add_tap(struct netlink_tap *nt)
if (unlikely(nt->dev->type != ARPHRD_NETLINK))
return -EINVAL;
- spin_lock(&nn->netlink_tap_lock);
+ mutex_lock(&nn->netlink_tap_lock);
list_add_rcu(&nt->list, &nn->netlink_tap_all);
- spin_unlock(&nn->netlink_tap_lock);
+ mutex_unlock(&nn->netlink_tap_lock);
__module_get(nt->module);
@@ -204,7 +204,7 @@ static int __netlink_remove_tap(struct netlink_tap *nt)
bool found = false;
struct netlink_tap *tmp;
- spin_lock(&nn->netlink_tap_lock);
+ mutex_lock(&nn->netlink_tap_lock);
list_for_each_entry(tmp, &nn->netlink_tap_all, list) {
if (nt == tmp) {
@@ -216,7 +216,7 @@ static int __netlink_remove_tap(struct netlink_tap *nt)
pr_warn("__netlink_remove_tap: %p not found\n", nt);
out:
- spin_unlock(&nn->netlink_tap_lock);
+ mutex_unlock(&nn->netlink_tap_lock);
if (found)
module_put(nt->module);
@@ -240,7 +240,7 @@ static __net_init int netlink_tap_init_net(struct net *net)
struct netlink_tap_net *nn = net_generic(net, netlink_tap_net_id);
INIT_LIST_HEAD(&nn->netlink_tap_all);
- spin_lock_init(&nn->netlink_tap_lock);
+ mutex_init(&nn->netlink_tap_lock);
return 0;
}
--
2.13.0
^ permalink raw reply related
* [Patch net-next 1/2] netlink: make netlink tap per netns
From: Cong Wang @ 2017-12-06 23:03 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, Daniel Borkmann, Kevin Cernekee
In-Reply-To: <20171206230320.22191-1-xiyou.wangcong@gmail.com>
nlmon device is not supposed to capture netlink events from
other netns, so instead of filtering events, we can simply
make netlink tap itself per netns.
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Kevin Cernekee <cernekee@chromium.org>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
net/netlink/af_netlink.c | 66 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b9e0ee4e22f5..de5324cc98d4 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -65,6 +65,7 @@
#include <linux/net_namespace.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#include <net/sock.h>
#include <net/scm.h>
#include <net/netlink.h>
@@ -145,8 +146,6 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
static BLOCKING_NOTIFIER_HEAD(netlink_chain);
-static DEFINE_SPINLOCK(netlink_tap_lock);
-static struct list_head netlink_tap_all __read_mostly;
static const struct rhashtable_params netlink_rhashtable_params;
@@ -173,14 +172,24 @@ static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
return new;
}
+static unsigned int netlink_tap_net_id;
+
+struct netlink_tap_net {
+ struct list_head netlink_tap_all;
+ spinlock_t netlink_tap_lock;
+};
+
int netlink_add_tap(struct netlink_tap *nt)
{
+ struct net *net = dev_net(nt->dev);
+ struct netlink_tap_net *nn = net_generic(net, netlink_tap_net_id);
+
if (unlikely(nt->dev->type != ARPHRD_NETLINK))
return -EINVAL;
- spin_lock(&netlink_tap_lock);
- list_add_rcu(&nt->list, &netlink_tap_all);
- spin_unlock(&netlink_tap_lock);
+ spin_lock(&nn->netlink_tap_lock);
+ list_add_rcu(&nt->list, &nn->netlink_tap_all);
+ spin_unlock(&nn->netlink_tap_lock);
__module_get(nt->module);
@@ -190,12 +199,14 @@ EXPORT_SYMBOL_GPL(netlink_add_tap);
static int __netlink_remove_tap(struct netlink_tap *nt)
{
+ struct net *net = dev_net(nt->dev);
+ struct netlink_tap_net *nn = net_generic(net, netlink_tap_net_id);
bool found = false;
struct netlink_tap *tmp;
- spin_lock(&netlink_tap_lock);
+ spin_lock(&nn->netlink_tap_lock);
- list_for_each_entry(tmp, &netlink_tap_all, list) {
+ list_for_each_entry(tmp, &nn->netlink_tap_all, list) {
if (nt == tmp) {
list_del_rcu(&nt->list);
found = true;
@@ -205,7 +216,7 @@ static int __netlink_remove_tap(struct netlink_tap *nt)
pr_warn("__netlink_remove_tap: %p not found\n", nt);
out:
- spin_unlock(&netlink_tap_lock);
+ spin_unlock(&nn->netlink_tap_lock);
if (found)
module_put(nt->module);
@@ -224,6 +235,26 @@ int netlink_remove_tap(struct netlink_tap *nt)
}
EXPORT_SYMBOL_GPL(netlink_remove_tap);
+static __net_init int netlink_tap_init_net(struct net *net)
+{
+ struct netlink_tap_net *nn = net_generic(net, netlink_tap_net_id);
+
+ INIT_LIST_HEAD(&nn->netlink_tap_all);
+ spin_lock_init(&nn->netlink_tap_lock);
+ return 0;
+}
+
+static void __net_exit netlink_tap_exit_net(struct net *net)
+{
+}
+
+static struct pernet_operations netlink_tap_net_ops = {
+ .init = netlink_tap_init_net,
+ .exit = netlink_tap_exit_net,
+ .id = &netlink_tap_net_id,
+ .size = sizeof(struct netlink_tap_net),
+};
+
static bool netlink_filter_tap(const struct sk_buff *skb)
{
struct sock *sk = skb->sk;
@@ -274,7 +305,7 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb,
return ret;
}
-static void __netlink_deliver_tap(struct sk_buff *skb)
+static void __netlink_deliver_tap(struct sk_buff *skb, struct netlink_tap_net *nn)
{
int ret;
struct netlink_tap *tmp;
@@ -282,19 +313,21 @@ static void __netlink_deliver_tap(struct sk_buff *skb)
if (!netlink_filter_tap(skb))
return;
- list_for_each_entry_rcu(tmp, &netlink_tap_all, list) {
+ list_for_each_entry_rcu(tmp, &nn->netlink_tap_all, list) {
ret = __netlink_deliver_tap_skb(skb, tmp->dev);
if (unlikely(ret))
break;
}
}
-static void netlink_deliver_tap(struct sk_buff *skb)
+static void netlink_deliver_tap(struct net *net, struct sk_buff *skb)
{
+ struct netlink_tap_net *nn = net_generic(net, netlink_tap_net_id);
+
rcu_read_lock();
- if (unlikely(!list_empty(&netlink_tap_all)))
- __netlink_deliver_tap(skb);
+ if (unlikely(!list_empty(&nn->netlink_tap_all)))
+ __netlink_deliver_tap(skb, nn);
rcu_read_unlock();
}
@@ -303,7 +336,7 @@ static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src,
struct sk_buff *skb)
{
if (!(netlink_is_kernel(dst) && netlink_is_kernel(src)))
- netlink_deliver_tap(skb);
+ netlink_deliver_tap(sock_net(dst), skb);
}
static void netlink_overrun(struct sock *sk)
@@ -1213,7 +1246,7 @@ static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
{
int len = skb->len;
- netlink_deliver_tap(skb);
+ netlink_deliver_tap(sock_net(sk), skb);
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk);
@@ -2730,12 +2763,11 @@ static int __init netlink_proto_init(void)
}
}
- INIT_LIST_HEAD(&netlink_tap_all);
-
netlink_add_usersock_entry();
sock_register(&netlink_family_ops);
register_pernet_subsys(&netlink_net_ops);
+ register_pernet_subsys(&netlink_tap_net_ops);
/* The netlink device handler may be needed early. */
rtnetlink_init();
out:
--
2.13.0
^ permalink raw reply related
* [Patch net-next 0/2] netlink: improve netlink tap code
From: Cong Wang @ 2017-12-06 23:03 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang
Cong Wang (2):
netlink: make netlink tap per netns
netlink: convert netlink tap spinlock to mutex
net/netlink/af_netlink.c | 66 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 17 deletions(-)
--
2.13.0
^ 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