1. 23 3月, 2021 1 次提交
    • M
      bnxt_en: Improve the status_reliable flag in bp->fw_health. · 43a440c4
      Michael Chan 提交于
      In order to read the firmware health status, we first need to determine
      the register location and then the register may need to be mapped.
      There are 2 code paths to do this.  The first one is done early as a
      best effort attempt by the function bnxt_try_map_fw_health_reg().  The
      second one is done later in the function bnxt_map_fw_health_regs()
      after establishing communications with the firmware.  We currently
      only set fw_health->status_reliable if we can successfully set up the
      health register in the first code path.
      
      Improve the scheme by setting the fw_health->status_reliable flag if
      either (or both) code paths can successfully set up the health
      register.  This flag is relied upon during run-time when we need to
      check the health status.  So this will make it work better.
      
      During ifdown, if the health register is mapped, we need to invalidate
      the health register mapping because a potential fw reset will reset
      the mapping.  Similarly, we need to do the same after firmware reset
      during recovery.  We'll remap it during ifup.
      Reviewed-by: NEdwin Peer <edwin.peer@broadcom.com>
      Reviewed-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      43a440c4
  2. 27 2月, 2021 2 次提交
    • E
      bnxt_en: reliably allocate IRQ table on reset to avoid crash · 20d7d1c5
      Edwin Peer 提交于
      The following trace excerpt corresponds with a NULL pointer dereference
      of 'bp->irq_tbl' in bnxt_setup_inta() on an Aarch64 system after many
      device resets:
      
          Unable to handle kernel NULL pointer dereference at ... 000000d
          ...
          pc : string+0x3c/0x80
          lr : vsnprintf+0x294/0x7e0
          sp : ffff00000f61ba70 pstate : 20000145
          x29: ffff00000f61ba70 x28: 000000000000000d
          x27: ffff0000009c8b5a x26: ffff00000f61bb80
          x25: ffff0000009c8b5a x24: 0000000000000012
          x23: 00000000ffffffe0 x22: ffff000008990428
          x21: ffff00000f61bb80 x20: 000000000000000d
          x19: 000000000000001f x18: 0000000000000000
          x17: 0000000000000000 x16: ffff800b6d0fb400
          x15: 0000000000000000 x14: ffff800b7fe31ae8
          x13: 00001ed16472c920 x12: ffff000008c6b1c9
          x11: ffff000008cf0580 x10: ffff00000f61bb80
          x9 : 00000000ffffffd8 x8 : 000000000000000c
          x7 : ffff800b684b8000 x6 : 0000000000000000
          x5 : 0000000000000065 x4 : 0000000000000001
          x3 : ffff0a00ffffff04 x2 : 000000000000001f
          x1 : 0000000000000000 x0 : 000000000000000d
          Call trace:
          string+0x3c/0x80
          vsnprintf+0x294/0x7e0
          snprintf+0x44/0x50
          __bnxt_open_nic+0x34c/0x928 [bnxt_en]
          bnxt_open+0xe8/0x238 [bnxt_en]
          __dev_open+0xbc/0x130
          __dev_change_flags+0x12c/0x168
          dev_change_flags+0x20/0x60
          ...
      
      Ordinarily, a call to bnxt_setup_inta() (not in trace due to inlining)
      would not be expected on a system supporting MSIX at all. However, if
      bnxt_init_int_mode() does not end up being called after the call to
      bnxt_clear_int_mode() in bnxt_fw_reset_close(), then the driver will
      think that only INTA is supported and bp->irq_tbl will be NULL,
      causing the above crash.
      
      In the error recovery scenario, we call bnxt_clear_int_mode() in
      bnxt_fw_reset_close() early in the sequence. Ordinarily, we will
      call bnxt_init_int_mode() in bnxt_hwrm_if_change() after we
      reestablish communication with the firmware after reset.  However,
      if the sequence has to abort before we call bnxt_init_int_mode() and
      if the user later attempts to re-open the device, then it will cause
      the crash above.
      
      We fix it in 2 ways:
      
      1. Check for bp->irq_tbl in bnxt_setup_int_mode(). If it is NULL, call
      bnxt_init_init_mode().
      
      2. If we need to abort in bnxt_hwrm_if_change() and cannot complete
      the error recovery sequence, set the BNXT_STATE_ABORT_ERR flag.  This
      will cause more drastic recovery at the next attempt to re-open the
      device, including a call to bnxt_init_int_mode().
      
      Fixes: 3bc7d4a3 ("bnxt_en: Add BNXT_STATE_IN_FW_RESET state.")
      Reviewed-by: NScott Branden <scott.branden@broadcom.com>
      Signed-off-by: NEdwin Peer <edwin.peer@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      20d7d1c5
    • V
      bnxt_en: Fix race between firmware reset and driver remove. · d20cd745
      Vasundhara Volam 提交于
      The driver's error recovery reset sequence can take many seconds to
      complete and only the critical sections are protected by rtnl_lock.
      A recent change has introduced a regression in this sequence.
      
      bnxt_remove_one() may be called while the recovery is in progress.
      Normally, unregister_netdev() would cause bnxt_close_nic() to be
      called and this would cause the error recovery to safely abort
      with the BNXT_STATE_ABORT_ERR flag set in bnxt_close_nic().
      
      Recently, we added bnxt_reinit_after_abort() to allow the user to
      reopen the device after an aborted recovery.  This causes the
      regression in the scenario described above because we would
      attempt to re-open even after the netdev has been unregistered.
      
      Fix it by checking the netdev reg_state in
      bnxt_reinit_after_abort() and abort if it is unregistered.
      
      Fixes: 6882c36c ("bnxt_en: attempt to reinitialize after aborted reset")
      Signed-off-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      d20cd745
  3. 15 2月, 2021 6 次提交
  4. 12 2月, 2021 1 次提交
  5. 27 1月, 2021 1 次提交
  6. 26 1月, 2021 14 次提交
  7. 08 1月, 2021 1 次提交
  8. 06 1月, 2021 1 次提交
  9. 29 12月, 2020 2 次提交
  10. 01 12月, 2020 1 次提交
  11. 21 11月, 2020 1 次提交
  12. 20 11月, 2020 2 次提交
  13. 17 11月, 2020 2 次提交
  14. 27 10月, 2020 5 次提交
    • V
      bnxt_en: Send HWRM_FUNC_RESET fw command unconditionally. · 825741b0
      Vasundhara Volam 提交于
      In the AER or firmware reset flow, if we are in fatal error state or
      if pci_channel_offline() is true, we don't send any commands to the
      firmware because the commands will likely not reach the firmware and
      most commands don't matter much because the firmware is likely to be
      reset imminently.
      
      However, the HWRM_FUNC_RESET command is different and we should always
      attempt to send it.  In the AER flow for example, the .slot_reset()
      call will trigger this fw command and we need to try to send it to
      effect the proper reset.
      
      Fixes: b340dc68 ("bnxt_en: Avoid sending firmware messages when AER error is detected.")
      Reviewed-by: NEdwin Peer <edwin.peer@broadcom.com>
      Signed-off-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      825741b0
    • M
      bnxt_en: Check abort error state in bnxt_open_nic(). · a1301f08
      Michael Chan 提交于
      bnxt_open_nic() is called during configuration changes that require
      the NIC to be closed and then opened.  This call is protected by
      rtnl_lock.  Firmware reset can be happening at the same time.  Only
      critical portions of the entire firmware reset sequence are protected
      by the rtnl_lock.  It is possible that bnxt_open_nic() can be called
      when the firmware reset sequence is aborting.  In that case,
      bnxt_open_nic() needs to check if the ABORT_ERR flag is set and
      abort if it is.  The configuration change that resulted in the
      bnxt_open_nic() call will fail but the NIC will be brought to a
      consistent IF_DOWN state.
      
      Without this patch, if bnxt_open_nic() were to continue in this error
      state, it may crash like this:
      
      [ 1648.659736] BUG: unable to handle kernel NULL pointer dereference at           (null)
      [ 1648.659768] IP: [<ffffffffc01e9b3a>] bnxt_alloc_mem+0x50a/0x1140 [bnxt_en]
      [ 1648.659796] PGD 101e1b3067 PUD 101e1b2067 PMD 0
      [ 1648.659813] Oops: 0000 [#1] SMP
      [ 1648.659825] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter sunrpc dell_smbios dell_wmi_descriptor dcdbas amd64_edac_mod edac_mce_amd kvm_amd kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper vfat cryptd fat pcspkr ipmi_ssif sg k10temp i2c_piix4 wmi ipmi_si ipmi_devintf ipmi_msghandler tpm_crb acpi_power_meter sch_fq_codel ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic mgag200 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm ahci drm libahci megaraid_sas crct10dif_pclmul crct10dif_common
      [ 1648.660063]  tg3 libata crc32c_intel bnxt_en(OE) drm_panel_orientation_quirks devlink ptp pps_core dm_mirror dm_region_hash dm_log dm_mod fuse
      [ 1648.660105] CPU: 13 PID: 3867 Comm: ethtool Kdump: loaded Tainted: G           OE  ------------   3.10.0-1152.el7.x86_64 #1
      [ 1648.660911] Hardware name: Dell Inc. PowerEdge R7515/0R4CNN, BIOS 1.2.14 01/28/2020
      [ 1648.661662] task: ffff94e64cbc9080 ti: ffff94f55df1c000 task.ti: ffff94f55df1c000
      [ 1648.662409] RIP: 0010:[<ffffffffc01e9b3a>]  [<ffffffffc01e9b3a>] bnxt_alloc_mem+0x50a/0x1140 [bnxt_en]
      [ 1648.663171] RSP: 0018:ffff94f55df1fba8  EFLAGS: 00010202
      [ 1648.663927] RAX: 0000000000000000 RBX: ffff94e6827e0000 RCX: 0000000000000000
      [ 1648.664684] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff94e6827e08c0
      [ 1648.665433] RBP: ffff94f55df1fc20 R08: 00000000000001ff R09: 0000000000000008
      [ 1648.666184] R10: 0000000000000d53 R11: ffff94f55df1f7ce R12: ffff94e6827e08c0
      [ 1648.666940] R13: ffff94e6827e08c0 R14: ffff94e6827e08c0 R15: ffffffffb9115e40
      [ 1648.667695] FS:  00007f8aadba5740(0000) GS:ffff94f57eb40000(0000) knlGS:0000000000000000
      [ 1648.668447] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [ 1648.669202] CR2: 0000000000000000 CR3: 0000001022772000 CR4: 0000000000340fe0
      [ 1648.669966] Call Trace:
      [ 1648.670730]  [<ffffffffc01f1d5d>] ? bnxt_need_reserve_rings+0x9d/0x170 [bnxt_en]
      [ 1648.671496]  [<ffffffffc01fa7ea>] __bnxt_open_nic+0x8a/0x9a0 [bnxt_en]
      [ 1648.672263]  [<ffffffffc01f7479>] ? bnxt_close_nic+0x59/0x1b0 [bnxt_en]
      [ 1648.673031]  [<ffffffffc01fb11b>] bnxt_open_nic+0x1b/0x50 [bnxt_en]
      [ 1648.673793]  [<ffffffffc020037c>] bnxt_set_ringparam+0x6c/0xa0 [bnxt_en]
      [ 1648.674550]  [<ffffffffb8a5f564>] dev_ethtool+0x1334/0x21a0
      [ 1648.675306]  [<ffffffffb8a719ff>] dev_ioctl+0x1ef/0x5f0
      [ 1648.676061]  [<ffffffffb8a324bd>] sock_do_ioctl+0x4d/0x60
      [ 1648.676810]  [<ffffffffb8a326bb>] sock_ioctl+0x1eb/0x2d0
      [ 1648.677548]  [<ffffffffb8663230>] do_vfs_ioctl+0x3a0/0x5b0
      [ 1648.678282]  [<ffffffffb8b8e678>] ? __do_page_fault+0x238/0x500
      [ 1648.679016]  [<ffffffffb86634e1>] SyS_ioctl+0xa1/0xc0
      [ 1648.679745]  [<ffffffffb8b93f92>] system_call_fastpath+0x25/0x2a
      [ 1648.680461] Code: 9e 60 01 00 00 0f 1f 40 00 45 8b 8e 48 01 00 00 31 c9 45 85 c9 0f 8e 73 01 00 00 66 0f 1f 44 00 00 49 8b 86 a8 00 00 00 48 63 d1 <48> 8b 14 d0 48 85 d2 0f 84 46 01 00 00 41 8b 86 44 01 00 00 c7
      [ 1648.681986] RIP  [<ffffffffc01e9b3a>] bnxt_alloc_mem+0x50a/0x1140 [bnxt_en]
      [ 1648.682724]  RSP <ffff94f55df1fba8>
      [ 1648.683451] CR2: 0000000000000000
      
      Fixes: ec5d31e3 ("bnxt_en: Handle firmware reset status during IF_UP.")
      Reviewed-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Reviewed-by: NPavan Chebbi <pavan.chebbi@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      a1301f08
    • V
      bnxt_en: Re-write PCI BARs after PCI fatal error. · f75d9a0a
      Vasundhara Volam 提交于
      When a PCIe fatal error occurs, the internal latched BAR addresses
      in the chip get reset even though the BAR register values in config
      space are retained.
      
      pci_restore_state() will not rewrite the BAR addresses if the
      BAR address values are valid, causing the chip's internal BAR addresses
      to stay invalid.  So we need to zero the BAR registers during PCIe fatal
      error to force pci_restore_state() to restore the BAR addresses.  These
      write cycles to the BAR registers will cause the proper BAR addresses to
      latch internally.
      
      Fixes: 6316ea6d ("bnxt_en: Enable AER support.")
      Signed-off-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      f75d9a0a
    • V
      bnxt_en: Invoke cancel_delayed_work_sync() for PFs also. · 631ce27a
      Vasundhara Volam 提交于
      As part of the commit b148bb23
      ("bnxt_en: Fix possible crash in bnxt_fw_reset_task()."),
      cancel_delayed_work_sync() is called only for VFs to fix a possible
      crash by cancelling any pending delayed work items. It was assumed
      by mistake that the flush_workqueue() call on the PF would flush
      delayed work items as well.
      
      As flush_workqueue() does not cancel the delayed workqueue, extend
      the fix for PFs. This fix will avoid the system crash, if there are
      any pending delayed work items in fw_reset_task() during driver's
      .remove() call.
      
      Unify the workqueue cleanup logic for both PF and VF by calling
      cancel_work_sync() and cancel_delayed_work_sync() directly in
      bnxt_remove_one().
      
      Fixes: b148bb23 ("bnxt_en: Fix possible crash in bnxt_fw_reset_task().")
      Reviewed-by: NPavan Chebbi <pavan.chebbi@broadcom.com>
      Reviewed-by: NAndy Gospodarek <gospo@broadcom.com>
      Signed-off-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      631ce27a
    • V
      bnxt_en: Fix regression in workqueue cleanup logic in bnxt_remove_one(). · 21d6a11e
      Vasundhara Volam 提交于
      A recent patch has moved the workqueue cleanup logic before
      calling unregister_netdev() in bnxt_remove_one().  This caused a
      regression because the workqueue can be restarted if the device is
      still open.  Workqueue cleanup must be done after unregister_netdev().
      The workqueue will not restart itself after the device is closed.
      
      Call bnxt_cancel_sp_work() after unregister_netdev() and
      call bnxt_dl_fw_reporters_destroy() after that.  This fixes the
      regession and the original NULL ptr dereference issue.
      
      Fixes: b16939b5 ("bnxt_en: Fix NULL ptr dereference crash in bnxt_fw_reset_task()")
      Signed-off-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      21d6a11e