1. 09 7月, 2020 1 次提交
    • X
      io_uring: export cq overflow status to userspace · 6d5f9049
      Xiaoguang Wang 提交于
      For those applications which are not willing to use io_uring_enter()
      to reap and handle cqes, they may completely rely on liburing's
      io_uring_peek_cqe(), but if cq ring has overflowed, currently because
      io_uring_peek_cqe() is not aware of this overflow, it won't enter
      kernel to flush cqes, below test program can reveal this bug:
      
      static void test_cq_overflow(struct io_uring *ring)
      {
              struct io_uring_cqe *cqe;
              struct io_uring_sqe *sqe;
              int issued = 0;
              int ret = 0;
      
              do {
                      sqe = io_uring_get_sqe(ring);
                      if (!sqe) {
                              fprintf(stderr, "get sqe failed\n");
                              break;;
                      }
                      ret = io_uring_submit(ring);
                      if (ret <= 0) {
                              if (ret != -EBUSY)
                                      fprintf(stderr, "sqe submit failed: %d\n", ret);
                              break;
                      }
                      issued++;
              } while (ret > 0);
              assert(ret == -EBUSY);
      
              printf("issued requests: %d\n", issued);
      
              while (issued) {
                      ret = io_uring_peek_cqe(ring, &cqe);
                      if (ret) {
                              if (ret != -EAGAIN) {
                                      fprintf(stderr, "peek completion failed: %s\n",
                                              strerror(ret));
                                      break;
                              }
                              printf("left requets: %d\n", issued);
                              continue;
                      }
                      io_uring_cqe_seen(ring, cqe);
                      issued--;
                      printf("left requets: %d\n", issued);
              }
      }
      
      int main(int argc, char *argv[])
      {
              int ret;
              struct io_uring ring;
      
              ret = io_uring_queue_init(16, &ring, 0);
              if (ret) {
                      fprintf(stderr, "ring setup failed: %d\n", ret);
                      return 1;
              }
      
              test_cq_overflow(&ring);
              return 0;
      }
      
      To fix this issue, export cq overflow status to userspace by adding new
      IORING_SQ_CQ_OVERFLOW flag, then helper functions() in liburing, such as
      io_uring_peek_cqe, can be aware of this cq overflow and do flush accordingly.
      Signed-off-by: NXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      6d5f9049
  2. 16 6月, 2020 1 次提交
    • V
      ndctl/papr_scm,uapi: Add support for PAPR nvdimm specific methods · f517f792
      Vaibhav Jain 提交于
      Introduce support for PAPR NVDIMM Specific Methods (PDSM) in papr_scm
      module and add the command family NVDIMM_FAMILY_PAPR to the white list
      of NVDIMM command sets. Also advertise support for ND_CMD_CALL for the
      nvdimm command mask and implement necessary scaffolding in the module
      to handle ND_CMD_CALL ioctl and PDSM requests that we receive.
      
      The layout of the PDSM request as we expect from libnvdimm/libndctl is
      described in newly introduced uapi header 'papr_pdsm.h' which
      defines a 'struct nd_pkg_pdsm' and a maximal union named
      'nd_pdsm_payload'. These new structs together with 'struct nd_cmd_pkg'
      for a pdsm envelop thats sent by libndctl to libnvdimm and serviced by
      papr_scm in 'papr_scm_service_pdsm()'. The PDSM request is
      communicated by member 'struct nd_cmd_pkg.nd_command' together with
      other information on the pdsm payload (size-in, size-out).
      
      The patch also introduces 'struct pdsm_cmd_desc' instances of which
      are stored in an array __pdsm_cmd_descriptors[] indexed with PDSM cmd
      and corresponding access function pdsm_cmd_desc() is
      introduced. 'struct pdsm_cdm_desc' holds the service function for a
      given PDSM and corresponding payload in/out sizes.
      
      A new function papr_scm_service_pdsm() is introduced and is called from
      papr_scm_ndctl() in case of a PDSM request is received via ND_CMD_CALL
      command from libnvdimm. The function performs validation on the PDSM
      payload based on info present in corresponding PDSM descriptor and if
      valid calls the 'struct pdcm_cmd_desc.service' function to service the
      PDSM.
      Signed-off-by: NVaibhav Jain <vaibhav@linux.ibm.com>
      Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Ira Weiny <ira.weiny@intel.com>
      Link: https://lore.kernel.org/r/20200615124407.32596-6-vaibhav@linux.ibm.comSigned-off-by: NDan Williams <dan.j.williams@intel.com>
      f517f792
  3. 13 6月, 2020 1 次提交
  4. 10 6月, 2020 1 次提交
    • J
      bpf: Devmap adjust uapi for attach bpf program · 281920b7
      Jesper Dangaard Brouer 提交于
      V2:
      - Defer changing BPF-syscall to start at file-descriptor 1
      - Use {} to zero initialise struct.
      
      The recent commit fbee97fe ("bpf: Add support to attach bpf program to a
      devmap entry"), introduced ability to attach (and run) a separate XDP
      bpf_prog for each devmap entry. A bpf_prog is added via a file-descriptor.
      As zero were a valid FD, not using the feature requires using value minus-1.
      The UAPI is extended via tail-extending struct bpf_devmap_val and using
      map->value_size to determine the feature set.
      
      This will break older userspace applications not using the bpf_prog feature.
      Consider an old userspace app that is compiled against newer kernel
      uapi/bpf.h, it will not know that it need to initialise the member
      bpf_prog.fd to minus-1. Thus, users will be forced to update source code to
      get program running on newer kernels.
      
      This patch remove the minus-1 checks, and have zero mean feature isn't used.
      
      Followup patches either for kernel or libbpf should handle and avoid
      returning file-descriptor zero in the first place.
      
      Fixes: fbee97fe ("bpf: Add support to attach bpf program to a devmap entry")
      Signed-off-by: NJesper Dangaard Brouer <brouer@redhat.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/159170950687.2102545.7235914718298050113.stgit@firesoul
      281920b7
  5. 09 6月, 2020 1 次提交
  6. 08 6月, 2020 1 次提交
  7. 07 6月, 2020 1 次提交
  8. 06 6月, 2020 1 次提交
  9. 05 6月, 2020 3 次提交
    • D
      virtio-mem: Don't rely on implicit compiler padding for requests · fce8afd7
      David Hildenbrand 提交于
      The compiler will add padding after the last member, make that explicit.
      The size of a request is always 24 bytes. The size of a response always
      10 bytes. Add compile-time checks.
      
      Cc: "Michael S. Tsirkin" <mst@redhat.com>
      Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
      Cc: teawater <teawaterz@linux.alibaba.com>
      Signed-off-by: NDavid Hildenbrand <david@redhat.com>
      Link: https://lore.kernel.org/r/20200515101402.16597-1-david@redhat.comSigned-off-by: NMichael S. Tsirkin <mst@redhat.com>
      fce8afd7
    • D
      virtio-mem: Allow to specify an ACPI PXM as nid · f2af6d39
      David Hildenbrand 提交于
      We want to allow to specify (similar as for a DIMM), to which node a
      virtio-mem device (and, therefore, its memory) belongs. Add a new
      virtio-mem feature flag and export pxm_to_node, so it can be used in kernel
      module context.
      
      Acked-by: Michal Hocko <mhocko@suse.com> # for the export
      Acked-by: "Rafael J. Wysocki" <rafael@kernel.org> # for the export
      Acked-by: NPankaj Gupta <pankaj.gupta.linux@gmail.com>
      Tested-by: NPankaj Gupta <pankaj.gupta.linux@gmail.com>
      Cc: "Michael S. Tsirkin" <mst@redhat.com>
      Cc: Jason Wang <jasowang@redhat.com>
      Cc: Oscar Salvador <osalvador@suse.de>
      Cc: Michal Hocko <mhocko@kernel.org>
      Cc: Igor Mammedov <imammedo@redhat.com>
      Cc: Dave Young <dyoung@redhat.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
      Cc: Stefan Hajnoczi <stefanha@redhat.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Cc: Len Brown <lenb@kernel.org>
      Cc: linux-acpi@vger.kernel.org
      Signed-off-by: NDavid Hildenbrand <david@redhat.com>
      Link: https://lore.kernel.org/r/20200507140139.17083-4-david@redhat.comSigned-off-by: NMichael S. Tsirkin <mst@redhat.com>
      f2af6d39
    • D
      virtio-mem: Paravirtualized memory hotplug · 5f1f79bb
      David Hildenbrand 提交于
      Each virtio-mem device owns exactly one memory region. It is responsible
      for adding/removing memory from that memory region on request.
      
      When the device driver starts up, the requested amount of memory is
      queried and then plugged to Linux. On request, further memory can be
      plugged or unplugged. This patch only implements the plugging part.
      
      On x86-64, memory can currently be plugged in 4MB ("subblock") granularity.
      When required, a new memory block will be added (e.g., usually 128MB on
      x86-64) in order to plug more subblocks. Only x86-64 was tested for now.
      
      The online_page callback is used to keep unplugged subblocks offline
      when onlining memory - similar to the Hyper-V balloon driver. Unplugged
      pages are marked PG_offline, to tell dump tools (e.g., makedumpfile) to
      skip them.
      
      User space is usually responsible for onlining the added memory. The
      memory hotplug notifier is used to synchronize virtio-mem activity
      against memory onlining/offlining.
      
      Each virtio-mem device can belong to a NUMA node, which allows us to
      easily add/remove small chunks of memory to/from a specific NUMA node by
      using multiple virtio-mem devices. Something that works even when the
      guest has no idea about the NUMA topology.
      
      One way to view virtio-mem is as a "resizable DIMM" or a DIMM with many
      "sub-DIMMS".
      
      This patch directly introduces the basic infrastructure to implement memory
      unplug. Especially the memory block states and subblock bitmaps will be
      heavily used there.
      
      Notes:
      - In case memory is to be onlined by user space, we limit the amount of
        offline memory blocks, to not run out of memory. This is esp. an
        issue if memory is added faster than it is getting onlined.
      - Suspend/Hibernate is not supported due to the way virtio-mem devices
        behave. Limited support might be possible in the future.
      - Reloading the device driver is not supported.
      Reviewed-by: NPankaj Gupta <pankaj.gupta.linux@gmail.com>
      Tested-by: NPankaj Gupta <pankaj.gupta.linux@gmail.com>
      Cc: "Michael S. Tsirkin" <mst@redhat.com>
      Cc: Jason Wang <jasowang@redhat.com>
      Cc: Oscar Salvador <osalvador@suse.de>
      Cc: Michal Hocko <mhocko@kernel.org>
      Cc: Igor Mammedov <imammedo@redhat.com>
      Cc: Dave Young <dyoung@redhat.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
      Cc: Stefan Hajnoczi <stefanha@redhat.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
      Cc: Len Brown <lenb@kernel.org>
      Cc: linux-acpi@vger.kernel.org
      Signed-off-by: NDavid Hildenbrand <david@redhat.com>
      Link: https://lore.kernel.org/r/20200507140139.17083-2-david@redhat.comSigned-off-by: NMichael S. Tsirkin <mst@redhat.com>
      5f1f79bb
  10. 04 6月, 2020 1 次提交
  11. 03 6月, 2020 4 次提交
  12. 02 6月, 2020 14 次提交
    • F
      vfio-ccw: Introduce a new schib region · 24c98674
      Farhan Ali 提交于
      The schib region can be used by userspace to get the subchannel-
      information block (SCHIB) for the passthrough subchannel.
      This can be useful to get information such as channel path
      information via the SCHIB.PMCW fields.
      Signed-off-by: NFarhan Ali <alifm@linux.ibm.com>
      Signed-off-by: NEric Farman <farman@linux.ibm.com>
      Reviewed-by: NCornelia Huck <cohuck@redhat.com>
      Message-Id: <20200505122745.53208-5-farman@linux.ibm.com>
      Signed-off-by: NCornelia Huck <cohuck@redhat.com>
      24c98674
    • M
      virtio: force spec specified alignment on types · a865e420
      Michael S. Tsirkin 提交于
      The ring element addresses are passed between components with different
      alignments assumptions. Thus, if guest/userspace selects a pointer and
      host then gets and dereferences it, we might need to decrease the
      compiler-selected alignment to prevent compiler on the host from
      assuming pointer is aligned.
      
      This actually triggers on ARM with -mabi=apcs-gnu - which is a
      deprecated configuration, but it seems safer to handle this
      generally.
      
      Note that userspace that allocates the memory is actually OK and does
      not need to be fixed, but userspace that gets it from guest or another
      process does need to be fixed. The later doesn't generally talk to the
      kernel so while it might be buggy it's not talking to the kernel in the
      buggy way - it's just using the header in the buggy way - so fixing
      header and asking userspace to recompile is the best we can do.
      
      I verified that the produced kernel binary on x86 is exactly identical
      before and after the change.
      Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
      Acked-by: NJason Wang <jasowang@redhat.com>
      a865e420
    • M
      virtio: add VIRTIO_RING_NO_LEGACY · e7c8cc35
      Matej Genci 提交于
      Add macro to disable legacy vring functions.
      Signed-off-by: NMatej Genci <matej.genci@nutanix.com>
      Link: https://lore.kernel.org/r/20190911124942.243713-1-matej.genci@nutanix.comSigned-off-by: NMichael S. Tsirkin <mst@redhat.com>
      e7c8cc35
    • J
      bpf: Add link-based BPF program attachment to network namespace · 7f045a49
      Jakub Sitnicki 提交于
      Extend bpf() syscall subcommands that operate on bpf_link, that is
      LINK_CREATE, LINK_UPDATE, OBJ_GET_INFO, to accept attach types tied to
      network namespaces (only flow dissector at the moment).
      
      Link-based and prog-based attachment can be used interchangeably, but only
      one can exist at a time. Attempts to attach a link when a prog is already
      attached directly, and the other way around, will be met with -EEXIST.
      Attempts to detach a program when link exists result in -EINVAL.
      
      Attachment of multiple links of same attach type to one netns is not
      supported with the intention to lift the restriction when a use-case
      presents itself. Because of that link create returns -E2BIG when trying to
      create another netns link, when one already exists.
      
      Link-based attachments to netns don't keep a netns alive by holding a ref
      to it. Instead links get auto-detached from netns when the latter is being
      destroyed, using a pernet pre_exit callback.
      
      When auto-detached, link lives in defunct state as long there are open FDs
      for it. -ENOLINK is returned if a user tries to update a defunct link.
      
      Because bpf_link to netns doesn't hold a ref to struct net, special care is
      taken when releasing, updating, or filling link info. The netns might be
      getting torn down when any of these link operations are in progress. That
      is why auto-detach and update/release/fill_info are synchronized by the
      same mutex. Also, link ops have to always check if auto-detach has not
      happened yet and if netns is still alive (refcnt > 0).
      Signed-off-by: NJakub Sitnicki <jakub@cloudflare.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200531082846.2117903-5-jakub@cloudflare.com
      7f045a49
    • D
      xdp: Add xdp_txq_info to xdp_buff · 64b59025
      David Ahern 提交于
      Add xdp_txq_info as the Tx counterpart to xdp_rxq_info. At the
      moment only the device is added. Other fields (queue_index)
      can be added as use cases arise.
      
      >From a UAPI perspective, add egress_ifindex to xdp context for
      bpf programs to see the Tx device.
      
      Update the verifier to only allow accesses to egress_ifindex by
      XDP programs with BPF_XDP_DEVMAP expected attach type.
      Signed-off-by: NDavid Ahern <dsahern@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NToke Høiland-Jørgensen <toke@redhat.com>
      Link: https://lore.kernel.org/bpf/20200529220716.75383-4-dsahern@kernel.orgSigned-off-by: NAlexei Starovoitov <ast@kernel.org>
      64b59025
    • D
      bpf: Add support to attach bpf program to a devmap entry · fbee97fe
      David Ahern 提交于
      Add BPF_XDP_DEVMAP attach type for use with programs associated with a
      DEVMAP entry.
      
      Allow DEVMAPs to associate a program with a device entry by adding
      a bpf_prog.fd to 'struct bpf_devmap_val'. Values read show the program
      id, so the fd and id are a union. bpf programs can get access to the
      struct via vmlinux.h.
      
      The program associated with the fd must have type XDP with expected
      attach type BPF_XDP_DEVMAP. When a program is associated with a device
      index, the program is run on an XDP_REDIRECT and before the buffer is
      added to the per-cpu queue. At this point rxq data is still valid; the
      next patch adds tx device information allowing the prorgam to see both
      ingress and egress device indices.
      
      XDP generic is skb based and XDP programs do not work with skb's. Block
      the use case by walking maps used by a program that is to be attached
      via xdpgeneric and fail if any of them are DEVMAP / DEVMAP_HASH with
      
      Block attach of BPF_XDP_DEVMAP programs to devices.
      Signed-off-by: NDavid Ahern <dsahern@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NToke Høiland-Jørgensen <toke@redhat.com>
      Link: https://lore.kernel.org/bpf/20200529220716.75383-3-dsahern@kernel.orgSigned-off-by: NAlexei Starovoitov <ast@kernel.org>
      fbee97fe
    • A
      bpf: Add rx_queue_mapping to bpf_sock · c3c16f2e
      Amritha Nambiar 提交于
      Add "rx_queue_mapping" to bpf_sock. This gives read access for the
      existing field (sk_rx_queue_mapping) of struct sock from bpf_sock.
      Semantics for the bpf_sock rx_queue_mapping access are similar to
      sk_rx_queue_get(), i.e the value NO_QUEUE_MAPPING is not allowed
      and -1 is returned in that case. This is useful for transmit queue
      selection based on the received queue index which is cached in the
      socket in the receive path.
      
      v3: Addressed review comments to add usecase in patch description,
          and fixed default value for rx_queue_mapping.
      v2: fixed build error for CONFIG_XPS wrapping, reported by
          kbuild test robot <lkp@intel.com>
      Signed-off-by: NAmritha Nambiar <amritha.nambiar@intel.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      c3c16f2e
    • A
      bpf: Implement BPF ring buffer and verifier support for it · 457f4436
      Andrii Nakryiko 提交于
      This commit adds a new MPSC ring buffer implementation into BPF ecosystem,
      which allows multiple CPUs to submit data to a single shared ring buffer. On
      the consumption side, only single consumer is assumed.
      
      Motivation
      ----------
      There are two distinctive motivators for this work, which are not satisfied by
      existing perf buffer, which prompted creation of a new ring buffer
      implementation.
        - more efficient memory utilization by sharing ring buffer across CPUs;
        - preserving ordering of events that happen sequentially in time, even
        across multiple CPUs (e.g., fork/exec/exit events for a task).
      
      These two problems are independent, but perf buffer fails to satisfy both.
      Both are a result of a choice to have per-CPU perf ring buffer.  Both can be
      also solved by having an MPSC implementation of ring buffer. The ordering
      problem could technically be solved for perf buffer with some in-kernel
      counting, but given the first one requires an MPSC buffer, the same solution
      would solve the second problem automatically.
      
      Semantics and APIs
      ------------------
      Single ring buffer is presented to BPF programs as an instance of BPF map of
      type BPF_MAP_TYPE_RINGBUF. Two other alternatives considered, but ultimately
      rejected.
      
      One way would be to, similar to BPF_MAP_TYPE_PERF_EVENT_ARRAY, make
      BPF_MAP_TYPE_RINGBUF could represent an array of ring buffers, but not enforce
      "same CPU only" rule. This would be more familiar interface compatible with
      existing perf buffer use in BPF, but would fail if application needed more
      advanced logic to lookup ring buffer by arbitrary key. HASH_OF_MAPS addresses
      this with current approach. Additionally, given the performance of BPF
      ringbuf, many use cases would just opt into a simple single ring buffer shared
      among all CPUs, for which current approach would be an overkill.
      
      Another approach could introduce a new concept, alongside BPF map, to
      represent generic "container" object, which doesn't necessarily have key/value
      interface with lookup/update/delete operations. This approach would add a lot
      of extra infrastructure that has to be built for observability and verifier
      support. It would also add another concept that BPF developers would have to
      familiarize themselves with, new syntax in libbpf, etc. But then would really
      provide no additional benefits over the approach of using a map.
      BPF_MAP_TYPE_RINGBUF doesn't support lookup/update/delete operations, but so
      doesn't few other map types (e.g., queue and stack; array doesn't support
      delete, etc).
      
      The approach chosen has an advantage of re-using existing BPF map
      infrastructure (introspection APIs in kernel, libbpf support, etc), being
      familiar concept (no need to teach users a new type of object in BPF program),
      and utilizing existing tooling (bpftool). For common scenario of using
      a single ring buffer for all CPUs, it's as simple and straightforward, as
      would be with a dedicated "container" object. On the other hand, by being
      a map, it can be combined with ARRAY_OF_MAPS and HASH_OF_MAPS map-in-maps to
      implement a wide variety of topologies, from one ring buffer for each CPU
      (e.g., as a replacement for perf buffer use cases), to a complicated
      application hashing/sharding of ring buffers (e.g., having a small pool of
      ring buffers with hashed task's tgid being a look up key to preserve order,
      but reduce contention).
      
      Key and value sizes are enforced to be zero. max_entries is used to specify
      the size of ring buffer and has to be a power of 2 value.
      
      There are a bunch of similarities between perf buffer
      (BPF_MAP_TYPE_PERF_EVENT_ARRAY) and new BPF ring buffer semantics:
        - variable-length records;
        - if there is no more space left in ring buffer, reservation fails, no
          blocking;
        - memory-mappable data area for user-space applications for ease of
          consumption and high performance;
        - epoll notifications for new incoming data;
        - but still the ability to do busy polling for new data to achieve the
          lowest latency, if necessary.
      
      BPF ringbuf provides two sets of APIs to BPF programs:
        - bpf_ringbuf_output() allows to *copy* data from one place to a ring
          buffer, similarly to bpf_perf_event_output();
        - bpf_ringbuf_reserve()/bpf_ringbuf_commit()/bpf_ringbuf_discard() APIs
          split the whole process into two steps. First, a fixed amount of space is
          reserved. If successful, a pointer to a data inside ring buffer data area
          is returned, which BPF programs can use similarly to a data inside
          array/hash maps. Once ready, this piece of memory is either committed or
          discarded. Discard is similar to commit, but makes consumer ignore the
          record.
      
      bpf_ringbuf_output() has disadvantage of incurring extra memory copy, because
      record has to be prepared in some other place first. But it allows to submit
      records of the length that's not known to verifier beforehand. It also closely
      matches bpf_perf_event_output(), so will simplify migration significantly.
      
      bpf_ringbuf_reserve() avoids the extra copy of memory by providing a memory
      pointer directly to ring buffer memory. In a lot of cases records are larger
      than BPF stack space allows, so many programs have use extra per-CPU array as
      a temporary heap for preparing sample. bpf_ringbuf_reserve() avoid this needs
      completely. But in exchange, it only allows a known constant size of memory to
      be reserved, such that verifier can verify that BPF program can't access
      memory outside its reserved record space. bpf_ringbuf_output(), while slightly
      slower due to extra memory copy, covers some use cases that are not suitable
      for bpf_ringbuf_reserve().
      
      The difference between commit and discard is very small. Discard just marks
      a record as discarded, and such records are supposed to be ignored by consumer
      code. Discard is useful for some advanced use-cases, such as ensuring
      all-or-nothing multi-record submission, or emulating temporary malloc()/free()
      within single BPF program invocation.
      
      Each reserved record is tracked by verifier through existing
      reference-tracking logic, similar to socket ref-tracking. It is thus
      impossible to reserve a record, but forget to submit (or discard) it.
      
      bpf_ringbuf_query() helper allows to query various properties of ring buffer.
      Currently 4 are supported:
        - BPF_RB_AVAIL_DATA returns amount of unconsumed data in ring buffer;
        - BPF_RB_RING_SIZE returns the size of ring buffer;
        - BPF_RB_CONS_POS/BPF_RB_PROD_POS returns current logical possition of
          consumer/producer, respectively.
      Returned values are momentarily snapshots of ring buffer state and could be
      off by the time helper returns, so this should be used only for
      debugging/reporting reasons or for implementing various heuristics, that take
      into account highly-changeable nature of some of those characteristics.
      
      One such heuristic might involve more fine-grained control over poll/epoll
      notifications about new data availability in ring buffer. Together with
      BPF_RB_NO_WAKEUP/BPF_RB_FORCE_WAKEUP flags for output/commit/discard helpers,
      it allows BPF program a high degree of control and, e.g., more efficient
      batched notifications. Default self-balancing strategy, though, should be
      adequate for most applications and will work reliable and efficiently already.
      
      Design and implementation
      -------------------------
      This reserve/commit schema allows a natural way for multiple producers, either
      on different CPUs or even on the same CPU/in the same BPF program, to reserve
      independent records and work with them without blocking other producers. This
      means that if BPF program was interruped by another BPF program sharing the
      same ring buffer, they will both get a record reserved (provided there is
      enough space left) and can work with it and submit it independently. This
      applies to NMI context as well, except that due to using a spinlock during
      reservation, in NMI context, bpf_ringbuf_reserve() might fail to get a lock,
      in which case reservation will fail even if ring buffer is not full.
      
      The ring buffer itself internally is implemented as a power-of-2 sized
      circular buffer, with two logical and ever-increasing counters (which might
      wrap around on 32-bit architectures, that's not a problem):
        - consumer counter shows up to which logical position consumer consumed the
          data;
        - producer counter denotes amount of data reserved by all producers.
      
      Each time a record is reserved, producer that "owns" the record will
      successfully advance producer counter. At that point, data is still not yet
      ready to be consumed, though. Each record has 8 byte header, which contains
      the length of reserved record, as well as two extra bits: busy bit to denote
      that record is still being worked on, and discard bit, which might be set at
      commit time if record is discarded. In the latter case, consumer is supposed
      to skip the record and move on to the next one. Record header also encodes
      record's relative offset from the beginning of ring buffer data area (in
      pages). This allows bpf_ringbuf_commit()/bpf_ringbuf_discard() to accept only
      the pointer to the record itself, without requiring also the pointer to ring
      buffer itself. Ring buffer memory location will be restored from record
      metadata header. This significantly simplifies verifier, as well as improving
      API usability.
      
      Producer counter increments are serialized under spinlock, so there is
      a strict ordering between reservations. Commits, on the other hand, are
      completely lockless and independent. All records become available to consumer
      in the order of reservations, but only after all previous records where
      already committed. It is thus possible for slow producers to temporarily hold
      off submitted records, that were reserved later.
      
      Reservation/commit/consumer protocol is verified by litmus tests in
      Documentation/litmus-test/bpf-rb.
      
      One interesting implementation bit, that significantly simplifies (and thus
      speeds up as well) implementation of both producers and consumers is how data
      area is mapped twice contiguously back-to-back in the virtual memory. This
      allows to not take any special measures for samples that have to wrap around
      at the end of the circular buffer data area, because the next page after the
      last data page would be first data page again, and thus the sample will still
      appear completely contiguous in virtual memory. See comment and a simple ASCII
      diagram showing this visually in bpf_ringbuf_area_alloc().
      
      Another feature that distinguishes BPF ringbuf from perf ring buffer is
      a self-pacing notifications of new data being availability.
      bpf_ringbuf_commit() implementation will send a notification of new record
      being available after commit only if consumer has already caught up right up
      to the record being committed. If not, consumer still has to catch up and thus
      will see new data anyways without needing an extra poll notification.
      Benchmarks (see tools/testing/selftests/bpf/benchs/bench_ringbuf.c) show that
      this allows to achieve a very high throughput without having to resort to
      tricks like "notify only every Nth sample", which are necessary with perf
      buffer. For extreme cases, when BPF program wants more manual control of
      notifications, commit/discard/output helpers accept BPF_RB_NO_WAKEUP and
      BPF_RB_FORCE_WAKEUP flags, which give full control over notifications of data
      availability, but require extra caution and diligence in using this API.
      
      Comparison to alternatives
      --------------------------
      Before considering implementing BPF ring buffer from scratch existing
      alternatives in kernel were evaluated, but didn't seem to meet the needs. They
      largely fell into few categores:
        - per-CPU buffers (perf, ftrace, etc), which don't satisfy two motivations
          outlined above (ordering and memory consumption);
        - linked list-based implementations; while some were multi-producer designs,
          consuming these from user-space would be very complicated and most
          probably not performant; memory-mapping contiguous piece of memory is
          simpler and more performant for user-space consumers;
        - io_uring is SPSC, but also requires fixed-sized elements. Naively turning
          SPSC queue into MPSC w/ lock would have subpar performance compared to
          locked reserve + lockless commit, as with BPF ring buffer. Fixed sized
          elements would be too limiting for BPF programs, given existing BPF
          programs heavily rely on variable-sized perf buffer already;
        - specialized implementations (like a new printk ring buffer, [0]) with lots
          of printk-specific limitations and implications, that didn't seem to fit
          well for intended use with BPF programs.
      
        [0] https://lwn.net/Articles/779550/Signed-off-by: NAndrii Nakryiko <andriin@fb.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20200529075424.3139988-2-andriin@fb.comSigned-off-by: NAlexei Starovoitov <ast@kernel.org>
      457f4436
    • J
    • H
      bridge: mrp: Add support for role MRA · c6676e7d
      Horatiu Vultur 提交于
      A node that has the MRA role, it can behave as MRM or MRC.
      
      Initially it starts as MRM and sends MRP_Test frames on both ring ports.
      If it detects that there are MRP_Test send by another MRM, then it
      checks if these frames have a lower priority than itself. In this case
      it would send MRP_Nack frames to notify the other node that it needs to
      stop sending MRP_Test frames.
      If it receives a MRP_Nack frame then it stops sending MRP_Test frames
      and starts to behave as a MRC but it would continue to monitor the
      MRP_Test frames send by MRM. If at a point the MRM stops to send
      MRP_Test frames it would get the MRM role and start to send MRP_Test
      frames.
      Signed-off-by: NHoratiu Vultur <horatiu.vultur@microchip.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c6676e7d
    • H
      bridge: mrp: Set the priority of MRP instance · 4b3a61b0
      Horatiu Vultur 提交于
      Each MRP instance has a priority, a lower value means a higher priority.
      The priority of MRP instance is stored in MRP_Test frame in this way
      all the MRP nodes in the ring can see other nodes priority.
      Signed-off-by: NHoratiu Vultur <horatiu.vultur@microchip.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4b3a61b0
    • H
      bridge: mrp: Update MRP frame type · 7e89ed8a
      Horatiu Vultur 提交于
      Replace u16/u32 with be16/be32 in the MRP frame types.
      This fixes sparse warnings like:
      warning: cast to restricted __be16
      Signed-off-by: NHoratiu Vultur <horatiu.vultur@microchip.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7e89ed8a
    • I
      devlink: Add 'control' trap type · 30a4e9a2
      Ido Schimmel 提交于
      This type is used for traps that trap control packets such as ARP
      request and IGMP query to the CPU.
      
      Do not report such packets to the kernel's drop monitor as they were not
      dropped by the device no encountered an exception during forwarding.
      Signed-off-by: NIdo Schimmel <idosch@mellanox.com>
      Reviewed-by: NJiri Pirko <jiri@mellanox.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      30a4e9a2
    • I
      devlink: Add 'mirror' trap action · 9eefeabe
      Ido Schimmel 提交于
      The action is used by control traps such as IGMP query. The packet is
      flooded by the device, but also trapped to the CPU in order for the
      software bridge to mark the receiving port as a multicast router port.
      Such packets are marked with 'skb->offload_fwd_mark = 1' in order to
      prevent the software bridge from flooding them again.
      Signed-off-by: NIdo Schimmel <idosch@mellanox.com>
      Reviewed-by: NJiri Pirko <jiri@mellanox.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      9eefeabe
  13. 01 6月, 2020 3 次提交
  14. 31 5月, 2020 3 次提交
  15. 29 5月, 2020 4 次提交