Netdev List
 help / color / mirror / Atom feed
* Re: [bnx2] [Regression 4.8] Driver loading fails without firmware
From: Baoquan He @ 2016-10-29  2:55 UTC (permalink / raw)
  To: Paul Menzel
  Cc: Sony Chacko, Dept-HSGLinuxNICDev, netdev, David S. Miller, dvteam
In-Reply-To: <f055c961-58ca-ea81-46d8-610fa055cce8@molgen.mpg.de>

On 10/27/16 at 03:21pm, Paul Menzel wrote:
> Dear Baoquan,
> > > Baoquan, could you please fix this regression. My suggestion is, that you
> > > add the old code back, but check if the firmware has been loaded. If it
> > > hasn’t, load it again.
> > > 
> > > That way, people can update their Linux kernel, and it continues working
> > > without changing the initramfs, or anything else.
> > 
> > I saw your mail but I am also not familiar with bnx2 driver. As the
> > commit log says I just tried to make bnx2 driver reset itself earlier.
> > 
> > So you did a git bisect and found this commit caused the regression,
> > right? If yes, and network developers have no action, I will look into
> > the code and see if I have idea to fix it.
> 
> Well, I looked through the commits and found that one, which would explain
> the changed behavior.
> 
> To be sure, and to follow your request, I took Linux 4.8.4 and reverted your
> commit (attached). Then I deleted the firmware again from the initramfs, and
> rebooted. The devices showed up just fine as before.
> 
> So to summarize, the commit is indeed the culprit.

Hi Paul,

Sorry for this.

Could you tell the steps to reproduce? I will find a machine with bnx2
NIC and check if there's other ways.

Thanks
Baoquan

> From 61b8dac8796343a797858b4a2eb0a59a0cfcd735 Mon Sep 17 00:00:00 2001
> From: Paul Menzel <pmenzel@molgen.mpg.de>
> Date: Thu, 27 Oct 2016 11:34:52 +0200
> Subject: [PATCH] Revert "bnx2: Reset device during driver initialization"
> 
> This reverts commit 3e1be7ad2d38c6bd6aeef96df9bd0a7822f4e51c.
> ---
>  drivers/net/ethernet/broadcom/bnx2.c | 12 +++++-------
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
> index 27f11a5..ecd357d 100644
> --- a/drivers/net/ethernet/broadcom/bnx2.c
> +++ b/drivers/net/ethernet/broadcom/bnx2.c
> @@ -6356,6 +6356,10 @@ bnx2_open(struct net_device *dev)
>  	struct bnx2 *bp = netdev_priv(dev);
>  	int rc;
>  
> +	rc = bnx2_request_firmware(bp);
> +	if (rc < 0)
> +		goto out;
> +
>  	netif_carrier_off(dev);
>  
>  	bnx2_disable_int(bp);
> @@ -6424,6 +6428,7 @@ bnx2_open(struct net_device *dev)
>  	bnx2_free_irq(bp);
>  	bnx2_free_mem(bp);
>  	bnx2_del_napi(bp);
> +	bnx2_release_firmware(bp);
>  	goto out;
>  }
>  
> @@ -8570,12 +8575,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  
>  	pci_set_drvdata(pdev, dev);
>  
> -	rc = bnx2_request_firmware(bp);
> -	if (rc < 0)
> -		goto error;
> -
> -
> -	bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
>  	memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
>  
>  	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
> @@ -8608,7 +8607,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	return 0;
>  
>  error:
> -	bnx2_release_firmware(bp);
>  	pci_iounmap(pdev, bp->regview);
>  	pci_release_regions(pdev);
>  	pci_disable_device(pdev);
> -- 
> 2.4.1
> 

^ permalink raw reply

* Re: [PATCH v2 0/5] make POSIX timers optional with some Kconfig help
From: Nicolas Pitre @ 2016-10-29  2:00 UTC (permalink / raw)
  To: Paul Bolle
  Cc: John Stultz, Richard Cochran, Michal Marek, Thomas Gleixner,
	Josh Triplett, Edward Cree, netdev, linux-kbuild, linux-kernel
In-Reply-To: <1477695045.2167.48.camel@tiscali.nl>

On Sat, 29 Oct 2016, Paul Bolle wrote:

> On Tue, 2016-10-25 at 22:28 -0400, Nicolas Pitre wrote:
> > When POSIX timers are configured out, the PTP clock subsystem should be
> > left out as well. However a bunch of ethernet drivers currently *select*
> > the later in their Kconfig entries. Therefore some more work was needed
> > to break that hard dependency from those drivers without preventing their
> > usage altogether.
> 
> By the way: would you have pointers to threads that discussed attempts
> to achieve this using currently available Kconfig options?

You could probably go backward from here:
https://lkml.org/lkml/2016/9/20/606


Nicolas

^ permalink raw reply

* Re: [PATCH 17/17] batman-adv: Avoid precedence issues in macros
From: Joe Perches @ 2016-10-29  1:56 UTC (permalink / raw)
  To: Sven Eckelmann
  Cc: Simon Wunderlich, davem, netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <4261316.fWqmHPy2zE@sven-edge>

On Fri, 2016-10-28 at 23:27 +0200, Sven Eckelmann wrote:
> On Freitag, 28. Oktober 2016 14:13:06 CEST Joe Perches wrote:
> > On Thu, 2016-10-27 at 21:01 +0200, Simon Wunderlich wrote:
> > > From: Sven Eckelmann <sven@narfation.org>
> > > 
> > > It must be avoided that arguments to a macro are evaluated ungrouped (which
> > > enforces normal operator precendence). Otherwise the result of the macro
> > > is not well defined.
> > 
> > Curiosity:
> > 
> > in net/batman-adv/tp_meter.c
> 
> [...]
> > 	orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
> > 	if (unlikely(!orig_node)) {
> > 		err = BATADV_TP_REASON_DST_UNREACHABLE;
> > 		tp_vars->reason = err;
> > 		goto out;
> > 	}
> > 
> > 	primary_if = batadv_primary_if_get_selected(bat_priv);
> > 	if (unlikely(!primary_if)) {
> > 		err = BATADV_TP_REASON_DST_UNREACHABLE;
> > 		goto out;
> > 	}
> > 
> > err is not used in the out block
> > 
> > Is the last if block supposed to set tp_vars->reason to err?
> 
> This seems to be unrelated to this patch.

Kinda.  I was looking at how the one instance of
batadv_tp_is_error was used and it's in this file.

> But yes, looks to me like it is missing. Do you want to propose a patch or
> should I do?

As you are working on this file, perhaps you should.

cheers, Joe

^ permalink raw reply

* Re: [PATCH v7 0/6] Add eBPF hooks for cgroups
From: Alexei Starovoitov @ 2016-10-29  1:42 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Daniel Mack, htejun-b10kYP2dOMg, daniel-FeC+5ew28dpmcu3hnIyYJQ,
	ast-b10kYP2dOMg, davem-fT/PcQaiUtIeIZ0/mPfg9Q, kafai-b10kYP2dOMg,
	fw-HFFVJYpyMKqzQB+pC5nmwQ, harald-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA, sargun-GaZTRHToo+CzQB+pC5nmwQ,
	cgroups-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161028112839.GA29798@salvia>

On Fri, Oct 28, 2016 at 01:28:39PM +0200, Pablo Neira Ayuso wrote:
> Hi Alexei,
> 
> On Wed, Oct 26, 2016 at 08:35:04PM -0700, Alexei Starovoitov wrote:
> > On Wed, Oct 26, 2016 at 09:59:33PM +0200, Pablo Neira Ayuso wrote:
> > > On Tue, Oct 25, 2016 at 12:14:08PM +0200, Daniel Mack wrote:
> > > [...]
> > > >   Dumping programs once they are installed is problematic because of
> > > >   the internal optimizations done to the eBPF program during its
> > > >   lifetime. Also, the references to maps etc. would need to be
> > > >   restored during the dump.
> > > > 
> > > >   Just exposing whether or not a program is attached would be
> > > >   trivial to do, however, most easily through another bpf(2)
> > > >   command. That can be added later on though.
> > > 
> > > I don't know if anyone told you, but during last netconf, this topic
> > > took a bit of time of discussion and it was controversial, I would say
> > > 1/3 of netdev hackers there showed their concerns, and that's
> > > something that should not be skipped IMO.
> > 
> > Though I attended netconf over hangouts, I think it was pretty
> > clear that bpf needs 'introspection' of loaded bpf programs and it
> > was a universal desire of everyone. Not 1/3 of hackers.
> 
> Introspection is a different thing, very useful, no doubt. But this
> infrastructure is allowing way more than simple innocuous introspection.

During netconf the discussion around bpf introspection was about
making bpf more visible to user space.
This patch does cgroup+bpf infrastructure which is orthogonal.

> > As commit log says it's an orthogonal work and over the last
> > month we've been discussing pros and cons of different approaches.
> > The audit infra, tracepoints and other ideas.
> > We kept the discussion in private because, unfortunately, public
> > discussions are not fruitful due to threads like this one.
> 
> We need to understand what people are trying to solve and it what way.
> That's why we have all those conferences and places to meet and
> discuss too. Please, don't think like that, this is sending the wrong
> message to everyone here, that is kind of: bypass public discussions
> and don't take time to describe what you're doing since it is a waste
> of time. That's not good.

In general I agree that it's best to discuss technical topics
on the mainling list and resolve personal conflicts in person
during the conferences.
Unfortunately the obstructionism seen in this thread forces people
discuss in private to have constructive conversation.
Anyway, neither your reply nor mine has nothing to do with this patch set
and being typical example why I prefer to discuss bpf related
ideas in private.

> > The further points below were disputed many times in the past.
> > Let's address them one more time:
> > 
> > > path. But this is adding hooks to push bpf programs in the middle of
> > > our generic stack, this is way different domain.
> > 
> > incorrect. look at socket filters, cls_bpf.
> 
> Classic socket filters don't allow you to deploy a global policy in
> such a fine grain way as this is doing. Then, cls_bpf is fine since it
> is visible via tc command, so sysadmins can use tools they are
> familiar with to inspect policies and say "oh look, some of the
> processes I'm deploying have installed filters via cls_bpf". However,
> this approach is visible in no way.

the audit and/or tracepoint infra that is being worked on in parallel
will answer this question in full detail.
It's no different from application using seccomp to control its children
or cls_bpf doing policy enforcement of containers or xdp doing low
level filtering.
xdp has boolean "is program loaded" flag and it turned out
to be not very useful for debuggability.
It should be solved in a universal way for all bpf programs.
We're not going to add something specific to this cgroup+bpf infra,
since it will be just as clumsy as xdp's bool flag.
Once again, audit/tracepoint for bpf prog introspection is a separate
work orthogonal to this set.

> [...]
> > > around this socket code in functions so we can invoke it. I guess
> > > filtering of UDP and TCP should be good for you at this stage.
> > 
> > DanielM mentioned few times that it's not only about UDP and TCP.
> 
> OK, since this is limited to the scope of inet sockets, let's revisit
> what we have around: DCCP is hopeless, who cares. We also have SCTP,
> that is deployed by telcos in datacenters, it cannot reach that domain
> because many Internet gateways are broken for it, so you may not get
> too far with it. Arguably it would be good to have SCTP support at
> some point, but I guess this is not a priority now. Then, UDPlite
> almost comes for free since it relies on the existing UDP
> infrastructure, it's basically UDP with a bit more features. What
> else?

thank you for nice description of current state of sctp,
but it has nothing to do with this patch set. The goal is to
monitor application networking activity at L3 level.

> > > This would require more work though, but this would come with no
> > > hooks in the stack and packets will not have to consume *lots of
> > > cycles* just to be dropped before entering the socket queue.
> > 
> > packets don't consume 'lost of cycles'. This is not a typical
> > n-tuple firewall framework. Not a DoS mitigation either. Please read
> > the cover letter and earlier submissions.
> > It's a framework centered around cgroups.
> > _Nothing_ in the current stack provides cgroup based monitoring
> > and application protection. Earlier cgroupv1 controllers don't
> > scale and we really cannot have more of v1 net controllers.
> > At the same time we've been brainstorming how this patch set
> > can work with v1. It's not easy. We're not giving up though.
> > For now it's v2 only.
> > Note that another two patchsets depend on this core cgroup+bpf framework.
> 
> I saw those, I would really like to have a closer look at David
> Ahern's usecase since that skb iif mangling looks kludgy to me, and
> given this is exposing a new helper for general use, not only vrf, it
> would be good to make sure helpers provide something useful for
> everyone. So that new helper is questionable at this stage IMO. I'm
> concerned that people may start using bpf as the adhesive tape to glue
> things to solve probably design problems.

the whole point of bpf is to be the fastest glue, so that kernel people
(like you and me) move out of the way for others to make their
own architectural choices for networking, DoS, firewalls, policy,
tracing, security, sandboxing and so on.
The job of the kernel is to be the best tool and not dictate
how firewalls should be done. People who work on DoS prevention
today have to use things like DPDK not only for performance reasons,
but due to flexible design choices and ability to change them quickly.
This cgroup+bpf set is a fundamental building block for all sorts of
other things like lsm, vrf, port binding policy and whatever
comes next. bpf is really nothing but the glue.

> The other patchset, I guess you refer to the new lsm module: I would
> suggest we address one thing at a time, I guess he can starts without
> relying on this chunk, as it can follow up later anyway.

lsm+bpf infra is only usable either via seccomp or via cgroup.
For our use case seccomp way is a non starter, since we manage
containers. Hence cgroup must be from the beginning. Therefore strong
dependency on this set.

> In general, I think bpf is very useful, but I think we have to
> accomodate new things in a way that makes sense into what we have. We
> have traditionally followed an "add in-kernel infrastructured +
> provide userspace interface as control plane" approach for long time.
> I have concerns (and my impression is that others were concerned in
> netconf too) on if we can go from the existing approach to a fully
> uninfrastructured use-bpf-everywhere, from one day to another without
> even taking the time to discuss the consequences of this decision.

bpf is already used everywhere and the work on bpf visibility is
orthogonal. Arguing that cgroup+bpf is no good without it is only
going to stall progress of everything that needs to be cgroup aware.
Note we already have experience dealing with cgroups from cls_bpf
via bpf_skb_under_cgroup() helper. And it didn't scale.
Hence this patch set.

^ permalink raw reply

* net/dccp: warning in dccp_feat_clone_sp_val/__might_sleep
From: Andrey Konovalov @ 2016-10-29  0:40 UTC (permalink / raw)
  To: Gerrit Renker, David S. Miller, dccp, netdev, LKML
  Cc: Dmitry Vyukov, Eric Dumazet, Alexander Potapenko,
	Kostya Serebryany, syzkaller

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

Hi,

I've got the following error report while running the syzkaller fuzzer:

------------[ cut here ]------------
WARNING: CPU: 0 PID: 4608 at kernel/sched/core.c:7724
__might_sleep+0x14c/0x1a0 kernel/sched/core.c:7719
do not call blocking ops when !TASK_RUNNING; state=1 set at
[<ffffffff811f5a5c>] prepare_to_wait+0xbc/0x210
kernel/sched/wait.c:178
Modules linked in:
CPU: 0 PID: 4608 Comm: syz-executor Not tainted 4.9.0-rc2+ #320
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
 ffff88006625f7a0 ffffffff81b46914 ffff88006625f818 0000000000000000
 ffffffff84052960 0000000000000000 ffff88006625f7e8 ffffffff81111237
 ffff88006aceac00 ffffffff00001e2c ffffed000cc4beff ffffffff84052960
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff81b46914>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
 [<ffffffff81111237>] __warn+0x1a7/0x1f0 kernel/panic.c:550
 [<ffffffff8111132c>] warn_slowpath_fmt+0xac/0xd0 kernel/panic.c:565
 [<ffffffff811922fc>] __might_sleep+0x14c/0x1a0 kernel/sched/core.c:7719
 [<     inline     >] slab_pre_alloc_hook mm/slab.h:393
 [<     inline     >] slab_alloc_node mm/slub.c:2634
 [<     inline     >] slab_alloc mm/slub.c:2716
 [<ffffffff81508da0>] __kmalloc_track_caller+0x150/0x2a0 mm/slub.c:4240
 [<ffffffff8146be14>] kmemdup+0x24/0x50 mm/util.c:113
 [<ffffffff8388b2cf>] dccp_feat_clone_sp_val.part.5+0x4f/0xe0
net/dccp/feat.c:374
 [<     inline     >] dccp_feat_clone_sp_val net/dccp/feat.c:1141
 [<     inline     >] dccp_feat_change_recv net/dccp/feat.c:1141
 [<ffffffff8388d491>] dccp_feat_parse_options+0xaa1/0x13d0 net/dccp/feat.c:1411
 [<ffffffff83894f01>] dccp_parse_options+0x721/0x1010 net/dccp/options.c:128
 [<ffffffff83891280>] dccp_rcv_state_process+0x200/0x15b0 net/dccp/input.c:644
 [<ffffffff838b8a94>] dccp_v4_do_rcv+0xf4/0x1a0 net/dccp/ipv4.c:681
 [<     inline     >] sk_backlog_rcv ./include/net/sock.h:872
 [<ffffffff82b7ceb6>] __release_sock+0x126/0x3a0 net/core/sock.c:2044
 [<ffffffff82b7d189>] release_sock+0x59/0x1c0 net/core/sock.c:2502
 [<     inline     >] inet_wait_for_connect net/ipv4/af_inet.c:547
 [<ffffffff8316b2a2>] __inet_stream_connect+0x5d2/0xbb0 net/ipv4/af_inet.c:617
 [<ffffffff8316b8d5>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:656
 [<ffffffff82b705e4>] SYSC_connect+0x244/0x2f0 net/socket.c:1533
 [<ffffffff82b72dd4>] SyS_connect+0x24/0x30 net/socket.c:1514
 [<ffffffff83fbf701>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
---[ end trace 0dc4109d69f4e51e ]---

On commit 14970f204b1993af7459d5bd34aaff38dfee6670 (Oct 27).

A reproducer is attached.

[-- Attachment #2: dccp-feat-warn-poc.c --]
[-- Type: application/octet-stream, Size: 7760 bytes --]

// autogenerated by syzkaller (http://github.com/google/syzkaller)

#ifndef __NR_bind
#define __NR_bind 49
#endif
#ifndef __NR_listen
#define __NR_listen 50
#endif
#ifndef __NR_syz_open_pts
#define __NR_syz_open_pts 1000003
#endif
#ifndef __NR_syz_test
#define __NR_syz_test 1000001
#endif
#ifndef __NR_mmap
#define __NR_mmap 9
#endif
#ifndef __NR_socket
#define __NR_socket 41
#endif
#ifndef __NR_connect
#define __NR_connect 42
#endif
#ifndef __NR_syz_fuse_mount
#define __NR_syz_fuse_mount 1000004
#endif
#ifndef __NR_syz_fuseblk_mount
#define __NR_syz_fuseblk_mount 1000005
#endif
#ifndef __NR_syz_open_dev
#define __NR_syz_open_dev 1000002
#endif

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>

#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <pthread.h>
#include <setjmp.h>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

__thread int skip_segv;
__thread jmp_buf segv_env;

static void segv_handler(int sig, siginfo_t* info, void* uctx)
{
  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
    _longjmp(segv_env, 1);
  exit(sig);
}

static void install_segv_handler()
{
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_sigaction = segv_handler;
  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
  sigaction(SIGSEGV, &sa, NULL);
  sigaction(SIGBUS, &sa, NULL);
}

#define NONFAILING(...)                                                \
  {                                                                    \
    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);               \
    if (_setjmp(segv_env) == 0) {                                      \
      __VA_ARGS__;                                                     \
    }                                                                  \
    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);               \
  }

static uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
{
  if (a0 == 0xc || a0 == 0xb) {

    char buf[128];
    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block",
            (uint8_t)a1, (uint8_t)a2);
    return open(buf, O_RDWR, 0);
  } else {

    char buf[1024];
    char* hash;
    strncpy(buf, (char*)a0, sizeof(buf));
    buf[sizeof(buf) - 1] = 0;
    while ((hash = strchr(buf, '#'))) {
      *hash = '0' + (char)(a1 % 10);
      a1 /= 10;
    }
    return open(buf, a2, 0);
  }
}

static uintptr_t syz_open_pts(uintptr_t a0, uintptr_t a1)
{

  int ptyno = 0;
  if (ioctl(a0, TIOCGPTN, &ptyno))
    return -1;
  char buf[128];
  sprintf(buf, "/dev/pts/%d", ptyno);
  return open(buf, a1, 0);
}

static uintptr_t syz_fuse_mount(uintptr_t a0, uintptr_t a1,
                                uintptr_t a2, uintptr_t a3,
                                uintptr_t a4, uintptr_t a5)
{

  uint64_t target = a0;
  uint64_t mode = a1;
  uint64_t uid = a2;
  uint64_t gid = a3;
  uint64_t maxread = a4;
  uint64_t flags = a5;

  int fd = open("/dev/fuse", O_RDWR);
  if (fd == -1)
    return fd;
  char buf[1024];
  sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
          (long)uid, (long)gid, (unsigned)mode & ~3u);
  if (maxread != 0)
    sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
  if (mode & 1)
    strcat(buf, ",default_permissions");
  if (mode & 2)
    strcat(buf, ",allow_other");
  syscall(SYS_mount, "", target, "fuse", flags, buf);

  return fd;
}

static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1,
                                   uintptr_t a2, uintptr_t a3,
                                   uintptr_t a4, uintptr_t a5,
                                   uintptr_t a6, uintptr_t a7)
{

  uint64_t target = a0;
  uint64_t blkdev = a1;
  uint64_t mode = a2;
  uint64_t uid = a3;
  uint64_t gid = a4;
  uint64_t maxread = a5;
  uint64_t blksize = a6;
  uint64_t flags = a7;

  int fd = open("/dev/fuse", O_RDWR);
  if (fd == -1)
    return fd;
  if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)))
    return fd;
  char buf[256];
  sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
          (long)uid, (long)gid, (unsigned)mode & ~3u);
  if (maxread != 0)
    sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
  if (blksize != 0)
    sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
  if (mode & 1)
    strcat(buf, ",default_permissions");
  if (mode & 2)
    strcat(buf, ",allow_other");
  syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf);

  return fd;
}

static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
                                 uintptr_t a2, uintptr_t a3,
                                 uintptr_t a4, uintptr_t a5,
                                 uintptr_t a6, uintptr_t a7,
                                 uintptr_t a8)
{
  switch (nr) {
  default:
    return syscall(nr, a0, a1, a2, a3, a4, a5);
  case __NR_syz_test:
    return 0;
  case __NR_syz_open_dev:
    return syz_open_dev(a0, a1, a2);
  case __NR_syz_open_pts:
    return syz_open_pts(a0, a1);
  case __NR_syz_fuse_mount:
    return syz_fuse_mount(a0, a1, a2, a3, a4, a5);
  case __NR_syz_fuseblk_mount:
    return syz_fuseblk_mount(a0, a1, a2, a3, a4, a5, a6, a7);
  }
}

long r[28];
void* thr(void* arg)
{
  switch ((long)arg) {
  case 0:
    r[0] =
        execute_syscall(__NR_mmap, 0x20000000ul, 0xe2b000ul, 0x3ul,
                        0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
    break;
  case 1:
    r[1] = execute_syscall(__NR_socket, 0x2ul, 0x806ul, 0x0ul, 0, 0, 0,
                           0, 0, 0);
    break;
  case 2:
    NONFAILING(*(uint16_t*)0x204e8000 = (uint16_t)0x2);
    NONFAILING(*(uint16_t*)0x204e8002 = (uint16_t)0x4242);
    NONFAILING(*(uint32_t*)0x204e8004 = (uint32_t)0x0);
    NONFAILING(*(uint8_t*)0x204e8008 = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e8009 = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800a = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800b = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800c = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800d = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800e = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x204e800f = (uint8_t)0x0);
    r[13] = execute_syscall(__NR_bind, r[1], 0x204e8000ul, 0x10ul, 0, 0,
                            0, 0, 0, 0);
    break;
  case 3:
    r[14] =
        execute_syscall(__NR_listen, r[1], 0x1ul, 0, 0, 0, 0, 0, 0, 0);
    break;
  case 4:
    r[15] = execute_syscall(__NR_socket, 0x2ul, 0x6ul, 0x0ul, 0, 0, 0,
                            0, 0, 0);
    break;
  case 5:
    NONFAILING(*(uint16_t*)0x20e26000 = (uint16_t)0x2);
    NONFAILING(*(uint16_t*)0x20e26002 = (uint16_t)0x4242);
    NONFAILING(*(uint32_t*)0x20e26004 = (uint32_t)0x0);
    NONFAILING(*(uint8_t*)0x20e26008 = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e26009 = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600a = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600b = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600c = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600d = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600e = (uint8_t)0x0);
    NONFAILING(*(uint8_t*)0x20e2600f = (uint8_t)0x0);
    r[27] = execute_syscall(__NR_connect, r[15], 0x20e26000ul, 0x10ul,
                            0, 0, 0, 0, 0, 0);
    break;
  }
  return 0;
}

int main()
{
  long i;
  pthread_t th[12];

  install_segv_handler();
  memset(r, -1, sizeof(r));
  srand(getpid());
  for (i = 0; i < 6; i++) {
    pthread_create(&th[i], 0, thr, (void*)i);
    usleep(10000);
  }
  for (i = 0; i < 6; i++) {
    pthread_create(&th[6 + i], 0, thr, (void*)i);
    if (rand() % 2)
      usleep(rand() % 10000);
  }
  usleep(100000);
  return 0;
}

^ permalink raw reply

* [PATCH net-next] bpf, inode: add support for symlinks and fix mtime/ctime
From: Daniel Borkmann @ 2016-10-29  0:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, ast, tgraf, Daniel Borkmann

While commit bb35a6ef7da4 ("bpf, inode: allow for rename and link ops")
added support for hard links that can be used for prog and map nodes,
this work adds simple symlink support, which can be used f.e. for
directories also when unpriviledged and works with cmdline tooling that
understands S_IFLNK anyway. Since the switch in e27f4a942a0e ("bpf: Use
mount_nodev not mount_ns to mount the bpf filesystem"), there can be
various mount instances with mount_nodev() and thus hierarchy can be
flattened to facilitate object sharing. Thus, we can keep bpf tooling
also working by repointing paths.

Most of the functionality can be used from vfs library operations. The
symlink is stored in the inode itself, that is in i_link, which is
sufficient in our case as opposed to storing it in the page cache.
While at it, I noticed that bpf_mkdir() and bpf_mkobj() don't update
the directories mtime and ctime, so add a common helper for it called
bpf_dentry_finalize() that takes care of it for all cases now.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/inode.c | 45 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index 1ed8473..2565809 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -87,6 +87,7 @@ static struct inode *bpf_get_inode(struct super_block *sb,
 	switch (mode & S_IFMT) {
 	case S_IFDIR:
 	case S_IFREG:
+	case S_IFLNK:
 		break;
 	default:
 		return ERR_PTR(-EINVAL);
@@ -119,6 +120,16 @@ static int bpf_inode_type(const struct inode *inode, enum bpf_type *type)
 	return 0;
 }
 
+static void bpf_dentry_finalize(struct dentry *dentry, struct inode *inode,
+				struct inode *dir)
+{
+	d_instantiate(dentry, inode);
+	dget(dentry);
+
+	dir->i_mtime = current_time(dir);
+	dir->i_ctime = dir->i_mtime;
+}
+
 static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
 	struct inode *inode;
@@ -133,9 +144,7 @@ static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	inc_nlink(inode);
 	inc_nlink(dir);
 
-	d_instantiate(dentry, inode);
-	dget(dentry);
-
+	bpf_dentry_finalize(dentry, inode, dir);
 	return 0;
 }
 
@@ -151,9 +160,7 @@ static int bpf_mkobj_ops(struct inode *dir, struct dentry *dentry,
 	inode->i_op = iops;
 	inode->i_private = dentry->d_fsdata;
 
-	d_instantiate(dentry, inode);
-	dget(dentry);
-
+	bpf_dentry_finalize(dentry, inode, dir);
 	return 0;
 }
 
@@ -181,13 +188,37 @@ static int bpf_mkobj(struct inode *dir, struct dentry *dentry, umode_t mode,
 {
 	if (strchr(dentry->d_name.name, '.'))
 		return ERR_PTR(-EPERM);
+
 	return simple_lookup(dir, dentry, flags);
 }
 
+static int bpf_symlink(struct inode *dir, struct dentry *dentry,
+		       const char *target)
+{
+	char *link = kstrdup(target, GFP_USER | __GFP_NOWARN);
+	struct inode *inode;
+
+	if (!link)
+		return -ENOMEM;
+
+	inode = bpf_get_inode(dir->i_sb, dir, S_IRWXUGO | S_IFLNK);
+	if (IS_ERR(inode)) {
+		kfree(link);
+		return PTR_ERR(inode);
+	}
+
+	inode->i_op = &simple_symlink_inode_operations;
+	inode->i_link = link;
+
+	bpf_dentry_finalize(dentry, inode, dir);
+	return 0;
+}
+
 static const struct inode_operations bpf_dir_iops = {
 	.lookup		= bpf_lookup,
 	.mknod		= bpf_mkobj,
 	.mkdir		= bpf_mkdir,
+	.symlink	= bpf_symlink,
 	.rmdir		= simple_rmdir,
 	.rename		= simple_rename,
 	.link		= simple_link,
@@ -324,6 +355,8 @@ static void bpf_evict_inode(struct inode *inode)
 	truncate_inode_pages_final(&inode->i_data);
 	clear_inode(inode);
 
+	if (S_ISLNK(inode->i_mode))
+		kfree(inode->i_link);
 	if (!bpf_inode_type(inode, &type))
 		bpf_any_put(inode->i_private, type);
 }
-- 
1.9.3

^ permalink raw reply related

* Re: [PATCH] [v2 netfilter-next] netfilter: nf_tables: fib warnings
From: Florian Westphal @ 2016-10-28 23:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
	David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Florian Westphal, netfilter-devel, coreteam,
	netdev, linux-kernel
In-Reply-To: <20161028201810.1076559-1-arnd@arndb.de>

Arnd Bergmann <arnd@arndb.de> wrote:
> The newly added nft fib code produces two warnings:
> 
> net/ipv4/netfilter/nft_fib_ipv4.c: In function 'nft_fib4_eval':
> net/ipv4/netfilter/nft_fib_ipv4.c:80:6: error: unused variable 'i' [-Werror=unused-variable]
> net/ipv4/netfilter/nft_fib_ipv4.c: In function ‘nft_fib4_eval’:
> net/ipv4/netfilter/nft_fib_ipv4.c:137:6: error: ‘oif’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
> 
> The first one is obvious as the only user of that variable is
> inside of an #ifdef
> 
> The second one is a bit trickier. It's clear that oif is in fact
> uninitialized when it gets used when neither NFTA_FIB_F_IIF nor
> NFTA_FIB_F_OIF are set, and just setting it to NULL won't work
> as it may later get dereferenced.
> 
> However, there is no need to search the result list if it is
> NULL, as Florian pointed out. This integrates his (untested)
> change to do so. I have confirmed that the combined patch
> solves both warnings, but as I don't fully understand Florian's
> change, I can't tell if it's correct.
> 
> Suggested-by: Florian Westphal <fw@strlen.de>
> Fixes: 84f5eedb983e ("netfilter: nf_tables: add fib expression")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

chain pre {
        type filter hook prerouting priority 0; policy accept;
        fib saddr oif "eth0"
}

eth0: default route, 192.168.7.10/16
eth1: 10.0.0.2/8

ping from 192.168.7.1 from peer on eth0: result eth0, ok
ping from 10.0.0.2 from peer on eth0: no result, ok
ping from 10.0.0.3 from peer on eth0: result eth1, ok

chain pre {
	        type filter hook prerouting priority 0; policy accept;
	        fib saddr . iif oif "eth0"
}

ping from 192.168.7.1 from peer on eth0: result eth0, ok
ping from 10.0.0.2 from peer on eth0: no result, ok
ping from 10.0.0.3 from peer on eth0: no result, ok

so:

Tested-by: Florian Westphal <fw@strlen.de>

^ permalink raw reply

* Re: [PATCH net-next] genetlink: Fix generic netlink family unregister
From: Johannes Berg @ 2016-10-28 23:24 UTC (permalink / raw)
  To: Pravin B Shelar, netdev
In-Reply-To: <1477695701-1147-1-git-send-email-pshelar@ovn.org>

On Fri, 2016-10-28 at 16:01 -0700, Pravin B Shelar wrote:
> This patch fixes a typo in unregister operation.
> 
> Following crash is fixed by this patch. It can be easily reproduced
> by repeating modprobe and rmmod module that uses genetlink.

Yikes, I ran all my tests in VMs and forgot this wasn't even executed.
Sorry about that!

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

johannes

^ permalink raw reply

* [PATCH net-next] genetlink: Fix generic netlink family unregister
From: Pravin B Shelar @ 2016-10-28 23:01 UTC (permalink / raw)
  To: netdev; +Cc: Pravin B Shelar, Johannes Berg

This patch fixes a typo in unregister operation.

Following crash is fixed by this patch. It can be easily reproduced
by repeating modprobe and rmmod module that uses genetlink.

[  261.446686] BUG: unable to handle kernel paging request at ffffffffa0264088
[  261.448921] IP: [<ffffffff813cb70e>] strcmp+0xe/0x30
[  261.450494] PGD 1c09067
[  261.451266] PUD 1c0a063
[  261.452091] PMD 8068d5067
[  261.452525] PTE 0
[  261.453164]
[  261.453618] Oops: 0000 [#1] SMP
[  261.454577] Modules linked in: openvswitch(+) ...
[  261.480753] RIP: 0010:[<ffffffff813cb70e>]  [<ffffffff813cb70e>] strcmp+0xe/0x30
[  261.483069] RSP: 0018:ffffc90003c0bc28  EFLAGS: 00010282
[  261.510145] Call Trace:
[  261.510896]  [<ffffffff816f10ca>] genl_family_find_byname+0x5a/0x70
[  261.512819]  [<ffffffff816f2319>] genl_register_family+0xb9/0x630
[  261.514805]  [<ffffffffa02840bc>] dp_init+0xbc/0x120 [openvswitch]
[  261.518268]  [<ffffffff8100217d>] do_one_initcall+0x3d/0x160
[  261.525041]  [<ffffffff811808a9>] do_init_module+0x60/0x1f1
[  261.526754]  [<ffffffff8110687f>] load_module+0x22af/0x2860
[  261.530144]  [<ffffffff81107026>] SYSC_finit_module+0x96/0xd0
[  261.531901]  [<ffffffff8110707e>] SyS_finit_module+0xe/0x10
[  261.533605]  [<ffffffff8100391e>] do_syscall_64+0x6e/0x180
[  261.535284]  [<ffffffff817c2faf>] entry_SYSCALL64_slow_path+0x25/0x25
[  261.546512] RIP  [<ffffffff813cb70e>] strcmp+0xe/0x30
[  261.550198] ---[ end trace 76505a814dd68770 ]---

Fixes: 2ae0f17df1c ("genetlink: use idr to track families").

Reported-by: Jarno Rajahalme <jarno@ovn.org>
CC: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
---
 net/netlink/genetlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index df0cbcd..caf04d7 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -399,7 +399,7 @@ int genl_unregister_family(const struct genl_family *family)
 {
 	genl_lock_all();
 
-	if (genl_family_find_byid(family->id)) {
+	if (!genl_family_find_byid(family->id)) {
 		genl_unlock_all();
 		return -ENOENT;
 	}
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v2 0/5] make POSIX timers optional with some Kconfig help
From: Paul Bolle @ 2016-10-28 22:50 UTC (permalink / raw)
  To: Nicolas Pitre, John Stultz, Richard Cochran, Michal Marek
  Cc: Thomas Gleixner, Josh Triplett, Edward Cree, netdev, linux-kbuild,
	linux-kernel
In-Reply-To: <1477448931-29051-1-git-send-email-nicolas.pitre@linaro.org>

On Tue, 2016-10-25 at 22:28 -0400, Nicolas Pitre wrote:
> When POSIX timers are configured out, the PTP clock subsystem should be
> left out as well. However a bunch of ethernet drivers currently *select*
> the later in their Kconfig entries. Therefore some more work was needed
> to break that hard dependency from those drivers without preventing their
> usage altogether.

By the way: would you have pointers to threads that discussed attempts
to achieve this using currently available Kconfig options?

Thanks,


Paul Bolle

^ permalink raw reply

* Re: [PATCH 2/2] at803x: double check SGMII side autoneg
From: Timur Tabi @ 2016-10-28 22:24 UTC (permalink / raw)
  To: Zefir Kurtisi, netdev
In-Reply-To: <1477305654-11328-3-git-send-email-zefir.kurtisi@neratec.com>

Zefir Kurtisi wrote:
> +	/* check if the SGMII link is OK. */
> +	if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
> +		pr_warn("803x_aneg_done: SGMII link is not ok\n");
> +		aneg_done = 0;

I see this message appear sometimes when bring up the interface via 
ifup.  However, contrary to your patch description, everything seems to 
work:

$ iperf3 -c 192.168.1.1 -t 3600
Connecting to host 192.168.1.1, port 5201
[  4] local 192.168.1.2 port 52640 connected to 192.168.1.1 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec   109 MBytes   909 Mbits/sec    0    485 KBytes
[  4]   1.00-2.00   sec   108 MBytes   902 Mbits/sec    0    622 KBytes

I wonder if you're impacted with all of the pause frame problems I'm having.

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* Re: [PATCH v2 1/5] kconfig: introduce the "imply" keyword
From: Paul Bolle @ 2016-10-28 22:09 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: John Stultz, Richard Cochran, Michal Marek, Thomas Gleixner,
	Josh Triplett, Edward Cree, netdev, linux-kbuild, linux-kernel
In-Reply-To: <alpine.LFD.2.20.1610272156050.14694@knanqh.ubzr>

On Thu, 2016-10-27 at 23:10 -0400, Nicolas Pitre wrote:
> On Fri, 28 Oct 2016, Paul Bolle wrote:
> > And in your example BAR is bool, right? Does the above get more
> > complicated if BAR would be tristate?
> 
> If BAR=m then implying BAZ from FOO=y will force BAZ to y or n, 
> bypassing the restriction provided by BAR like "select" does.  This is 
> somewhat questionable for "select" to do that, and the code emits a 
> warning when "select" bypasses a direct dependency set to n, but not 
> when set to m. For now "imply" simply tries to be consistent with 
> the "select" behavior.

Side note: yes, one can select a symbol that's missing one or more
dependencies. But since Kconfig has two separate methods to describe
relations (ie, selecting and depending) there's logically the
possibility of conflict. So we need a rule to resolve that conflict.
That rule is: "select" beats "depends on". I don't think that this rule
is less plausible than the opposite rule.


Paul Bolle

^ permalink raw reply

* Re: [PATCH v2 1/5] kconfig: introduce the "imply" keyword
From: Nicolas Pitre @ 2016-10-28 22:03 UTC (permalink / raw)
  To: Paul Bolle
  Cc: John Stultz, Richard Cochran, Michal Marek, Thomas Gleixner,
	Josh Triplett, Edward Cree, netdev, linux-kbuild, linux-kernel
In-Reply-To: <1477690300.2167.26.camel@tiscali.nl>

On Fri, 28 Oct 2016, Paul Bolle wrote:

> On Thu, 2016-10-27 at 23:10 -0400, Nicolas Pitre wrote:
> > On Fri, 28 Oct 2016, Paul Bolle wrote:
> > > What happens when a tristate symbol is implied by a symbol set to 'y'
> > > and by a symbol set to 'm'?
> > 
> > That's respectively the third and second rows in the table above.
> 
> I meant: two separate symbols implying the same symbol at the same
> time. One of those symbols set to 'y' and the other set to 'm'.

Then it's the greatest of the set i.e. y.


Nicolas

^ permalink raw reply

* [net-next PATCH v2 4/4] net: Add support for XPS with QoS via traffic classes
From: Alexander Duyck @ 2016-10-28 15:50 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: john.r.fastabend, tom, davem
In-Reply-To: <20161028154126.67826.76735.stgit@ahduyck-blue-test.jf.intel.com>

This patch adds support for setting and using XPS when QoS via traffic
classes is enabled.  With this change we will factor in the priority and
traffic class mapping of the packet and use that information to correctly
select the queue.

This allows us to define a set of queues for a given traffic class via
mqprio and then configure the XPS mapping for those queues so that the
traffic flows can avoid head-of-line blocking between the individual CPUs
if so desired.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---

v2: Mostly for loop updates based on changes in patch 3
    Replaced "i = 0; i < X; i++" with "i = X; i--;" as i was just a counter

 include/linux/netdevice.h |    4 +-
 net/core/dev.c            |  117 ++++++++++++++++++++++++++++++++-------------
 net/core/net-sysfs.c      |   31 ++++++++----
 3 files changed, 105 insertions(+), 47 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b60a156..56f90f7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -732,8 +732,8 @@ struct xps_dev_maps {
 	struct rcu_head rcu;
 	struct xps_map __rcu *cpu_map[0];
 };
-#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) +		\
-    (nr_cpu_ids * sizeof(struct xps_map *)))
+#define XPS_DEV_MAPS_SIZE(_tcs) (sizeof(struct xps_dev_maps) +		\
+	(nr_cpu_ids * (_tcs) * sizeof(struct xps_map *)))
 #endif /* CONFIG_XPS */
 
 #define TC_MAX_QUEUE	16
diff --git a/net/core/dev.c b/net/core/dev.c
index fea7061..0ebb035 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2002,14 +2002,22 @@ static bool remove_xps_queue_cpu(struct net_device *dev,
 				 struct xps_dev_maps *dev_maps,
 				 int cpu, u16 offset, u16 count)
 {
-	int i, j;
+	int num_tc = dev->num_tc ? : 1;
+	bool active = false;
+	int tci;
 
-	for (i = count, j = offset; i--; j++) {
-		if (!remove_xps_queue(dev_maps, cpu, j))
-			break;
+	for (tci = cpu * num_tc; num_tc--; tci++) {
+		int i, j;
+
+		for (i = count, j = offset; i--; j++) {
+			if (!remove_xps_queue(dev_maps, cpu, j))
+				break;
+		}
+
+		active |= i < 0;
 	}
 
-	return i < 0;
+	return active;
 }
 
 static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
@@ -2086,20 +2094,28 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			u16 index)
 {
 	struct xps_dev_maps *dev_maps, *new_dev_maps = NULL;
+	int i, cpu, tci, numa_node_id = -2;
+	int maps_sz, num_tc = 1, tc = 0;
 	struct xps_map *map, *new_map;
-	int maps_sz = max_t(unsigned int, XPS_DEV_MAPS_SIZE, L1_CACHE_BYTES);
-	int cpu, numa_node_id = -2;
 	bool active = false;
 
+	if (dev->num_tc) {
+		num_tc = dev->num_tc;
+		tc = netdev_txq_to_tc(dev, index);
+		if (tc < 0)
+			return -EINVAL;
+	}
+
+	maps_sz = XPS_DEV_MAPS_SIZE(num_tc);
+	if (maps_sz < L1_CACHE_BYTES)
+		maps_sz = L1_CACHE_BYTES;
+
 	mutex_lock(&xps_map_mutex);
 
 	dev_maps = xmap_dereference(dev->xps_maps);
 
 	/* allocate memory for queue storage */
-	for_each_online_cpu(cpu) {
-		if (!cpumask_test_cpu(cpu, mask))
-			continue;
-
+	for_each_cpu_and(cpu, cpu_online_mask, mask) {
 		if (!new_dev_maps)
 			new_dev_maps = kzalloc(maps_sz, GFP_KERNEL);
 		if (!new_dev_maps) {
@@ -2107,25 +2123,38 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			return -ENOMEM;
 		}
 
-		map = dev_maps ? xmap_dereference(dev_maps->cpu_map[cpu]) :
+		tci = cpu * num_tc + tc;
+		map = dev_maps ? xmap_dereference(dev_maps->cpu_map[tci]) :
 				 NULL;
 
 		map = expand_xps_map(map, cpu, index);
 		if (!map)
 			goto error;
 
-		RCU_INIT_POINTER(new_dev_maps->cpu_map[cpu], map);
+		RCU_INIT_POINTER(new_dev_maps->cpu_map[tci], map);
 	}
 
 	if (!new_dev_maps)
 		goto out_no_new_maps;
 
 	for_each_possible_cpu(cpu) {
+		/* copy maps belonging to foreign traffic classes */
+		for (i = tc, tci = cpu * num_tc; dev_maps && i--; tci++) {
+			/* fill in the new device map from the old device map */
+			map = xmap_dereference(dev_maps->cpu_map[tci]);
+			RCU_INIT_POINTER(new_dev_maps->cpu_map[tci], map);
+		}
+
+		/* We need to explicitly update tci as prevous loop
+		 * could break out early if dev_maps is NULL.
+		 */
+		tci = cpu * num_tc + tc;
+
 		if (cpumask_test_cpu(cpu, mask) && cpu_online(cpu)) {
 			/* add queue to CPU maps */
 			int pos = 0;
 
-			map = xmap_dereference(new_dev_maps->cpu_map[cpu]);
+			map = xmap_dereference(new_dev_maps->cpu_map[tci]);
 			while ((pos < map->len) && (map->queues[pos] != index))
 				pos++;
 
@@ -2139,26 +2168,36 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 #endif
 		} else if (dev_maps) {
 			/* fill in the new device map from the old device map */
-			map = xmap_dereference(dev_maps->cpu_map[cpu]);
-			RCU_INIT_POINTER(new_dev_maps->cpu_map[cpu], map);
+			map = xmap_dereference(dev_maps->cpu_map[tci]);
+			RCU_INIT_POINTER(new_dev_maps->cpu_map[tci], map);
 		}
 
+		/* copy maps belonging to foreign traffic classes */
+		for (i = num_tc - tc, tci++; dev_maps && --i; tci++) {
+			/* fill in the new device map from the old device map */
+			map = xmap_dereference(dev_maps->cpu_map[tci]);
+			RCU_INIT_POINTER(new_dev_maps->cpu_map[tci], map);
+		}
 	}
 
 	rcu_assign_pointer(dev->xps_maps, new_dev_maps);
 
 	/* Cleanup old maps */
-	if (dev_maps) {
-		for_each_possible_cpu(cpu) {
-			new_map = xmap_dereference(new_dev_maps->cpu_map[cpu]);
-			map = xmap_dereference(dev_maps->cpu_map[cpu]);
+	if (!dev_maps)
+		goto out_no_old_maps;
+
+	for_each_possible_cpu(cpu) {
+		for (i = num_tc, tci = cpu * num_tc; i--; tci++) {
+			new_map = xmap_dereference(new_dev_maps->cpu_map[tci]);
+			map = xmap_dereference(dev_maps->cpu_map[tci]);
 			if (map && map != new_map)
 				kfree_rcu(map, rcu);
 		}
-
-		kfree_rcu(dev_maps, rcu);
 	}
 
+	kfree_rcu(dev_maps, rcu);
+
+out_no_old_maps:
 	dev_maps = new_dev_maps;
 	active = true;
 
@@ -2173,11 +2212,12 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 
 	/* removes queue from unused CPUs */
 	for_each_possible_cpu(cpu) {
-		if (cpumask_test_cpu(cpu, mask) && cpu_online(cpu))
-			continue;
-
-		if (remove_xps_queue(dev_maps, cpu, index))
-			active = true;
+		for (i = tc, tci = cpu * num_tc; i--; tci++)
+			active |= remove_xps_queue(dev_maps, tci, index);
+		if (!cpumask_test_cpu(cpu, mask) || !cpu_online(cpu))
+			active |= remove_xps_queue(dev_maps, tci, index);
+		for (i = num_tc - tc, tci++; --i; tci++)
+			active |= remove_xps_queue(dev_maps, tci, index);
 	}
 
 	/* free map if not active */
@@ -2193,11 +2233,14 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 error:
 	/* remove any maps that we added */
 	for_each_possible_cpu(cpu) {
-		new_map = xmap_dereference(new_dev_maps->cpu_map[cpu]);
-		map = dev_maps ? xmap_dereference(dev_maps->cpu_map[cpu]) :
-				 NULL;
-		if (new_map && new_map != map)
-			kfree(new_map);
+		for (i = num_tc, tci = cpu * num_tc; i--; tci++) {
+			new_map = xmap_dereference(new_dev_maps->cpu_map[tci]);
+			map = dev_maps ?
+			      xmap_dereference(dev_maps->cpu_map[tci]) :
+			      NULL;
+			if (new_map && new_map != map)
+				kfree(new_map);
+		}
 	}
 
 	mutex_unlock(&xps_map_mutex);
@@ -3157,8 +3200,14 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
 	rcu_read_lock();
 	dev_maps = rcu_dereference(dev->xps_maps);
 	if (dev_maps) {
-		map = rcu_dereference(
-		    dev_maps->cpu_map[skb->sender_cpu - 1]);
+		unsigned int tci = skb->sender_cpu - 1;
+
+		if (dev->num_tc) {
+			tci *= dev->num_tc;
+			tci += netdev_get_prio_tc_map(dev, skb->priority);
+		}
+
+		map = rcu_dereference(dev_maps->cpu_map[tci]);
 		if (map) {
 			if (map->len == 1)
 				queue_index = map->queues[0];
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index c4e4e7d..3b2b935 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1207,29 +1207,38 @@ static ssize_t show_xps_map(struct netdev_queue *queue,
 			    struct netdev_queue_attribute *attribute, char *buf)
 {
 	struct net_device *dev = queue->dev;
+	int cpu, len, num_tc = 1, tc = 0;
 	struct xps_dev_maps *dev_maps;
 	cpumask_var_t mask;
 	unsigned long index;
-	int i, len;
 
 	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
 		return -ENOMEM;
 
 	index = get_netdev_queue_index(queue);
 
+	if (dev->num_tc) {
+		num_tc = dev->num_tc;
+		tc = netdev_txq_to_tc(dev, index);
+		if (tc < 0)
+			return -EINVAL;
+	}
+
 	rcu_read_lock();
 	dev_maps = rcu_dereference(dev->xps_maps);
 	if (dev_maps) {
-		for_each_possible_cpu(i) {
-			struct xps_map *map =
-			    rcu_dereference(dev_maps->cpu_map[i]);
-			if (map) {
-				int j;
-				for (j = 0; j < map->len; j++) {
-					if (map->queues[j] == index) {
-						cpumask_set_cpu(i, mask);
-						break;
-					}
+		for_each_possible_cpu(cpu) {
+			int i, tci = cpu * num_tc + tc;
+			struct xps_map *map;
+
+			map = rcu_dereference(dev_maps->cpu_map[tci]);
+			if (!map)
+				continue;
+
+			for (i = map->len; i--;) {
+				if (map->queues[i] == index) {
+					cpumask_set_cpu(cpu, mask);
+					break;
 				}
 			}
 		}

^ permalink raw reply related

* [net-next PATCH v2 3/4] net: Refactor removal of queues from XPS map and apply on num_tc changes
From: Alexander Duyck @ 2016-10-28 15:46 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: john.r.fastabend, tom, davem
In-Reply-To: <20161028154126.67826.76735.stgit@ahduyck-blue-test.jf.intel.com>

This patch updates the code for removing queues from the XPS map and makes
it so that we can apply the code any time we change either the number of
traffic classes or the mapping of a given block of queues.  This way we
avoid having queues pulling traffic from a foreign traffic class.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---

v2: Replaced do/while with for loop
    Changed order for remove_xps_queue_cpu loop
    Updated i to reflect count, j to be temporary offset
    Updated test to check for i < 0 instead of i < offset

 net/core/dev.c |   73 ++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 23 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 08ed625..fea7061 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1970,32 +1970,50 @@ int netdev_txq_to_tc(struct net_device *dev, unsigned int txq)
 #define xmap_dereference(P)		\
 	rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex))
 
-static struct xps_map *remove_xps_queue(struct xps_dev_maps *dev_maps,
-					int cpu, u16 index)
+static bool remove_xps_queue(struct xps_dev_maps *dev_maps,
+			     int tci, u16 index)
 {
 	struct xps_map *map = NULL;
 	int pos;
 
 	if (dev_maps)
-		map = xmap_dereference(dev_maps->cpu_map[cpu]);
+		map = xmap_dereference(dev_maps->cpu_map[tci]);
+	if (!map)
+		return false;
 
-	for (pos = 0; map && pos < map->len; pos++) {
-		if (map->queues[pos] == index) {
-			if (map->len > 1) {
-				map->queues[pos] = map->queues[--map->len];
-			} else {
-				RCU_INIT_POINTER(dev_maps->cpu_map[cpu], NULL);
-				kfree_rcu(map, rcu);
-				map = NULL;
-			}
+	for (pos = map->len; pos--;) {
+		if (map->queues[pos] != index)
+			continue;
+
+		if (map->len > 1) {
+			map->queues[pos] = map->queues[--map->len];
 			break;
 		}
+
+		RCU_INIT_POINTER(dev_maps->cpu_map[tci], NULL);
+		kfree_rcu(map, rcu);
+		return false;
 	}
 
-	return map;
+	return true;
 }
 
-static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
+static bool remove_xps_queue_cpu(struct net_device *dev,
+				 struct xps_dev_maps *dev_maps,
+				 int cpu, u16 offset, u16 count)
+{
+	int i, j;
+
+	for (i = count, j = offset; i--; j++) {
+		if (!remove_xps_queue(dev_maps, cpu, j))
+			break;
+	}
+
+	return i < 0;
+}
+
+static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
+				   u16 count)
 {
 	struct xps_dev_maps *dev_maps;
 	int cpu, i;
@@ -2007,21 +2025,16 @@ static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
 	if (!dev_maps)
 		goto out_no_maps;
 
-	for_each_possible_cpu(cpu) {
-		for (i = index; i < dev->num_tx_queues; i++) {
-			if (!remove_xps_queue(dev_maps, cpu, i))
-				break;
-		}
-		if (i == dev->num_tx_queues)
-			active = true;
-	}
+	for_each_possible_cpu(cpu)
+		active |= remove_xps_queue_cpu(dev, dev_maps, cpu,
+					       offset, count);
 
 	if (!active) {
 		RCU_INIT_POINTER(dev->xps_maps, NULL);
 		kfree_rcu(dev_maps, rcu);
 	}
 
-	for (i = index; i < dev->num_tx_queues; i++)
+	for (i = offset + (count - 1); count--; i--)
 		netdev_queue_numa_node_write(netdev_get_tx_queue(dev, i),
 					     NUMA_NO_NODE);
 
@@ -2029,6 +2042,11 @@ static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
 	mutex_unlock(&xps_map_mutex);
 }
 
+static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
+{
+	netif_reset_xps_queues(dev, index, dev->num_tx_queues - index);
+}
+
 static struct xps_map *expand_xps_map(struct xps_map *map,
 				      int cpu, u16 index)
 {
@@ -2192,6 +2210,9 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 #endif
 void netdev_reset_tc(struct net_device *dev)
 {
+#ifdef CONFIG_XPS
+	netif_reset_xps_queues_gt(dev, 0);
+#endif
 	dev->num_tc = 0;
 	memset(dev->tc_to_txq, 0, sizeof(dev->tc_to_txq));
 	memset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));
@@ -2203,6 +2224,9 @@ int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
 	if (tc >= dev->num_tc)
 		return -EINVAL;
 
+#ifdef CONFIG_XPS
+	netif_reset_xps_queues(dev, offset, count);
+#endif
 	dev->tc_to_txq[tc].count = count;
 	dev->tc_to_txq[tc].offset = offset;
 	return 0;
@@ -2214,6 +2238,9 @@ int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
 	if (num_tc > TC_MAX_QUEUE)
 		return -EINVAL;
 
+#ifdef CONFIG_XPS
+	netif_reset_xps_queues_gt(dev, 0);
+#endif
 	dev->num_tc = num_tc;
 	return 0;
 }

^ permalink raw reply related

* [net-next PATCH v2 2/4] net: Add sysfs value to determine queue traffic class
From: Alexander Duyck @ 2016-10-28 15:43 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: john.r.fastabend, tom, davem
In-Reply-To: <20161028154126.67826.76735.stgit@ahduyck-blue-test.jf.intel.com>

Add a sysfs attribute for a Tx queue that allows us to determine the
traffic class for a given queue.  This will allow us to more easily
determine this in the future.  It is needed as XPS will take the traffic
class for a group of queues into account in order to avoid pulling traffic
from one traffic class into another.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---

v2: Added this patch to the series.

 include/linux/netdevice.h |    1 +
 net/core/dev.c            |   17 +++++++++++++++++
 net/core/net-sysfs.c      |   20 +++++++++++++++++++-
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d045432..b60a156 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1920,6 +1920,7 @@ int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
 	return 0;
 }
 
+int netdev_txq_to_tc(struct net_device *dev, unsigned int txq);
 void netdev_reset_tc(struct net_device *dev);
 int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset);
 int netdev_set_num_tc(struct net_device *dev, u8 num_tc);
diff --git a/net/core/dev.c b/net/core/dev.c
index d4d45bf..08ed625 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1948,6 +1948,23 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
 	}
 }
 
+int netdev_txq_to_tc(struct net_device *dev, unsigned int txq)
+{
+	if (dev->num_tc) {
+		struct netdev_tc_txq *tc = &dev->tc_to_txq[0];
+		int i;
+
+		for (i = 0; i < TC_MAX_QUEUE; i++, tc++) {
+			if ((txq - tc->offset) < tc->count)
+				return i;
+		}
+
+		return -1;
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_XPS
 static DEFINE_MUTEX(xps_map_mutex);
 #define xmap_dereference(P)		\
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 6e4f347..c4e4e7d 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1021,7 +1021,6 @@ static ssize_t show_trans_timeout(struct netdev_queue *queue,
 	return sprintf(buf, "%lu", trans_timeout);
 }
 
-#ifdef CONFIG_XPS
 static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
 {
 	struct net_device *dev = queue->dev;
@@ -1033,6 +1032,21 @@ static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
 	return i;
 }
 
+static ssize_t show_traffic_class(struct netdev_queue *queue,
+				  struct netdev_queue_attribute *attribute,
+				  char *buf)
+{
+	struct net_device *dev = queue->dev;
+	int index = get_netdev_queue_index(queue);
+	int tc = netdev_txq_to_tc(dev, index);
+
+	if (tc < 0)
+		return -EINVAL;
+
+	return sprintf(buf, "%u\n", tc);
+}
+
+#ifdef CONFIG_XPS
 static ssize_t show_tx_maxrate(struct netdev_queue *queue,
 			       struct netdev_queue_attribute *attribute,
 			       char *buf)
@@ -1075,6 +1089,9 @@ static ssize_t set_tx_maxrate(struct netdev_queue *queue,
 static struct netdev_queue_attribute queue_trans_timeout =
 	__ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
 
+static struct netdev_queue_attribute queue_traffic_class =
+	__ATTR(traffic_class, S_IRUGO, show_traffic_class, NULL);
+
 #ifdef CONFIG_BQL
 /*
  * Byte queue limits sysfs structures and functions.
@@ -1260,6 +1277,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
 
 static struct attribute *netdev_queue_default_attrs[] = {
 	&queue_trans_timeout.attr,
+	&queue_traffic_class.attr,
 #ifdef CONFIG_XPS
 	&xps_cpus_attribute.attr,
 	&queue_tx_maxrate.attr,

^ permalink raw reply related

* [net-next PATCH v2 1/4] net: Move functions for configuring traffic classes out of inline headers
From: Alexander Duyck @ 2016-10-28 15:43 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: john.r.fastabend, tom, davem
In-Reply-To: <20161028154126.67826.76735.stgit@ahduyck-blue-test.jf.intel.com>

The functions for configuring the traffic class to queue mappings have
other effects that need to be addressed.  Instead of trying to export a
bunch of new functions just relocate the functions so that we can
instrument them directly with the functionality they will need.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 include/linux/netdevice.h |   31 +++----------------------------
 net/core/dev.c            |   29 +++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 458c876..d045432 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1920,34 +1920,9 @@ int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
 	return 0;
 }
 
-static inline
-void netdev_reset_tc(struct net_device *dev)
-{
-	dev->num_tc = 0;
-	memset(dev->tc_to_txq, 0, sizeof(dev->tc_to_txq));
-	memset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));
-}
-
-static inline
-int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
-{
-	if (tc >= dev->num_tc)
-		return -EINVAL;
-
-	dev->tc_to_txq[tc].count = count;
-	dev->tc_to_txq[tc].offset = offset;
-	return 0;
-}
-
-static inline
-int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
-{
-	if (num_tc > TC_MAX_QUEUE)
-		return -EINVAL;
-
-	dev->num_tc = num_tc;
-	return 0;
-}
+void netdev_reset_tc(struct net_device *dev);
+int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset);
+int netdev_set_num_tc(struct net_device *dev, u8 num_tc);
 
 static inline
 int netdev_get_num_tc(struct net_device *dev)
diff --git a/net/core/dev.c b/net/core/dev.c
index f55fb45..d4d45bf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2173,6 +2173,35 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 EXPORT_SYMBOL(netif_set_xps_queue);
 
 #endif
+void netdev_reset_tc(struct net_device *dev)
+{
+	dev->num_tc = 0;
+	memset(dev->tc_to_txq, 0, sizeof(dev->tc_to_txq));
+	memset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));
+}
+EXPORT_SYMBOL(netdev_reset_tc);
+
+int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
+{
+	if (tc >= dev->num_tc)
+		return -EINVAL;
+
+	dev->tc_to_txq[tc].count = count;
+	dev->tc_to_txq[tc].offset = offset;
+	return 0;
+}
+EXPORT_SYMBOL(netdev_set_tc_queue);
+
+int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
+{
+	if (num_tc > TC_MAX_QUEUE)
+		return -EINVAL;
+
+	dev->num_tc = num_tc;
+	return 0;
+}
+EXPORT_SYMBOL(netdev_set_num_tc);
+
 /*
  * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
  * greater then real_num_tx_queues stale skbs on the qdisc must be flushed.

^ permalink raw reply related

* [net-next PATCH v2 0/4] Add support for XPS when using DCB
From: Alexander Duyck @ 2016-10-28 15:42 UTC (permalink / raw)
  To: netdev, intel-wired-lan; +Cc: john.r.fastabend, tom, davem

This patch series enables proper isolation between traffic classes when
using XPS while DCB is enabled.  Previously enabling XPS would cause the
traffic to be potentially pulled from one traffic class into another on
egress.  This change essentially multiplies the XPS map by the number of
traffic classes and allows us to do a lookup per traffic class for a given
CPU.

To guarantee the isolation I invalidate the XPS map for any queues that are
moved from one traffic class to another, or if we change the number of
traffic classes.

v2: Added sysfs to display traffic class
    Replaced do/while with for loop
    Cleaned up several other for for loops throughout the patch

---

Alexander Duyck (4):
      net: Move functions for configuring traffic classes out of inline headers
      net: Add sysfs value to determine queue traffic class
      net: Refactor removal of queues from XPS map and apply on num_tc changes
      net: Add support for XPS with QoS via traffic classes


 include/linux/netdevice.h |   36 +------
 net/core/dev.c            |  226 +++++++++++++++++++++++++++++++++++----------
 net/core/net-sysfs.c      |   51 ++++++++--
 3 files changed, 219 insertions(+), 94 deletions(-)

^ permalink raw reply

* Re: [PATCH net 2/3] sctp: return back transport in __sctp_rcv_init_lookup
From: Marcelo Ricardo Leitner @ 2016-10-28 21:39 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Vlad Yasevich, daniel
In-Reply-To: <20161028194221.GC4193@localhost.localdomain>

On Fri, Oct 28, 2016 at 05:42:21PM -0200, Marcelo Ricardo Leitner wrote:
> On Fri, Oct 28, 2016 at 06:10:53PM +0800, Xin Long wrote:
> > Prior to this patch, it used a local variable to save the transport that is
> > looked up by __sctp_lookup_association(), and didn't return it back. But in
> > sctp_rcv, it is used to initialize chunk->transport. So when hitting this
> > code, it was initializing chunk->transport with some random stack value
> > instead.
> > 
> > This patch is to return the transport back through transport pointer
> > that is from __sctp_rcv_lookup_harder().
> > 
> > Signed-off-by: Xin Long <lucien.xin@gmail.com>
> 
> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
> 
> transport pointer in sctp_rcv() is initialized to null and there are
> checks for it after this path, so this shouldn't be exploitable, just
> malfunction.

This actually sort of contradicts the changelog.

Xin, did I miss something here? Seems we need to update the changelog if
not.

^ permalink raw reply

* Re: Why do we need tasklet in IFB?
From: Stephen Hemminger @ 2016-10-28 21:38 UTC (permalink / raw)
  To: Michael Ma; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAAmHdhz_g5_+Uqp47cPm3NQd=8=9tCecddQLVCfHbChx=Tjhcw@mail.gmail.com>

On Fri, 28 Oct 2016 14:36:27 -0700
Michael Ma <make0818@gmail.com> wrote:

> Hi -
> 
> Currently IFB uses tasklet to process tx/rx on the interface that
> forwarded the packet to IFB. My understanding on why we're doing this
> is that since dev_queue_xmit() can be invoked in interrupt, we want to
> defer the processing of original tx/rx in case ifb_xmit() is called
> from interrupt.

dev_queue_xmit is only called from interrupt if doing netconsole.

^ permalink raw reply

* Why do we need tasklet in IFB?
From: Michael Ma @ 2016-10-28 21:36 UTC (permalink / raw)
  To: Linux Kernel Network Developers

Hi -

Currently IFB uses tasklet to process tx/rx on the interface that
forwarded the packet to IFB. My understanding on why we're doing this
is that since dev_queue_xmit() can be invoked in interrupt, we want to
defer the processing of original tx/rx in case ifb_xmit() is called
from interrupt.

However, if the packet is originally from rx, calling context should
already be a tasklet and there is no need to queue the processing to
another tasklet anymore. Even if the packet is originated from tx, we
can rely on the deferred processing of the "original device" or TC if
necessary. Did I miss anything here?

Furthermore, looking at the bonding device's code there isn't this
kind of buffering/tasklet handling for packet forwarding even though
bond also has its own txq/rxq configured separately from the actual
nic, which is very similar to IFB.

So why do we need tasklet in IFB?

Thanks,
Michael

^ permalink raw reply

* Re: [PATCH v2 1/5] kconfig: introduce the "imply" keyword
From: Paul Bolle @ 2016-10-28 21:31 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: John Stultz, Richard Cochran, Michal Marek, Thomas Gleixner,
	Josh Triplett, Edward Cree, netdev, linux-kbuild, linux-kernel
In-Reply-To: <alpine.LFD.2.20.1610272156050.14694@knanqh.ubzr>

On Thu, 2016-10-27 at 23:10 -0400, Nicolas Pitre wrote:
> On Fri, 28 Oct 2016, Paul Bolle wrote:
> > What happens when a tristate symbol is implied by a symbol set to 'y'
> > and by a symbol set to 'm'?
> 
> That's respectively the third and second rows in the table above.

I meant: two separate symbols implying the same symbol at the same
time. One of those symbols set to 'y' and the other set to 'm'.

Anyhow, I hope to play with a mock Kconfig fragment the next few days
to find out myself.

Thanks,


Paul Bolle

^ permalink raw reply

* Re: [PATCH 17/17] batman-adv: Avoid precedence issues in macros
From: Sven Eckelmann @ 2016-10-28 21:27 UTC (permalink / raw)
  To: Joe Perches
  Cc: Simon Wunderlich, davem, netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1477689186.23018.1.camel@perches.com>

[-- Attachment #1: Type: text/plain, Size: 1209 bytes --]

On Freitag, 28. Oktober 2016 14:13:06 CEST Joe Perches wrote:
> On Thu, 2016-10-27 at 21:01 +0200, Simon Wunderlich wrote:
> > From: Sven Eckelmann <sven@narfation.org>
> > 
> > It must be avoided that arguments to a macro are evaluated ungrouped (which
> > enforces normal operator precendence). Otherwise the result of the macro
> > is not well defined.
> 
> Curiosity:
> 
> in net/batman-adv/tp_meter.c
[...]
> 	orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
> 	if (unlikely(!orig_node)) {
> 		err = BATADV_TP_REASON_DST_UNREACHABLE;
> 		tp_vars->reason = err;
> 		goto out;
> 	}
> 
> 	primary_if = batadv_primary_if_get_selected(bat_priv);
> 	if (unlikely(!primary_if)) {
> 		err = BATADV_TP_REASON_DST_UNREACHABLE;
> 		goto out;
> 	}
> 
> err is not used in the out block
> 
> Is the last if block supposed to set tp_vars->reason to err?

This seems to be unrelated to this patch.

But yes, looks to me like it is missing. Do you want to propose a patch or
should I do? Just make sure you Cc Antonio Quartulli <a@unstable.cc> (and of
course b.a.t.m.a.n@lists.open-mesh.org). He is the original author of
33a3bb4a3345 ("batman-adv: throughput meter implementation").

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/5] kconfig: introduce the "imply" keyword
From: Paul Bolle @ 2016-10-28 21:26 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: John Stultz, Richard Cochran, Michal Marek, Thomas Gleixner,
	Josh Triplett, Edward Cree, netdev, linux-kbuild, linux-kernel
In-Reply-To: <alpine.LFD.2.20.1610272156050.14694@knanqh.ubzr>

On Thu, 2016-10-27 at 23:10 -0400, Nicolas Pitre wrote:
> On Fri, 28 Oct 2016, Paul Bolle wrote:
> > You probably got "["if" <expr>]" for free by copying what's there for
> > select. But this series doesn't use it, so perhaps it would be better
> > to not document it yet. But that is rather sneaky. Dunno.
> 
> If it is not documented then the chance that someone uses it are slim. 
> And since it comes "for free" I don't see the point of making the tool 
> less flexible. And not having this flexibility could make some 
> transitions from "select" to "imply" needlessly difficult.

My point is moot. I somehow missed that this series adds
    imply PTP_1588_CLOCK if TILEGX

So you are quite right in documenting this.


Paul Bolle

^ permalink raw reply

* Re: [PATCH net] net: clear sk_err_soft in sk_clone_lock()
From: Soheil Hassas Yeganeh @ 2016-10-28 21:25 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1477687224.7065.261.camel@edumazet-glaptop3.roam.corp.google.com>

On Fri, Oct 28, 2016 at 4:40 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> At accept() time, it is possible the parent has a non zero
> sk_err_soft, leftover from a prior error.
>
> Make sure we do not leave this value in the child, as it
> makes future getsockopt(SO_ERROR) calls quite unreliable.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>

> ---
>  net/core/sock.c |    1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/net/core/sock.c b/net/core/sock.c
> index d8e4532e89e7c28737c95c723e5f5b3d184a7805..662ccf1c40ed1b66ee253b063dcbfbd186deccee 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -1543,6 +1543,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
>                 RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL);
>
>                 newsk->sk_err      = 0;
> +               newsk->sk_err_soft = 0;
>                 newsk->sk_priority = 0;
>                 newsk->sk_incoming_cpu = raw_smp_processor_id();
>                 atomic64_set(&newsk->sk_cookie, 0);
>
>

Very nice catch! Thank you, Eric!

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox