Commit 006e8964 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'mlx5-updates-2024-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2024-02-01

1) IPSec global stats for xfrm and mlx5
2) XSK memory improvements for non-linear SKBs
3) Software steering debug dump to use seq_file ops
4) Various code clean-ups

* tag 'mlx5-updates-2024-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5e: XDP, Exclude headroom and tailroom from memory calculations
  net/mlx5e: XSK, Exclude tailroom from non-linear SKBs memory calculations
  net/mlx5: DR, Change SWS usage to debug fs seq_file interface
  net/mlx5: Change missing SyncE capability print to debug
  net/mlx5: Remove initial segmentation duplicate definitions
  net/mlx5: Return specific error code for timeout on wait_fw_init
  net/mlx5: SF, Stop waiting for FW as teardown was called
  net/mlx5: remove fw reporter dump option for non PF
  net/mlx5: remove fw_fatal reporter dump option for non PF
  net/mlx5: Rename mlx5_sf_dev_remove
  Documentation: Fix counter name of mlx5 vnic reporter
  net/mlx5e: Delete obsolete IPsec code
  net/mlx5e: Connect mlx5 IPsec statistics with XFRM core
  xfrm: get global statistics from the offloaded device
  xfrm: generalize xdo_dev_state_update_curlft to allow statistics update
====================

Link: https://lore.kernel.org/r/20240206005527.1353368-1-saeed@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 313fb184 a90f5591
...@@ -250,7 +250,7 @@ them in realtime. ...@@ -250,7 +250,7 @@ them in realtime.
Description of the vnic counters: Description of the vnic counters:
- total_q_under_processor_handle - total_error_queues
number of queues in an error state due to number of queues in an error state due to
an async error or errored command. an async error or errored command.
- send_queue_priority_update_flow - send_queue_priority_update_flow
...@@ -259,7 +259,8 @@ Description of the vnic counters: ...@@ -259,7 +259,8 @@ Description of the vnic counters:
number of times CQ entered an error state due to an overflow. number of times CQ entered an error state due to an overflow.
- async_eq_overrun - async_eq_overrun
number of times an EQ mapped to async events was overrun. number of times an EQ mapped to async events was overrun.
comp_eq_overrun number of times an EQ mapped to completion events was - comp_eq_overrun
number of times an EQ mapped to completion events was
overrun. overrun.
- quota_exceeded_command - quota_exceeded_command
number of commands issued and failed due to quota exceeded. number of commands issued and failed due to quota exceeded.
......
...@@ -71,9 +71,9 @@ Callbacks to implement ...@@ -71,9 +71,9 @@ Callbacks to implement
bool (*xdo_dev_offload_ok) (struct sk_buff *skb, bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
struct xfrm_state *x); struct xfrm_state *x);
void (*xdo_dev_state_advance_esn) (struct xfrm_state *x); void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
void (*xdo_dev_state_update_stats) (struct xfrm_state *x);
/* Solely packet offload callbacks */ /* Solely packet offload callbacks */
void (*xdo_dev_state_update_curlft) (struct xfrm_state *x);
int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack); int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack);
void (*xdo_dev_policy_delete) (struct xfrm_policy *x); void (*xdo_dev_policy_delete) (struct xfrm_policy *x);
void (*xdo_dev_policy_free) (struct xfrm_policy *x); void (*xdo_dev_policy_free) (struct xfrm_policy *x);
...@@ -191,6 +191,6 @@ xdo_dev_policy_free() on any remaining offloaded states. ...@@ -191,6 +191,6 @@ xdo_dev_policy_free() on any remaining offloaded states.
Outcome of HW handling packets, the XFRM core can't count hard, soft limits. Outcome of HW handling packets, the XFRM core can't count hard, soft limits.
The HW/driver are responsible to perform it and provide accurate data when The HW/driver are responsible to perform it and provide accurate data when
xdo_dev_state_update_curlft() is called. In case of one of these limits xdo_dev_state_update_stats() is called. In case of one of these limits
occuried, the driver needs to call to xfrm_state_check_expire() to make sure occuried, the driver needs to call to xfrm_state_check_expire() to make sure
that XFRM performs rekeying sequence. that XFRM performs rekeying sequence.
...@@ -210,7 +210,7 @@ static bool is_dpll_supported(struct mlx5_core_dev *dev) ...@@ -210,7 +210,7 @@ static bool is_dpll_supported(struct mlx5_core_dev *dev)
return false; return false;
if (!MLX5_CAP_MCAM_REG2(dev, synce_registers)) { if (!MLX5_CAP_MCAM_REG2(dev, synce_registers)) {
mlx5_core_warn(dev, "Missing SyncE capability\n"); mlx5_core_dbg(dev, "Missing SyncE capability\n");
return false; return false;
} }
......
...@@ -240,11 +240,14 @@ static u32 mlx5e_rx_get_linear_sz_xsk(struct mlx5e_params *params, ...@@ -240,11 +240,14 @@ static u32 mlx5e_rx_get_linear_sz_xsk(struct mlx5e_params *params,
return xsk->headroom + hw_mtu; return xsk->headroom + hw_mtu;
} }
static u32 mlx5e_rx_get_linear_sz_skb(struct mlx5e_params *params, bool xsk) static u32 mlx5e_rx_get_linear_sz_skb(struct mlx5e_params *params, bool no_head_tail_room)
{ {
/* SKBs built on XDP_PASS on XSK RQs don't have headroom. */
u16 headroom = xsk ? 0 : mlx5e_get_linear_rq_headroom(params, NULL);
u32 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); u32 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
u16 headroom;
if (no_head_tail_room)
return SKB_DATA_ALIGN(hw_mtu);
headroom = mlx5e_get_linear_rq_headroom(params, NULL);
return MLX5_SKB_FRAG_SZ(headroom + hw_mtu); return MLX5_SKB_FRAG_SZ(headroom + hw_mtu);
} }
...@@ -254,6 +257,7 @@ static u32 mlx5e_rx_get_linear_stride_sz(struct mlx5_core_dev *mdev, ...@@ -254,6 +257,7 @@ static u32 mlx5e_rx_get_linear_stride_sz(struct mlx5_core_dev *mdev,
struct mlx5e_xsk_param *xsk, struct mlx5e_xsk_param *xsk,
bool mpwqe) bool mpwqe)
{ {
bool no_head_tail_room;
u32 sz; u32 sz;
/* XSK frames are mapped as individual pages, because frames may come in /* XSK frames are mapped as individual pages, because frames may come in
...@@ -262,7 +266,13 @@ static u32 mlx5e_rx_get_linear_stride_sz(struct mlx5_core_dev *mdev, ...@@ -262,7 +266,13 @@ static u32 mlx5e_rx_get_linear_stride_sz(struct mlx5_core_dev *mdev,
if (xsk) if (xsk)
return mpwqe ? 1 << mlx5e_mpwrq_page_shift(mdev, xsk) : PAGE_SIZE; return mpwqe ? 1 << mlx5e_mpwrq_page_shift(mdev, xsk) : PAGE_SIZE;
sz = roundup_pow_of_two(mlx5e_rx_get_linear_sz_skb(params, false)); no_head_tail_room = params->xdp_prog && mpwqe && !mlx5e_rx_is_linear_skb(mdev, params, xsk);
/* When no_head_tail_room is set, headroom and tailroom are excluded from skb calculations.
* no_head_tail_room should be set in the case of XDP with Striding RQ
* when SKB is not linear. This is because another page is allocated for the linear part.
*/
sz = roundup_pow_of_two(mlx5e_rx_get_linear_sz_skb(params, no_head_tail_room));
/* XDP in mlx5e doesn't support multiple packets per page. /* XDP in mlx5e doesn't support multiple packets per page.
* Do not assume sz <= PAGE_SIZE if params->xdp_prog is set. * Do not assume sz <= PAGE_SIZE if params->xdp_prog is set.
...@@ -289,7 +299,11 @@ bool mlx5e_rx_is_linear_skb(struct mlx5_core_dev *mdev, ...@@ -289,7 +299,11 @@ bool mlx5e_rx_is_linear_skb(struct mlx5_core_dev *mdev,
if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE)
return false; return false;
/* Both XSK and non-XSK cases allocate an SKB on XDP_PASS. Packet data /* Call mlx5e_rx_get_linear_sz_skb with the no_head_tail_room parameter set
* to exclude headroom and tailroom from calculations.
* no_head_tail_room is true when SKB is built on XDP_PASS on XSK RQs
* since packet data buffers don't have headroom and tailroom resreved for the SKB.
* Both XSK and non-XSK cases allocate an SKB on XDP_PASS. Packet data
* must fit into a CPU page. * must fit into a CPU page.
*/ */
if (mlx5e_rx_get_linear_sz_skb(params, xsk) > PAGE_SIZE) if (mlx5e_rx_get_linear_sz_skb(params, xsk) > PAGE_SIZE)
......
...@@ -984,21 +984,41 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x) ...@@ -984,21 +984,41 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)
queue_work(sa_entry->ipsec->wq, &work->work); queue_work(sa_entry->ipsec->wq, &work->work);
} }
static void mlx5e_xfrm_update_curlft(struct xfrm_state *x) static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
{ {
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule; struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;
struct net *net = dev_net(x->xso.dev);
u64 packets, bytes, lastuse; u64 packets, bytes, lastuse;
lockdep_assert(lockdep_is_held(&x->lock) || lockdep_assert(lockdep_is_held(&x->lock) ||
lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex)); lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex) ||
lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_state_lock));
if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ) if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
return; return;
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
mlx5_fc_query_cached(ipsec_rule->auth.fc, &bytes, &packets, &lastuse);
x->stats.integrity_failed += packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, packets);
mlx5_fc_query_cached(ipsec_rule->trailer.fc, &bytes, &packets, &lastuse);
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, packets);
}
if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
return;
mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse); mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
x->curlft.packets += packets; x->curlft.packets += packets;
x->curlft.bytes += bytes; x->curlft.bytes += bytes;
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
mlx5_fc_query_cached(ipsec_rule->replay.fc, &bytes, &packets, &lastuse);
x->stats.replay += packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, packets);
}
} }
static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev, static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
...@@ -1156,7 +1176,7 @@ static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = { ...@@ -1156,7 +1176,7 @@ static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = {
.xdo_dev_offload_ok = mlx5e_ipsec_offload_ok, .xdo_dev_offload_ok = mlx5e_ipsec_offload_ok,
.xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state, .xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state,
.xdo_dev_state_update_curlft = mlx5e_xfrm_update_curlft, .xdo_dev_state_update_stats = mlx5e_xfrm_update_stats,
.xdo_dev_policy_add = mlx5e_xfrm_add_policy, .xdo_dev_policy_add = mlx5e_xfrm_add_policy,
.xdo_dev_policy_delete = mlx5e_xfrm_del_policy, .xdo_dev_policy_delete = mlx5e_xfrm_del_policy,
.xdo_dev_policy_free = mlx5e_xfrm_free_policy, .xdo_dev_policy_free = mlx5e_xfrm_free_policy,
......
...@@ -137,7 +137,6 @@ struct mlx5e_ipsec_hw_stats { ...@@ -137,7 +137,6 @@ struct mlx5e_ipsec_hw_stats {
struct mlx5e_ipsec_sw_stats { struct mlx5e_ipsec_sw_stats {
atomic64_t ipsec_rx_drop_sp_alloc; atomic64_t ipsec_rx_drop_sp_alloc;
atomic64_t ipsec_rx_drop_sadb_miss; atomic64_t ipsec_rx_drop_sadb_miss;
atomic64_t ipsec_rx_drop_syndrome;
atomic64_t ipsec_tx_drop_bundle; atomic64_t ipsec_tx_drop_bundle;
atomic64_t ipsec_tx_drop_no_state; atomic64_t ipsec_tx_drop_no_state;
atomic64_t ipsec_tx_drop_not_ip; atomic64_t ipsec_tx_drop_not_ip;
......
...@@ -304,12 +304,6 @@ bool mlx5e_ipsec_handle_tx_skb(struct net_device *netdev, ...@@ -304,12 +304,6 @@ bool mlx5e_ipsec_handle_tx_skb(struct net_device *netdev,
return false; return false;
} }
enum {
MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED,
MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
};
void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev, void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb, struct sk_buff *skb,
u32 ipsec_meta_data) u32 ipsec_meta_data)
...@@ -343,20 +337,7 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev, ...@@ -343,20 +337,7 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
xo = xfrm_offload(skb); xo = xfrm_offload(skb);
xo->flags = CRYPTO_DONE; xo->flags = CRYPTO_DONE;
xo->status = CRYPTO_SUCCESS;
switch (MLX5_IPSEC_METADATA_SYNDROM(ipsec_meta_data)) {
case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED:
xo->status = CRYPTO_SUCCESS;
break;
case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED:
xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED;
break;
case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER:
xo->status = CRYPTO_INVALID_PACKET_SYNTAX;
break;
default:
atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_syndrome);
}
} }
int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata) int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata)
...@@ -374,8 +355,6 @@ int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metada ...@@ -374,8 +355,6 @@ int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metada
return err; return err;
} }
*metadata = MLX5_IPSEC_METADATA_CREATE(ipsec_obj_id, *metadata = ipsec_obj_id;
MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED);
return 0; return 0;
} }
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1) #define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1)
#define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0)) #define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
#define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0)) #define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0))
#define MLX5_IPSEC_METADATA_CREATE(id, syndrome) ((id) | ((syndrome) << 24))
struct mlx5e_accel_tx_ipsec_state { struct mlx5e_accel_tx_ipsec_state {
struct xfrm_offload *xo; struct xfrm_offload *xo;
......
...@@ -51,7 +51,6 @@ static const struct counter_desc mlx5e_ipsec_hw_stats_desc[] = { ...@@ -51,7 +51,6 @@ static const struct counter_desc mlx5e_ipsec_hw_stats_desc[] = {
static const struct counter_desc mlx5e_ipsec_sw_stats_desc[] = { static const struct counter_desc mlx5e_ipsec_sw_stats_desc[] = {
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_rx_drop_sp_alloc) }, { MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_rx_drop_sp_alloc) },
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_rx_drop_sadb_miss) }, { MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_rx_drop_sadb_miss) },
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_rx_drop_syndrome) },
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_bundle) }, { MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_bundle) },
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_no_state) }, { MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_no_state) },
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_not_ip) }, { MLX5E_DECLARE_STAT(struct mlx5e_ipsec_sw_stats, ipsec_tx_drop_not_ip) },
......
...@@ -366,18 +366,18 @@ int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev) ...@@ -366,18 +366,18 @@ int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev)
return -EIO; return -EIO;
} }
mlx5_set_nic_state(dev, MLX5_NIC_IFC_DISABLED); mlx5_set_nic_state(dev, MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED);
/* Loop until device state turns to disable */ /* Loop until device state turns to disable */
end = jiffies + msecs_to_jiffies(delay_ms); end = jiffies + msecs_to_jiffies(delay_ms);
do { do {
if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED)
break; break;
cond_resched(); cond_resched();
} while (!time_after(jiffies, end)); } while (!time_after(jiffies, end));
if (mlx5_get_nic_state(dev) != MLX5_NIC_IFC_DISABLED) { if (mlx5_get_nic_state(dev) != MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED) {
dev_err(&dev->pdev->dev, "NIC IFC still %d after %lums.\n", dev_err(&dev->pdev->dev, "NIC IFC still %d after %lums.\n",
mlx5_get_nic_state(dev), delay_ms); mlx5_get_nic_state(dev), delay_ms);
return -EIO; return -EIO;
......
...@@ -116,9 +116,9 @@ u32 mlx5_health_check_fatal_sensors(struct mlx5_core_dev *dev) ...@@ -116,9 +116,9 @@ u32 mlx5_health_check_fatal_sensors(struct mlx5_core_dev *dev)
return MLX5_SENSOR_PCI_COMM_ERR; return MLX5_SENSOR_PCI_COMM_ERR;
if (pci_channel_offline(dev->pdev)) if (pci_channel_offline(dev->pdev))
return MLX5_SENSOR_PCI_ERR; return MLX5_SENSOR_PCI_ERR;
if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED)
return MLX5_SENSOR_NIC_DISABLED; return MLX5_SENSOR_NIC_DISABLED;
if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_SW_RESET) if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_SW_RESET)
return MLX5_SENSOR_NIC_SW_RESET; return MLX5_SENSOR_NIC_SW_RESET;
if (sensor_fw_synd_rfr(dev)) if (sensor_fw_synd_rfr(dev))
return MLX5_SENSOR_FW_SYND_RFR; return MLX5_SENSOR_FW_SYND_RFR;
...@@ -185,7 +185,7 @@ static bool reset_fw_if_needed(struct mlx5_core_dev *dev) ...@@ -185,7 +185,7 @@ static bool reset_fw_if_needed(struct mlx5_core_dev *dev)
/* Write the NIC interface field to initiate the reset, the command /* Write the NIC interface field to initiate the reset, the command
* interface address also resides here, don't overwrite it. * interface address also resides here, don't overwrite it.
*/ */
mlx5_set_nic_state(dev, MLX5_NIC_IFC_SW_RESET); mlx5_set_nic_state(dev, MLX5_INITIAL_SEG_NIC_INTERFACE_SW_RESET);
return true; return true;
} }
...@@ -246,13 +246,13 @@ void mlx5_error_sw_reset(struct mlx5_core_dev *dev) ...@@ -246,13 +246,13 @@ void mlx5_error_sw_reset(struct mlx5_core_dev *dev)
/* Recover from SW reset */ /* Recover from SW reset */
end = jiffies + msecs_to_jiffies(delay_ms); end = jiffies + msecs_to_jiffies(delay_ms);
do { do {
if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) if (mlx5_get_nic_state(dev) == MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED)
break; break;
msleep(20); msleep(20);
} while (!time_after(jiffies, end)); } while (!time_after(jiffies, end));
if (mlx5_get_nic_state(dev) != MLX5_NIC_IFC_DISABLED) { if (mlx5_get_nic_state(dev) != MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED) {
dev_err(&dev->pdev->dev, "NIC IFC still %d after %lums.\n", dev_err(&dev->pdev->dev, "NIC IFC still %d after %lums.\n",
mlx5_get_nic_state(dev), delay_ms); mlx5_get_nic_state(dev), delay_ms);
} }
...@@ -272,26 +272,26 @@ static void mlx5_handle_bad_state(struct mlx5_core_dev *dev) ...@@ -272,26 +272,26 @@ static void mlx5_handle_bad_state(struct mlx5_core_dev *dev)
u8 nic_interface = mlx5_get_nic_state(dev); u8 nic_interface = mlx5_get_nic_state(dev);
switch (nic_interface) { switch (nic_interface) {
case MLX5_NIC_IFC_FULL: case MLX5_INITIAL_SEG_NIC_INTERFACE_FULL_DRIVER:
mlx5_core_warn(dev, "Expected to see disabled NIC but it is full driver\n"); mlx5_core_warn(dev, "Expected to see disabled NIC but it is full driver\n");
break; break;
case MLX5_NIC_IFC_DISABLED: case MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED:
mlx5_core_warn(dev, "starting teardown\n"); mlx5_core_warn(dev, "starting teardown\n");
break; break;
case MLX5_NIC_IFC_NO_DRAM_NIC: case MLX5_INITIAL_SEG_NIC_INTERFACE_NO_DRAM_NIC:
mlx5_core_warn(dev, "Expected to see disabled NIC but it is no dram nic\n"); mlx5_core_warn(dev, "Expected to see disabled NIC but it is no dram nic\n");
break; break;
case MLX5_NIC_IFC_SW_RESET: case MLX5_INITIAL_SEG_NIC_INTERFACE_SW_RESET:
/* The IFC mode field is 3 bits, so it will read 0x7 in 2 cases: /* The IFC mode field is 3 bits, so it will read 0x7 in 2 cases:
* 1. PCI has been disabled (ie. PCI-AER, PF driver unloaded * 1. PCI has been disabled (ie. PCI-AER, PF driver unloaded
* and this is a VF), this is not recoverable by SW reset. * and this is a VF), this is not recoverable by SW reset.
* Logging of this is handled elsewhere. * Logging of this is handled elsewhere.
* 2. FW reset has been issued by another function, driver can * 2. FW reset has been issued by another function, driver can
* be reloaded to recover after the mode switches to * be reloaded to recover after the mode switches to
* MLX5_NIC_IFC_DISABLED. * MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED.
*/ */
if (dev->priv.health.fatal_error != MLX5_SENSOR_PCI_COMM_ERR) if (dev->priv.health.fatal_error != MLX5_SENSOR_PCI_COMM_ERR)
mlx5_core_warn(dev, "NIC SW reset in progress\n"); mlx5_core_warn(dev, "NIC SW reset in progress\n");
...@@ -555,12 +555,17 @@ static void mlx5_fw_reporter_err_work(struct work_struct *work) ...@@ -555,12 +555,17 @@ static void mlx5_fw_reporter_err_work(struct work_struct *work)
&fw_reporter_ctx); &fw_reporter_ctx);
} }
static const struct devlink_health_reporter_ops mlx5_fw_reporter_ops = { static const struct devlink_health_reporter_ops mlx5_fw_reporter_pf_ops = {
.name = "fw", .name = "fw",
.diagnose = mlx5_fw_reporter_diagnose, .diagnose = mlx5_fw_reporter_diagnose,
.dump = mlx5_fw_reporter_dump, .dump = mlx5_fw_reporter_dump,
}; };
static const struct devlink_health_reporter_ops mlx5_fw_reporter_ops = {
.name = "fw",
.diagnose = mlx5_fw_reporter_diagnose,
};
static int static int
mlx5_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter, mlx5_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
void *priv_ctx, void *priv_ctx,
...@@ -646,12 +651,17 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work) ...@@ -646,12 +651,17 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
} }
} }
static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = { static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_pf_ops = {
.name = "fw_fatal", .name = "fw_fatal",
.recover = mlx5_fw_fatal_reporter_recover, .recover = mlx5_fw_fatal_reporter_recover,
.dump = mlx5_fw_fatal_reporter_dump, .dump = mlx5_fw_fatal_reporter_dump,
}; };
static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = {
.name = "fw_fatal",
.recover = mlx5_fw_fatal_reporter_recover,
};
#define MLX5_FW_REPORTER_ECPF_GRACEFUL_PERIOD 180000 #define MLX5_FW_REPORTER_ECPF_GRACEFUL_PERIOD 180000
#define MLX5_FW_REPORTER_PF_GRACEFUL_PERIOD 60000 #define MLX5_FW_REPORTER_PF_GRACEFUL_PERIOD 60000
#define MLX5_FW_REPORTER_VF_GRACEFUL_PERIOD 30000 #define MLX5_FW_REPORTER_VF_GRACEFUL_PERIOD 30000
...@@ -659,10 +669,14 @@ static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = { ...@@ -659,10 +669,14 @@ static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = {
void mlx5_fw_reporters_create(struct mlx5_core_dev *dev) void mlx5_fw_reporters_create(struct mlx5_core_dev *dev)
{ {
const struct devlink_health_reporter_ops *fw_fatal_ops;
struct mlx5_core_health *health = &dev->priv.health; struct mlx5_core_health *health = &dev->priv.health;
const struct devlink_health_reporter_ops *fw_ops;
struct devlink *devlink = priv_to_devlink(dev); struct devlink *devlink = priv_to_devlink(dev);
u64 grace_period; u64 grace_period;
fw_fatal_ops = &mlx5_fw_fatal_reporter_pf_ops;
fw_ops = &mlx5_fw_reporter_pf_ops;
if (mlx5_core_is_ecpf(dev)) { if (mlx5_core_is_ecpf(dev)) {
grace_period = MLX5_FW_REPORTER_ECPF_GRACEFUL_PERIOD; grace_period = MLX5_FW_REPORTER_ECPF_GRACEFUL_PERIOD;
} else if (mlx5_core_is_pf(dev)) { } else if (mlx5_core_is_pf(dev)) {
...@@ -670,18 +684,19 @@ void mlx5_fw_reporters_create(struct mlx5_core_dev *dev) ...@@ -670,18 +684,19 @@ void mlx5_fw_reporters_create(struct mlx5_core_dev *dev)
} else { } else {
/* VF or SF */ /* VF or SF */
grace_period = MLX5_FW_REPORTER_DEFAULT_GRACEFUL_PERIOD; grace_period = MLX5_FW_REPORTER_DEFAULT_GRACEFUL_PERIOD;
fw_fatal_ops = &mlx5_fw_fatal_reporter_ops;
fw_ops = &mlx5_fw_reporter_ops;
} }
health->fw_reporter = health->fw_reporter =
devl_health_reporter_create(devlink, &mlx5_fw_reporter_ops, devl_health_reporter_create(devlink, fw_ops, 0, dev);
0, dev);
if (IS_ERR(health->fw_reporter)) if (IS_ERR(health->fw_reporter))
mlx5_core_warn(dev, "Failed to create fw reporter, err = %ld\n", mlx5_core_warn(dev, "Failed to create fw reporter, err = %ld\n",
PTR_ERR(health->fw_reporter)); PTR_ERR(health->fw_reporter));
health->fw_fatal_reporter = health->fw_fatal_reporter =
devl_health_reporter_create(devlink, devl_health_reporter_create(devlink,
&mlx5_fw_fatal_reporter_ops, fw_fatal_ops,
grace_period, grace_period,
dev); dev);
if (IS_ERR(health->fw_fatal_reporter)) if (IS_ERR(health->fw_fatal_reporter))
......
...@@ -187,31 +187,36 @@ static struct mlx5_profile profile[] = { ...@@ -187,31 +187,36 @@ static struct mlx5_profile profile[] = {
}; };
static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili, static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili,
u32 warn_time_mili) u32 warn_time_mili, const char *init_state)
{ {
unsigned long warn = jiffies + msecs_to_jiffies(warn_time_mili); unsigned long warn = jiffies + msecs_to_jiffies(warn_time_mili);
unsigned long end = jiffies + msecs_to_jiffies(max_wait_mili); unsigned long end = jiffies + msecs_to_jiffies(max_wait_mili);
u32 fw_initializing; u32 fw_initializing;
int err = 0;
do { do {
fw_initializing = ioread32be(&dev->iseg->initializing); fw_initializing = ioread32be(&dev->iseg->initializing);
if (!(fw_initializing >> 31)) if (!(fw_initializing >> 31))
break; break;
if (time_after(jiffies, end) || if (time_after(jiffies, end)) {
test_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state)) { mlx5_core_err(dev, "Firmware over %u MS in %s state, aborting\n",
err = -EBUSY; max_wait_mili, init_state);
break; return -ETIMEDOUT;
}
if (test_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state)) {
mlx5_core_warn(dev, "device is being removed, stop waiting for FW %s\n",
init_state);
return -ENODEV;
} }
if (warn_time_mili && time_after(jiffies, warn)) { if (warn_time_mili && time_after(jiffies, warn)) {
mlx5_core_warn(dev, "Waiting for FW initialization, timeout abort in %ds (0x%x)\n", mlx5_core_warn(dev, "Waiting for FW %s, timeout abort in %ds (0x%x)\n",
jiffies_to_msecs(end - warn) / 1000, fw_initializing); init_state, jiffies_to_msecs(end - warn) / 1000,
fw_initializing);
warn = jiffies + msecs_to_jiffies(warn_time_mili); warn = jiffies + msecs_to_jiffies(warn_time_mili);
} }
msleep(mlx5_tout_ms(dev, FW_PRE_INIT_WAIT)); msleep(mlx5_tout_ms(dev, FW_PRE_INIT_WAIT));
} while (true); } while (true);
return err; return 0;
} }
static void mlx5_set_driver_version(struct mlx5_core_dev *dev) static void mlx5_set_driver_version(struct mlx5_core_dev *dev)
...@@ -1151,12 +1156,10 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou ...@@ -1151,12 +1156,10 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
/* wait for firmware to accept initialization segments configurations /* wait for firmware to accept initialization segments configurations
*/ */
err = wait_fw_init(dev, timeout, err = wait_fw_init(dev, timeout,
mlx5_tout_ms(dev, FW_PRE_INIT_WARN_MESSAGE_INTERVAL)); mlx5_tout_ms(dev, FW_PRE_INIT_WARN_MESSAGE_INTERVAL),
if (err) { "pre-initializing");
mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n", if (err)
timeout);
return err; return err;
}
err = mlx5_cmd_enable(dev); err = mlx5_cmd_enable(dev);
if (err) { if (err) {
...@@ -1166,12 +1169,9 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou ...@@ -1166,12 +1169,9 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
mlx5_tout_query_iseg(dev); mlx5_tout_query_iseg(dev);
err = wait_fw_init(dev, mlx5_tout_ms(dev, FW_INIT), 0); err = wait_fw_init(dev, mlx5_tout_ms(dev, FW_INIT), 0, "initializing");
if (err) { if (err)
mlx5_core_err(dev, "Firmware over %llu MS in initializing state, aborting\n",
mlx5_tout_ms(dev, FW_INIT));
goto err_cmd_cleanup; goto err_cmd_cleanup;
}
dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev); dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP); mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
......
...@@ -312,13 +312,6 @@ static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev) ...@@ -312,13 +312,6 @@ static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
return ret; return ret;
} }
enum {
MLX5_NIC_IFC_FULL = 0,
MLX5_NIC_IFC_DISABLED = 1,
MLX5_NIC_IFC_NO_DRAM_NIC = 2,
MLX5_NIC_IFC_SW_RESET = 7
};
u8 mlx5_get_nic_state(struct mlx5_core_dev *dev); u8 mlx5_get_nic_state(struct mlx5_core_dev *dev);
void mlx5_set_nic_state(struct mlx5_core_dev *dev, u8 state); void mlx5_set_nic_state(struct mlx5_core_dev *dev, u8 state);
......
...@@ -74,7 +74,8 @@ static void mlx5_sf_dev_release(struct device *device) ...@@ -74,7 +74,8 @@ static void mlx5_sf_dev_release(struct device *device)
kfree(sf_dev); kfree(sf_dev);
} }
static void mlx5_sf_dev_remove(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_dev) static void mlx5_sf_dev_remove_aux(struct mlx5_core_dev *dev,
struct mlx5_sf_dev *sf_dev)
{ {
int id; int id;
...@@ -138,7 +139,7 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u16 fn_id, ...@@ -138,7 +139,7 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u16 fn_id,
return; return;
xa_err: xa_err:
mlx5_sf_dev_remove(dev, sf_dev); mlx5_sf_dev_remove_aux(dev, sf_dev);
add_err: add_err:
mlx5_core_err(dev, "SF DEV: fail device add for index=%d sfnum=%d err=%d\n", mlx5_core_err(dev, "SF DEV: fail device add for index=%d sfnum=%d err=%d\n",
sf_index, sfnum, err); sf_index, sfnum, err);
...@@ -149,7 +150,7 @@ static void mlx5_sf_dev_del(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_de ...@@ -149,7 +150,7 @@ static void mlx5_sf_dev_del(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_de
struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;
xa_erase(&table->devices, sf_index); xa_erase(&table->devices, sf_index);
mlx5_sf_dev_remove(dev, sf_dev); mlx5_sf_dev_remove_aux(dev, sf_dev);
} }
static int static int
...@@ -367,7 +368,7 @@ static void mlx5_sf_dev_destroy_all(struct mlx5_sf_dev_table *table) ...@@ -367,7 +368,7 @@ static void mlx5_sf_dev_destroy_all(struct mlx5_sf_dev_table *table)
xa_for_each(&table->devices, index, sf_dev) { xa_for_each(&table->devices, index, sf_dev) {
xa_erase(&table->devices, index); xa_erase(&table->devices, index);
mlx5_sf_dev_remove(table->dev, sf_dev); mlx5_sf_dev_remove_aux(table->dev, sf_dev);
} }
} }
......
...@@ -95,24 +95,29 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia ...@@ -95,24 +95,29 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
static void mlx5_sf_dev_remove(struct auxiliary_device *adev) static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
{ {
struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
struct devlink *devlink = priv_to_devlink(sf_dev->mdev); struct mlx5_core_dev *mdev = sf_dev->mdev;
struct devlink *devlink;
mlx5_drain_health_wq(sf_dev->mdev); devlink = priv_to_devlink(mdev);
set_bit(MLX5_BREAK_FW_WAIT, &mdev->intf_state);
mlx5_drain_health_wq(mdev);
devlink_unregister(devlink); devlink_unregister(devlink);
if (mlx5_dev_is_lightweight(sf_dev->mdev)) if (mlx5_dev_is_lightweight(mdev))
mlx5_uninit_one_light(sf_dev->mdev); mlx5_uninit_one_light(mdev);
else else
mlx5_uninit_one(sf_dev->mdev); mlx5_uninit_one(mdev);
iounmap(sf_dev->mdev->iseg); iounmap(mdev->iseg);
mlx5_mdev_uninit(sf_dev->mdev); mlx5_mdev_uninit(mdev);
mlx5_devlink_free(devlink); mlx5_devlink_free(devlink);
} }
static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev) static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev)
{ {
struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
struct mlx5_core_dev *mdev = sf_dev->mdev;
mlx5_unload_one(sf_dev->mdev, false); set_bit(MLX5_BREAK_FW_WAIT, &mdev->intf_state);
mlx5_unload_one(mdev, false);
} }
static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = { static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
......
...@@ -54,6 +54,107 @@ enum dr_dump_rec_type { ...@@ -54,6 +54,107 @@ enum dr_dump_rec_type {
DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE = 3425, DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE = 3425,
}; };
static struct mlx5dr_dbg_dump_buff *
mlx5dr_dbg_dump_data_init_new_buff(struct mlx5dr_dbg_dump_data *dump_data)
{
struct mlx5dr_dbg_dump_buff *new_buff;
new_buff = kzalloc(sizeof(*new_buff), GFP_KERNEL);
if (!new_buff)
return NULL;
new_buff->buff = kvzalloc(MLX5DR_DEBUG_DUMP_BUFF_SIZE, GFP_KERNEL);
if (!new_buff->buff) {
kfree(new_buff);
return NULL;
}
INIT_LIST_HEAD(&new_buff->node);
list_add_tail(&new_buff->node, &dump_data->buff_list);
return new_buff;
}
static struct mlx5dr_dbg_dump_data *
mlx5dr_dbg_create_dump_data(void)
{
struct mlx5dr_dbg_dump_data *dump_data;
dump_data = kzalloc(sizeof(*dump_data), GFP_KERNEL);
if (!dump_data)
return NULL;
INIT_LIST_HEAD(&dump_data->buff_list);
if (!mlx5dr_dbg_dump_data_init_new_buff(dump_data)) {
kfree(dump_data);
return NULL;
}
return dump_data;
}
static void
mlx5dr_dbg_destroy_dump_data(struct mlx5dr_dbg_dump_data *dump_data)
{
struct mlx5dr_dbg_dump_buff *dump_buff, *tmp_buff;
if (!dump_data)
return;
list_for_each_entry_safe(dump_buff, tmp_buff, &dump_data->buff_list, node) {
kvfree(dump_buff->buff);
list_del(&dump_buff->node);
kfree(dump_buff);
}
kfree(dump_data);
}
static int
mlx5dr_dbg_dump_data_print(struct seq_file *file, char *str, u32 size)
{
struct mlx5dr_domain *dmn = file->private;
struct mlx5dr_dbg_dump_data *dump_data;
struct mlx5dr_dbg_dump_buff *buff;
u32 buff_capacity, write_size;
int remain_size, ret;
if (size >= MLX5DR_DEBUG_DUMP_BUFF_SIZE)
return -EINVAL;
dump_data = dmn->dump_info.dump_data;
buff = list_last_entry(&dump_data->buff_list,
struct mlx5dr_dbg_dump_buff, node);
buff_capacity = (MLX5DR_DEBUG_DUMP_BUFF_SIZE - 1) - buff->index;
remain_size = buff_capacity - size;
write_size = (remain_size > 0) ? size : buff_capacity;
if (likely(write_size)) {
ret = snprintf(buff->buff + buff->index, write_size + 1, "%s", str);
if (ret < 0)
return ret;
buff->index += write_size;
}
if (remain_size < 0) {
remain_size *= -1;
buff = mlx5dr_dbg_dump_data_init_new_buff(dump_data);
if (!buff)
return -ENOMEM;
ret = snprintf(buff->buff, remain_size + 1, "%s", str + write_size);
if (ret < 0)
return ret;
buff->index += remain_size;
}
return 0;
}
void mlx5dr_dbg_tbl_add(struct mlx5dr_table *tbl) void mlx5dr_dbg_tbl_add(struct mlx5dr_table *tbl)
{ {
mutex_lock(&tbl->dmn->dump_info.dbg_mutex); mutex_lock(&tbl->dmn->dump_info.dbg_mutex);
...@@ -109,36 +210,68 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id, ...@@ -109,36 +210,68 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
{ {
struct mlx5dr_action *action = action_mem->action; struct mlx5dr_action *action = action_mem->action;
const u64 action_id = DR_DBG_PTR_TO_ID(action); const u64 action_id = DR_DBG_PTR_TO_ID(action);
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
u64 hit_tbl_ptr, miss_tbl_ptr; u64 hit_tbl_ptr, miss_tbl_ptr;
u32 hit_tbl_id, miss_tbl_id; u32 hit_tbl_id, miss_tbl_id;
int ret;
switch (action->action_type) { switch (action->action_type) {
case DR_ACTION_TYP_DROP: case DR_ACTION_TYP_DROP:
seq_printf(file, "%d,0x%llx,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_DROP, action_id, rule_id); "%d,0x%llx,0x%llx\n",
DR_DUMP_REC_TYPE_ACTION_DROP, action_id,
rule_id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_FT: case DR_ACTION_TYP_FT:
if (action->dest_tbl->is_fw_tbl) if (action->dest_tbl->is_fw_tbl)
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_FT, action_id, "%d,0x%llx,0x%llx,0x%x,0x%x\n",
rule_id, action->dest_tbl->fw_tbl.id, DR_DUMP_REC_TYPE_ACTION_FT, action_id,
-1); rule_id, action->dest_tbl->fw_tbl.id,
-1);
else else
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_FT, action_id, "%d,0x%llx,0x%llx,0x%x,0x%llx\n",
rule_id, action->dest_tbl->tbl->table_id, DR_DUMP_REC_TYPE_ACTION_FT, action_id,
DR_DBG_PTR_TO_ID(action->dest_tbl->tbl)); rule_id, action->dest_tbl->tbl->table_id,
DR_DBG_PTR_TO_ID(action->dest_tbl->tbl));
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_CTR: case DR_ACTION_TYP_CTR:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_CTR, action_id, rule_id, "%d,0x%llx,0x%llx,0x%x\n",
action->ctr->ctr_id + action->ctr->offset); DR_DUMP_REC_TYPE_ACTION_CTR, action_id, rule_id,
action->ctr->ctr_id + action->ctr->offset);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_TAG: case DR_ACTION_TYP_TAG:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_TAG, action_id, rule_id, "%d,0x%llx,0x%llx,0x%x\n",
action->flow_tag->flow_tag); DR_DUMP_REC_TYPE_ACTION_TAG, action_id, rule_id,
action->flow_tag->flow_tag);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_MODIFY_HDR: case DR_ACTION_TYP_MODIFY_HDR:
{ {
...@@ -150,83 +283,171 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id, ...@@ -150,83 +283,171 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
ptrn_arg = !action->rewrite->single_action_opt && ptrn && arg; ptrn_arg = !action->rewrite->single_action_opt && ptrn && arg;
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,%d,0x%x,0x%x,0x%x", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_MODIFY_HDR, action_id, "%d,0x%llx,0x%llx,0x%x,%d,0x%x,0x%x,0x%x",
rule_id, action->rewrite->index, DR_DUMP_REC_TYPE_ACTION_MODIFY_HDR, action_id,
action->rewrite->single_action_opt, rule_id, action->rewrite->index,
ptrn_arg ? action->rewrite->num_of_actions : 0, action->rewrite->single_action_opt,
ptrn_arg ? ptrn->index : 0, ptrn_arg ? action->rewrite->num_of_actions : 0,
ptrn_arg ? mlx5dr_arg_get_obj_id(arg) : 0); ptrn_arg ? ptrn->index : 0,
ptrn_arg ? mlx5dr_arg_get_obj_id(arg) : 0);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (ptrn_arg) { if (ptrn_arg) {
for (i = 0; i < action->rewrite->num_of_actions; i++) { for (i = 0; i < action->rewrite->num_of_actions; i++) {
seq_printf(file, ",0x%016llx", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
be64_to_cpu(((__be64 *)rewrite_data)[i])); ",0x%016llx",
be64_to_cpu(((__be64 *)rewrite_data)[i]));
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
} }
} }
seq_puts(file, "\n"); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, "\n");
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
} }
case DR_ACTION_TYP_VPORT: case DR_ACTION_TYP_VPORT:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_VPORT, action_id, rule_id, "%d,0x%llx,0x%llx,0x%x\n",
action->vport->caps->num); DR_DUMP_REC_TYPE_ACTION_VPORT, action_id, rule_id,
action->vport->caps->num);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_TNL_L2_TO_L2: case DR_ACTION_TYP_TNL_L2_TO_L2:
seq_printf(file, "%d,0x%llx,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_DECAP_L2, action_id, "%d,0x%llx,0x%llx\n",
rule_id); DR_DUMP_REC_TYPE_ACTION_DECAP_L2, action_id,
rule_id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_TNL_L3_TO_L2: case DR_ACTION_TYP_TNL_L3_TO_L2:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_DECAP_L3, action_id, "%d,0x%llx,0x%llx,0x%x\n",
rule_id, DR_DUMP_REC_TYPE_ACTION_DECAP_L3, action_id,
(action->rewrite->ptrn && action->rewrite->arg) ? rule_id,
mlx5dr_arg_get_obj_id(action->rewrite->arg) : (action->rewrite->ptrn && action->rewrite->arg) ?
action->rewrite->index); mlx5dr_arg_get_obj_id(action->rewrite->arg) :
action->rewrite->index);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_L2_TO_TNL_L2: case DR_ACTION_TYP_L2_TO_TNL_L2:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_ENCAP_L2, action_id, "%d,0x%llx,0x%llx,0x%x\n",
rule_id, action->reformat->id); DR_DUMP_REC_TYPE_ACTION_ENCAP_L2, action_id,
rule_id, action->reformat->id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_L2_TO_TNL_L3: case DR_ACTION_TYP_L2_TO_TNL_L3:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_ENCAP_L3, action_id, "%d,0x%llx,0x%llx,0x%x\n",
rule_id, action->reformat->id); DR_DUMP_REC_TYPE_ACTION_ENCAP_L3, action_id,
rule_id, action->reformat->id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_POP_VLAN: case DR_ACTION_TYP_POP_VLAN:
seq_printf(file, "%d,0x%llx,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_POP_VLAN, action_id, "%d,0x%llx,0x%llx\n",
rule_id); DR_DUMP_REC_TYPE_ACTION_POP_VLAN, action_id,
rule_id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_PUSH_VLAN: case DR_ACTION_TYP_PUSH_VLAN:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_PUSH_VLAN, action_id, "%d,0x%llx,0x%llx,0x%x\n",
rule_id, action->push_vlan->vlan_hdr); DR_DUMP_REC_TYPE_ACTION_PUSH_VLAN, action_id,
rule_id, action->push_vlan->vlan_hdr);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_INSERT_HDR: case DR_ACTION_TYP_INSERT_HDR:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_INSERT_HDR, action_id, "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n",
rule_id, action->reformat->id, DR_DUMP_REC_TYPE_ACTION_INSERT_HDR, action_id,
action->reformat->param_0, rule_id, action->reformat->id,
action->reformat->param_1); action->reformat->param_0,
action->reformat->param_1);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_REMOVE_HDR: case DR_ACTION_TYP_REMOVE_HDR:
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR, action_id, "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x\n",
rule_id, action->reformat->id, DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR, action_id,
action->reformat->param_0, rule_id, action->reformat->id,
action->reformat->param_1); action->reformat->param_0,
action->reformat->param_1);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_SAMPLER: case DR_ACTION_TYP_SAMPLER:
seq_printf(file, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%d,0x%llx,0x%llx,0x%x,0x%x,0x%x,0x%llx,0x%llx\n", "%d,0x%llx,0x%llx,0x%x,0x%x,0x%x,0x%llx,0x%llx\n",
DR_DUMP_REC_TYPE_ACTION_SAMPLER, action_id, rule_id, DR_DUMP_REC_TYPE_ACTION_SAMPLER, action_id,
0, 0, action->sampler->sampler_id, rule_id, 0, 0, action->sampler->sampler_id,
action->sampler->rx_icm_addr, action->sampler->rx_icm_addr,
action->sampler->tx_icm_addr); action->sampler->tx_icm_addr);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
case DR_ACTION_TYP_RANGE: case DR_ACTION_TYP_RANGE:
if (action->range->hit_tbl_action->dest_tbl->is_fw_tbl) { if (action->range->hit_tbl_action->dest_tbl->is_fw_tbl) {
...@@ -247,10 +468,17 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id, ...@@ -247,10 +468,17 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
DR_DBG_PTR_TO_ID(action->range->miss_tbl_action->dest_tbl->tbl); DR_DBG_PTR_TO_ID(action->range->miss_tbl_action->dest_tbl->tbl);
} }
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%llx,0x%x,0x%llx,0x%x\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE, action_id, rule_id, "%d,0x%llx,0x%llx,0x%x,0x%llx,0x%x,0x%llx,0x%x\n",
hit_tbl_id, hit_tbl_ptr, miss_tbl_id, miss_tbl_ptr, DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE, action_id,
action->range->definer_id); rule_id, hit_tbl_id, hit_tbl_ptr, miss_tbl_id,
miss_tbl_ptr, action->range->definer_id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
break; break;
default: default:
return 0; return 0;
...@@ -263,8 +491,10 @@ static int ...@@ -263,8 +491,10 @@ static int
dr_dump_rule_mem(struct seq_file *file, struct mlx5dr_ste *ste, dr_dump_rule_mem(struct seq_file *file, struct mlx5dr_ste *ste,
bool is_rx, const u64 rule_id, u8 format_ver) bool is_rx, const u64 rule_id, u8 format_ver)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
char hw_ste_dump[DR_HEX_SIZE]; char hw_ste_dump[DR_HEX_SIZE];
u32 mem_rec_type; u32 mem_rec_type;
int ret;
if (format_ver == MLX5_STEERING_FORMAT_CONNECTX_5) { if (format_ver == MLX5_STEERING_FORMAT_CONNECTX_5) {
mem_rec_type = is_rx ? DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 : mem_rec_type = is_rx ? DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 :
...@@ -277,9 +507,16 @@ dr_dump_rule_mem(struct seq_file *file, struct mlx5dr_ste *ste, ...@@ -277,9 +507,16 @@ dr_dump_rule_mem(struct seq_file *file, struct mlx5dr_ste *ste,
dr_dump_hex_print(hw_ste_dump, (char *)mlx5dr_ste_get_hw_ste(ste), dr_dump_hex_print(hw_ste_dump, (char *)mlx5dr_ste_get_hw_ste(ste),
DR_STE_SIZE_REDUCED); DR_STE_SIZE_REDUCED);
seq_printf(file, "%d,0x%llx,0x%llx,%s\n", mem_rec_type, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
dr_dump_icm_to_idx(mlx5dr_ste_get_icm_addr(ste)), rule_id, "%d,0x%llx,0x%llx,%s\n", mem_rec_type,
hw_ste_dump); dr_dump_icm_to_idx(mlx5dr_ste_get_icm_addr(ste)),
rule_id, hw_ste_dump);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -309,6 +546,7 @@ static int dr_dump_rule(struct seq_file *file, struct mlx5dr_rule *rule) ...@@ -309,6 +546,7 @@ static int dr_dump_rule(struct seq_file *file, struct mlx5dr_rule *rule)
{ {
struct mlx5dr_rule_action_member *action_mem; struct mlx5dr_rule_action_member *action_mem;
const u64 rule_id = DR_DBG_PTR_TO_ID(rule); const u64 rule_id = DR_DBG_PTR_TO_ID(rule);
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
struct mlx5dr_rule_rx_tx *rx = &rule->rx; struct mlx5dr_rule_rx_tx *rx = &rule->rx;
struct mlx5dr_rule_rx_tx *tx = &rule->tx; struct mlx5dr_rule_rx_tx *tx = &rule->tx;
u8 format_ver; u8 format_ver;
...@@ -316,8 +554,15 @@ static int dr_dump_rule(struct seq_file *file, struct mlx5dr_rule *rule) ...@@ -316,8 +554,15 @@ static int dr_dump_rule(struct seq_file *file, struct mlx5dr_rule *rule)
format_ver = rule->matcher->tbl->dmn->info.caps.sw_format_ver; format_ver = rule->matcher->tbl->dmn->info.caps.sw_format_ver;
seq_printf(file, "%d,0x%llx,0x%llx\n", DR_DUMP_REC_TYPE_RULE, rule_id, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DBG_PTR_TO_ID(rule->matcher)); "%d,0x%llx,0x%llx\n", DR_DUMP_REC_TYPE_RULE,
rule_id, DR_DBG_PTR_TO_ID(rule->matcher));
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (rx->nic_matcher) { if (rx->nic_matcher) {
ret = dr_dump_rule_rx_tx(file, rx, true, rule_id, format_ver); ret = dr_dump_rule_rx_tx(file, rx, true, rule_id, format_ver);
...@@ -344,46 +589,94 @@ static int ...@@ -344,46 +589,94 @@ static int
dr_dump_matcher_mask(struct seq_file *file, struct mlx5dr_match_param *mask, dr_dump_matcher_mask(struct seq_file *file, struct mlx5dr_match_param *mask,
u8 criteria, const u64 matcher_id) u8 criteria, const u64 matcher_id)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
char dump[DR_HEX_SIZE]; char dump[DR_HEX_SIZE];
int ret;
seq_printf(file, "%d,0x%llx,", DR_DUMP_REC_TYPE_MATCHER_MASK, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, "%d,0x%llx,",
matcher_id); DR_DUMP_REC_TYPE_MATCHER_MASK, matcher_id);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (criteria & DR_MATCHER_CRITERIA_OUTER) { if (criteria & DR_MATCHER_CRITERIA_OUTER) {
dr_dump_hex_print(dump, (char *)&mask->outer, sizeof(mask->outer)); dr_dump_hex_print(dump, (char *)&mask->outer, sizeof(mask->outer));
seq_printf(file, "%s,", dump); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%s,", dump);
} else { } else {
seq_puts(file, ","); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
} }
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (criteria & DR_MATCHER_CRITERIA_INNER) { if (criteria & DR_MATCHER_CRITERIA_INNER) {
dr_dump_hex_print(dump, (char *)&mask->inner, sizeof(mask->inner)); dr_dump_hex_print(dump, (char *)&mask->inner, sizeof(mask->inner));
seq_printf(file, "%s,", dump); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%s,", dump);
} else { } else {
seq_puts(file, ","); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
} }
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (criteria & DR_MATCHER_CRITERIA_MISC) { if (criteria & DR_MATCHER_CRITERIA_MISC) {
dr_dump_hex_print(dump, (char *)&mask->misc, sizeof(mask->misc)); dr_dump_hex_print(dump, (char *)&mask->misc, sizeof(mask->misc));
seq_printf(file, "%s,", dump); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%s,", dump);
} else { } else {
seq_puts(file, ","); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
} }
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (criteria & DR_MATCHER_CRITERIA_MISC2) { if (criteria & DR_MATCHER_CRITERIA_MISC2) {
dr_dump_hex_print(dump, (char *)&mask->misc2, sizeof(mask->misc2)); dr_dump_hex_print(dump, (char *)&mask->misc2, sizeof(mask->misc2));
seq_printf(file, "%s,", dump); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%s,", dump);
} else { } else {
seq_puts(file, ","); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",");
} }
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (criteria & DR_MATCHER_CRITERIA_MISC3) { if (criteria & DR_MATCHER_CRITERIA_MISC3) {
dr_dump_hex_print(dump, (char *)&mask->misc3, sizeof(mask->misc3)); dr_dump_hex_print(dump, (char *)&mask->misc3, sizeof(mask->misc3));
seq_printf(file, "%s\n", dump); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%s\n", dump);
} else { } else {
seq_puts(file, ",\n"); ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH, ",\n");
} }
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -391,9 +684,19 @@ static int ...@@ -391,9 +684,19 @@ static int
dr_dump_matcher_builder(struct seq_file *file, struct mlx5dr_ste_build *builder, dr_dump_matcher_builder(struct seq_file *file, struct mlx5dr_ste_build *builder,
u32 index, bool is_rx, const u64 matcher_id) u32 index, bool is_rx, const u64 matcher_id)
{ {
seq_printf(file, "%d,0x%llx,%d,%d,0x%x\n", char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
DR_DUMP_REC_TYPE_MATCHER_BUILDER, matcher_id, index, is_rx, int ret;
builder->lu_type);
ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%d,0x%llx,%d,%d,0x%x\n",
DR_DUMP_REC_TYPE_MATCHER_BUILDER, matcher_id, index,
is_rx, builder->lu_type);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -403,6 +706,7 @@ dr_dump_matcher_rx_tx(struct seq_file *file, bool is_rx, ...@@ -403,6 +706,7 @@ dr_dump_matcher_rx_tx(struct seq_file *file, bool is_rx,
struct mlx5dr_matcher_rx_tx *matcher_rx_tx, struct mlx5dr_matcher_rx_tx *matcher_rx_tx,
const u64 matcher_id) const u64 matcher_id)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
enum dr_dump_rec_type rec_type; enum dr_dump_rec_type rec_type;
u64 s_icm_addr, e_icm_addr; u64 s_icm_addr, e_icm_addr;
int i, ret; int i, ret;
...@@ -412,11 +716,19 @@ dr_dump_matcher_rx_tx(struct seq_file *file, bool is_rx, ...@@ -412,11 +716,19 @@ dr_dump_matcher_rx_tx(struct seq_file *file, bool is_rx,
s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->s_htbl->chunk); s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->s_htbl->chunk);
e_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->e_anchor->chunk); e_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(matcher_rx_tx->e_anchor->chunk);
seq_printf(file, "%d,0x%llx,0x%llx,%d,0x%llx,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
rec_type, DR_DBG_PTR_TO_ID(matcher_rx_tx), "%d,0x%llx,0x%llx,%d,0x%llx,0x%llx\n",
matcher_id, matcher_rx_tx->num_of_builders, rec_type, DR_DBG_PTR_TO_ID(matcher_rx_tx),
dr_dump_icm_to_idx(s_icm_addr), matcher_id, matcher_rx_tx->num_of_builders,
dr_dump_icm_to_idx(e_icm_addr)); dr_dump_icm_to_idx(s_icm_addr),
dr_dump_icm_to_idx(e_icm_addr));
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
for (i = 0; i < matcher_rx_tx->num_of_builders; i++) { for (i = 0; i < matcher_rx_tx->num_of_builders; i++) {
ret = dr_dump_matcher_builder(file, ret = dr_dump_matcher_builder(file,
...@@ -434,13 +746,22 @@ dr_dump_matcher(struct seq_file *file, struct mlx5dr_matcher *matcher) ...@@ -434,13 +746,22 @@ dr_dump_matcher(struct seq_file *file, struct mlx5dr_matcher *matcher)
{ {
struct mlx5dr_matcher_rx_tx *rx = &matcher->rx; struct mlx5dr_matcher_rx_tx *rx = &matcher->rx;
struct mlx5dr_matcher_rx_tx *tx = &matcher->tx; struct mlx5dr_matcher_rx_tx *tx = &matcher->tx;
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
u64 matcher_id; u64 matcher_id;
int ret; int ret;
matcher_id = DR_DBG_PTR_TO_ID(matcher); matcher_id = DR_DBG_PTR_TO_ID(matcher);
seq_printf(file, "%d,0x%llx,0x%llx,%d\n", DR_DUMP_REC_TYPE_MATCHER, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
matcher_id, DR_DBG_PTR_TO_ID(matcher->tbl), matcher->prio); "%d,0x%llx,0x%llx,%d\n", DR_DUMP_REC_TYPE_MATCHER,
matcher_id, DR_DBG_PTR_TO_ID(matcher->tbl),
matcher->prio);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
ret = dr_dump_matcher_mask(file, &matcher->mask, ret = dr_dump_matcher_mask(file, &matcher->mask,
matcher->match_criteria, matcher_id); matcher->match_criteria, matcher_id);
...@@ -486,15 +807,24 @@ dr_dump_table_rx_tx(struct seq_file *file, bool is_rx, ...@@ -486,15 +807,24 @@ dr_dump_table_rx_tx(struct seq_file *file, bool is_rx,
struct mlx5dr_table_rx_tx *table_rx_tx, struct mlx5dr_table_rx_tx *table_rx_tx,
const u64 table_id) const u64 table_id)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
enum dr_dump_rec_type rec_type; enum dr_dump_rec_type rec_type;
u64 s_icm_addr; u64 s_icm_addr;
int ret;
rec_type = is_rx ? DR_DUMP_REC_TYPE_TABLE_RX : rec_type = is_rx ? DR_DUMP_REC_TYPE_TABLE_RX :
DR_DUMP_REC_TYPE_TABLE_TX; DR_DUMP_REC_TYPE_TABLE_TX;
s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(table_rx_tx->s_anchor->chunk); s_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(table_rx_tx->s_anchor->chunk);
seq_printf(file, "%d,0x%llx,0x%llx\n", rec_type, table_id, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
dr_dump_icm_to_idx(s_icm_addr)); "%d,0x%llx,0x%llx\n", rec_type, table_id,
dr_dump_icm_to_idx(s_icm_addr));
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -503,11 +833,19 @@ static int dr_dump_table(struct seq_file *file, struct mlx5dr_table *table) ...@@ -503,11 +833,19 @@ static int dr_dump_table(struct seq_file *file, struct mlx5dr_table *table)
{ {
struct mlx5dr_table_rx_tx *rx = &table->rx; struct mlx5dr_table_rx_tx *rx = &table->rx;
struct mlx5dr_table_rx_tx *tx = &table->tx; struct mlx5dr_table_rx_tx *tx = &table->tx;
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
int ret; int ret;
seq_printf(file, "%d,0x%llx,0x%llx,%d,%d\n", DR_DUMP_REC_TYPE_TABLE, ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DBG_PTR_TO_ID(table), DR_DBG_PTR_TO_ID(table->dmn), "%d,0x%llx,0x%llx,%d,%d\n", DR_DUMP_REC_TYPE_TABLE,
table->table_type, table->level); DR_DBG_PTR_TO_ID(table), DR_DBG_PTR_TO_ID(table->dmn),
table->table_type, table->level);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
if (rx->nic_dmn) { if (rx->nic_dmn) {
ret = dr_dump_table_rx_tx(file, true, rx, ret = dr_dump_table_rx_tx(file, true, rx,
...@@ -546,46 +884,86 @@ static int ...@@ -546,46 +884,86 @@ static int
dr_dump_send_ring(struct seq_file *file, struct mlx5dr_send_ring *ring, dr_dump_send_ring(struct seq_file *file, struct mlx5dr_send_ring *ring,
const u64 domain_id) const u64 domain_id)
{ {
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x\n", char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
DR_DUMP_REC_TYPE_DOMAIN_SEND_RING, DR_DBG_PTR_TO_ID(ring), int ret;
domain_id, ring->cq->mcq.cqn, ring->qp->qpn);
ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%d,0x%llx,0x%llx,0x%x,0x%x\n",
DR_DUMP_REC_TYPE_DOMAIN_SEND_RING,
DR_DBG_PTR_TO_ID(ring), domain_id,
ring->cq->mcq.cqn, ring->qp->qpn);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
static int static noinline_for_stack int
dr_dump_domain_info_flex_parser(struct seq_file *file, dr_dump_domain_info_flex_parser(struct seq_file *file,
const char *flex_parser_name, const char *flex_parser_name,
const u8 flex_parser_value, const u8 flex_parser_value,
const u64 domain_id) const u64 domain_id)
{ {
seq_printf(file, "%d,0x%llx,%s,0x%x\n", char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
DR_DUMP_REC_TYPE_DOMAIN_INFO_FLEX_PARSER, domain_id, int ret;
flex_parser_name, flex_parser_value);
ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
"%d,0x%llx,%s,0x%x\n",
DR_DUMP_REC_TYPE_DOMAIN_INFO_FLEX_PARSER, domain_id,
flex_parser_name, flex_parser_value);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
return 0; return 0;
} }
static int static noinline_for_stack int
dr_dump_domain_info_caps(struct seq_file *file, struct mlx5dr_cmd_caps *caps, dr_dump_domain_info_caps(struct seq_file *file, struct mlx5dr_cmd_caps *caps,
const u64 domain_id) const u64 domain_id)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
struct mlx5dr_cmd_vport_cap *vport_caps; struct mlx5dr_cmd_vport_cap *vport_caps;
unsigned long i, vports_num; unsigned long i, vports_num;
int ret;
xa_for_each(&caps->vports.vports_caps_xa, vports_num, vport_caps) xa_for_each(&caps->vports.vports_caps_xa, vports_num, vport_caps)
; /* count the number of vports in xarray */ ; /* count the number of vports in xarray */
seq_printf(file, "%d,0x%llx,0x%x,0x%llx,0x%llx,0x%x,%lu,%d\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_DOMAIN_INFO_CAPS, domain_id, caps->gvmi, "%d,0x%llx,0x%x,0x%llx,0x%llx,0x%x,%lu,%d\n",
caps->nic_rx_drop_address, caps->nic_tx_drop_address, DR_DUMP_REC_TYPE_DOMAIN_INFO_CAPS, domain_id, caps->gvmi,
caps->flex_protocols, vports_num, caps->eswitch_manager); caps->nic_rx_drop_address, caps->nic_tx_drop_address,
caps->flex_protocols, vports_num, caps->eswitch_manager);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
xa_for_each(&caps->vports.vports_caps_xa, i, vport_caps) { xa_for_each(&caps->vports.vports_caps_xa, i, vport_caps) {
vport_caps = xa_load(&caps->vports.vports_caps_xa, i); vport_caps = xa_load(&caps->vports.vports_caps_xa, i);
seq_printf(file, "%d,0x%llx,%lu,0x%x,0x%llx,0x%llx\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_DOMAIN_INFO_VPORT, domain_id, i, "%d,0x%llx,%lu,0x%x,0x%llx,0x%llx\n",
vport_caps->vport_gvmi, vport_caps->icm_address_rx, DR_DUMP_REC_TYPE_DOMAIN_INFO_VPORT,
vport_caps->icm_address_tx); domain_id, i, vport_caps->vport_gvmi,
vport_caps->icm_address_rx,
vport_caps->icm_address_tx);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
} }
return 0; return 0;
} }
...@@ -627,24 +1005,32 @@ dr_dump_domain_info(struct seq_file *file, struct mlx5dr_domain_info *info, ...@@ -627,24 +1005,32 @@ dr_dump_domain_info(struct seq_file *file, struct mlx5dr_domain_info *info,
return 0; return 0;
} }
static int static noinline_for_stack int
dr_dump_domain(struct seq_file *file, struct mlx5dr_domain *dmn) dr_dump_domain(struct seq_file *file, struct mlx5dr_domain *dmn)
{ {
char buff[MLX5DR_DEBUG_DUMP_BUFF_LENGTH];
u64 domain_id = DR_DBG_PTR_TO_ID(dmn); u64 domain_id = DR_DBG_PTR_TO_ID(dmn);
int ret; int ret;
seq_printf(file, "%d,0x%llx,%d,0%x,%d,%u.%u.%u,%s,%d,%u,%u,%u\n", ret = snprintf(buff, MLX5DR_DEBUG_DUMP_BUFF_LENGTH,
DR_DUMP_REC_TYPE_DOMAIN, "%d,0x%llx,%d,0%x,%d,%u.%u.%u,%s,%d,%u,%u,%u\n",
domain_id, dmn->type, dmn->info.caps.gvmi, DR_DUMP_REC_TYPE_DOMAIN,
dmn->info.supp_sw_steering, domain_id, dmn->type, dmn->info.caps.gvmi,
/* package version */ dmn->info.supp_sw_steering,
LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL, /* package version */
LINUX_VERSION_SUBLEVEL, LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL,
pci_name(dmn->mdev->pdev), LINUX_VERSION_SUBLEVEL,
0, /* domain flags */ pci_name(dmn->mdev->pdev),
dmn->num_buddies[DR_ICM_TYPE_STE], 0, /* domain flags */
dmn->num_buddies[DR_ICM_TYPE_MODIFY_ACTION], dmn->num_buddies[DR_ICM_TYPE_STE],
dmn->num_buddies[DR_ICM_TYPE_MODIFY_HDR_PTRN]); dmn->num_buddies[DR_ICM_TYPE_MODIFY_ACTION],
dmn->num_buddies[DR_ICM_TYPE_MODIFY_HDR_PTRN]);
if (ret < 0)
return ret;
ret = mlx5dr_dbg_dump_data_print(file, buff, ret);
if (ret)
return ret;
ret = dr_dump_domain_info(file, &dmn->info, domain_id); ret = dr_dump_domain_info(file, &dmn->info, domain_id);
if (ret < 0) if (ret < 0)
...@@ -683,11 +1069,91 @@ static int dr_dump_domain_all(struct seq_file *file, struct mlx5dr_domain *dmn) ...@@ -683,11 +1069,91 @@ static int dr_dump_domain_all(struct seq_file *file, struct mlx5dr_domain *dmn)
return ret; return ret;
} }
static int dr_dump_show(struct seq_file *file, void *priv) static void *
dr_dump_start(struct seq_file *file, loff_t *pos)
{ {
return dr_dump_domain_all(file, file->private); struct mlx5dr_domain *dmn = file->private;
struct mlx5dr_dbg_dump_data *dump_data;
if (atomic_read(&dmn->dump_info.state) != MLX5DR_DEBUG_DUMP_STATE_FREE) {
mlx5_core_warn(dmn->mdev, "Dump already in progress\n");
return ERR_PTR(-EBUSY);
}
atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_IN_PROGRESS);
dump_data = dmn->dump_info.dump_data;
if (dump_data) {
return seq_list_start(&dump_data->buff_list, *pos);
} else if (*pos == 0) {
dump_data = mlx5dr_dbg_create_dump_data();
if (!dump_data)
goto exit;
dmn->dump_info.dump_data = dump_data;
if (dr_dump_domain_all(file, dmn)) {
mlx5dr_dbg_destroy_dump_data(dump_data);
dmn->dump_info.dump_data = NULL;
goto exit;
}
return seq_list_start(&dump_data->buff_list, *pos);
}
exit:
atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_FREE);
return NULL;
} }
DEFINE_SHOW_ATTRIBUTE(dr_dump);
static void *
dr_dump_next(struct seq_file *file, void *v, loff_t *pos)
{
struct mlx5dr_domain *dmn = file->private;
struct mlx5dr_dbg_dump_data *dump_data;
dump_data = dmn->dump_info.dump_data;
return seq_list_next(v, &dump_data->buff_list, pos);
}
static void
dr_dump_stop(struct seq_file *file, void *v)
{
struct mlx5dr_domain *dmn = file->private;
struct mlx5dr_dbg_dump_data *dump_data;
if (v && IS_ERR(v))
return;
if (!v) {
dump_data = dmn->dump_info.dump_data;
if (dump_data) {
mlx5dr_dbg_destroy_dump_data(dump_data);
dmn->dump_info.dump_data = NULL;
}
}
atomic_set(&dmn->dump_info.state, MLX5DR_DEBUG_DUMP_STATE_FREE);
}
static int
dr_dump_show(struct seq_file *file, void *v)
{
struct mlx5dr_dbg_dump_buff *entry;
entry = list_entry(v, struct mlx5dr_dbg_dump_buff, node);
seq_printf(file, "%s", entry->buff);
return 0;
}
static const struct seq_operations dr_dump_sops = {
.start = dr_dump_start,
.next = dr_dump_next,
.stop = dr_dump_stop,
.show = dr_dump_show,
};
DEFINE_SEQ_ATTRIBUTE(dr_dump);
void mlx5dr_dbg_init_dump(struct mlx5dr_domain *dmn) void mlx5dr_dbg_init_dump(struct mlx5dr_domain *dmn)
{ {
......
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ /* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#define MLX5DR_DEBUG_DUMP_BUFF_SIZE (64 * 1024 * 1024)
#define MLX5DR_DEBUG_DUMP_BUFF_LENGTH 512
enum {
MLX5DR_DEBUG_DUMP_STATE_FREE,
MLX5DR_DEBUG_DUMP_STATE_IN_PROGRESS,
};
struct mlx5dr_dbg_dump_buff {
char *buff;
u32 index;
struct list_head node;
};
struct mlx5dr_dbg_dump_data {
struct list_head buff_list;
};
struct mlx5dr_dbg_dump_info { struct mlx5dr_dbg_dump_info {
struct mutex dbg_mutex; /* protect dbg lists */ struct mutex dbg_mutex; /* protect dbg lists */
struct dentry *steering_debugfs; struct dentry *steering_debugfs;
struct dentry *fdb_debugfs; struct dentry *fdb_debugfs;
struct mlx5dr_dbg_dump_data *dump_data;
atomic_t state;
}; };
void mlx5dr_dbg_init_dump(struct mlx5dr_domain *dmn); void mlx5dr_dbg_init_dump(struct mlx5dr_domain *dmn);
......
...@@ -10661,6 +10661,7 @@ enum { ...@@ -10661,6 +10661,7 @@ enum {
MLX5_INITIAL_SEG_NIC_INTERFACE_FULL_DRIVER = 0x0, MLX5_INITIAL_SEG_NIC_INTERFACE_FULL_DRIVER = 0x0,
MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED = 0x1, MLX5_INITIAL_SEG_NIC_INTERFACE_DISABLED = 0x1,
MLX5_INITIAL_SEG_NIC_INTERFACE_NO_DRAM_NIC = 0x2, MLX5_INITIAL_SEG_NIC_INTERFACE_NO_DRAM_NIC = 0x2,
MLX5_INITIAL_SEG_NIC_INTERFACE_SW_RESET = 0x7,
}; };
enum { enum {
......
...@@ -1062,7 +1062,7 @@ struct xfrmdev_ops { ...@@ -1062,7 +1062,7 @@ struct xfrmdev_ops {
bool (*xdo_dev_offload_ok) (struct sk_buff *skb, bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
struct xfrm_state *x); struct xfrm_state *x);
void (*xdo_dev_state_advance_esn) (struct xfrm_state *x); void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
void (*xdo_dev_state_update_curlft) (struct xfrm_state *x); void (*xdo_dev_state_update_stats) (struct xfrm_state *x);
int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack); int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack);
void (*xdo_dev_policy_delete) (struct xfrm_policy *x); void (*xdo_dev_policy_delete) (struct xfrm_policy *x);
void (*xdo_dev_policy_free) (struct xfrm_policy *x); void (*xdo_dev_policy_free) (struct xfrm_policy *x);
......
...@@ -51,8 +51,10 @@ ...@@ -51,8 +51,10 @@
#ifdef CONFIG_XFRM_STATISTICS #ifdef CONFIG_XFRM_STATISTICS
#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field) #define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
#define XFRM_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.xfrm_statistics, field, val)
#else #else
#define XFRM_INC_STATS(net, field) ((void)(net)) #define XFRM_INC_STATS(net, field) ((void)(net))
#define XFRM_ADD_STATS(net, field, val) ((void)(net))
#endif #endif
...@@ -1577,22 +1579,20 @@ struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id, ...@@ -1577,22 +1579,20 @@ struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi, struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
unsigned short family); unsigned short family);
int xfrm_state_check_expire(struct xfrm_state *x); int xfrm_state_check_expire(struct xfrm_state *x);
void xfrm_state_update_stats(struct net *net);
#ifdef CONFIG_XFRM_OFFLOAD #ifdef CONFIG_XFRM_OFFLOAD
static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) static inline void xfrm_dev_state_update_stats(struct xfrm_state *x)
{ {
struct xfrm_dev_offload *xdo = &x->xso; struct xfrm_dev_offload *xdo = &x->xso;
struct net_device *dev = xdo->dev; struct net_device *dev = xdo->dev;
if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
return;
if (dev && dev->xfrmdev_ops && if (dev && dev->xfrmdev_ops &&
dev->xfrmdev_ops->xdo_dev_state_update_curlft) dev->xfrmdev_ops->xdo_dev_state_update_stats)
dev->xfrmdev_ops->xdo_dev_state_update_curlft(x); dev->xfrmdev_ops->xdo_dev_state_update_stats(x);
} }
#else #else
static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) {} static inline void xfrm_dev_state_update_stats(struct xfrm_state *x) {}
#endif #endif
void xfrm_state_insert(struct xfrm_state *x); void xfrm_state_insert(struct xfrm_state *x);
int xfrm_state_add(struct xfrm_state *x); int xfrm_state_add(struct xfrm_state *x);
......
...@@ -52,6 +52,7 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v) ...@@ -52,6 +52,7 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
memset(buff, 0, sizeof(unsigned long) * LINUX_MIB_XFRMMAX); memset(buff, 0, sizeof(unsigned long) * LINUX_MIB_XFRMMAX);
xfrm_state_update_stats(net);
snmp_get_cpu_field_batch(buff, xfrm_mib_list, snmp_get_cpu_field_batch(buff, xfrm_mib_list,
net->mib.xfrm_statistics); net->mib.xfrm_statistics);
for (i = 0; xfrm_mib_list[i].name; i++) for (i = 0; xfrm_mib_list[i].name; i++)
......
...@@ -570,7 +570,7 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) ...@@ -570,7 +570,7 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
int err = 0; int err = 0;
spin_lock(&x->lock); spin_lock(&x->lock);
xfrm_dev_state_update_curlft(x); xfrm_dev_state_update_stats(x);
if (x->km.state == XFRM_STATE_DEAD) if (x->km.state == XFRM_STATE_DEAD)
goto out; goto out;
...@@ -1935,7 +1935,7 @@ EXPORT_SYMBOL(xfrm_state_update); ...@@ -1935,7 +1935,7 @@ EXPORT_SYMBOL(xfrm_state_update);
int xfrm_state_check_expire(struct xfrm_state *x) int xfrm_state_check_expire(struct xfrm_state *x)
{ {
xfrm_dev_state_update_curlft(x); xfrm_dev_state_update_stats(x);
if (!READ_ONCE(x->curlft.use_time)) if (!READ_ONCE(x->curlft.use_time))
WRITE_ONCE(x->curlft.use_time, ktime_get_real_seconds()); WRITE_ONCE(x->curlft.use_time, ktime_get_real_seconds());
...@@ -1957,6 +1957,19 @@ int xfrm_state_check_expire(struct xfrm_state *x) ...@@ -1957,6 +1957,19 @@ int xfrm_state_check_expire(struct xfrm_state *x)
} }
EXPORT_SYMBOL(xfrm_state_check_expire); EXPORT_SYMBOL(xfrm_state_check_expire);
void xfrm_state_update_stats(struct net *net)
{
struct xfrm_state *x;
int i;
spin_lock_bh(&net->xfrm.xfrm_state_lock);
for (i = 0; i <= net->xfrm.state_hmask; i++) {
hlist_for_each_entry(x, net->xfrm.state_bydst + i, bydst)
xfrm_dev_state_update_stats(x);
}
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
}
struct xfrm_state * struct xfrm_state *
xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi, xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi,
u8 proto, unsigned short family) u8 proto, unsigned short family)
......
...@@ -902,7 +902,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) ...@@ -902,7 +902,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
memcpy(&p->sel, &x->sel, sizeof(p->sel)); memcpy(&p->sel, &x->sel, sizeof(p->sel));
memcpy(&p->lft, &x->lft, sizeof(p->lft)); memcpy(&p->lft, &x->lft, sizeof(p->lft));
if (x->xso.dev) if (x->xso.dev)
xfrm_dev_state_update_curlft(x); xfrm_dev_state_update_stats(x);
memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); memcpy(&p->curlft, &x->curlft, sizeof(p->curlft));
put_unaligned(x->stats.replay_window, &p->stats.replay_window); put_unaligned(x->stats.replay_window, &p->stats.replay_window);
put_unaligned(x->stats.replay, &p->stats.replay); put_unaligned(x->stats.replay, &p->stats.replay);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment