* Re: [PATCH] wext: handle NULL exta data in iwe_stream_add_point better
From: Johannes Berg @ 2017-01-12 9:16 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-wireless, David S. Miller, Networking, linux-kernel
In-Reply-To: <3292373.oxnXTOSWCQ@wuerfel>
On Wed, 2017-01-11 at 21:39 +0100, Arnd Bergmann wrote:
> On Wednesday, January 11, 2017 4:06:17 PM CET Johannes Berg wrote:
> >
> > Applied. Also fixed the typo in the subject :)
>
> Thanks! Unfortunately I now got another warning for the same
> function, and though I would have expected the patch to fix it, that
> did not work:
>
> In file included from /git/arm-
> soc/drivers/net/wireless/intersil/prism54/islpci_dev.h:27:0,
> from /git/arm-
> soc/drivers/net/wireless/intersil/prism54/isl_ioctl.h:24,
> from /git/arm-
> soc/drivers/net/wireless/intersil/prism54/isl_ioctl.c:32:
> /git/arm-soc/drivers/net/wireless/intersil/prism54/isl_ioctl.c: In
> function 'prism54_get_scan':
> /git/arm-soc/include/net/iw_handler.h:560:4: error: argument 2 null
> where non-null expected [-Werror=nonnull]
> memcpy(stream + point_len, extra, iwe->u.data.length);
And I realized only now that this was a different place ...
I've just added the check you suggested - spent way too much time
already on this old crap :)
johannes
^ permalink raw reply
* Re: [PATCH] wext: handle NULL exta data in iwe_stream_add_point better
From: Johannes Berg @ 2017-01-12 9:13 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-wireless, David S. Miller, Networking, linux-kernel
In-Reply-To: <1484210226.5391.1.camel@sipsolutions.net>
> Come to think of it, I'm thinking I should drop this patch and the
> driver should just use iwe_stream_add_event() instead? It'll be
> somewhat tricky to get the length correct though.
No, turns out that's basically impossible with all the compat etc.
stuff here.
johannes
^ permalink raw reply
* Re: [PATCH/RFC v2 net-next] ravb: unmap descriptors when freeing rings
From: Simon Horman @ 2017-01-12 9:11 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: David Miller, Magnus Damm, netdev, linux-renesas-soc
In-Reply-To: <6fcec500-bed6-ffa3-2887-d45b34703682@cogentembedded.com>
On Fri, Jan 06, 2017 at 10:02:36PM +0300, Sergei Shtylyov wrote:
> Hello!
>
> On 01/05/2017 01:43 PM, Simon Horman wrote:
>
> >From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> >
> >"swiotlb buffer is full" errors occur after repeated initialisation of a
> >device - f.e. suspend/resume or ip link set up/down. This is because memory
> >mapped using dma_map_single() in ravb_ring_format() and ravb_start_xmit()
> >is not released. Resolve this problem by unmapping descriptors when
> >freeing rings.
> >
> >Note, ravb_tx_free() is moved but not otherwise modified by this patch.
> >
> >Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> >[simon: reworked]
> >Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> >--
> >v1 [Kazuya Mizuguchi]
> >
> >v2 [Simon Horman]
> >* As suggested by Sergei Shtylyov
> > - Use dma_mapping_error() and rx_desc->ds_cc when unmapping RX descriptors;
> > this is consistent with the way that they are mapped
> > - Use ravb_tx_free() to clear TX descriptors
>
> Not sure that was good idea (sorry)... ravb_tx_ring() only unmaps the
> transmitted buffers, while we need to unmap everything...
>
> >* Reduce scope of new local variable
> >---
> > drivers/net/ethernet/renesas/ravb_main.c | 89 ++++++++++++++++++--------------
> > 1 file changed, 51 insertions(+), 38 deletions(-)
> >
> >diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> >index 92d7692c840d..1797c48e3176 100644
> >--- a/drivers/net/ethernet/renesas/ravb_main.c
> >+++ b/drivers/net/ethernet/renesas/ravb_main.c
> >@@ -179,6 +179,44 @@ static struct mdiobb_ops bb_ops = {
> > .get_mdio_data = ravb_get_mdio_data,
> > };
> >
> >+/* Free TX skb function for AVB-IP */
> >+static int ravb_tx_free(struct net_device *ndev, int q)
> >+{
> >+ struct ravb_private *priv = netdev_priv(ndev);
> >+ struct net_device_stats *stats = &priv->stats[q];
> >+ struct ravb_tx_desc *desc;
> >+ int free_num = 0;
> >+ int entry;
> >+ u32 size;
> >+
> >+ for (; priv->cur_tx[q] - priv->dirty_tx[q] > 0; priv->dirty_tx[q]++) {
> >+ entry = priv->dirty_tx[q] % (priv->num_tx_ring[q] *
> >+ NUM_TX_DESC);
> >+ desc = &priv->tx_ring[q][entry];
> >+ if (desc->die_dt != DT_FEMPTY)
>
> Here, it stop once an untransmitted buffer is encountered...
Yes, I see that now.
I wonder if we should:
a) paramatise ravb_tx_free() so it may either clear all transmitted buffers
(current behaviour) or all buffers (new behaviour).
b) provide a different version of this loop in ravb_ring_free()
What are your thoughts?
> >+ break;
> >+ /* Descriptor type must be checked before all other reads */
> >+ dma_rmb();
> >+ size = le16_to_cpu(desc->ds_tagl) & TX_DS;
> >+ /* Free the original skb. */
> >+ if (priv->tx_skb[q][entry / NUM_TX_DESC]) {
> >+ dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr),
> >+ size, DMA_TO_DEVICE);
> >+ /* Last packet descriptor? */
> >+ if (entry % NUM_TX_DESC == NUM_TX_DESC - 1) {
> >+ entry /= NUM_TX_DESC;
> >+ dev_kfree_skb_any(priv->tx_skb[q][entry]);
> >+ priv->tx_skb[q][entry] = NULL;
> >+ stats->tx_packets++;
> >+ }
> >+ free_num++;
> >+ }
> >+ stats->tx_bytes += size;
> >+ desc->die_dt = DT_EEMPTY;
> >+ }
> >+ return free_num;
> >+}
> >+
> > /* Free skb's and DMA buffers for Ethernet AVB */
> > static void ravb_ring_free(struct net_device *ndev, int q)
> > {
> >@@ -207,6 +245,18 @@ static void ravb_ring_free(struct net_device *ndev, int q)
> > priv->tx_align[q] = NULL;
> >
> > if (priv->rx_ring[q]) {
> >+ for (i = 0; i < priv->num_rx_ring[q]; i++) {
> >+ struct ravb_ex_rx_desc *rx_desc = &priv->rx_ring[q][i];
> >+
> >+ if (!dma_mapping_error(ndev->dev.parent,
> >+ rx_desc->dptr)) {
>
> You forgot le32_to_cpu() here, we can't use the raw descriptor fields.
Thanks, I will fix that.
> >+ dma_unmap_single(ndev->dev.parent,
> >+ le32_to_cpu(rx_desc->dptr),
> >+ PKT_BUF_SZ,
> >+ DMA_FROM_DEVICE);
> >+ rx_desc->ds_cc = cpu_to_le16(0);
>
> You don't check it anyway, not sure what that buys...
Thanks, I will see about dropping that.
^ permalink raw reply
* Re: [PATCH] [v2] net: qcom/emac: grab a reference to the phydev on ACPI systems
From: Johan Hovold @ 2017-01-12 9:07 UTC (permalink / raw)
To: Timur Tabi; +Cc: David Miller, netdev, johan
In-Reply-To: <1484174751-19036-1-git-send-email-timur@codeaurora.org>
On Wed, Jan 11, 2017 at 04:45:51PM -0600, Timur Tabi wrote:
> Commit 6ffe1c4cd0a7 ("net: qcom/emac: fix of_node and phydev leaks")
> fixed the problem with reference leaks on phydev, but the fix is
> device-tree specific. When the driver unloads, the reference is
> dropped only on DT systems.
>
> Instead, it's cleaner if up grab an reference on ACPI systems.
> When the driver unloads, we can drop the reference without having
> to check whether we're on a DT system.
>
> Signed-off-by: Timur Tabi <timur@codeaurora.org>
Reviewed-by: Johan Hovold <johan@kernel.org>
^ permalink raw reply
* Re: wl1251 & mac address & calibration data
From: Pavel Machek @ 2017-01-12 8:50 UTC (permalink / raw)
To: Kalle Valo
Cc: Arend Van Spriel, Pali Rohár, Daniel Wagner,
Luis R. Rodriguez, Tom Gundersen, Johannes Berg, Ming Lei,
Mimi Zohar, Bjorn Andersson, Rafał Miłecki,
Sebastian Reichel, Michal Kazior, Ivaylo Dimitrov, Aaro Koskinen,
Tony Lindgren, linux-wireless, Network Development,
linux-kernel@vger.kernel.org
In-Reply-To: <87shpiu8j8.fsf@kamboji.qca.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 987 bytes --]
Hi!
> >> But overwriting that one file is not possible as it next update of
> >> linux-firmware package will overwrite it back. It break any normal usage
> >> of package management.
> >>
> >> Also it is ridiculously broken by design if some "boot" files needs to
> >> be overwritten to initialize hardware properly. To not break booting you
> >> need to overwrite that file before first boot. But without booting
> >> device you cannot read calibration data. So some hack with autoreboot
> >> after boot is needed.
>
> Providing the calibration data via Device Tree is the proper way to
> solve this. Yes yes, I know N900 doesn't support it but that's a
> deficiency in N900, not Linux.
Linux has to work with whatever hardware provides. You may not like
N900 design, but we have to support it, anyway.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [Patch net] atm: remove an unnecessary loop
From: Michal Hocko @ 2017-01-12 8:43 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, romieu, 3chas3, andreyknvl
In-Reply-To: <1484197322-958-1-git-send-email-xiyou.wangcong@gmail.com>
On Wed 11-01-17 21:02:01, Cong Wang wrote:
> alloc_tx() is already inside a wait loop for a successful skb
> allocation, this loop inside alloc_tx() is quite unnecessary
> and actually problematic.
I am not familiar with this code at all but vcc_sendmsg seems to be one
of those cases where open coding __GFP_NOFAIL semantic makes sense as
there is an allocation fallback strategy implemented.
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
I cannot give my reviewed-by because I am not familiar with the code but
this looks like an improvement to me.
> ---
> net/atm/common.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/net/atm/common.c b/net/atm/common.c
> index a3ca922..7ec3bbc 100644
> --- a/net/atm/common.c
> +++ b/net/atm/common.c
> @@ -72,10 +72,11 @@ static struct sk_buff *alloc_tx(struct atm_vcc *vcc, unsigned int size)
> sk_wmem_alloc_get(sk), size, sk->sk_sndbuf);
> return NULL;
> }
> - while (!(skb = alloc_skb(size, GFP_KERNEL)))
> - schedule();
> - pr_debug("%d += %d\n", sk_wmem_alloc_get(sk), skb->truesize);
> - atomic_add(skb->truesize, &sk->sk_wmem_alloc);
> + skb = alloc_skb(size, GFP_KERNEL);
> + if (skb) {
> + pr_debug("%d += %d\n", sk_wmem_alloc_get(sk), skb->truesize);
> + atomic_add(skb->truesize, &sk->sk_wmem_alloc);
> + }
> return skb;
> }
>
> --
> 2.5.5
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* [PATCH/RFC net] ravb: Remove Rx overflow log messages
From: Simon Horman @ 2017-01-12 8:41 UTC (permalink / raw)
To: David Miller, Sergei Shtylyov; +Cc: Magnus Damm, netdev, linux-renesas-soc
From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Remove Rx overflow log messages as in an environment where logging results
in network traffic logging may cause further overflows.
Fixes: c156633f1353 ("Renesas Ethernet AVB driver proper")
Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
[simon: reworked changelog]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
drivers/net/ethernet/renesas/ravb_main.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 92d7692c840d..5e5ad978eab9 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -926,14 +926,10 @@ static int ravb_poll(struct napi_struct *napi, int budget)
/* Receive error message handling */
priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors;
priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
- if (priv->rx_over_errors != ndev->stats.rx_over_errors) {
+ if (priv->rx_over_errors != ndev->stats.rx_over_errors)
ndev->stats.rx_over_errors = priv->rx_over_errors;
- netif_err(priv, rx_err, ndev, "Receive Descriptor Empty\n");
- }
- if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors) {
+ if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
ndev->stats.rx_fifo_errors = priv->rx_fifo_errors;
- netif_err(priv, rx_err, ndev, "Receive FIFO Overflow\n");
- }
out:
return budget - quota;
}
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* Re: [PATCH] wext: handle NULL exta data in iwe_stream_add_point better
From: Johannes Berg @ 2017-01-12 8:37 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-wireless, David S. Miller, Networking, linux-kernel
In-Reply-To: <3292373.oxnXTOSWCQ@wuerfel>
On Wed, 2017-01-11 at 21:39 +0100, Arnd Bergmann wrote:
> On Wednesday, January 11, 2017 4:06:17 PM CET Johannes Berg wrote:
> >
> > Applied. Also fixed the typo in the subject :)
>
> Thanks! Unfortunately I now got another warning for the same
> function, and though I would have expected the patch to fix it, that
> did not work:
I've come to expect better of you (i.e. testing your own patches) ;-)
Come to think of it, I'm thinking I should drop this patch and the
driver should just use iwe_stream_add_event() instead? It'll be
somewhat tricky to get the length correct though.
Alternatively, perhaps we should just uninline all the crap and then
the compiler can't bother us :)
johannes
^ permalink raw reply
* Re: [PATCH iproute2 1/3] sr: add header files for SR-IPv6
From: David Lebrun @ 2017-01-12 8:35 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20170110103328.726fc537@xeon-e3>
[-- Attachment #1: Type: text/plain, Size: 441 bytes --]
On 01/10/2017 07:33 PM, Stephen Hemminger wrote:
> I get all headers from santized kernel headers generated by
> $ make headers_install
> but the segmentation stuff is missing.
>
> When you added segment routing headers you forgot to export them.
> Please send a patch to include/uapi/linux/Kbuild, after that is merged
> I will pick them up.
>
> Also this patch is only for net-next.
Oops ! Will do that, thanks
David
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 163 bytes --]
^ permalink raw reply
* Re: [PATCH] [net] net/mlx5e: fix another -Wmaybe-uninitialized warning
From: Or Gerlitz @ 2017-01-12 8:30 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Saeed Mahameed, Hadar Hen Zion, David S . Miller, netdev,
linux-kernel
In-Reply-To: <20170111211451.2705705-1-arnd@arndb.de>
On 1/11/2017 11:14 PM, Arnd Bergmann wrote:
> @@ -666,14 +666,15 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
> struct rtable *rt;
> struct neighbour *n = NULL;
> int ttl;
> + int ret;
> +
> + if (!IS_ENABLED(CONFIG_INET))
> + return -EOPNOTSUPP;
>
> -#if IS_ENABLED(CONFIG_INET)
> rt = ip_route_output_key(dev_net(mirred_dev), fl4);
> - if (IS_ERR(rt))
> - return PTR_ERR(rt);
> -#else
> - return -EOPNOTSUPP;
> -#endif
> + ret = PTR_ERR_OR_ZERO(rt);
> + if (ret)
> + return ret;
but this means that if we got NULL from ip_route_output_key, we will
return success (0) here which is wrong.
^ permalink raw reply
* Re: [PATCH net-next 2/2] bpf: allow b/h/w/dw access for bpf's cb in ctx
From: Quentin Monnet @ 2017-01-12 8:25 UTC (permalink / raw)
To: Daniel Borkmann, davem; +Cc: alexei.starovoitov, netdev
In-Reply-To: <fff467f83e48c6c15053a7637893bf247c9be102.1484182858.git.daniel@iogearbox.net>
Hi Daniel,
2017-01-12 (02:21 +0100) ~ Daniel Borkmann <daniel@iogearbox.net>
> When structs are used to store temporary state in cb[] buffer that is
> used with programs and among tail calls, then the generated code will
> not always access the buffer in bpf_w chunks. We can ease programming
> of it and let this act more natural by allowing for aligned b/h/w/dw
> sized access for cb[] ctx member. Various test cases are attached as
> well for the selftest suite. Potentially, this can also be reused for
> other program types to pass data around.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
> ---
> kernel/bpf/verifier.c | 8 +-
> net/core/filter.c | 41 ++-
> tools/testing/selftests/bpf/test_verifier.c | 442 +++++++++++++++++++++++++++-
> 3 files changed, 478 insertions(+), 13 deletions(-)
>
[...]
> diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
> index 9bb4534..f664bed 100644
> --- a/tools/testing/selftests/bpf/test_verifier.c
> +++ b/tools/testing/selftests/bpf/test_verifier.c
> @@ -859,15 +859,451 @@ struct test_val {
[...]
> + {
> + "check cb access: doulbe, oob 5",
> + .insns = {
> + BPF_MOV64_IMM(BPF_REG_0, 0),
> + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
> + offsetof(struct __sk_buff, cb[4]) + 8),
> + BPF_EXIT_INSN(),
> + },
> + .errstr = "invalid bpf_context access",
> + .result = REJECT,
> + },
Nitpicking: typo ("doulbe").
Regards,
Quentin
^ permalink raw reply
* Re: [PATCH] can: Fix kernel panic at security_sock_rcv_skb
From: Oliver Hartkopp @ 2017-01-12 8:22 UTC (permalink / raw)
To: Liu ShuoX, linux-kernel
Cc: yanmin_zhang, shuox.liu, Zhang Yanmin, He, Bo, Marc Kleine-Budde,
David S. Miller, open list:CAN NETWORK LAYER,
open list:NETWORKING [GENERAL]
In-Reply-To: <1484202799-7287-1-git-send-email-shuo.a.liu@intel.com>
On 01/12/2017 07:33 AM, Liu ShuoX wrote:
> From: Zhang Yanmin <yanmin.zhang@intel.com>
>
> The patch is for fix the below kernel panic:
> BUG: unable to handle kernel NULL pointer dereference at (null)
> IP: [<ffffffff81495e25>] selinux_socket_sock_rcv_skb+0x65/0x2a0
>
> Call Trace:
> <IRQ>
> [<ffffffff81485d8c>] security_sock_rcv_skb+0x4c/0x60
> [<ffffffff81d55771>] sk_filter+0x41/0x210
> [<ffffffff81d12913>] sock_queue_rcv_skb+0x53/0x3a0
> [<ffffffff81f0a2b3>] raw_rcv+0x2a3/0x3c0
> [<ffffffff81f06eab>] can_rcv_filter+0x12b/0x370
> [<ffffffff81f07af9>] can_receive+0xd9/0x120
> [<ffffffff81f07beb>] can_rcv+0xab/0x100
> [<ffffffff81d362ac>] __netif_receive_skb_core+0xd8c/0x11f0
> [<ffffffff81d36734>] __netif_receive_skb+0x24/0xb0
> [<ffffffff81d37f67>] process_backlog+0x127/0x280
> [<ffffffff81d36f7b>] net_rx_action+0x33b/0x4f0
> [<ffffffff810c88d4>] __do_softirq+0x184/0x440
> [<ffffffff81f9e86c>] do_softirq_own_stack+0x1c/0x30
> <EOI>
> [<ffffffff810c76fb>] do_softirq.part.18+0x3b/0x40
> [<ffffffff810c8bed>] do_softirq+0x1d/0x20
> [<ffffffff81d30085>] netif_rx_ni+0xe5/0x110
> [<ffffffff8199cc87>] slcan_receive_buf+0x507/0x520
> [<ffffffff8167ef7c>] flush_to_ldisc+0x21c/0x230
> [<ffffffff810e3baf>] process_one_work+0x24f/0x670
> [<ffffffff810e44ed>] worker_thread+0x9d/0x6f0
> [<ffffffff810e4450>] ? rescuer_thread+0x480/0x480
> [<ffffffff810ebafc>] kthread+0x12c/0x150
> [<ffffffff81f9ccef>] ret_from_fork+0x3f/0x70
>
> The sk dereferenced in panic has been released. After the rcu_call in
> can_rx_unregister, receiver was protected by RCU but inner data was
> not, then later sk will be freed while other CPU is still using it.
> We need wait here to make sure sk referenced via receiver was safe.
>
> => security_sk_free
> => sk_destruct
> => __sk_free
> => sk_free
> => raw_release
> => sock_release
> => sock_close
> => __fput
> => ____fput
> => task_work_run
> => exit_to_usermode_loop
> => syscall_return_slowpath
> => int_ret_from_sys_call
>
> Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
> Signed-off-by: He, Bo <bo.he@intel.com>
> Signed-off-by: Liu Shuo A <shuo.a.liu@intel.com>
> ---
> net/can/af_can.c | 14 ++++++++------
> net/can/af_can.h | 1 -
> 2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index 1108079..fcbe971 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -517,10 +517,8 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
> /*
> * can_rx_delete_receiver - rcu callback for single receiver entry removal
> */
> -static void can_rx_delete_receiver(struct rcu_head *rp)
> +static void can_rx_delete_receiver(struct receiver *r)
> {
> - struct receiver *r = container_of(rp, struct receiver, rcu);
> -
> kmem_cache_free(rcv_cache, r);
> }
>
> @@ -595,9 +593,13 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
> out:
> spin_unlock(&can_rcvlists_lock);
>
> - /* schedule the receiver item for deletion */
> - if (r)
> - call_rcu(&r->rcu, can_rx_delete_receiver);
> + /* synchronize_rcu to wait until a grace period has elapsed, to make
> + * sure all receiver's sk dereferenced by others.
> + */
> + if (r) {
> + synchronize_rcu();
> + can_rx_delete_receiver(r);
Nitpick: When can_rx_delete_receiver() just contains
kmem_cache_free(rcv_cache, r), then the function definition should be
removed.
But my main concern is:
The reason why can_rx_delete_receiver() was introduced was the need to
remove a huge number of receivers with can_rx_unregister().
When you call synchronize_rcu() after each receiver removal this would
potentially lead to a big performance issue when e.g. closing CAN_RAW
sockets with a high number of receivers.
So the idea was to remove/unlink the receiver hlist_del_rcu(&r->list)
and also kmem_cache_free(rcv_cache, r) by some rcu mechanism - so that
all elements are cleaned up by rcu at a later point.
Is it possible that the problems emerge due to hlist_del_rcu(&r->list)
and you accidently fix it with your introduced synchronize_rcu()?
Regards,
Oliver
> + }
> }
> EXPORT_SYMBOL(can_rx_unregister);
>
> diff --git a/net/can/af_can.h b/net/can/af_can.h
> index fca0fe9..a0cbf83 100644
> --- a/net/can/af_can.h
> +++ b/net/can/af_can.h
> @@ -50,7 +50,6 @@
>
> struct receiver {
> struct hlist_node list;
> - struct rcu_head rcu;
> canid_t can_id;
> canid_t mask;
> unsigned long matches;
>
^ permalink raw reply
* [PATCH iproute2/net-next 2/2] tc: flower: Support matching ARP
From: Simon Horman @ 2017-01-12 8:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dinan Gunawardena, netdev, Simon Horman
In-Reply-To: <1484208719-1581-1-git-send-email-simon.horman@netronome.com>
Support matching on ARP operation, and hardware and protocol addresses
for Ethernet hardware and IPv4 protocol addresses.
Example usage:
tc qdisc add dev eth0 ingress
tc filter add dev eth0 protocol arp parent ffff: flower indev eth0 \ arp_op request arp_sip 10.0.0.1 action drop
tc filter add dev eth0 protocol rarp parent ffff: flower indev eth0 \ arp_op reply arp_tha 52:54:3f:00:00:00/24 action drop
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
man/man8/tc-flower.8 | 41 +++++++++-
tc/f_flower.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 232 insertions(+), 17 deletions(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 5904a9ecafdf..2dd2c5e6e4a5 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -34,7 +34,13 @@ flower \- flow based traffic control filter
.BR dst_ip " | " src_ip " } "
.IR PREFIX " | { "
.BR dst_port " | " src_port " } "
-.IR port_number " } | "
+.IR port_number " } | { "
+.BR arp_tip " | " arp_sip " } "
+.IR PREFIX " | "
+.BR arp_op " { " request " | " reply " | "
+.IR OP " } | { "
+.BR arp_tha " | " arp_sha " } "
+.IR MASKED_LLADDR " | "
.B enc_key_id
.IR KEY-ID " | {"
.BR enc_dst_ip " | " enc_src_ip " } { "
@@ -131,6 +137,36 @@ Match on ICMP type or code. Only available for
.BR ip_proto " values " icmp " and " icmpv6
which have to be specified in beforehand.
.TP
+.BI arp_tip " PREFIX"
+.TQ
+.BI arp_sip " PREFIX"
+Match on ARP or RARP sender or target IP address.
+.I PREFIX
+must be a valid IPv4 address optionally followed by a slash and the prefix
+length. If the prefix is missing, \fBtc\fR assumes a full-length host
+match.
+.TP
+.BI arp_op " ARP_OP"
+Match on ARP or RARP operation.
+.I ARP_OP
+may be
+.BR request ", " reply
+or an integer value 0, 1 or 2. A mask may be optionally provided to limit
+the bits of the operation which are matched. A mask is provided by
+following the address with a slash and then the mask. It may be provided as
+an unsigned 8 bit value representing a bitwise mask. If the mask is missing
+then a match on all bits is assumed.
+.TP
+.BI arp_sha " MASKED_LLADDR"
+.TQ
+.BI arp_tha " MASKED_LLADDR"
+Match on ARP or RARP sender or target MAC address. A mask may be optionally
+provided to limit the bits of the address which are matched. A mask is
+provided by following the address with a slash and then the mask. It may be
+provided in LLADDR format, in which case it is a bitwise mask, or as a
+number of high bits to match. If the mask is missing then a match on all
+bits is assumed.
+.TP
.BI enc_key_id " NUMBER"
.TQ
.BI enc_dst_ip " PREFIX"
@@ -152,7 +188,8 @@ As stated above where applicable, matches of a certain layer implicitly depend
on the matches of the next lower layer. Precisely, layer one and two matches
(\fBindev\fR, \fBdst_mac\fR and \fBsrc_mac\fR)
have no dependency, layer three matches
-(\fBip_proto\fR, \fBdst_ip\fR and \fBsrc_ip\fR)
+(\fBip_proto\fR, \fBdst_ip\fR, \fBsrc_ip\fR, \fBarp_tip\fR, \fBarp_sip\fR,
+\fBarp_op\fR, \fBarp_tha\fR and \fBarp_sha\fR)
depend on the
.B protocol
option of tc filter, layer four port matches
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 99f5f8163ee0..d301db36a549 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -15,6 +15,7 @@
#include <syslog.h>
#include <string.h>
#include <net/if.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tc_act/tc_vlan.h>
@@ -54,6 +55,11 @@ static void explain(void)
" src_port PORT-NUMBER |\n"
" type ICMP-TYPE |\n"
" code ICMP-CODE |\n"
+ " arp_tip PREFIX |\n"
+ " arp_sip PREFIX |\n"
+ " arp_op [ request | reply | OP ] |\n"
+ " arp_tha MASKED-LLADDR |\n"
+ " arp_sha MASKED-LLADDR |\n"
" enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" enc_key_id [ KEY-ID ] |\n"
@@ -192,27 +198,16 @@ err:
return -1;
}
-static int flower_parse_ip_addr(char *str, __be16 eth_type,
- int addr4_type, int mask4_type,
- int addr6_type, int mask6_type,
- struct nlmsghdr *n)
+static int __flower_parse_ip_addr(char *str, int family,
+ int addr4_type, int mask4_type,
+ int addr6_type, int mask6_type,
+ struct nlmsghdr *n)
{
int ret;
inet_prefix addr;
- int family;
int bits;
int i;
- if (eth_type == htons(ETH_P_IP)) {
- family = AF_INET;
- } else if (eth_type == htons(ETH_P_IPV6)) {
- family = AF_INET6;
- } else if (!eth_type) {
- family = AF_UNSPEC;
- } else {
- return -1;
- }
-
ret = get_prefix(&addr, str, family);
if (ret)
return -1;
@@ -245,6 +240,89 @@ static int flower_parse_ip_addr(char *str, __be16 eth_type,
return 0;
}
+static int flower_parse_ip_addr(char *str, __be16 eth_type,
+ int addr4_type, int mask4_type,
+ int addr6_type, int mask6_type,
+ struct nlmsghdr *n)
+{
+ int family;
+
+ if (eth_type == htons(ETH_P_IP)) {
+ family = AF_INET;
+ } else if (eth_type == htons(ETH_P_IPV6)) {
+ family = AF_INET6;
+ } else if (!eth_type) {
+ family = AF_UNSPEC;
+ } else {
+ return -1;
+ }
+
+ return __flower_parse_ip_addr(str, family, addr4_type, addr6_type,
+ mask4_type, mask6_type, n);
+}
+
+static bool flower_eth_type_arp(__be16 eth_type)
+{
+ return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP);
+}
+
+static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
+ int addr_type, int mask_type,
+ struct nlmsghdr *n)
+{
+ if (!flower_eth_type_arp(eth_type))
+ return -1;
+
+ return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type,
+ TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
+}
+
+static int flower_parse_arp_op(char *str, __be16 eth_type,
+ int op_type, int mask_type,
+ struct nlmsghdr *n)
+{
+ char *slash;
+ int ret, err = -1;
+ uint8_t value, mask;
+
+ slash = strchr(str, '/');
+ if (slash)
+ *slash = '\0';
+
+ if (!flower_eth_type_arp(eth_type))
+ goto err;
+
+ if (!strcmp(str, "request")) {
+ value = ARPOP_REQUEST;
+ } else if (!strcmp(str, "reply")) {
+ value = ARPOP_REPLY;
+ } else {
+ ret = get_u8(&value, str, 10);
+ if (ret)
+ goto err;
+ if (value && value != ARPOP_REQUEST && value != ARPOP_REPLY)
+ goto err;
+ }
+
+ if (slash) {
+ ret = get_u8(&mask, slash + 1, 10);
+ if (ret)
+ goto err;
+ }
+ else {
+ mask = UINT8_MAX;
+ }
+
+ addattr8(n, MAX_MSG, op_type, value);
+ addattr8(n, MAX_MSG, mask_type, mask);
+
+ err = 0;
+err:
+ if (slash)
+ *slash = '/';
+ return err;
+}
+
static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
enum flower_icmp_field field)
{
@@ -530,6 +608,59 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"icmp code\"\n");
return -1;
}
+ } else if (matches(*argv, "arp_tip") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
+ vlan_ethtype : eth_type,
+ TCA_FLOWER_KEY_ARP_TIP,
+ TCA_FLOWER_KEY_ARP_TIP_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"arp_tip\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "arp_sip") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
+ vlan_ethtype : eth_type,
+ TCA_FLOWER_KEY_ARP_SIP,
+ TCA_FLOWER_KEY_ARP_SIP_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"arp_sip\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "arp_op") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_arp_op(*argv, vlan_ethtype ?
+ vlan_ethtype : eth_type,
+ TCA_FLOWER_KEY_ARP_OP,
+ TCA_FLOWER_KEY_ARP_OP_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"arp_op\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "arp_tha") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_eth_addr(*argv,
+ TCA_FLOWER_KEY_ARP_THA,
+ TCA_FLOWER_KEY_ARP_THA_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"arp_tha\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "arp_sha") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_eth_addr(*argv,
+ TCA_FLOWER_KEY_ARP_SHA,
+ TCA_FLOWER_KEY_ARP_SHA_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"arp_sha\"\n");
+ return -1;
+ }
} else if (matches(*argv, "enc_dst_ip") == 0) {
NEXT_ARG();
ret = flower_parse_ip_addr(*argv, 0,
@@ -662,6 +793,10 @@ static void flower_print_eth_type(FILE *f, __be16 *p_eth_type,
fprintf(f, "ipv4");
else if (eth_type == htons(ETH_P_IPV6))
fprintf(f, "ipv6");
+ else if (eth_type == htons(ETH_P_ARP))
+ fprintf(f, "arp");
+ else if (eth_type == htons(ETH_P_RARP))
+ fprintf(f, "rarp");
else
fprintf(f, "%04x", ntohs(eth_type));
*p_eth_type = eth_type;
@@ -739,6 +874,13 @@ static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
else if (bits < len * 8)
fprintf(f, "/%d", bits);
}
+static void flower_print_ip4_addr(FILE *f, char *name,
+ struct rtattr *addr_attr,
+ struct rtattr *mask_attr)
+{
+ return flower_print_ip_addr(f, name, htons(ETH_P_IP),
+ addr_attr, mask_attr, 0, 0);
+}
static void flower_print_port(FILE *f, char *name, struct rtattr *attr)
{
@@ -759,6 +901,31 @@ static void flower_print_icmp(FILE *f, char *name, struct rtattr *attr)
fprintf(f, "\n %s %d", name, rta_getattr_u8(attr));
}
+static void flower_print_arp_op(FILE *f, char *name,
+ struct rtattr *op_attr,
+ struct rtattr *mask_attr)
+{
+ uint8_t op, mask;
+
+ if (!op_attr)
+ return;
+
+ op = rta_getattr_u8(op_attr);
+ mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
+
+ fprintf(f, "\n %s ", name);
+
+ if (mask == UINT8_MAX && op == ARPOP_REQUEST)
+ fprintf(f, "request");
+ else if (mask == UINT8_MAX && op == ARPOP_REPLY)
+ fprintf(f, "reply");
+ else
+ fprintf(f, "%d", op);
+
+ if (mask != UINT8_MAX)
+ fprintf(f, "/%d", mask);
+}
+
static int flower_print_opt(struct filter_util *qu, FILE *f,
struct rtattr *opt, __u32 handle)
{
@@ -834,6 +1001,17 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
if (nl_type >= 0)
flower_print_icmp(f, "icmp_code", tb[nl_type]);
+ flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
+ tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
+ flower_print_ip4_addr(f, "arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
+ tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
+ flower_print_arp_op(f, "arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
+ tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
+ flower_print_eth_addr(f, "arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
+ tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
+ flower_print_eth_addr(f, "arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
+ tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
+
flower_print_ip_addr(f, "enc_dst_ip",
tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
htons(ETH_P_IP) : htons(ETH_P_IPV6),
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH iproute2/net-next 1/2] tc: flower: update headers for TCA_FLOWER_KEY_ARP*
From: Simon Horman @ 2017-01-12 8:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dinan Gunawardena, netdev, Simon Horman
In-Reply-To: <1484208719-1581-1-git-send-email-simon.horman@netronome.com>
Present in net-next.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
include/linux/pkt_cls.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index a081efbd61a2..1e5e1ddfdaca 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -416,6 +416,17 @@ enum {
TCA_FLOWER_KEY_ICMPV6_TYPE, /* u8 */
TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,/* u8 */
+ TCA_FLOWER_KEY_ARP_SIP, /* be32 */
+ TCA_FLOWER_KEY_ARP_SIP_MASK, /* be32 */
+ TCA_FLOWER_KEY_ARP_TIP, /* be32 */
+ TCA_FLOWER_KEY_ARP_TIP_MASK, /* be32 */
+ TCA_FLOWER_KEY_ARP_OP, /* u8 */
+ TCA_FLOWER_KEY_ARP_OP_MASK, /* u8 */
+ TCA_FLOWER_KEY_ARP_SHA, /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_SHA_MASK, /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_THA, /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_THA_MASK, /* ETH_ALEN */
+
__TCA_FLOWER_MAX,
};
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH iproute2/net-next 0/2] net/sched: cls_flower: Support matching ARP
From: Simon Horman @ 2017-01-12 8:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dinan Gunawardena, netdev, Simon Horman
Add support for support matching on ARP operation, and hardware and
protocol addresses for Ethernet hardware and IPv4 protocol addresses.
Changes since RFC:
* Drop RFC designation; kernel patches are present in net-next
Simon Horman (2):
tc: flower: update headers for TCA_FLOWER_KEY_ARP*
tc: flower: Support matching ARP
include/linux/pkt_cls.h | 11 +++
man/man8/tc-flower.8 | 41 +++++++++-
tc/f_flower.c | 208 ++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 243 insertions(+), 17 deletions(-)
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply
* [patch net 3/3] mlxsw: pci: Fix EQE structure definition
From: Jiri Pirko @ 2017-01-12 8:10 UTC (permalink / raw)
To: netdev; +Cc: davem, arkadis, eladr, yotamg, nogahf, idosch
In-Reply-To: <1484208639-1890-1-git-send-email-jiri@resnulli.us>
From: Elad Raz <eladr@mellanox.com>
The event_data starts from address 0x00-0x0C and not from 0x08-0x014. This
leads to duplication with other fields in the Event Queue Element such as
sub-type, cqn and owner.
Fixes: eda6500a987a0 ("mlxsw: Add PCI bus implementation")
Signed-off-by: Elad Raz <eladr@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index d147ddd..0af3338 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -209,21 +209,21 @@ MLXSW_ITEM32(pci, eqe, owner, 0x0C, 0, 1);
/* pci_eqe_cmd_token
* Command completion event - token
*/
-MLXSW_ITEM32(pci, eqe, cmd_token, 0x08, 16, 16);
+MLXSW_ITEM32(pci, eqe, cmd_token, 0x00, 16, 16);
/* pci_eqe_cmd_status
* Command completion event - status
*/
-MLXSW_ITEM32(pci, eqe, cmd_status, 0x08, 0, 8);
+MLXSW_ITEM32(pci, eqe, cmd_status, 0x00, 0, 8);
/* pci_eqe_cmd_out_param_h
* Command completion event - output parameter - higher part
*/
-MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x0C, 0, 32);
+MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x04, 0, 32);
/* pci_eqe_cmd_out_param_l
* Command completion event - output parameter - lower part
*/
-MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x10, 0, 32);
+MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x08, 0, 32);
#endif
--
2.7.4
^ permalink raw reply related
* [patch net 2/3] mlxsw: switchx2: Fix memory leak at skb reallocation
From: Jiri Pirko @ 2017-01-12 8:10 UTC (permalink / raw)
To: netdev; +Cc: davem, arkadis, eladr, yotamg, nogahf, idosch
In-Reply-To: <1484208639-1890-1-git-send-email-jiri@resnulli.us>
From: Arkadi Sharshevsky <arkadis@mellanox.com>
During transmission the skb is checked for headroom in order to
add vendor specific header. In case the skb needs to be re-allocated,
skb_realloc_headroom() is called to make a private copy of the original,
but doesn't release it. Current code assumes that the original skb is
released during reallocation and only releases it at the error path
which causes a memory leak.
Fix this by adding the original skb release to the main path.
Fixes: d003462a50de ("mlxsw: Simplify mlxsw_sx_port_xmit function")
Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 150ccf5..2e88115e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -345,6 +345,7 @@ static netdev_tx_t mlxsw_sx_port_xmit(struct sk_buff *skb,
dev_kfree_skb_any(skb_orig);
return NETDEV_TX_OK;
}
+ dev_consume_skb_any(skb_orig);
}
mlxsw_sx_txhdr_construct(skb, &tx_info);
/* TX header is consumed by HW on the way so we shouldn't count its
--
2.7.4
^ permalink raw reply related
* [patch net 1/3] mlxsw: spectrum: Fix memory leak at skb reallocation
From: Jiri Pirko @ 2017-01-12 8:10 UTC (permalink / raw)
To: netdev; +Cc: davem, arkadis, eladr, yotamg, nogahf, idosch
In-Reply-To: <1484208639-1890-1-git-send-email-jiri@resnulli.us>
From: Arkadi Sharshevsky <arkadis@mellanox.com>
During transmission the skb is checked for headroom in order to
add vendor specific header. In case the skb needs to be re-allocated,
skb_realloc_headroom() is called to make a private copy of the original,
but doesn't release it. Current code assumes that the original skb is
released during reallocation and only releases it at the error path
which causes a memory leak.
Fix this by adding the original skb release to the main path.
Fixes: 56ade8fe3fe1 ("mlxsw: spectrum: Add initial support for Spectrum ASIC")
Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index d768c7b..003093a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -684,6 +684,7 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
dev_kfree_skb_any(skb_orig);
return NETDEV_TX_OK;
}
+ dev_consume_skb_any(skb_orig);
}
if (eth_skb_pad(skb)) {
--
2.7.4
^ permalink raw reply related
* [patch net 0/3] mlxsw: Couple of fixes
From: Jiri Pirko @ 2017-01-12 8:10 UTC (permalink / raw)
To: netdev; +Cc: davem, arkadis, eladr, yotamg, nogahf, idosch
From: Jiri Pirko <jiri@mellanox.com>
Couple of simple fixes from Arkadi and Elad.
Please queue these up for stable. Thanks.
Arkadi Sharshevsky (2):
mlxsw: spectrum: Fix memory leak at skb reallocation
mlxsw: switchx2: Fix memory leak at skb reallocation
Elad Raz (1):
mlxsw: pci: Fix EQE structure definition
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 8 ++++----
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 +
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 1 +
3 files changed, 6 insertions(+), 4 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH v2 8/8] crypto/testmgr: Allocate only the required output size for hash tests
From: Andy Lutomirski @ 2017-01-12 7:52 UTC (permalink / raw)
To: Herbert Xu
Cc: Andy Lutomirski, Daniel Borkmann, Network Development,
linux-kernel@vger.kernel.org, Linux Crypto Mailing List,
Jason A. Donenfeld, Hannes Frederic Sowa, Alexei Starovoitov,
Eric Dumazet, Eric Biggers, Tom Herbert, David S. Miller,
Ard Biesheuvel
In-Reply-To: <20170112074752.GA14230@gondor.apana.org.au>
On Wed, Jan 11, 2017 at 11:47 PM, Herbert Xu
<herbert@gondor.apana.org.au> wrote:
> Andy Lutomirski <luto@kernel.org> wrote:
>> There are some hashes (e.g. sha224) that have some internal trickery
>> to make sure that only the correct number of output bytes are
>> generated. If something goes wrong, they could potentially overrun
>> the output buffer.
>>
>> Make the test more robust by allocating only enough space for the
>> correct output size so that memory debugging will catch the error if
>> the output is overrun.
>>
>> Tested by intentionally breaking sha224 to output all 256
>> internally-generated bits while running on KASAN.
>>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Cc: Herbert Xu <herbert@gondor.apana.org.au>
>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>
> This patch doesn't seem to depend on anything else in the series.
> Do you want me to take it separately?
Yes, please. Its only relation to the rest of the series is that I
wanted to make sure that I didn't mess up sha224's finalization code.
--Andy
^ permalink raw reply
* Re: [PATCH v2 8/8] crypto/testmgr: Allocate only the required output size for hash tests
From: Herbert Xu @ 2017-01-12 7:47 UTC (permalink / raw)
To: Andy Lutomirski
Cc: daniel, netdev, linux-kernel, linux-crypto, Jason, hannes,
alexei.starovoitov, edumazet, ebiggers3, tom, davem, luto,
ard.biesheuvel
In-Reply-To: <890f4bdb28a1cf72f6b802b220b35ebaf0f76bb9.1484090585.git.luto@kernel.org>
Andy Lutomirski <luto@kernel.org> wrote:
> There are some hashes (e.g. sha224) that have some internal trickery
> to make sure that only the correct number of output bytes are
> generated. If something goes wrong, they could potentially overrun
> the output buffer.
>
> Make the test more robust by allocating only enough space for the
> correct output size so that memory debugging will catch the error if
> the output is overrun.
>
> Tested by intentionally breaking sha224 to output all 256
> internally-generated bits while running on KASAN.
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
This patch doesn't seem to depend on anything else in the series.
Do you want me to take it separately?
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH net-next] cxgb4: Initialize mbox lock and list for mgmt dev
From: Ganesh Goudar @ 2017-01-12 6:53 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, hariprasad, Ganesh Goudar
Initialize mbox lock and list for mgmt dev to avoid NULL pointer
dereference when cxgb_set_vf_mac is called.
And also allocate memory for private data while allocating mgmt
netdev.
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 3349e1f..e95bb6a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -4516,7 +4516,8 @@ static int config_mgmt_dev(struct pci_dev *pdev)
int err;
snprintf(name, IFNAMSIZ, "mgmtpf%d%d", adap->adap_idx, adap->pf);
- netdev = alloc_netdev(0, name, NET_NAME_UNKNOWN, dummy_setup);
+ netdev = alloc_netdev(sizeof(struct port_info), name, NET_NAME_UNKNOWN,
+ dummy_setup);
if (!netdev)
return -ENOMEM;
@@ -4990,6 +4991,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
err = -ENOMEM;
goto free_adapter;
}
+ spin_lock_init(&adapter->mbox_lock);
+ INIT_LIST_HEAD(&adapter->mlist.list);
pci_set_drvdata(pdev, adapter);
return 0;
--
2.1.0
^ permalink raw reply related
* [PATCH v2 net-next] Introduce a sysctl that modifies the value of PROT_SOCK.
From: Krister Johansen @ 2017-01-12 6:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David S. Miller, netdev
In-Reply-To: <20161231125505.7f0c7dff@xeon-e3>
Add net.ipv4.ip_unprotected_port_start, which is a per namespace sysctl
that denotes the first unprotected inet port in the namespace. To
disable all protected ports set this to zero. It also checks for
overlap with the local port range. The protected and local range may
not overlap.
The use case for this change is to allow containerized processes to bind
to priviliged ports, but prevent them from ever being allowed to modify
their container's network configuration. The latter is accomplished by
ensuring that the network namespace is not a child of the user
namespace. This modification was needed to allow the container manager
to disable a namespace's priviliged port restrictions without exposing
control of the network namespace to processes in the user namespace.
Signed-off-by: Krister Johansen <kjlx@templeofstupid.com>
---
include/net/ip.h | 10 +++++++++
include/net/netns/ipv4.h | 1 +
net/ipv4/af_inet.c | 5 ++++-
net/ipv4/sysctl_net_ipv4.c | 50 +++++++++++++++++++++++++++++++++++++++++-
net/ipv6/af_inet6.c | 3 ++-
net/netfilter/ipvs/ip_vs_ctl.c | 7 +++---
net/sctp/socket.c | 10 +++++----
security/selinux/hooks.c | 3 ++-
8 files changed, 77 insertions(+), 12 deletions(-)
Changes v1 -> v2:
Remove LOWPORT_SYSCTL config option. This is now always enabled as long
as CONFIG_SYSCTL is.
diff --git a/include/net/ip.h b/include/net/ip.h
index ab6761a..bf264a8 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -263,11 +263,21 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
return strcmp(name, "default") != 0 && strcmp(name, "all") != 0;
}
+static inline int inet_prot_sock(struct net *net)
+{
+ return net->ipv4.sysctl_ip_prot_sock;
+}
+
#else
static inline int inet_is_local_reserved_port(struct net *net, int port)
{
return 0;
}
+
+static inline int inet_prot_sock(struct net *net)
+{
+ return PROT_SOCK;
+}
#endif
__be32 inet_current_timestamp(void);
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 8e3f5b6..e365732 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -135,6 +135,7 @@ struct netns_ipv4 {
#ifdef CONFIG_SYSCTL
unsigned long *sysctl_local_reserved_ports;
+ int sysctl_ip_prot_sock;
#endif
#ifdef CONFIG_IP_MROUTE
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index aae410b..28fe8da 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -479,7 +479,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
snum = ntohs(addr->sin_port);
err = -EACCES;
- if (snum && snum < PROT_SOCK &&
+ if (snum && snum < inet_prot_sock(net) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
goto out;
@@ -1700,6 +1700,9 @@ static __net_init int inet_init_net(struct net *net)
net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
net->ipv4.sysctl_ip_dynaddr = 0;
net->ipv4.sysctl_ip_early_demux = 1;
+#ifdef CONFIG_SYSCTL
+ net->ipv4.sysctl_ip_prot_sock = PROT_SOCK;
+#endif
return 0;
}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 134d8e1..6ad3b39 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -35,6 +35,8 @@ static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
+static int ip_protected_port_min;
+static int ip_protected_port_max = 65535;
static int ip_ttl_min = 1;
static int ip_ttl_max = 255;
static int tcp_syn_retries_min = 1;
@@ -79,7 +81,12 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
if (write && ret == 0) {
- if (range[1] < range[0])
+ /* Ensure that the upper limit is not smaller than the lower,
+ * and that the lower does not encroach upon the protected
+ * port limit.
+ */
+ if ((range[1] < range[0]) ||
+ (range[0] < net->ipv4.sysctl_ip_prot_sock))
ret = -EINVAL;
else
set_local_port_range(net, range);
@@ -88,6 +95,40 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
return ret;
}
+/* Validate changes from /proc interface. */
+static int ipv4_protected_ports(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct net *net = container_of(table->data, struct net,
+ ipv4.sysctl_ip_prot_sock);
+ int ret;
+ int pports;
+ int range[2];
+ struct ctl_table tmp = {
+ .data = &pports,
+ .maxlen = sizeof(pports),
+ .mode = table->mode,
+ .extra1 = &ip_protected_port_min,
+ .extra2 = &ip_protected_port_max,
+ };
+
+ pports = net->ipv4.sysctl_ip_prot_sock;
+
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+ if (write && ret == 0) {
+ inet_get_local_port_range(net, &range[0], &range[1]);
+ /* Ensure that the local port range doesn't overlap with the
+ * protected port range.
+ */
+ if (range[0] < pports)
+ ret = -EINVAL;
+ else
+ net->ipv4.sysctl_ip_prot_sock = pports;
+ }
+
+ return ret;
+}
static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
{
@@ -971,6 +1012,13 @@ static struct ctl_table ipv4_net_table[] = {
.extra2 = &one,
},
#endif
+ {
+ .procname = "ip_unprotected_port_start",
+ .maxlen = sizeof(int),
+ .data = &init_net.ipv4.sysctl_ip_prot_sock,
+ .mode = 0644,
+ .proc_handler = ipv4_protected_ports,
+ },
{ }
};
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index aa42123..04db406 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -302,7 +302,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return -EINVAL;
snum = ntohs(addr->sin6_port);
- if (snum && snum < PROT_SOCK && !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
+ if (snum && snum < inet_prot_sock(net) &&
+ !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES;
lock_sock(sk);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 55e0169..8b7416f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -426,10 +426,9 @@ ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol
*/
svc = __ip_vs_service_find(ipvs, af, protocol, vaddr, vport);
- if (svc == NULL
- && protocol == IPPROTO_TCP
- && atomic_read(&ipvs->ftpsvc_counter)
- && (vport == FTPDATA || ntohs(vport) >= PROT_SOCK)) {
+ if (!svc && protocol == IPPROTO_TCP &&
+ atomic_read(&ipvs->ftpsvc_counter) &&
+ (vport == FTPDATA || ntohs(vport) >= inet_prot_sock(ipvs->net))) {
/*
* Check if ftp service entry exists, the packet
* might belong to FTP data connections.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 318c678..2723f4a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -360,7 +360,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
}
}
- if (snum && snum < PROT_SOCK &&
+ if (snum && snum < inet_prot_sock(net) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES;
@@ -1152,8 +1152,10 @@ static int __sctp_connect(struct sock *sk,
* accept new associations, but it SHOULD NOT
* be permitted to open new associations.
*/
- if (ep->base.bind_addr.port < PROT_SOCK &&
- !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
+ if (ep->base.bind_addr.port <
+ inet_prot_sock(net) &&
+ !ns_capable(net->user_ns,
+ CAP_NET_BIND_SERVICE)) {
err = -EACCES;
goto out_free;
}
@@ -1818,7 +1820,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
* but it SHOULD NOT be permitted to open new
* associations.
*/
- if (ep->base.bind_addr.port < PROT_SOCK &&
+ if (ep->base.bind_addr.port < inet_prot_sock(net) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
err = -EACCES;
goto out_unlock;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c7c6619..53cb6da 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4365,7 +4365,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
inet_get_local_port_range(sock_net(sk), &low, &high);
- if (snum < max(PROT_SOCK, low) || snum > high) {
+ if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
+ snum > high) {
err = sel_netport_sid(sk->sk_protocol,
snum, &sid);
if (err)
--
2.7.4
^ permalink raw reply related
* [PATCH] can: Fix kernel panic at security_sock_rcv_skb
From: Liu ShuoX @ 2017-01-12 6:33 UTC (permalink / raw)
To: linux-kernel
Cc: yanmin_zhang, shuox.liu, Zhang Yanmin, He, Bo, Liu Shuo A,
Oliver Hartkopp, Marc Kleine-Budde, David S. Miller,
open list:CAN NETWORK LAYER, open list:NETWORKING [GENERAL]
From: Zhang Yanmin <yanmin.zhang@intel.com>
The patch is for fix the below kernel panic:
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff81495e25>] selinux_socket_sock_rcv_skb+0x65/0x2a0
Call Trace:
<IRQ>
[<ffffffff81485d8c>] security_sock_rcv_skb+0x4c/0x60
[<ffffffff81d55771>] sk_filter+0x41/0x210
[<ffffffff81d12913>] sock_queue_rcv_skb+0x53/0x3a0
[<ffffffff81f0a2b3>] raw_rcv+0x2a3/0x3c0
[<ffffffff81f06eab>] can_rcv_filter+0x12b/0x370
[<ffffffff81f07af9>] can_receive+0xd9/0x120
[<ffffffff81f07beb>] can_rcv+0xab/0x100
[<ffffffff81d362ac>] __netif_receive_skb_core+0xd8c/0x11f0
[<ffffffff81d36734>] __netif_receive_skb+0x24/0xb0
[<ffffffff81d37f67>] process_backlog+0x127/0x280
[<ffffffff81d36f7b>] net_rx_action+0x33b/0x4f0
[<ffffffff810c88d4>] __do_softirq+0x184/0x440
[<ffffffff81f9e86c>] do_softirq_own_stack+0x1c/0x30
<EOI>
[<ffffffff810c76fb>] do_softirq.part.18+0x3b/0x40
[<ffffffff810c8bed>] do_softirq+0x1d/0x20
[<ffffffff81d30085>] netif_rx_ni+0xe5/0x110
[<ffffffff8199cc87>] slcan_receive_buf+0x507/0x520
[<ffffffff8167ef7c>] flush_to_ldisc+0x21c/0x230
[<ffffffff810e3baf>] process_one_work+0x24f/0x670
[<ffffffff810e44ed>] worker_thread+0x9d/0x6f0
[<ffffffff810e4450>] ? rescuer_thread+0x480/0x480
[<ffffffff810ebafc>] kthread+0x12c/0x150
[<ffffffff81f9ccef>] ret_from_fork+0x3f/0x70
The sk dereferenced in panic has been released. After the rcu_call in
can_rx_unregister, receiver was protected by RCU but inner data was
not, then later sk will be freed while other CPU is still using it.
We need wait here to make sure sk referenced via receiver was safe.
=> security_sk_free
=> sk_destruct
=> __sk_free
=> sk_free
=> raw_release
=> sock_release
=> sock_close
=> __fput
=> ____fput
=> task_work_run
=> exit_to_usermode_loop
=> syscall_return_slowpath
=> int_ret_from_sys_call
Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
Signed-off-by: He, Bo <bo.he@intel.com>
Signed-off-by: Liu Shuo A <shuo.a.liu@intel.com>
---
net/can/af_can.c | 14 ++++++++------
net/can/af_can.h | 1 -
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 1108079..fcbe971 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -517,10 +517,8 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
/*
* can_rx_delete_receiver - rcu callback for single receiver entry removal
*/
-static void can_rx_delete_receiver(struct rcu_head *rp)
+static void can_rx_delete_receiver(struct receiver *r)
{
- struct receiver *r = container_of(rp, struct receiver, rcu);
-
kmem_cache_free(rcv_cache, r);
}
@@ -595,9 +593,13 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
out:
spin_unlock(&can_rcvlists_lock);
- /* schedule the receiver item for deletion */
- if (r)
- call_rcu(&r->rcu, can_rx_delete_receiver);
+ /* synchronize_rcu to wait until a grace period has elapsed, to make
+ * sure all receiver's sk dereferenced by others.
+ */
+ if (r) {
+ synchronize_rcu();
+ can_rx_delete_receiver(r);
+ }
}
EXPORT_SYMBOL(can_rx_unregister);
diff --git a/net/can/af_can.h b/net/can/af_can.h
index fca0fe9..a0cbf83 100644
--- a/net/can/af_can.h
+++ b/net/can/af_can.h
@@ -50,7 +50,6 @@
struct receiver {
struct hlist_node list;
- struct rcu_head rcu;
canid_t can_id;
canid_t mask;
unsigned long matches;
--
1.9.4
^ permalink raw reply related
* [PATCH net-next] net: core: Make netif_wake_subqueue a wrapper
From: Florian Fainelli @ 2017-01-12 5:13 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
netif_wake_subqueue() is duplicating the same thing that netif_tx_wake_queue()
does, so make it call it directly after looking up the queue from the index.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/netdevice.h | 14 +++++++++++++-
net/core/dev.c | 22 ----------------------
2 files changed, 13 insertions(+), 23 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d532c070163f..6d021c37b774 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3106,7 +3106,19 @@ static inline bool netif_subqueue_stopped(const struct net_device *dev,
return __netif_subqueue_stopped(dev, skb_get_queue_mapping(skb));
}
-void netif_wake_subqueue(struct net_device *dev, u16 queue_index);
+/**
+ * netif_wake_subqueue - allow sending packets on subqueue
+ * @dev: network device
+ * @queue_index: sub queue index
+ *
+ * Resume individual transmit queue of a device with multiple transmit queues.
+ */
+static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
+{
+ struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
+
+ netif_tx_wake_queue(txq);
+}
#ifdef CONFIG_XPS
int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
diff --git a/net/core/dev.c b/net/core/dev.c
index 643e4a4491c6..7547e2ccc06b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2408,28 +2408,6 @@ void netif_schedule_queue(struct netdev_queue *txq)
}
EXPORT_SYMBOL(netif_schedule_queue);
-/**
- * netif_wake_subqueue - allow sending packets on subqueue
- * @dev: network device
- * @queue_index: sub queue index
- *
- * Resume individual transmit queue of a device with multiple transmit queues.
- */
-void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
-{
- struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
-
- if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &txq->state)) {
- struct Qdisc *q;
-
- rcu_read_lock();
- q = rcu_dereference(txq->qdisc);
- __netif_schedule(q);
- rcu_read_unlock();
- }
-}
-EXPORT_SYMBOL(netif_wake_subqueue);
-
void netif_tx_wake_queue(struct netdev_queue *dev_queue)
{
if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state)) {
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox