2018-03-22 10:08:48 -07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2018-04-26 08:08:09 -07:00
|
|
|
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
#ifndef _IAVF_H_
|
|
|
|
#define _IAVF_H_
|
2013-12-21 06:13:06 +00:00
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/pci.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/vmalloc.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/ethtool.h>
|
|
|
|
#include <linux/if_vlan.h>
|
|
|
|
#include <linux/ip.h>
|
|
|
|
#include <linux/tcp.h>
|
|
|
|
#include <linux/sctp.h>
|
|
|
|
#include <linux/ipv6.h>
|
2017-06-20 15:17:01 -07:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/bitops.h>
|
|
|
|
#include <linux/timer.h>
|
|
|
|
#include <linux/workqueue.h>
|
2017-06-23 04:24:44 -04:00
|
|
|
#include <linux/wait.h>
|
2017-06-20 15:17:01 -07:00
|
|
|
#include <linux/delay.h>
|
|
|
|
#include <linux/gfp.h>
|
|
|
|
#include <linux/skbuff.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
|
#include <linux/socket.h>
|
|
|
|
#include <linux/jiffies.h>
|
2013-12-21 06:13:06 +00:00
|
|
|
#include <net/ip6_checksum.h>
|
2018-01-23 08:50:57 -08:00
|
|
|
#include <net/pkt_cls.h>
|
2023-02-04 15:52:57 +02:00
|
|
|
#include <net/pkt_sched.h>
|
2013-12-21 06:13:06 +00:00
|
|
|
#include <net/udp.h>
|
2018-01-23 08:51:05 -08:00
|
|
|
#include <net/tc_act/tc_gact.h>
|
|
|
|
#include <net/tc_act/tc_mirred.h>
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2018-09-14 17:37:56 -07:00
|
|
|
#include "iavf_type.h"
|
2017-05-11 11:23:09 -07:00
|
|
|
#include <linux/avf/virtchnl.h>
|
2018-09-14 17:37:48 -07:00
|
|
|
#include "iavf_txrx.h"
|
2021-03-09 11:08:11 +08:00
|
|
|
#include "iavf_fdir.h"
|
2021-04-13 08:48:41 +08:00
|
|
|
#include "iavf_adv_rss.h"
|
2021-06-04 09:53:27 -07:00
|
|
|
#include <linux/bitmap.h>
|
2013-12-21 06:13:06 +00:00
|
|
|
|
|
|
|
#define DEFAULT_DEBUG_LEVEL_SHIFT 3
|
2018-09-14 17:37:46 -07:00
|
|
|
#define PFX "iavf: "
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2022-01-27 15:16:29 +01:00
|
|
|
int iavf_status_to_errno(enum iavf_status status);
|
|
|
|
int virtchnl_status_to_errno(enum virtchnl_status_code v_status);
|
|
|
|
|
2017-04-21 13:38:05 -07:00
|
|
|
/* VSI state flags shared with common code */
|
2018-09-14 17:37:46 -07:00
|
|
|
enum iavf_vsi_state_t {
|
2018-09-14 17:37:55 -07:00
|
|
|
__IAVF_VSI_DOWN,
|
2017-04-19 09:25:55 -04:00
|
|
|
/* This must be last as it determines the size of the BITMAP */
|
2018-09-14 17:37:55 -07:00
|
|
|
__IAVF_VSI_STATE_SIZE__,
|
2017-04-21 13:38:05 -07:00
|
|
|
};
|
|
|
|
|
2013-12-21 06:13:06 +00:00
|
|
|
/* dummy struct to make common code less painful */
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_vsi {
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_adapter *back;
|
2013-12-21 06:13:06 +00:00
|
|
|
struct net_device *netdev;
|
|
|
|
u16 seid;
|
|
|
|
u16 id;
|
2018-09-14 17:37:55 -07:00
|
|
|
DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
|
2013-12-21 06:13:06 +00:00
|
|
|
int base_vector;
|
2015-08-28 17:55:58 -04:00
|
|
|
u16 qs_handle;
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* How many Rx Buffers do we bundle into one write to the hardware ? */
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */
|
|
|
|
#define IAVF_DEFAULT_TXD 512
|
|
|
|
#define IAVF_DEFAULT_RXD 512
|
|
|
|
#define IAVF_MAX_TXD 4096
|
|
|
|
#define IAVF_MIN_TXD 64
|
|
|
|
#define IAVF_MAX_RXD 4096
|
|
|
|
#define IAVF_MIN_RXD 64
|
|
|
|
#define IAVF_REQ_DESCRIPTOR_MULTIPLE 32
|
|
|
|
#define IAVF_MAX_AQ_BUF_SIZE 4096
|
|
|
|
#define IAVF_AQ_LEN 32
|
|
|
|
#define IAVF_AQ_MAX_ERR 20 /* times to try before resetting AQ */
|
2013-12-21 06:13:06 +00:00
|
|
|
|
|
|
|
#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
|
|
|
|
|
2018-09-14 17:37:55 -07:00
|
|
|
#define IAVF_RX_DESC(R, i) (&(((union iavf_32byte_rx_desc *)((R)->desc))[i]))
|
|
|
|
#define IAVF_TX_DESC(R, i) (&(((struct iavf_tx_desc *)((R)->desc))[i]))
|
2018-09-14 17:37:49 -07:00
|
|
|
#define IAVF_TX_CTXTDESC(R, i) \
|
2018-09-14 17:37:55 -07:00
|
|
|
(&(((struct iavf_tx_context_desc *)((R)->desc))[i]))
|
2020-02-27 10:14:51 -08:00
|
|
|
#define IAVF_MAX_REQ_QUEUES 16
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2018-09-14 17:37:49 -07:00
|
|
|
#define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4)
|
|
|
|
#define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4)
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */
|
2022-06-13 18:41:23 -04:00
|
|
|
#define IAVF_MBPS_QUANTA 50
|
2015-06-23 19:00:04 -04:00
|
|
|
|
2023-07-28 17:52:06 +02:00
|
|
|
#define IAVF_VIRTCHNL_VF_RESOURCE_SIZE \
|
|
|
|
virtchnl_struct_size((struct virtchnl_vf_resource *)NULL, \
|
|
|
|
vsi_res, IAVF_MAX_VF_VSI)
|
2020-06-05 10:09:43 -07:00
|
|
|
|
2013-12-21 06:13:06 +00:00
|
|
|
/* MAX_MSIX_Q_VECTORS of these are allocated,
|
|
|
|
* but we only use one per queue-specific vector.
|
|
|
|
*/
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_q_vector {
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_adapter *adapter;
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_vsi *vsi;
|
2013-12-21 06:13:06 +00:00
|
|
|
struct napi_struct napi;
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_ring_container rx;
|
|
|
|
struct iavf_ring_container tx;
|
2013-12-21 06:13:06 +00:00
|
|
|
u32 ring_mask;
|
2017-12-29 08:52:19 -05:00
|
|
|
u8 itr_countdown; /* when 0 should adjust adaptive ITR */
|
2013-12-21 06:13:06 +00:00
|
|
|
u8 num_ringpairs; /* total number of ring pairs in vector */
|
2017-12-29 08:48:53 -05:00
|
|
|
u16 v_idx; /* index in the vsi->q_vector array. */
|
|
|
|
u16 reg_idx; /* register index of the interrupt */
|
2017-07-12 05:46:11 -04:00
|
|
|
char name[IFNAMSIZ + 15];
|
2015-06-05 12:20:30 -04:00
|
|
|
bool arm_wb_state;
|
i40e/i40evf: fix interrupt affinity bug
There exists a bug in which a 'perfect storm' can occur and cause
interrupts to fail to be correctly affinitized. This causes unexpected
behavior and has a substantial impact on performance when it happens.
The bug occurs if there is heavy traffic, any number of CPUs that have
an i40e interrupt are pegged at 100%, and the interrupt afffinity for
those CPUs is changed. Instead of moving to the new CPU, the interrupt
continues to be polled while there is heavy traffic.
The bug is most readily realized as the driver is first brought up and
all interrupts start on CPU0. If there is heavy traffic and the
interrupt starts polling before the interrupt is affinitized, the
interrupt will be stuck on CPU0 until traffic stops. The bug, however,
can also be wrought out more simply by affinitizing all the interrupts
to a single CPU and then attempting to move any of those interrupts off
while there is heavy traffic.
This patch fixes the bug by registering for update notifications from
the kernel when the interrupt affinity changes. When that fires, we
cache the intended affinity mask. Then, while polling, if the cpu is
pegged at 100% and we failed to clean the rings, we check to make sure
we have the correct affinity and stop polling if we're firing on the
wrong CPU. When the kernel successfully moves the interrupt, it will
start polling on the correct CPU. The performance impact is minimal
since the only time this section gets executed is when performance is
already compromised by the CPU.
Change-ID: I4410a880159b9dba1f8297aa72bef36dca34e830
Signed-off-by: Alan Brady <alan.brady@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
2016-09-14 16:24:38 -07:00
|
|
|
cpumask_t affinity_mask;
|
|
|
|
struct irq_affinity_notify affinity_notify;
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Helper macros to switch between ints/sec and what the register uses.
|
|
|
|
* And yes, it's the same math going both ways. The lowest value
|
2019-04-17 15:17:36 -07:00
|
|
|
* supported by all of the iavf hardware is 8.
|
2013-12-21 06:13:06 +00:00
|
|
|
*/
|
|
|
|
#define EITR_INTS_PER_SEC_TO_REG(_eitr) \
|
|
|
|
((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8)
|
|
|
|
#define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_DESC_UNUSED(R) \
|
2013-12-21 06:13:06 +00:00
|
|
|
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
|
|
|
|
(R)->next_to_clean - (R)->next_to_use - 1)
|
|
|
|
|
|
|
|
#define OTHER_VECTOR 1
|
|
|
|
#define NONQ_VECS (OTHER_VECTOR)
|
|
|
|
|
|
|
|
#define MIN_MSIX_Q_VECTORS 1
|
|
|
|
#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NONQ_VECS)
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_QUEUE_END_OF_LIST 0x7FF
|
|
|
|
#define IAVF_FREE_VECTOR 0x7FFF
|
|
|
|
struct iavf_mac_filter {
|
2013-12-21 06:13:06 +00:00
|
|
|
struct list_head list;
|
|
|
|
u8 macaddr[ETH_ALEN];
|
2021-08-30 08:25:36 +00:00
|
|
|
struct {
|
|
|
|
u8 is_new_mac:1; /* filter is new, wait for PF decision */
|
|
|
|
u8 remove:1; /* filter needs to be removed */
|
|
|
|
u8 add:1; /* filter needs to be added */
|
|
|
|
u8 is_primary:1; /* filter is a default VF MAC */
|
2022-05-20 12:07:13 +02:00
|
|
|
u8 add_handled:1; /* received response for filter add */
|
|
|
|
u8 padding:3;
|
2021-08-30 08:25:36 +00:00
|
|
|
};
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
iavf: Add support VIRTCHNL_VF_OFFLOAD_VLAN_V2 during netdev config
Based on VIRTCHNL_VF_OFFLOAD_VLAN_V2, the VF can now support more VLAN
capabilities (i.e. 802.1AD offloads and filtering). In order to
communicate these capabilities to the netdev layer, the VF needs to
parse its VLAN capabilities based on whether it was able to negotiation
VIRTCHNL_VF_OFFLOAD_VLAN or VIRTCHNL_VF_OFFLOAD_VLAN_V2 or neither of
these.
In order to support this, add the following functionality:
iavf_get_netdev_vlan_hw_features() - This is used to determine the VLAN
features that the underlying hardware supports and that can be toggled
off/on based on the negotiated capabiltiies. For example, if
VIRTCHNL_VF_OFFLOAD_VLAN_V2 was negotiated, then any capability marked
with VIRTCHNL_VLAN_TOGGLE can be toggled on/off by the VF. If
VIRTCHNL_VF_OFFLOAD_VLAN was negotiated, then only VLAN insertion and/or
stripping can be toggled on/off.
iavf_get_netdev_vlan_features() - This is used to determine the VLAN
features that the underlying hardware supports and that should be
enabled by default. For example, if VIRTHCNL_VF_OFFLOAD_VLAN_V2 was
negotiated, then any supported capability that has its ethertype_init
filed set should be enabled by default. If VIRTCHNL_VF_OFFLOAD_VLAN was
negotiated, then filtering, stripping, and insertion should be enabled
by default.
Also, refactor iavf_fix_features() to take into account the new
capabilities. To do this, query all the supported features (enabled by
default and toggleable) and make sure the requested change is supported.
If VIRTCHNL_VF_OFFLOAD_VLAN_V2 is successfully negotiated, there is no
need to check VIRTCHNL_VLAN_TOGGLE here because the driver already told
the netdev layer which features can be toggled via netdev->hw_features
during iavf_process_config(), so only those features will be requested
to change.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-11-29 16:16:01 -08:00
|
|
|
#define IAVF_VLAN(vid, tpid) ((struct iavf_vlan){ vid, tpid })
|
|
|
|
struct iavf_vlan {
|
|
|
|
u16 vid;
|
|
|
|
u16 tpid;
|
|
|
|
};
|
|
|
|
|
2023-04-06 15:35:27 -06:00
|
|
|
enum iavf_vlan_state_t {
|
|
|
|
IAVF_VLAN_INVALID,
|
|
|
|
IAVF_VLAN_ADD, /* filter needs to be added */
|
|
|
|
IAVF_VLAN_IS_NEW, /* filter is new, wait for PF answer */
|
|
|
|
IAVF_VLAN_ACTIVE, /* filter is accepted by PF */
|
2023-04-06 15:35:28 -06:00
|
|
|
IAVF_VLAN_DISABLE, /* filter needs to be deleted by PF, then marked INACTIVE */
|
|
|
|
IAVF_VLAN_INACTIVE, /* filter is inactive, we are in IFF_DOWN */
|
|
|
|
IAVF_VLAN_REMOVE, /* filter needs to be removed from list */
|
2023-04-06 15:35:27 -06:00
|
|
|
};
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_vlan_filter {
|
2013-12-21 06:13:06 +00:00
|
|
|
struct list_head list;
|
iavf: Add support VIRTCHNL_VF_OFFLOAD_VLAN_V2 during netdev config
Based on VIRTCHNL_VF_OFFLOAD_VLAN_V2, the VF can now support more VLAN
capabilities (i.e. 802.1AD offloads and filtering). In order to
communicate these capabilities to the netdev layer, the VF needs to
parse its VLAN capabilities based on whether it was able to negotiation
VIRTCHNL_VF_OFFLOAD_VLAN or VIRTCHNL_VF_OFFLOAD_VLAN_V2 or neither of
these.
In order to support this, add the following functionality:
iavf_get_netdev_vlan_hw_features() - This is used to determine the VLAN
features that the underlying hardware supports and that can be toggled
off/on based on the negotiated capabiltiies. For example, if
VIRTCHNL_VF_OFFLOAD_VLAN_V2 was negotiated, then any capability marked
with VIRTCHNL_VLAN_TOGGLE can be toggled on/off by the VF. If
VIRTCHNL_VF_OFFLOAD_VLAN was negotiated, then only VLAN insertion and/or
stripping can be toggled on/off.
iavf_get_netdev_vlan_features() - This is used to determine the VLAN
features that the underlying hardware supports and that should be
enabled by default. For example, if VIRTHCNL_VF_OFFLOAD_VLAN_V2 was
negotiated, then any supported capability that has its ethertype_init
filed set should be enabled by default. If VIRTCHNL_VF_OFFLOAD_VLAN was
negotiated, then filtering, stripping, and insertion should be enabled
by default.
Also, refactor iavf_fix_features() to take into account the new
capabilities. To do this, query all the supported features (enabled by
default and toggleable) and make sure the requested change is supported.
If VIRTCHNL_VF_OFFLOAD_VLAN_V2 is successfully negotiated, there is no
need to check VIRTCHNL_VLAN_TOGGLE here because the driver already told
the netdev layer which features can be toggled via netdev->hw_features
during iavf_process_config(), so only those features will be requested
to change.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-11-29 16:16:01 -08:00
|
|
|
struct iavf_vlan vlan;
|
2023-04-06 15:35:27 -06:00
|
|
|
enum iavf_vlan_state_t state;
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_MAX_TRAFFIC_CLASS 4
|
2018-01-23 08:50:57 -08:00
|
|
|
/* State of traffic class creation */
|
2018-09-14 17:37:46 -07:00
|
|
|
enum iavf_tc_state_t {
|
|
|
|
__IAVF_TC_INVALID, /* no traffic class, default state */
|
|
|
|
__IAVF_TC_RUNNING, /* traffic classes have been created */
|
2018-01-23 08:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* channel info */
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_channel_config {
|
|
|
|
struct virtchnl_channel_info ch_info[IAVF_MAX_TRAFFIC_CLASS];
|
|
|
|
enum iavf_tc_state_t state;
|
2018-01-23 08:50:57 -08:00
|
|
|
u8 total_qps;
|
|
|
|
};
|
|
|
|
|
2018-01-23 08:51:05 -08:00
|
|
|
/* State of cloud filter */
|
2018-09-14 17:37:46 -07:00
|
|
|
enum iavf_cloud_filter_state_t {
|
|
|
|
__IAVF_CF_INVALID, /* cloud filter not added */
|
|
|
|
__IAVF_CF_ADD_PENDING, /* cloud filter pending add by the PF */
|
|
|
|
__IAVF_CF_DEL_PENDING, /* cloud filter pending del by the PF */
|
|
|
|
__IAVF_CF_ACTIVE, /* cloud filter is active */
|
2018-01-23 08:51:05 -08:00
|
|
|
};
|
|
|
|
|
2013-12-21 06:13:06 +00:00
|
|
|
/* Driver state. The order of these is important! */
|
2018-09-14 17:37:46 -07:00
|
|
|
enum iavf_state_t {
|
|
|
|
__IAVF_STARTUP, /* driver loaded, probe complete */
|
|
|
|
__IAVF_REMOVE, /* driver is being unloaded */
|
|
|
|
__IAVF_INIT_VERSION_CHECK, /* aq msg sent, awaiting reply */
|
|
|
|
__IAVF_INIT_GET_RESOURCES, /* aq msg sent, awaiting reply */
|
iavf: refactor processing of VLAN V2 capability message
In order to handle the capability exchange necessary for
VIRTCHNL_VF_OFFLOAD_VLAN_V2, the driver must send
a VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS message. This must occur prior to
__IAVF_CONFIG_ADAPTER, and the driver must wait for the response from
the PF.
To handle this, the __IAVF_INIT_GET_OFFLOAD_VLAN_V2_CAPS state was
introduced. This state is intended to process the response from the VLAN
V2 caps message. This works ok, but is difficult to extend to adding
more extended capability exchange.
Existing (and future) AVF features are relying more and more on these
sort of extended ops for processing additional capabilities. Just like
VLAN V2, this exchange must happen prior to __IAVF_CONFIG_ADPATER.
Since we only send one outstanding AQ message at a time during init, it
is not clear where to place this state. Adding more capability specific
states becomes a mess. Instead of having the "previous" state send
a message and then transition into a capability-specific state,
introduce __IAVF_EXTENDED_CAPS state. This state will use a list of
extended_caps that determines what messages to send and receive. As long
as there are extended_caps bits still set, the driver will remain in
this state performing one send or one receive per state machine loop.
Refactor the VLAN V2 negotiation to use this new state, and remove the
capability-specific state. This makes it significantly easier to add
a new similar capability exchange going forward.
Extended capabilities are processed by having an associated SEND and
RECV extended capability bit. During __IAVF_EXTENDED_CAPS, the
driver checks these bits in order by feature, first the send bit for
a feature, then the recv bit for a feature. Each send flag will call
a function that sends the necessary response, while each receive flag
will wait for the response from the PF. If a given feature can't be
negotiated with the PF, the associated flags will be cleared in
order to skip processing of that feature.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2022-01-14 10:36:36 +01:00
|
|
|
__IAVF_INIT_EXTENDED_CAPS, /* process extended caps which require aq msg exchange */
|
2021-11-29 16:16:00 -08:00
|
|
|
__IAVF_INIT_CONFIG_ADAPTER,
|
2018-09-14 17:37:46 -07:00
|
|
|
__IAVF_INIT_SW, /* got resources, setting up structs */
|
2021-08-19 08:47:49 +00:00
|
|
|
__IAVF_INIT_FAILED, /* init failed, restarting procedure */
|
2018-09-14 17:37:46 -07:00
|
|
|
__IAVF_RESETTING, /* in reset */
|
2019-05-14 10:37:06 -07:00
|
|
|
__IAVF_COMM_FAILED, /* communication with PF failed */
|
2013-12-21 06:13:06 +00:00
|
|
|
/* Below here, watchdog is running */
|
2018-09-14 17:37:46 -07:00
|
|
|
__IAVF_DOWN, /* ready, can be opened */
|
|
|
|
__IAVF_DOWN_PENDING, /* descending, waiting for watchdog */
|
|
|
|
__IAVF_TESTING, /* in ethtool self-test */
|
|
|
|
__IAVF_RUNNING, /* opened, working */
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
2022-02-23 13:37:10 +01:00
|
|
|
enum iavf_critical_section_t {
|
|
|
|
__IAVF_IN_REMOVE_TASK, /* device being removed */
|
|
|
|
};
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_CLOUD_FIELD_OMAC 0x01
|
|
|
|
#define IAVF_CLOUD_FIELD_IMAC 0x02
|
|
|
|
#define IAVF_CLOUD_FIELD_IVLAN 0x04
|
|
|
|
#define IAVF_CLOUD_FIELD_TEN_ID 0x08
|
|
|
|
#define IAVF_CLOUD_FIELD_IIP 0x10
|
|
|
|
|
|
|
|
#define IAVF_CF_FLAGS_OMAC IAVF_CLOUD_FIELD_OMAC
|
|
|
|
#define IAVF_CF_FLAGS_IMAC IAVF_CLOUD_FIELD_IMAC
|
|
|
|
#define IAVF_CF_FLAGS_IMAC_IVLAN (IAVF_CLOUD_FIELD_IMAC |\
|
|
|
|
IAVF_CLOUD_FIELD_IVLAN)
|
|
|
|
#define IAVF_CF_FLAGS_IMAC_TEN_ID (IAVF_CLOUD_FIELD_IMAC |\
|
|
|
|
IAVF_CLOUD_FIELD_TEN_ID)
|
|
|
|
#define IAVF_CF_FLAGS_OMAC_TEN_ID_IMAC (IAVF_CLOUD_FIELD_OMAC |\
|
|
|
|
IAVF_CLOUD_FIELD_IMAC |\
|
|
|
|
IAVF_CLOUD_FIELD_TEN_ID)
|
|
|
|
#define IAVF_CF_FLAGS_IMAC_IVLAN_TEN_ID (IAVF_CLOUD_FIELD_IMAC |\
|
|
|
|
IAVF_CLOUD_FIELD_IVLAN |\
|
|
|
|
IAVF_CLOUD_FIELD_TEN_ID)
|
2018-09-14 17:37:55 -07:00
|
|
|
#define IAVF_CF_FLAGS_IIP IAVF_CLOUD_FIELD_IIP
|
2018-01-23 08:51:05 -08:00
|
|
|
|
|
|
|
/* bookkeeping of cloud filters */
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_cloud_filter {
|
|
|
|
enum iavf_cloud_filter_state_t state;
|
2018-01-23 08:51:05 -08:00
|
|
|
struct list_head list;
|
|
|
|
struct virtchnl_filter f;
|
|
|
|
unsigned long cookie;
|
|
|
|
bool del; /* filter needs to be deleted */
|
|
|
|
bool add; /* filter needs to be added */
|
|
|
|
};
|
|
|
|
|
2020-06-05 10:09:46 -07:00
|
|
|
#define IAVF_RESET_WAIT_MS 10
|
|
|
|
#define IAVF_RESET_WAIT_DETECTED_COUNT 500
|
|
|
|
#define IAVF_RESET_WAIT_COMPLETE_COUNT 2000
|
|
|
|
|
2013-12-21 06:13:06 +00:00
|
|
|
/* board specific private data structure */
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_adapter {
|
2022-12-15 23:50:48 +01:00
|
|
|
struct workqueue_struct *wq;
|
2013-12-21 06:13:06 +00:00
|
|
|
struct work_struct reset_task;
|
|
|
|
struct work_struct adminq_task;
|
iavf: fix a deadlock caused by rtnl and driver's lock circular dependencies
A driver's lock (crit_lock) is used to serialize all the driver's tasks.
Lockdep, however, shows a circular dependency between rtnl and
crit_lock. This happens when an ndo that already holds the rtnl requests
the driver to reset, since the reset task (in some paths) tries to grab
rtnl to either change real number of queues of update netdev features.
[566.241851] ======================================================
[566.241893] WARNING: possible circular locking dependency detected
[566.241936] 6.2.14-100.fc36.x86_64+debug #1 Tainted: G OE
[566.241984] ------------------------------------------------------
[566.242025] repro.sh/2604 is trying to acquire lock:
[566.242061] ffff9280fc5ceee8 (&adapter->crit_lock){+.+.}-{3:3}, at: iavf_close+0x3c/0x240 [iavf]
[566.242167]
but task is already holding lock:
[566.242209] ffffffff9976d350 (rtnl_mutex){+.+.}-{3:3}, at: iavf_remove+0x6b5/0x730 [iavf]
[566.242300]
which lock already depends on the new lock.
[566.242353]
the existing dependency chain (in reverse order) is:
[566.242401]
-> #1 (rtnl_mutex){+.+.}-{3:3}:
[566.242451] __mutex_lock+0xc1/0xbb0
[566.242489] iavf_init_interrupt_scheme+0x179/0x440 [iavf]
[566.242560] iavf_watchdog_task+0x80b/0x1400 [iavf]
[566.242627] process_one_work+0x2b3/0x560
[566.242663] worker_thread+0x4f/0x3a0
[566.242696] kthread+0xf2/0x120
[566.242730] ret_from_fork+0x29/0x50
[566.242763]
-> #0 (&adapter->crit_lock){+.+.}-{3:3}:
[566.242815] __lock_acquire+0x15ff/0x22b0
[566.242869] lock_acquire+0xd2/0x2c0
[566.242901] __mutex_lock+0xc1/0xbb0
[566.242934] iavf_close+0x3c/0x240 [iavf]
[566.242997] __dev_close_many+0xac/0x120
[566.243036] dev_close_many+0x8b/0x140
[566.243071] unregister_netdevice_many_notify+0x165/0x7c0
[566.243116] unregister_netdevice_queue+0xd3/0x110
[566.243157] iavf_remove+0x6c1/0x730 [iavf]
[566.243217] pci_device_remove+0x33/0xa0
[566.243257] device_release_driver_internal+0x1bc/0x240
[566.243299] pci_stop_bus_device+0x6c/0x90
[566.243338] pci_stop_and_remove_bus_device+0xe/0x20
[566.243380] pci_iov_remove_virtfn+0xd1/0x130
[566.243417] sriov_disable+0x34/0xe0
[566.243448] ice_free_vfs+0x2da/0x330 [ice]
[566.244383] ice_sriov_configure+0x88/0xad0 [ice]
[566.245353] sriov_numvfs_store+0xde/0x1d0
[566.246156] kernfs_fop_write_iter+0x15e/0x210
[566.246921] vfs_write+0x288/0x530
[566.247671] ksys_write+0x74/0xf0
[566.248408] do_syscall_64+0x58/0x80
[566.249145] entry_SYSCALL_64_after_hwframe+0x72/0xdc
[566.249886]
other info that might help us debug this:
[566.252014] Possible unsafe locking scenario:
[566.253432] CPU0 CPU1
[566.254118] ---- ----
[566.254800] lock(rtnl_mutex);
[566.255514] lock(&adapter->crit_lock);
[566.256233] lock(rtnl_mutex);
[566.256897] lock(&adapter->crit_lock);
[566.257388]
*** DEADLOCK ***
The deadlock can be triggered by a script that is continuously resetting
the VF adapter while doing other operations requiring RTNL, e.g:
while :; do
ip link set $VF up
ethtool --set-channels $VF combined 2
ip link set $VF down
ip link set $VF up
ethtool --set-channels $VF combined 4
ip link set $VF down
done
Any operation that triggers a reset can substitute "ethtool --set-channles"
As a fix, add a new task "finish_config" that do all the work which
needs rtnl lock. With the exception of iavf_remove(), all work that
require rtnl should be called from this task.
As for iavf_remove(), at the point where we need to call
unregister_netdevice() (and grab rtnl_lock), we make sure the finish_config
task is not running (cancel_work_sync()) to safely grab rtnl. Subsequent
finish_config work cannot restart after that since the task is guarded
by the __IAVF_IN_REMOVE_TASK bit in iavf_schedule_finish_config().
Fixes: 5ac49f3c2702 ("iavf: use mutexes for locking of critical sections")
Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2023-06-05 10:52:25 -04:00
|
|
|
struct work_struct finish_config;
|
2017-06-23 04:24:44 -04:00
|
|
|
wait_queue_head_t down_waitqueue;
|
2023-06-05 10:52:22 -04:00
|
|
|
wait_queue_head_t reset_waitqueue;
|
2022-05-20 12:07:13 +02:00
|
|
|
wait_queue_head_t vc_waitqueue;
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_q_vector *q_vectors;
|
2013-12-21 06:13:06 +00:00
|
|
|
struct list_head vlan_filter_list;
|
2023-04-06 15:35:28 -06:00
|
|
|
int num_vlan_filters;
|
2017-10-27 11:06:50 -04:00
|
|
|
struct list_head mac_filter_list;
|
2021-08-04 10:22:24 +02:00
|
|
|
struct mutex crit_lock;
|
2017-10-27 11:06:50 -04:00
|
|
|
/* Lock to protect accesses to MAC and VLAN lists */
|
|
|
|
spinlock_t mac_vlan_list_lock;
|
2014-02-13 03:48:51 -08:00
|
|
|
char misc_vector_name[IFNAMSIZ + 9];
|
2014-10-25 03:24:34 +00:00
|
|
|
int num_active_queues;
|
2017-08-22 06:57:50 -04:00
|
|
|
int num_req_queues;
|
2013-12-21 06:13:06 +00:00
|
|
|
|
|
|
|
/* TX */
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_ring *tx_rings;
|
2013-12-21 06:13:06 +00:00
|
|
|
u32 tx_timeout_count;
|
2014-04-24 06:41:37 +00:00
|
|
|
u32 tx_desc_count;
|
2013-12-21 06:13:06 +00:00
|
|
|
|
|
|
|
/* RX */
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_ring *rx_rings;
|
2013-12-21 06:13:06 +00:00
|
|
|
u64 hw_csum_rx_error;
|
2014-04-24 06:41:37 +00:00
|
|
|
u32 rx_desc_count;
|
2013-12-21 06:13:06 +00:00
|
|
|
int num_msix_vectors;
|
|
|
|
struct msix_entry *msix_entries;
|
|
|
|
|
2014-02-13 03:48:52 -08:00
|
|
|
u32 flags;
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_FLAG_RX_CSUM_ENABLED BIT(0)
|
|
|
|
#define IAVF_FLAG_PF_COMMS_FAILED BIT(3)
|
|
|
|
#define IAVF_FLAG_RESET_PENDING BIT(4)
|
|
|
|
#define IAVF_FLAG_RESET_NEEDED BIT(5)
|
|
|
|
#define IAVF_FLAG_WB_ON_ITR_CAPABLE BIT(6)
|
iavf: kill "legacy-rx" for good
Ever since build_skb() became stable, the old way with allocating an skb
for storing the headers separately, which will be then copied manually,
was slower, less flexible, and thus obsolete.
* It had higher pressure on MM since it actually allocates new pages,
which then get split and refcount-biased (NAPI page cache);
* It implies memcpy() of packet headers (40+ bytes per each frame);
* the actual header length was calculated via eth_get_headlen(), which
invokes Flow Dissector and thus wastes a bunch of CPU cycles;
* XDP makes it even more weird since it requires headroom for long and
also tailroom for some time (since mbuf landed). Take a look at the
ice driver, which is built around work-arounds to make XDP work with
it.
Even on some quite low-end hardware (not a common case for 100G NICs) it
was performing worse.
The only advantage "legacy-rx" had is that it didn't require any
reserved headroom and tailroom. But iavf didn't use this, as it always
splits pages into two halves of 2k, while that save would only be useful
when striding. And again, XDP effectively removes that sole pro.
There's a train of features to land in IAVF soon: Page Pool, XDP, XSk,
multi-buffer etc. Each new would require adding more and more Danse
Macabre for absolutely no reason, besides making hotpath less and less
effective.
Remove the "feature" with all the related code. This includes at least
one very hot branch (typically hit on each new frame), which was either
always-true or always-false at least for a complete NAPI bulk of 64
frames, the whole private flags cruft, and so on. Some stats:
Function: add/remove: 0/4 grow/shrink: 0/7 up/down: 0/-721 (-721)
RO Data: add/remove: 0/1 grow/shrink: 0/0 up/down: 0/-40 (-40)
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2024-04-18 13:36:08 +02:00
|
|
|
/* BIT(15) is free, was IAVF_FLAG_LEGACY_RX */
|
2018-09-14 17:37:46 -07:00
|
|
|
#define IAVF_FLAG_REINIT_ITR_NEEDED BIT(16)
|
|
|
|
#define IAVF_FLAG_QUEUES_DISABLED BIT(17)
|
2022-02-23 13:37:50 +01:00
|
|
|
#define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18)
|
2022-02-02 12:44:54 +00:00
|
|
|
#define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20)
|
iavf: Introduce new state machines for flow director
New states introduced:
IAVF_FDIR_FLTR_DIS_REQUEST
IAVF_FDIR_FLTR_DIS_PENDING
IAVF_FDIR_FLTR_INACTIVE
Current FDIR state machines (SM) are not adequate to handle a few
scenarios in the link DOWN/UP event, reset event and ntuple-feature.
For example, when VF link goes DOWN and comes back UP administratively,
the expectation is that previously installed filters should also be
restored. But with current SM, filters are not restored.
So with new SM, during link DOWN filters are marked as INACTIVE in
the iavf list but removed from PF. After link UP, SM will transition
from INACTIVE to ADD_REQUEST to restore the filter.
Similarly, with VF reset, filters will be removed from the PF, but
marked as INACTIVE in the iavf list. Filters will be restored after
reset completion.
Steps to reproduce:
-------------------
1. Create a VF. Here VF is enp8s0.
2. Assign IP addresses to VF and link partner and ping continuously
from remote. Here remote IP is 1.1.1.1.
3. Check default RX Queue of traffic.
ethtool -S enp8s0 | grep -E "rx-[[:digit:]]+\.packets"
4. Add filter - change default RX Queue (to 15 here)
ethtool -U ens8s0 flow-type ip4 src-ip 1.1.1.1 action 15 loc 5
5. Ensure filter gets added and traffic is received on RX queue 15 now.
Link event testing:
-------------------
6. Bring VF link down and up. If traffic flows to configured queue 15,
test is success, otherwise it is a failure.
Reset event testing:
--------------------
7. Reset the VF. If traffic flows to configured queue 15, test is success,
otherwise it is a failure.
Fixes: 0dbfbabb840d ("iavf: Add framework to enable ethtool ntuple filters")
Signed-off-by: Piotr Gardocki <piotrx.gardocki@intel.com>
Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
Signed-off-by: Ranganatha Rao <ranganatha.rao@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2023-11-21 22:47:15 -05:00
|
|
|
#define IAVF_FLAG_FDIR_ENABLED BIT(21)
|
2015-06-05 12:20:26 -04:00
|
|
|
/* duplicates for common code */
|
2018-09-14 17:37:55 -07:00
|
|
|
#define IAVF_FLAG_DCB_ENABLED 0
|
2013-12-21 06:13:06 +00:00
|
|
|
/* flags for admin queue service task */
|
2021-11-29 16:16:03 -08:00
|
|
|
u64 aq_required;
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_QUEUES BIT_ULL(0)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_QUEUES BIT_ULL(1)
|
|
|
|
#define IAVF_FLAG_AQ_ADD_MAC_FILTER BIT_ULL(2)
|
|
|
|
#define IAVF_FLAG_AQ_ADD_VLAN_FILTER BIT_ULL(3)
|
|
|
|
#define IAVF_FLAG_AQ_DEL_MAC_FILTER BIT_ULL(4)
|
|
|
|
#define IAVF_FLAG_AQ_DEL_VLAN_FILTER BIT_ULL(5)
|
|
|
|
#define IAVF_FLAG_AQ_CONFIGURE_QUEUES BIT_ULL(6)
|
|
|
|
#define IAVF_FLAG_AQ_MAP_VECTORS BIT_ULL(7)
|
|
|
|
#define IAVF_FLAG_AQ_HANDLE_RESET BIT_ULL(8)
|
|
|
|
#define IAVF_FLAG_AQ_CONFIGURE_RSS BIT_ULL(9) /* direct AQ config */
|
|
|
|
#define IAVF_FLAG_AQ_GET_CONFIG BIT_ULL(10)
|
2016-04-12 08:30:44 -07:00
|
|
|
/* Newer style, RSS done by the PF so we can ignore hardware vagaries. */
|
2021-11-29 16:16:03 -08:00
|
|
|
#define IAVF_FLAG_AQ_GET_HENA BIT_ULL(11)
|
|
|
|
#define IAVF_FLAG_AQ_SET_HENA BIT_ULL(12)
|
|
|
|
#define IAVF_FLAG_AQ_SET_RSS_KEY BIT_ULL(13)
|
|
|
|
#define IAVF_FLAG_AQ_SET_RSS_LUT BIT_ULL(14)
|
2023-12-12 17:33:21 -07:00
|
|
|
#define IAVF_FLAG_AQ_SET_RSS_HFUNC BIT_ULL(15)
|
|
|
|
#define IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE BIT_ULL(16)
|
2021-11-29 16:16:03 -08:00
|
|
|
#define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT_ULL(19)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT_ULL(20)
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_CHANNELS BIT_ULL(21)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_CHANNELS BIT_ULL(22)
|
|
|
|
#define IAVF_FLAG_AQ_ADD_CLOUD_FILTER BIT_ULL(23)
|
|
|
|
#define IAVF_FLAG_AQ_DEL_CLOUD_FILTER BIT_ULL(24)
|
|
|
|
#define IAVF_FLAG_AQ_ADD_FDIR_FILTER BIT_ULL(25)
|
|
|
|
#define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT_ULL(26)
|
|
|
|
#define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT_ULL(27)
|
|
|
|
#define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT_ULL(28)
|
|
|
|
#define IAVF_FLAG_AQ_REQUEST_STATS BIT_ULL(29)
|
|
|
|
#define IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS BIT_ULL(30)
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING BIT_ULL(31)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING BIT_ULL(32)
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING BIT_ULL(33)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING BIT_ULL(34)
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION BIT_ULL(35)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION BIT_ULL(36)
|
|
|
|
#define IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION BIT_ULL(37)
|
|
|
|
#define IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION BIT_ULL(38)
|
i40evf: refactor reset handling
Respond better to a VF reset event. When a reset is signaled by the
PF, or detected by the watchdog task, prevent the watchdog from
processing admin queue requests, and schedule the reset task.
In the reset task, wait first for the reset to start, then for it to
complete, then reinit the driver.
If the reset never appears to complete after a long, long time (>10
seconds is possible depending on what's going on with the PF driver),
then set a flag to indicate that PF communications have failed.
If this flag is set, check for the reset to complete in the watchdog,
and attempt to do a full reinitialization of the driver from scratch.
With these changes the VF driver correctly handles a PF reset event
while running on bare metal, or in a VM.
Also update copyrights.
Change-ID: I93513efd0b50523a8345e7f6a33a5e4f8a2a5996
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-02-13 03:48:53 -08:00
|
|
|
|
iavf: refactor processing of VLAN V2 capability message
In order to handle the capability exchange necessary for
VIRTCHNL_VF_OFFLOAD_VLAN_V2, the driver must send
a VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS message. This must occur prior to
__IAVF_CONFIG_ADAPTER, and the driver must wait for the response from
the PF.
To handle this, the __IAVF_INIT_GET_OFFLOAD_VLAN_V2_CAPS state was
introduced. This state is intended to process the response from the VLAN
V2 caps message. This works ok, but is difficult to extend to adding
more extended capability exchange.
Existing (and future) AVF features are relying more and more on these
sort of extended ops for processing additional capabilities. Just like
VLAN V2, this exchange must happen prior to __IAVF_CONFIG_ADPATER.
Since we only send one outstanding AQ message at a time during init, it
is not clear where to place this state. Adding more capability specific
states becomes a mess. Instead of having the "previous" state send
a message and then transition into a capability-specific state,
introduce __IAVF_EXTENDED_CAPS state. This state will use a list of
extended_caps that determines what messages to send and receive. As long
as there are extended_caps bits still set, the driver will remain in
this state performing one send or one receive per state machine loop.
Refactor the VLAN V2 negotiation to use this new state, and remove the
capability-specific state. This makes it significantly easier to add
a new similar capability exchange going forward.
Extended capabilities are processed by having an associated SEND and
RECV extended capability bit. During __IAVF_EXTENDED_CAPS, the
driver checks these bits in order by feature, first the send bit for
a feature, then the recv bit for a feature. Each send flag will call
a function that sends the necessary response, while each receive flag
will wait for the response from the PF. If a given feature can't be
negotiated with the PF, the associated flags will be cleared in
order to skip processing of that feature.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2022-01-14 10:36:36 +01:00
|
|
|
/* flags for processing extended capability messages during
|
|
|
|
* __IAVF_INIT_EXTENDED_CAPS. Each capability exchange requires
|
|
|
|
* both a SEND and a RECV step, which must be processed in sequence.
|
|
|
|
*
|
|
|
|
* During the __IAVF_INIT_EXTENDED_CAPS state, the driver will
|
|
|
|
* process one flag at a time during each state loop.
|
|
|
|
*/
|
|
|
|
u64 extended_caps;
|
|
|
|
#define IAVF_EXTENDED_CAP_SEND_VLAN_V2 BIT_ULL(0)
|
|
|
|
#define IAVF_EXTENDED_CAP_RECV_VLAN_V2 BIT_ULL(1)
|
|
|
|
|
|
|
|
#define IAVF_EXTENDED_CAPS \
|
|
|
|
(IAVF_EXTENDED_CAP_SEND_VLAN_V2 | \
|
|
|
|
IAVF_EXTENDED_CAP_RECV_VLAN_V2)
|
|
|
|
|
2023-08-21 17:01:44 -06:00
|
|
|
/* Lock to prevent possible clobbering of
|
|
|
|
* current_netdev_promisc_flags
|
|
|
|
*/
|
|
|
|
spinlock_t current_netdev_promisc_flags_lock;
|
|
|
|
netdev_features_t current_netdev_promisc_flags;
|
|
|
|
|
2013-12-21 06:13:06 +00:00
|
|
|
/* OS defined structs */
|
|
|
|
struct net_device *netdev;
|
|
|
|
struct pci_dev *pdev;
|
|
|
|
|
2018-09-14 17:37:56 -07:00
|
|
|
struct iavf_hw hw; /* defined in iavf_type.h */
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
enum iavf_state_t state;
|
2021-08-19 08:47:40 +00:00
|
|
|
enum iavf_state_t last_state;
|
2014-11-11 20:02:42 +00:00
|
|
|
unsigned long crit_section;
|
2013-12-21 06:13:06 +00:00
|
|
|
|
2019-05-14 10:37:05 -07:00
|
|
|
struct delayed_work watchdog_task;
|
2013-12-21 06:13:06 +00:00
|
|
|
bool link_up;
|
2017-05-11 11:23:16 -07:00
|
|
|
enum virtchnl_link_speed link_speed;
|
2020-06-05 10:09:43 -07:00
|
|
|
/* This is only populated if the VIRTCHNL_VF_CAP_ADV_LINK_SPEED is set
|
|
|
|
* in vf_res->vf_cap_flags. Use ADV_LINK_SUPPORT macro to determine if
|
|
|
|
* this field is valid. This field should be used going forward and the
|
|
|
|
* enum virtchnl_link_speed above should be considered the legacy way of
|
|
|
|
* storing/communicating link speeds.
|
|
|
|
*/
|
|
|
|
u32 link_speed_mbps;
|
|
|
|
|
2017-05-11 11:23:11 -07:00
|
|
|
enum virtchnl_ops current_op;
|
2016-04-12 08:30:44 -07:00
|
|
|
/* RSS by the PF should be preferred over RSS via other methods. */
|
2017-06-29 15:12:24 +02:00
|
|
|
#define RSS_PF(_a) ((_a)->vf_res->vf_cap_flags & \
|
2017-05-11 11:23:11 -07:00
|
|
|
VIRTCHNL_VF_OFFLOAD_RSS_PF)
|
2017-06-29 15:12:24 +02:00
|
|
|
#define RSS_AQ(_a) ((_a)->vf_res->vf_cap_flags & \
|
2017-05-11 11:23:11 -07:00
|
|
|
VIRTCHNL_VF_OFFLOAD_RSS_AQ)
|
2017-06-29 15:12:24 +02:00
|
|
|
#define RSS_REG(_a) (!((_a)->vf_res->vf_cap_flags & \
|
2017-05-11 11:23:11 -07:00
|
|
|
(VIRTCHNL_VF_OFFLOAD_RSS_AQ | \
|
|
|
|
VIRTCHNL_VF_OFFLOAD_RSS_PF)))
|
2017-06-29 15:12:24 +02:00
|
|
|
#define VLAN_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
|
2017-05-11 11:23:11 -07:00
|
|
|
VIRTCHNL_VF_OFFLOAD_VLAN)
|
2021-11-29 16:16:00 -08:00
|
|
|
#define VLAN_V2_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
|
|
|
|
VIRTCHNL_VF_OFFLOAD_VLAN_V2)
|
2023-09-06 13:57:04 -06:00
|
|
|
#define CRC_OFFLOAD_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
|
|
|
|
VIRTCHNL_VF_OFFLOAD_CRC)
|
iavf: Add support VIRTCHNL_VF_OFFLOAD_VLAN_V2 during netdev config
Based on VIRTCHNL_VF_OFFLOAD_VLAN_V2, the VF can now support more VLAN
capabilities (i.e. 802.1AD offloads and filtering). In order to
communicate these capabilities to the netdev layer, the VF needs to
parse its VLAN capabilities based on whether it was able to negotiation
VIRTCHNL_VF_OFFLOAD_VLAN or VIRTCHNL_VF_OFFLOAD_VLAN_V2 or neither of
these.
In order to support this, add the following functionality:
iavf_get_netdev_vlan_hw_features() - This is used to determine the VLAN
features that the underlying hardware supports and that can be toggled
off/on based on the negotiated capabiltiies. For example, if
VIRTCHNL_VF_OFFLOAD_VLAN_V2 was negotiated, then any capability marked
with VIRTCHNL_VLAN_TOGGLE can be toggled on/off by the VF. If
VIRTCHNL_VF_OFFLOAD_VLAN was negotiated, then only VLAN insertion and/or
stripping can be toggled on/off.
iavf_get_netdev_vlan_features() - This is used to determine the VLAN
features that the underlying hardware supports and that should be
enabled by default. For example, if VIRTHCNL_VF_OFFLOAD_VLAN_V2 was
negotiated, then any supported capability that has its ethertype_init
filed set should be enabled by default. If VIRTCHNL_VF_OFFLOAD_VLAN was
negotiated, then filtering, stripping, and insertion should be enabled
by default.
Also, refactor iavf_fix_features() to take into account the new
capabilities. To do this, query all the supported features (enabled by
default and toggleable) and make sure the requested change is supported.
If VIRTCHNL_VF_OFFLOAD_VLAN_V2 is successfully negotiated, there is no
need to check VIRTCHNL_VLAN_TOGGLE here because the driver already told
the netdev layer which features can be toggled via netdev->hw_features
during iavf_process_config(), so only those features will be requested
to change.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-11-29 16:16:01 -08:00
|
|
|
#define VLAN_V2_FILTERING_ALLOWED(_a) \
|
|
|
|
(VLAN_V2_ALLOWED((_a)) && \
|
|
|
|
((_a)->vlan_v2_caps.filtering.filtering_support.outer || \
|
|
|
|
(_a)->vlan_v2_caps.filtering.filtering_support.inner))
|
|
|
|
#define VLAN_FILTERING_ALLOWED(_a) \
|
|
|
|
(VLAN_ALLOWED((_a)) || VLAN_V2_FILTERING_ALLOWED((_a)))
|
2020-06-05 10:09:43 -07:00
|
|
|
#define ADV_LINK_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
|
|
|
|
VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
|
2021-03-09 11:08:11 +08:00
|
|
|
#define FDIR_FLTR_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
|
|
|
|
VIRTCHNL_VF_OFFLOAD_FDIR_PF)
|
2021-04-13 08:48:41 +08:00
|
|
|
#define ADV_RSS_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
|
|
|
|
VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF)
|
2017-05-11 11:23:11 -07:00
|
|
|
struct virtchnl_vf_resource *vf_res; /* incl. all VSIs */
|
|
|
|
struct virtchnl_vsi_resource *vsi_res; /* our LAN VSI */
|
|
|
|
struct virtchnl_version_info pf_version;
|
2015-06-04 16:23:56 -04:00
|
|
|
#define PF_IS_V11(_a) (((_a)->pf_version.major == 1) && \
|
|
|
|
((_a)->pf_version.minor == 1))
|
2021-11-29 16:16:00 -08:00
|
|
|
struct virtchnl_vlan_caps vlan_v2_caps;
|
2013-12-21 06:13:06 +00:00
|
|
|
u16 msg_enable;
|
2018-09-14 17:37:55 -07:00
|
|
|
struct iavf_eth_stats current_stats;
|
|
|
|
struct iavf_vsi vsi;
|
2013-12-21 06:13:06 +00:00
|
|
|
u32 aq_wait_count;
|
2016-04-12 08:30:44 -07:00
|
|
|
/* RSS stuff */
|
2023-12-12 17:33:21 -07:00
|
|
|
enum virtchnl_rss_algorithm hfunc;
|
2016-04-12 08:30:44 -07:00
|
|
|
u64 hena;
|
|
|
|
u16 rss_key_size;
|
|
|
|
u16 rss_lut_size;
|
|
|
|
u8 *rss_key;
|
|
|
|
u8 *rss_lut;
|
2018-01-23 08:50:57 -08:00
|
|
|
/* ADQ related members */
|
2018-09-14 17:37:46 -07:00
|
|
|
struct iavf_channel_config ch_config;
|
2018-01-23 08:50:57 -08:00
|
|
|
u8 num_tc;
|
2018-01-23 08:51:05 -08:00
|
|
|
struct list_head cloud_filter_list;
|
2018-09-25 08:42:18 -07:00
|
|
|
/* lock to protect access to the cloud filter list */
|
2018-01-23 08:51:05 -08:00
|
|
|
spinlock_t cloud_filter_list_lock;
|
|
|
|
u16 num_cloud_filters;
|
2022-06-15 15:36:29 +02:00
|
|
|
/* snapshot of "num_active_queues" before setup_tc for qdisc add
|
|
|
|
* is invoked. This information is useful during qdisc del flow,
|
|
|
|
* to restore correct number of queues
|
|
|
|
*/
|
|
|
|
int orig_num_active_queues;
|
2021-03-09 11:08:11 +08:00
|
|
|
|
|
|
|
#define IAVF_MAX_FDIR_FILTERS 128 /* max allowed Flow Director filters */
|
|
|
|
u16 fdir_active_fltr;
|
|
|
|
struct list_head fdir_list_head;
|
|
|
|
spinlock_t fdir_fltr_lock; /* protect the Flow Director filter list */
|
2021-04-13 08:48:41 +08:00
|
|
|
|
|
|
|
struct list_head adv_rss_list_head;
|
|
|
|
spinlock_t adv_rss_lock; /* protect the RSS management list */
|
2013-12-21 06:13:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-01-15 14:33:10 -08:00
|
|
|
/* Ethtool Private Flags */
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
/* needed by iavf_ethtool.c */
|
|
|
|
extern char iavf_driver_name[];
|
|
|
|
|
iavf: Fix kernel BUG in free_msi_irqs
Fix driver not freeing VF's traffic irqs, prior to calling
pci_disable_msix in iavf_remove.
There were possible 2 erroneous states in which, iavf_close would
not be called.
One erroneous state is fixed by allowing netdev to register, when state
is already running. It was possible for VF adapter to enter state loop
from running to resetting, where iavf_open would subsequently fail.
If user would then unload driver/remove VF pci, iavf_close would not be
called, as the netdev was not registered, leaving traffic pcis still
allocated.
Fixed this by breaking loop, allowing netdev to open device when adapter
state is __IAVF_RUNNING and it is not explicitily downed.
Other possiblity is entering to iavf_remove from __IAVF_RESETTING state,
where iavf_close would not free irqs, but just return 0.
Fixed this by checking for last adapter state and then removing irqs.
Kernel panic:
[ 2773.628585] kernel BUG at drivers/pci/msi.c:375!
...
[ 2773.631567] RIP: 0010:free_msi_irqs+0x180/0x1b0
...
[ 2773.640939] Call Trace:
[ 2773.641572] pci_disable_msix+0xf7/0x120
[ 2773.642224] iavf_reset_interrupt_capability.part.41+0x15/0x30 [iavf]
[ 2773.642897] iavf_remove+0x12e/0x500 [iavf]
[ 2773.643578] pci_device_remove+0x3b/0xc0
[ 2773.644266] device_release_driver_internal+0x103/0x1f0
[ 2773.644948] pci_stop_bus_device+0x69/0x90
[ 2773.645576] pci_stop_and_remove_bus_device+0xe/0x20
[ 2773.646215] pci_iov_remove_virtfn+0xba/0x120
[ 2773.646862] sriov_disable+0x2f/0xe0
[ 2773.647531] ice_free_vfs+0x2f8/0x350 [ice]
[ 2773.648207] ice_sriov_configure+0x94/0x960 [ice]
[ 2773.648883] ? _kstrtoull+0x3b/0x90
[ 2773.649560] sriov_numvfs_store+0x10a/0x190
[ 2773.650249] kernfs_fop_write+0x116/0x190
[ 2773.650948] vfs_write+0xa5/0x1a0
[ 2773.651651] ksys_write+0x4f/0xb0
[ 2773.652358] do_syscall_64+0x5b/0x1a0
[ 2773.653075] entry_SYSCALL_64_after_hwframe+0x65/0xca
Fixes: 22ead37f8af8 ("i40evf: Add longer wait after remove module")
Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-10-22 10:30:14 +02:00
|
|
|
static inline const char *iavf_state_str(enum iavf_state_t state)
|
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case __IAVF_STARTUP:
|
|
|
|
return "__IAVF_STARTUP";
|
|
|
|
case __IAVF_REMOVE:
|
|
|
|
return "__IAVF_REMOVE";
|
|
|
|
case __IAVF_INIT_VERSION_CHECK:
|
|
|
|
return "__IAVF_INIT_VERSION_CHECK";
|
|
|
|
case __IAVF_INIT_GET_RESOURCES:
|
|
|
|
return "__IAVF_INIT_GET_RESOURCES";
|
2022-06-15 13:57:20 -04:00
|
|
|
case __IAVF_INIT_EXTENDED_CAPS:
|
|
|
|
return "__IAVF_INIT_EXTENDED_CAPS";
|
|
|
|
case __IAVF_INIT_CONFIG_ADAPTER:
|
|
|
|
return "__IAVF_INIT_CONFIG_ADAPTER";
|
iavf: Fix kernel BUG in free_msi_irqs
Fix driver not freeing VF's traffic irqs, prior to calling
pci_disable_msix in iavf_remove.
There were possible 2 erroneous states in which, iavf_close would
not be called.
One erroneous state is fixed by allowing netdev to register, when state
is already running. It was possible for VF adapter to enter state loop
from running to resetting, where iavf_open would subsequently fail.
If user would then unload driver/remove VF pci, iavf_close would not be
called, as the netdev was not registered, leaving traffic pcis still
allocated.
Fixed this by breaking loop, allowing netdev to open device when adapter
state is __IAVF_RUNNING and it is not explicitily downed.
Other possiblity is entering to iavf_remove from __IAVF_RESETTING state,
where iavf_close would not free irqs, but just return 0.
Fixed this by checking for last adapter state and then removing irqs.
Kernel panic:
[ 2773.628585] kernel BUG at drivers/pci/msi.c:375!
...
[ 2773.631567] RIP: 0010:free_msi_irqs+0x180/0x1b0
...
[ 2773.640939] Call Trace:
[ 2773.641572] pci_disable_msix+0xf7/0x120
[ 2773.642224] iavf_reset_interrupt_capability.part.41+0x15/0x30 [iavf]
[ 2773.642897] iavf_remove+0x12e/0x500 [iavf]
[ 2773.643578] pci_device_remove+0x3b/0xc0
[ 2773.644266] device_release_driver_internal+0x103/0x1f0
[ 2773.644948] pci_stop_bus_device+0x69/0x90
[ 2773.645576] pci_stop_and_remove_bus_device+0xe/0x20
[ 2773.646215] pci_iov_remove_virtfn+0xba/0x120
[ 2773.646862] sriov_disable+0x2f/0xe0
[ 2773.647531] ice_free_vfs+0x2f8/0x350 [ice]
[ 2773.648207] ice_sriov_configure+0x94/0x960 [ice]
[ 2773.648883] ? _kstrtoull+0x3b/0x90
[ 2773.649560] sriov_numvfs_store+0x10a/0x190
[ 2773.650249] kernfs_fop_write+0x116/0x190
[ 2773.650948] vfs_write+0xa5/0x1a0
[ 2773.651651] ksys_write+0x4f/0xb0
[ 2773.652358] do_syscall_64+0x5b/0x1a0
[ 2773.653075] entry_SYSCALL_64_after_hwframe+0x65/0xca
Fixes: 22ead37f8af8 ("i40evf: Add longer wait after remove module")
Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-10-22 10:30:14 +02:00
|
|
|
case __IAVF_INIT_SW:
|
|
|
|
return "__IAVF_INIT_SW";
|
|
|
|
case __IAVF_INIT_FAILED:
|
|
|
|
return "__IAVF_INIT_FAILED";
|
|
|
|
case __IAVF_RESETTING:
|
|
|
|
return "__IAVF_RESETTING";
|
|
|
|
case __IAVF_COMM_FAILED:
|
|
|
|
return "__IAVF_COMM_FAILED";
|
|
|
|
case __IAVF_DOWN:
|
|
|
|
return "__IAVF_DOWN";
|
|
|
|
case __IAVF_DOWN_PENDING:
|
|
|
|
return "__IAVF_DOWN_PENDING";
|
|
|
|
case __IAVF_TESTING:
|
|
|
|
return "__IAVF_TESTING";
|
|
|
|
case __IAVF_RUNNING:
|
|
|
|
return "__IAVF_RUNNING";
|
|
|
|
default:
|
|
|
|
return "__IAVF_UNKNOWN_STATE";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-19 08:47:40 +00:00
|
|
|
static inline void iavf_change_state(struct iavf_adapter *adapter,
|
|
|
|
enum iavf_state_t state)
|
|
|
|
{
|
|
|
|
if (adapter->state != state) {
|
|
|
|
adapter->last_state = adapter->state;
|
|
|
|
adapter->state = state;
|
|
|
|
}
|
iavf: Fix kernel BUG in free_msi_irqs
Fix driver not freeing VF's traffic irqs, prior to calling
pci_disable_msix in iavf_remove.
There were possible 2 erroneous states in which, iavf_close would
not be called.
One erroneous state is fixed by allowing netdev to register, when state
is already running. It was possible for VF adapter to enter state loop
from running to resetting, where iavf_open would subsequently fail.
If user would then unload driver/remove VF pci, iavf_close would not be
called, as the netdev was not registered, leaving traffic pcis still
allocated.
Fixed this by breaking loop, allowing netdev to open device when adapter
state is __IAVF_RUNNING and it is not explicitily downed.
Other possiblity is entering to iavf_remove from __IAVF_RESETTING state,
where iavf_close would not free irqs, but just return 0.
Fixed this by checking for last adapter state and then removing irqs.
Kernel panic:
[ 2773.628585] kernel BUG at drivers/pci/msi.c:375!
...
[ 2773.631567] RIP: 0010:free_msi_irqs+0x180/0x1b0
...
[ 2773.640939] Call Trace:
[ 2773.641572] pci_disable_msix+0xf7/0x120
[ 2773.642224] iavf_reset_interrupt_capability.part.41+0x15/0x30 [iavf]
[ 2773.642897] iavf_remove+0x12e/0x500 [iavf]
[ 2773.643578] pci_device_remove+0x3b/0xc0
[ 2773.644266] device_release_driver_internal+0x103/0x1f0
[ 2773.644948] pci_stop_bus_device+0x69/0x90
[ 2773.645576] pci_stop_and_remove_bus_device+0xe/0x20
[ 2773.646215] pci_iov_remove_virtfn+0xba/0x120
[ 2773.646862] sriov_disable+0x2f/0xe0
[ 2773.647531] ice_free_vfs+0x2f8/0x350 [ice]
[ 2773.648207] ice_sriov_configure+0x94/0x960 [ice]
[ 2773.648883] ? _kstrtoull+0x3b/0x90
[ 2773.649560] sriov_numvfs_store+0x10a/0x190
[ 2773.650249] kernfs_fop_write+0x116/0x190
[ 2773.650948] vfs_write+0xa5/0x1a0
[ 2773.651651] ksys_write+0x4f/0xb0
[ 2773.652358] do_syscall_64+0x5b/0x1a0
[ 2773.653075] entry_SYSCALL_64_after_hwframe+0x65/0xca
Fixes: 22ead37f8af8 ("i40evf: Add longer wait after remove module")
Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-10-22 10:30:14 +02:00
|
|
|
dev_dbg(&adapter->pdev->dev,
|
|
|
|
"state transition from:%s to:%s\n",
|
|
|
|
iavf_state_str(adapter->last_state),
|
|
|
|
iavf_state_str(adapter->state));
|
2021-08-19 08:47:40 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 17:37:46 -07:00
|
|
|
int iavf_up(struct iavf_adapter *adapter);
|
|
|
|
void iavf_down(struct iavf_adapter *adapter);
|
|
|
|
int iavf_process_config(struct iavf_adapter *adapter);
|
2021-11-29 16:16:00 -08:00
|
|
|
int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter);
|
2023-06-05 10:52:26 -04:00
|
|
|
void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags);
|
2023-09-07 17:02:50 +02:00
|
|
|
void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags);
|
iavf: fix a deadlock caused by rtnl and driver's lock circular dependencies
A driver's lock (crit_lock) is used to serialize all the driver's tasks.
Lockdep, however, shows a circular dependency between rtnl and
crit_lock. This happens when an ndo that already holds the rtnl requests
the driver to reset, since the reset task (in some paths) tries to grab
rtnl to either change real number of queues of update netdev features.
[566.241851] ======================================================
[566.241893] WARNING: possible circular locking dependency detected
[566.241936] 6.2.14-100.fc36.x86_64+debug #1 Tainted: G OE
[566.241984] ------------------------------------------------------
[566.242025] repro.sh/2604 is trying to acquire lock:
[566.242061] ffff9280fc5ceee8 (&adapter->crit_lock){+.+.}-{3:3}, at: iavf_close+0x3c/0x240 [iavf]
[566.242167]
but task is already holding lock:
[566.242209] ffffffff9976d350 (rtnl_mutex){+.+.}-{3:3}, at: iavf_remove+0x6b5/0x730 [iavf]
[566.242300]
which lock already depends on the new lock.
[566.242353]
the existing dependency chain (in reverse order) is:
[566.242401]
-> #1 (rtnl_mutex){+.+.}-{3:3}:
[566.242451] __mutex_lock+0xc1/0xbb0
[566.242489] iavf_init_interrupt_scheme+0x179/0x440 [iavf]
[566.242560] iavf_watchdog_task+0x80b/0x1400 [iavf]
[566.242627] process_one_work+0x2b3/0x560
[566.242663] worker_thread+0x4f/0x3a0
[566.242696] kthread+0xf2/0x120
[566.242730] ret_from_fork+0x29/0x50
[566.242763]
-> #0 (&adapter->crit_lock){+.+.}-{3:3}:
[566.242815] __lock_acquire+0x15ff/0x22b0
[566.242869] lock_acquire+0xd2/0x2c0
[566.242901] __mutex_lock+0xc1/0xbb0
[566.242934] iavf_close+0x3c/0x240 [iavf]
[566.242997] __dev_close_many+0xac/0x120
[566.243036] dev_close_many+0x8b/0x140
[566.243071] unregister_netdevice_many_notify+0x165/0x7c0
[566.243116] unregister_netdevice_queue+0xd3/0x110
[566.243157] iavf_remove+0x6c1/0x730 [iavf]
[566.243217] pci_device_remove+0x33/0xa0
[566.243257] device_release_driver_internal+0x1bc/0x240
[566.243299] pci_stop_bus_device+0x6c/0x90
[566.243338] pci_stop_and_remove_bus_device+0xe/0x20
[566.243380] pci_iov_remove_virtfn+0xd1/0x130
[566.243417] sriov_disable+0x34/0xe0
[566.243448] ice_free_vfs+0x2da/0x330 [ice]
[566.244383] ice_sriov_configure+0x88/0xad0 [ice]
[566.245353] sriov_numvfs_store+0xde/0x1d0
[566.246156] kernfs_fop_write_iter+0x15e/0x210
[566.246921] vfs_write+0x288/0x530
[566.247671] ksys_write+0x74/0xf0
[566.248408] do_syscall_64+0x58/0x80
[566.249145] entry_SYSCALL_64_after_hwframe+0x72/0xdc
[566.249886]
other info that might help us debug this:
[566.252014] Possible unsafe locking scenario:
[566.253432] CPU0 CPU1
[566.254118] ---- ----
[566.254800] lock(rtnl_mutex);
[566.255514] lock(&adapter->crit_lock);
[566.256233] lock(rtnl_mutex);
[566.256897] lock(&adapter->crit_lock);
[566.257388]
*** DEADLOCK ***
The deadlock can be triggered by a script that is continuously resetting
the VF adapter while doing other operations requiring RTNL, e.g:
while :; do
ip link set $VF up
ethtool --set-channels $VF combined 2
ip link set $VF down
ip link set $VF up
ethtool --set-channels $VF combined 4
ip link set $VF down
done
Any operation that triggers a reset can substitute "ethtool --set-channles"
As a fix, add a new task "finish_config" that do all the work which
needs rtnl lock. With the exception of iavf_remove(), all work that
require rtnl should be called from this task.
As for iavf_remove(), at the point where we need to call
unregister_netdevice() (and grab rtnl_lock), we make sure the finish_config
task is not running (cancel_work_sync()) to safely grab rtnl. Subsequent
finish_config work cannot restart after that since the task is guarded
by the __IAVF_IN_REMOVE_TASK bit in iavf_schedule_finish_config().
Fixes: 5ac49f3c2702 ("iavf: use mutexes for locking of critical sections")
Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2023-06-05 10:52:25 -04:00
|
|
|
void iavf_schedule_finish_config(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
void iavf_reset(struct iavf_adapter *adapter);
|
|
|
|
void iavf_set_ethtool_ops(struct net_device *netdev);
|
|
|
|
void iavf_update_stats(struct iavf_adapter *adapter);
|
|
|
|
void iavf_free_all_tx_resources(struct iavf_adapter *adapter);
|
|
|
|
void iavf_free_all_rx_resources(struct iavf_adapter *adapter);
|
|
|
|
|
2018-09-14 17:37:55 -07:00
|
|
|
void iavf_napi_add_all(struct iavf_adapter *adapter);
|
|
|
|
void iavf_napi_del_all(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
|
|
|
|
int iavf_send_api_ver(struct iavf_adapter *adapter);
|
|
|
|
int iavf_verify_api_ver(struct iavf_adapter *adapter);
|
|
|
|
int iavf_send_vf_config_msg(struct iavf_adapter *adapter);
|
|
|
|
int iavf_get_vf_config(struct iavf_adapter *adapter);
|
2021-11-29 16:16:00 -08:00
|
|
|
int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
|
|
|
|
int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
|
2021-11-29 16:16:02 -08:00
|
|
|
void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
|
2022-06-10 14:15:54 +02:00
|
|
|
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
|
|
|
|
void iavf_configure_queues(struct iavf_adapter *adapter);
|
|
|
|
void iavf_deconfigure_queues(struct iavf_adapter *adapter);
|
|
|
|
void iavf_enable_queues(struct iavf_adapter *adapter);
|
|
|
|
void iavf_disable_queues(struct iavf_adapter *adapter);
|
|
|
|
void iavf_map_queues(struct iavf_adapter *adapter);
|
|
|
|
int iavf_request_queues(struct iavf_adapter *adapter, int num);
|
|
|
|
void iavf_add_ether_addrs(struct iavf_adapter *adapter);
|
|
|
|
void iavf_del_ether_addrs(struct iavf_adapter *adapter);
|
|
|
|
void iavf_add_vlans(struct iavf_adapter *adapter);
|
|
|
|
void iavf_del_vlans(struct iavf_adapter *adapter);
|
2023-08-21 17:01:44 -06:00
|
|
|
void iavf_set_promiscuous(struct iavf_adapter *adapter);
|
|
|
|
bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
void iavf_request_stats(struct iavf_adapter *adapter);
|
2022-01-27 15:16:29 +01:00
|
|
|
int iavf_request_reset(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
void iavf_get_hena(struct iavf_adapter *adapter);
|
|
|
|
void iavf_set_hena(struct iavf_adapter *adapter);
|
|
|
|
void iavf_set_rss_key(struct iavf_adapter *adapter);
|
|
|
|
void iavf_set_rss_lut(struct iavf_adapter *adapter);
|
2023-12-12 17:33:21 -07:00
|
|
|
void iavf_set_rss_hfunc(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
void iavf_enable_vlan_stripping(struct iavf_adapter *adapter);
|
|
|
|
void iavf_disable_vlan_stripping(struct iavf_adapter *adapter);
|
|
|
|
void iavf_virtchnl_completion(struct iavf_adapter *adapter,
|
|
|
|
enum virtchnl_ops v_opcode,
|
2019-04-17 15:17:30 -07:00
|
|
|
enum iavf_status v_retval, u8 *msg, u16 msglen);
|
2018-09-14 17:37:46 -07:00
|
|
|
int iavf_config_rss(struct iavf_adapter *adapter);
|
|
|
|
int iavf_lan_add_device(struct iavf_adapter *adapter);
|
|
|
|
int iavf_lan_del_device(struct iavf_adapter *adapter);
|
|
|
|
void iavf_enable_channels(struct iavf_adapter *adapter);
|
|
|
|
void iavf_disable_channels(struct iavf_adapter *adapter);
|
|
|
|
void iavf_add_cloud_filter(struct iavf_adapter *adapter);
|
|
|
|
void iavf_del_cloud_filter(struct iavf_adapter *adapter);
|
2021-11-29 16:16:03 -08:00
|
|
|
void iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
|
|
|
|
void iavf_disable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
|
|
|
|
void iavf_enable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
|
|
|
|
void iavf_disable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
|
2021-03-09 11:08:11 +08:00
|
|
|
void iavf_add_fdir_filter(struct iavf_adapter *adapter);
|
|
|
|
void iavf_del_fdir_filter(struct iavf_adapter *adapter);
|
2021-04-13 08:48:41 +08:00
|
|
|
void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
|
|
|
|
void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
|
2019-12-17 11:29:23 +01:00
|
|
|
struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
|
|
|
|
const u8 *macaddr);
|
2023-06-05 10:52:22 -04:00
|
|
|
int iavf_wait_for_reset(struct iavf_adapter *adapter);
|
2018-09-14 17:37:46 -07:00
|
|
|
#endif /* _IAVF_H_ */
|