1. 10 Aug, 2017 16 commits
  2. 09 Aug, 2017 24 commits
    • David S. Miller's avatar
      Merge branch 'rtnetlink-allow-selected-handlers-to-run-without-rtnl' · cd9cb389
      David S. Miller authored
      Florian Westphal says:
      
      ====================
      rtnetlink: allow selected handlers to run without rtnl
      
      Changes since v1:
       In patch 6, don't make ipv6 route handlers lockless, they all have
       assumptions on rtnl being held.  Other patches are unchanged.
      
      The RTNL mutex is used to serialize both rtnetlink calls and
      dump requests.
      Its also used to protect other things such as the list of current
      net namespaces.
      
      Unfortunately RTNL mutex is a performance issue, e.g. a cpu adding an
      ip address prevents other cpus from seemingly unrelated tasks such as
      dumping tc classifiers or doing rtnetlink route lookups.
      
      This patch set adds basic infrastructure to start pushing the rtnl lock
      down to those places that need it, or even elide it entirely in some cases.
      
      Subsystems can now indicate that their doit() callback can run without
      RTNL mutex, such callbacks can then run in parallel.
      
      This will obviously need a lot of followup work; all current
      users need to be audited/changed to benefit from this.
      Initial no-rtnl spot is netns new/getid.
      
      We have various 'get' handlers that are also a tempting target,
      however, several of these depend on rtnl mutex to prevent information
      from changing while objects are being read by rtnl handlers; however,
      it doesn't appear impossible to change this.
      
      Dumps are another problem entirely, see
      commit 2907c35f ("net: hold rtnl again in dump callbacks"),
      this patchset doesn't touch dump requests.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      cd9cb389
    • Florian Westphal's avatar
      net: call newid/getid without rtnl mutex held · 165b9117
      Florian Westphal authored
      Both functions take nsid_lock and don't rely on rtnl lock.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      165b9117
    • Florian Westphal's avatar
      rtnetlink: add RTNL_FLAG_DOIT_UNLOCKED · 62256f98
      Florian Westphal authored
      Allow callers to tell rtnetlink core that its doit callback
      should be invoked without holding rtnl mutex.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      62256f98
    • Florian Westphal's avatar
      rtnetlink: protect handler table with rcu · 6853dd48
      Florian Westphal authored
      Note that netlink dumps still acquire rtnl mutex via the netlink
      dump infrastructure.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      6853dd48
    • Florian Westphal's avatar
      rtnetlink: small rtnl lock pushdown · 0cc09020
      Florian Westphal authored
      instead of rtnl lock/unload at the top level, push it down
      to the called function.
      
      This is just an intermediate step, next commit switches protection
      of the rtnl_link ops table to rcu, in which case (for dumps) the
      rtnl lock is acquired only by the netlink dumper infrastructure
      (current lock/unlock/dump/lock/unlock rtnl sequence becomes
       rcu lock/rcu unlock/dump).
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      0cc09020
    • Florian Westphal's avatar
      rtnetlink: add reference counting to prevent module unload while dump is in progress · 019a3169
      Florian Westphal authored
      I don't see what prevents rmmod (unregister_all is called) while a dump
      is active.
      
      Even if we'd add rtnl lock/unlock pair to unregister_all (as done here),
      thats not enough either as rtnl_lock is released right before the dump
      process starts.
      
      So this adds a refcount:
       * acquire rtnl mutex
       * bump refcount
       * release mutex
       * start the dump
      
      ... and make unregister_all remove the callbacks (no new dumps possible)
      and then wait until refcount is 0.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      019a3169
    • Florian Westphal's avatar
      rtnetlink: make rtnl_register accept a flags parameter · b97bac64
      Florian Westphal authored
      This change allows us to later indicate to rtnetlink core that certain
      doit functions should be called without acquiring rtnl_mutex.
      
      This change should have no effect, we simply replace the last (now
      unused) calcit argument with the new flag.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      b97bac64
    • Florian Westphal's avatar
      rtnetlink: call rtnl_calcit directly · e1fa6d21
      Florian Westphal authored
      There is only a single place in the kernel that regisers the "calcit"
      callback (to determine min allocation for dumps).
      
      This is in rtnetlink.c for PF_UNSPEC RTM_GETLINK.
      The function that checks for calcit presence at run time will first check
      the requested family (which will always fail for !PF_UNSPEC as no callsite
      registers this), then falls back to checking PF_UNSPEC.
      
      Therefore we can just check if type is RTM_GETLINK and then do a direct
      call.  Because of fallback to PF_UNSPEC all RTM_GETLINK types used this
      regardless of family.
      
      This has the advantage that we don't need to allocate space for
      the function pointer for all the other families.
      
      A followup patch will drop the calcit function pointer from the
      rtnl_link callback structure.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      e1fa6d21
    • David S. Miller's avatar
      Merge branch 'bpf-new-branches' · 078295fb
      David S. Miller authored
      Daniel Borkmann says:
      
      ====================
      bpf: Add BPF_J{LT,LE,SLT,SLE} instructions
      
      This set adds BPF_J{LT,LE,SLT,SLE} instructions to the BPF
      insn set, interpreter, JIT hardening code and all JITs are
      also updated to support the new instructions. Basic idea is
      to reduce register pressure by avoiding BPF_J{GT,GE,SGT,SGE}
      rewrites. Removing the workaround for the rewrites in LLVM,
      this can result in shorter BPF programs, less stack usage
      and less verification complexity. First patch provides some
      more details on rationale and integration.
      
      Thanks a lot!
      
      v1 -> v2:
        - Reworded commit msg in patch 1
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      078295fb
    • Daniel Borkmann's avatar
      bpf: add test cases for new BPF_J{LT, LE, SLT, SLE} instructions · 31e482bf
      Daniel Borkmann authored
      Add test cases to the verifier selftest suite in order to verify that
      i) direct packet access, and ii) dynamic map value access is working
      with the changes related to the new instructions.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      31e482bf
    • Daniel Borkmann's avatar
      bpf: enable BPF_J{LT, LE, SLT, SLE} opcodes in verifier · b4e432f1
      Daniel Borkmann authored
      Enable the newly added jump opcodes, main parts are in two
      different areas, namely direct packet access and dynamic map
      value access. For the direct packet access, we now allow for
      the following two new patterns to match in order to trigger
      markings with find_good_pkt_pointers():
      
      Variant 1 (access ok when taking the branch):
      
        0: (61) r2 = *(u32 *)(r1 +76)
        1: (61) r3 = *(u32 *)(r1 +80)
        2: (bf) r0 = r2
        3: (07) r0 += 8
        4: (ad) if r0 < r3 goto pc+2
        R0=pkt(id=0,off=8,r=0) R1=ctx R2=pkt(id=0,off=0,r=0)
        R3=pkt_end R10=fp
        5: (b7) r0 = 0
        6: (95) exit
      
        from 4 to 7: R0=pkt(id=0,off=8,r=8) R1=ctx
                     R2=pkt(id=0,off=0,r=8) R3=pkt_end R10=fp
        7: (71) r0 = *(u8 *)(r2 +0)
        8: (05) goto pc-4
        5: (b7) r0 = 0
        6: (95) exit
        processed 11 insns, stack depth 0
      
      Variant 2 (access ok on fall-through):
      
        0: (61) r2 = *(u32 *)(r1 +76)
        1: (61) r3 = *(u32 *)(r1 +80)
        2: (bf) r0 = r2
        3: (07) r0 += 8
        4: (bd) if r3 <= r0 goto pc+1
        R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8)
        R3=pkt_end R10=fp
        5: (71) r0 = *(u8 *)(r2 +0)
        6: (b7) r0 = 1
        7: (95) exit
      
        from 4 to 6: R0=pkt(id=0,off=8,r=0) R1=ctx
                     R2=pkt(id=0,off=0,r=0) R3=pkt_end R10=fp
        6: (b7) r0 = 1
        7: (95) exit
        processed 10 insns, stack depth 0
      
      The above two basically just swap the branches where we need
      to handle an exception and allow packet access compared to the
      two already existing variants for find_good_pkt_pointers().
      
      For the dynamic map value access, we add the new instructions
      to reg_set_min_max() and reg_set_min_max_inv() in order to
      learn bounds. Verifier test cases for both are added in a
      follow-up patch.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      b4e432f1
    • Daniel Borkmann's avatar
      bpf, nfp: implement jiting of BPF_J{LT,LE} · 5dd294d4
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE} instructions with
      BPF_X/BPF_K variants for the nfp eBPF JIT. The two BPF_J{SLT,SLE}
      instructions have not been added yet given BPF_J{SGT,SGE} are
      not supported yet either.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      5dd294d4
    • Daniel Borkmann's avatar
      bpf, ppc64: implement jiting of BPF_J{LT, LE, SLT, SLE} · 20dbf5cc
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
      with BPF_X/BPF_K variants for the ppc64 eBPF JIT.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
      Tested-by: default avatarNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      20dbf5cc
    • Daniel Borkmann's avatar
      bpf, s390x: implement jiting of BPF_J{LT, LE, SLT, SLE} · 3b497806
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
      with BPF_X/BPF_K variants for the s390x eBPF JIT.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      3b497806
    • Daniel Borkmann's avatar
      bpf, sparc64: implement jiting of BPF_J{LT, LE, SLT, SLE} · 18423550
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
      with BPF_X/BPF_K variants for the sparc64 eBPF JIT.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      18423550
    • Daniel Borkmann's avatar
      bpf, arm64: implement jiting of BPF_J{LT, LE, SLT, SLE} · c362b2f3
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
      with BPF_X/BPF_K variants for the arm64 eBPF JIT.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c362b2f3
    • Daniel Borkmann's avatar
      bpf, x86: implement jiting of BPF_J{LT,LE,SLT,SLE} · 52afc51e
      Daniel Borkmann authored
      This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
      with BPF_X/BPF_K variants for the x86_64 eBPF JIT.
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      52afc51e
    • Daniel Borkmann's avatar
      bpf: add BPF_J{LT,LE,SLT,SLE} instructions · 92b31a9a
      Daniel Borkmann authored
      Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
      BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
      particularly *JLT/*JLE counterparts involving immediates need
      to be rewritten from e.g. X < [IMM] by swapping arguments into
      [IMM] > X, meaning the immediate first is required to be loaded
      into a register Y := [IMM], such that then we can compare with
      Y > X. Note that the destination operand is always required to
      be a register.
      
      This has the downside of having unnecessarily increased register
      pressure, meaning complex program would need to spill other
      registers temporarily to stack in order to obtain an unused
      register for the [IMM]. Loading to registers will thus also
      affect state pruning since we need to account for that register
      use and potentially those registers that had to be spilled/filled
      again. As a consequence slightly more stack space might have
      been used due to spilling, and BPF programs are a bit longer
      due to extra code involving the register load and potentially
      required spill/fills.
      
      Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
      counterparts to the eBPF instruction set. Modifying LLVM to
      remove the NegateCC() workaround in a PoC patch at [1] and
      allowing it to also emit the new instructions resulted in
      cilium's BPF programs that are injected into the fast-path to
      have a reduced program length in the range of 2-3% (e.g.
      accumulated main and tail call sections from one of the object
      file reduced from 4864 to 4729 insns), reduced complexity in
      the range of 10-30% (e.g. accumulated sections reduced in one
      of the cases from 116432 to 88428 insns), and reduced stack
      usage in the range of 1-5% (e.g. accumulated sections from one
      of the object files reduced from 824 to 784b).
      
      The modification for LLVM will be incorporated in a backwards
      compatible way. Plan is for LLVM to have i) a target specific
      option to offer a possibility to explicitly enable the extension
      by the user (as we have with -m target specific extensions today
      for various CPU insns), and ii) have the kernel checked for
      presence of the extensions and enable them transparently when
      the user is selecting more aggressive options such as -march=native
      in a bpf target context. (Other frontends generating BPF byte
      code, e.g. ply can probe the kernel directly for its code
      generation.)
      
        [1] https://github.com/borkmann/llvm/tree/bpf-insnsSigned-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      92b31a9a
    • David S. Miller's avatar
      Merge branch 'net-zerocopy-fixes' · 0bdf7101
      David S. Miller authored
      Willem de Bruijn says:
      
      ====================
      net: zerocopy fixes
      
      Fix two issues introduced in the msg_zerocopy patchset.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      0bdf7101
    • Willem de Bruijn's avatar
      sock: fix zerocopy_success regression with msg_zerocopy · 0a4a060b
      Willem de Bruijn authored
      Do not use uarg->zerocopy outside msg_zerocopy. In other paths the
      field is not explicitly initialized and aliases another field.
      
      Those paths have only one reference so do not need this intermediate
      variable. Call uarg->callback directly.
      
      Fixes: 1f8b977a ("sock: enable MSG_ZEROCOPY")
      Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      0a4a060b
    • Willem de Bruijn's avatar
      sock: fix zerocopy panic in mem accounting · ccaffff1
      Willem de Bruijn authored
      Only call mm_unaccount_pinned_pages when releasing a struct ubuf_info
      that has initialized its field uarg->mmp.
      
      Before this patch, a vhost-net with experimental_zcopytx can crash in
      
        mm_unaccount_pinned_pages
        sock_zerocopy_put
        skb_zcopy_clear
        skb_release_data
      
      Only sock_zerocopy_alloc initializes this field. Move the unaccount
      call from generic sock_zerocopy_put to its specific callback
      sock_zerocopy_callback.
      
      Fixes: a91dbff5 ("sock: ulimit on MSG_ZEROCOPY pages")
      Reported-by: default avatarDavid Ahern <dsahern@gmail.com>
      Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      ccaffff1
    • David S. Miller's avatar
      Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue · d5e7f827
      David S. Miller authored
      Jeff Kirsher says:
      
      ====================
      1GbE Intel Wired LAN Driver Updates 2017-08-08
      
      This series contains updates to e1000e and igb/igbvf.
      
      Gangfeng Huang fixes an issue with receive network flow classification,
      where igb_nfc_filter_exit() was not being called in igb_down() which
      would cause the filter tables to "fill up" if a user where to change
      the adapter settings (such as speed) which requires a reset of the
      adapter.
      
      Cliff Spradlin fixes a timestamping issue, where igb was allowing requests
      for hardware timestamping even if it was not configured for hardware
      transmit timestamping.
      
      Corinna Vinschen removes the error message that there was an "unexpected
      SYS WRAP", when it is actually expected.  So remove the message to not
      confuse users.
      
      Greg Edwards provides several patches for the mailbox interface between
      the PF and VF drivers.  Added a mailbox unlock method to be used to unlock
      the PF/VF mailbox by the PF.  Added a lock around the VF mailbox ops to
      prevent the VF from sending another message while the PF is still
      processing the previous message.  Fixed a "scheduling while atomic" issue
      by changing msleep() to mdelay().
      
      Sasha adds support for the next LOM generations i219 (v8 & v9) which
      will be available in the next Intel client platform IceLake.
      
      John Linville adds support for a Broadcom PHY to the igb driver, since
      there are designs out in the world which use the igb MAC and a third
      party PHY.  This allows the driver to load and function as expected on
      these designs.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      d5e7f827
    • David S. Miller's avatar
      Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net · 3118e6e1
      David S. Miller authored
      The UDP offload conflict is dealt with by simply taking what is
      in net-next where we have removed all of the UFO handling code
      entirely.
      
      The TCP conflict was a case of local variables in a function
      being removed from both net and net-next.
      
      In netvsc we had an assignment right next to where a missing
      set of u64 stats sync object inits were added.
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      3118e6e1
    • Mel Gorman's avatar
      futex: Remove unnecessary warning from get_futex_key · 48fb6f4d
      Mel Gorman authored
      Commit 65d8fc77 ("futex: Remove requirement for lock_page() in
      get_futex_key()") removed an unnecessary lock_page() with the
      side-effect that page->mapping needed to be treated very carefully.
      
      Two defensive warnings were added in case any assumption was missed and
      the first warning assumed a correct application would not alter a
      mapping backing a futex key.  Since merging, it has not triggered for
      any unexpected case but Mark Rutland reported the following bug
      triggering due to the first warning.
      
        kernel BUG at kernel/futex.c:679!
        Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
        Modules linked in:
        CPU: 0 PID: 3695 Comm: syz-executor1 Not tainted 4.13.0-rc3-00020-g307fec773ba3 #3
        Hardware name: linux,dummy-virt (DT)
        task: ffff80001e271780 task.stack: ffff000010908000
        PC is at get_futex_key+0x6a4/0xcf0 kernel/futex.c:679
        LR is at get_futex_key+0x6a4/0xcf0 kernel/futex.c:679
        pc : [<ffff00000821ac14>] lr : [<ffff00000821ac14>] pstate: 80000145
      
      The fact that it's a bug instead of a warning was due to an unrelated
      arm64 problem, but the warning itself triggered because the underlying
      mapping changed.
      
      This is an application issue but from a kernel perspective it's a
      recoverable situation and the warning is unnecessary so this patch
      removes the warning.  The warning may potentially be triggered with the
      following test program from Mark although it may be necessary to adjust
      NR_FUTEX_THREADS to be a value smaller than the number of CPUs in the
      system.
      
          #include <linux/futex.h>
          #include <pthread.h>
          #include <stdio.h>
          #include <stdlib.h>
          #include <sys/mman.h>
          #include <sys/syscall.h>
          #include <sys/time.h>
          #include <unistd.h>
      
          #define NR_FUTEX_THREADS 16
          pthread_t threads[NR_FUTEX_THREADS];
      
          void *mem;
      
          #define MEM_PROT  (PROT_READ | PROT_WRITE)
          #define MEM_SIZE  65536
      
          static int futex_wrapper(int *uaddr, int op, int val,
                                   const struct timespec *timeout,
                                   int *uaddr2, int val3)
          {
              syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
          }
      
          void *poll_futex(void *unused)
          {
              for (;;) {
                  futex_wrapper(mem, FUTEX_CMP_REQUEUE_PI, 1, NULL, mem + 4, 1);
              }
          }
      
          int main(int argc, char *argv[])
          {
              int i;
      
              mem = mmap(NULL, MEM_SIZE, MEM_PROT,
                     MAP_SHARED | MAP_ANONYMOUS, -1, 0);
      
              printf("Mapping @ %p\n", mem);
      
              printf("Creating futex threads...\n");
      
              for (i = 0; i < NR_FUTEX_THREADS; i++)
                  pthread_create(&threads[i], NULL, poll_futex, NULL);
      
              printf("Flipping mapping...\n");
              for (;;) {
                  mmap(mem, MEM_SIZE, MEM_PROT,
                       MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
              }
      
              return 0;
          }
      Reported-and-tested-by: default avatarMark Rutland <mark.rutland@arm.com>
      Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
      Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: stable@vger.kernel.org # 4.7+
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      48fb6f4d