1. 03 10月, 2017 13 次提交
  2. 30 9月, 2017 15 次提交
  3. 27 9月, 2017 2 次提交
    • D
      bpf, ixgbe: add meta data support · 366a88fe
      Daniel Borkmann 提交于
      Implement support for transferring XDP meta data into skb for
      ixgbe driver; before calling into the program, xdp.data_meta points
      to xdp.data, where on program return with pass verdict, we call
      into skb_metadata_set().
      
      We implement this for the default ixgbe_build_skb() variant. For the
      ixgbe_construct_skb() that is used when legacy-rx buffer mananagement
      mode is turned on via ethtool, I found that XDP gets 0 headroom, so
      neither xdp_adjust_head() nor xdp_adjust_meta() can be used with this.
      Just add a comment with explanation for this operating mode.
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      366a88fe
    • D
      bpf: add meta pointer for direct access · de8f3a83
      Daniel Borkmann 提交于
      This work enables generic transfer of metadata from XDP into skb. The
      basic idea is that we can make use of the fact that the resulting skb
      must be linear and already comes with a larger headroom for supporting
      bpf_xdp_adjust_head(), which mangles xdp->data. Here, we base our work
      on a similar principle and introduce a small helper bpf_xdp_adjust_meta()
      for adjusting a new pointer called xdp->data_meta. Thus, the packet has
      a flexible and programmable room for meta data, followed by the actual
      packet data. struct xdp_buff is therefore laid out that we first point
      to data_hard_start, then data_meta directly prepended to data followed
      by data_end marking the end of packet. bpf_xdp_adjust_head() takes into
      account whether we have meta data already prepended and if so, memmove()s
      this along with the given offset provided there's enough room.
      
      xdp->data_meta is optional and programs are not required to use it. The
      rationale is that when we process the packet in XDP (e.g. as DoS filter),
      we can push further meta data along with it for the XDP_PASS case, and
      give the guarantee that a clsact ingress BPF program on the same device
      can pick this up for further post-processing. Since we work with skb
      there, we can also set skb->mark, skb->priority or other skb meta data
      out of BPF, thus having this scratch space generic and programmable
      allows for more flexibility than defining a direct 1:1 transfer of
      potentially new XDP members into skb (it's also more efficient as we
      don't need to initialize/handle each of such new members). The facility
      also works together with GRO aggregation. The scratch space at the head
      of the packet can be multiple of 4 byte up to 32 byte large. Drivers not
      yet supporting xdp->data_meta can simply be set up with xdp->data_meta
      as xdp->data + 1 as bpf_xdp_adjust_meta() will detect this and bail out,
      such that the subsequent match against xdp->data for later access is
      guaranteed to fail.
      
      The verifier treats xdp->data_meta/xdp->data the same way as we treat
      xdp->data/xdp->data_end pointer comparisons. The requirement for doing
      the compare against xdp->data is that it hasn't been modified from it's
      original address we got from ctx access. It may have a range marking
      already from prior successful xdp->data/xdp->data_end pointer comparisons
      though.
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      de8f3a83
  4. 22 9月, 2017 4 次提交
  5. 06 9月, 2017 2 次提交
    • J
      i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq · 3c8f3e96
      Jacob Keller 提交于
      When introducing the functions to read the NVM through the AdminQ, we
      did not correctly mark the wb_desc.
      
      Fixes: 7073f46e ("i40e: Add AQ commands for NVM Update for X722", 2015-06-05)
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      3c8f3e96
    • A
      i40e: avoid NVM acquire deadlock during NVM update · 09f79fd4
      Anjali Singhai Jain 提交于
      X722 devices use the AdminQ to access the NVM, and this requires taking
      the AdminQ lock. Because of this, we lock the AdminQ during
      i40e_read_nvm(), which is also called in places where the lock is
      already held, such as the firmware update path which wants to lock once
      and then unlock when finished after performing several tasks.
      
      Although this should have only affected X722 devices, commit
      96a39aed ("i40e: Acquire NVM lock before reads on all devices",
      2016-12-02) added locking for all NVM reads, regardless of device
      family.
      
      This resulted in us accidentally causing NVM acquire timeouts on all
      devices, causing failed firmware updates which left the eeprom in
      a corrupt state.
      
      Create unsafe non-locked variants of i40e_read_nvm_word and
      i40e_read_nvm_buffer, __i40e_read_nvm_word and __i40e_read_nvm_buffer
      respectively. These variants will not take the NVM lock and are expected
      to only be called in places where the NVM lock is already held if
      needed.
      
      Since the only caller of i40e_read_nvm_buffer() was in such a path,
      remove it entirely in favor of the unsafe version. If necessary we can
      always add it back in the future.
      
      Additionally, we now need to hold the NVM lock in i40e_validate_checksum
      because the call to i40e_calc_nvm_checksum now assumes that the NVM lock
      is held. We can further move the call to read I40E_SR_SW_CHECKSUM_WORD
      up a bit so that we do not need to acquire the NVM lock twice.
      
      This should resolve firmware updates and also fix potential raise that
      could have caused the driver to report an invalid NVM checksum upon
      driver load.
      Reported-by: NStefan Assmann <sassmann@kpanic.de>
      Fixes: 96a39aed ("i40e: Acquire NVM lock before reads on all devices", 2016-12-02)
      Signed-off-by: NAnjali Singhai Jain <anjali.singhai@intel.com>
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      09f79fd4
  6. 28 8月, 2017 4 次提交
    • J
      i40e/i40evf: avoid dynamic ITR updates when polling or low packet rate · 742c9875
      Jacob Keller 提交于
      The dynamic ITR algorithm depends on a calculation of usecs which
      assumes that the interrupts have been firing constantly at the interrupt
      throttle rate. This is not guaranteed because we could have a low packet
      rate, or have been polling in software.
      
      We'll estimate whether this is the case by using jiffies to determine if
      we've been too long. If the time difference of jiffies is larger we are
      guaranteed to have an incorrect calculation. If the time difference of
      jiffies is smaller we might have been polling some but the difference
      shouldn't affect the calculation too much.
      
      This ensures that we don't get stuck in BULK latency during certain rare
      situations where we receive bursts of packets that force us into NAPI
      polling.
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      742c9875
    • J
      i40e/i40evf: remove ULTRA latency mode · 0a2c7722
      Jacob Keller 提交于
      Since commit c56625d5 ("i40e/i40evf: change dynamic interrupt
      thresholds") a new higher latency ITR setting called I40E_ULTRA_LATENCY
      was added with a cryptic comment about how it was meant for adjusting Rx
      more aggressively when streaming small packets.
      
      This mode was attempting to calculate packets per second and then kick
      in when we have a huge number of small packets.
      
      Unfortunately, the ULTRA setting was kicking in for workloads it wasn't
      intended for including single-thread UDP_STREAM workloads.
      
      This wasn't caught for a variety of reasons. First, the ip_defrag
      routines were improved somewhat which makes the UDP_STREAM test still
      reasonable at 10GbE, even when dropped down to 8k interrupts a second.
      Additionally, some other obvious workloads appear to work fine, such
      as TCP_STREAM.
      
      The number 40k doesn't make sense for a number of reasons. First, we
      absolutely can do more than 40k packets per second. Second, we calculate
      the value inline in an integer, which sometimes can overflow resulting
      in using incorrect values.
      
      If we fix this overflow it makes it even more likely that we'll enter
      ULTRA mode which is the opposite of what we want.
      
      The ULTRA mode was added originally as a way to reduce CPU utilization
      during a small packet workload where we weren't keeping up anyways. It
      should never have been kicking in during these other workloads.
      
      Given the issues outlined above, let's remove the ULTRA latency mode. If
      necessary, a better solution to the CPU utilization issue for small
      packet workloads will be added in a future patch.
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      0a2c7722
    • J
      i40e: invert logic for checking incorrect cpu vs irq affinity · 6d977729
      Jacob Keller 提交于
      In commit 96db776a ("i40e/vf: fix interrupt affinity bug")
      we added some code to force exit of polling in case we did
      not have the correct CPU. This is important since it was possible for
      the IRQ affinity to be changed while the CPU is pegged at 100%. This can
      result in the polling routine being stuck on the wrong CPU until
      traffic finally stops.
      
      Unfortunately, the implementation, "if the CPU is correct, exit as
      normal, otherwise, fall-through to the end-polling exit" is incredibly
      confusing to reason about. In this case, the normal flow looks like the
      exception, while the exception actually occurs far away from the if
      statement and comment.
      
      We recently discovered and fixed a bug in this code because we were
      incorrectly initializing the affinity mask.
      
      Re-write the code so that the exceptional case is handled at the check,
      rather than having the logic be spread through the regular exit flow.
      This does end up with minor code duplication, but the resulting code is
      much easier to reason about.
      
      The new logic is identical, but inverted. If we are running on a CPU not
      in our affinity mask, we'll exit polling. However, the code flow is much
      easier to understand.
      
      Note that we don't actually have to check for MSI-X, because in the MSI
      case we'll only have one q_vector, but its default affinity mask should
      be correct as it includes all CPUs when it's initialized. Further, we
      could at some point add code to setup the notifier for the non-MSI-X
      case and enable this workaround for that case too, if desired, though
      there isn't much gain since its unlikely to be the common case.
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      6d977729
    • J
      i40e: initialize our affinity_mask based on cpu_possible_mask · 759dc4a7
      Jacob Keller 提交于
      On older kernels a call to irq_set_affinity_hint does not guarantee that
      the IRQ affinity will be set. If nothing else on the system sets the IRQ
      affinity this can result in a bug in the i40e_napi_poll() routine where
      we notice that our interrupt fired on the "wrong" CPU according to our
      internal affinity_mask variable.
      
      This results in a bug where we continuously tell NAPI to stop polling to
      move the interrupt to a new CPU, but the CPU never changes because our
      affinity mask does not match the actual mask setup for the IRQ.
      
      The root problem is a mismatched affinity mask value. So lets initialize
      the value to cpu_possible_mask instead. This ensures that prior to the
      first time we get an IRQ affinity notification we'll have the mask set
      to include every possible CPU.
      
      We use cpu_possible_mask instead of cpu_online_mask since the former is
      almost certainly never going to change, while the later might change
      after we've made a copy.
      Signed-off-by: NJacob Keller <jacob.e.keller@intel.com>
      Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
      Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
      759dc4a7