2018-01-16 21:04:14 +07:00
|
|
|
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 Mellanox Technologies. All rights reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _MLX5_ESWITCH_
|
|
|
|
#define _MLX5_ESWITCH_
|
|
|
|
|
|
|
|
#include <linux/mlx5/driver.h>
|
|
|
|
|
2018-05-31 15:16:18 +07:00
|
|
|
#define MLX5_ESWITCH_MANAGER(mdev) MLX5_CAP_GEN(mdev, eswitch_manager)
|
|
|
|
|
2018-01-16 21:04:14 +07:00
|
|
|
enum {
|
|
|
|
SRIOV_NONE,
|
|
|
|
SRIOV_LEGACY,
|
|
|
|
SRIOV_OFFLOADS
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
REP_ETH,
|
2018-01-16 21:13:46 +07:00
|
|
|
REP_IB,
|
2018-01-16 21:04:14 +07:00
|
|
|
NUM_REP_TYPES,
|
|
|
|
};
|
|
|
|
|
2019-01-30 10:48:31 +07:00
|
|
|
enum {
|
|
|
|
REP_UNREGISTERED,
|
|
|
|
REP_REGISTERED,
|
|
|
|
REP_LOADED,
|
|
|
|
};
|
|
|
|
|
2018-01-16 21:04:14 +07:00
|
|
|
struct mlx5_eswitch_rep;
|
|
|
|
struct mlx5_eswitch_rep_if {
|
|
|
|
int (*load)(struct mlx5_core_dev *dev,
|
|
|
|
struct mlx5_eswitch_rep *rep);
|
|
|
|
void (*unload)(struct mlx5_eswitch_rep *rep);
|
|
|
|
void *(*get_proto_dev)(struct mlx5_eswitch_rep *rep);
|
|
|
|
void *priv;
|
net/mlx5: E-Switch, Use atomic rep state to serialize state change
When the state of rep was introduced, it was also designed to prevent
duplicate unloading of the same rep. Considering the following two
flows when an eswitch manager is at switchdev mode with n VF reps loaded.
+--------------------------------------+--------------------------------+
| cpu-0 | cpu-1 |
| -------- | -------- |
| mlx5_ib_remove | mlx5_eswitch_disable_sriov |
| mlx5_ib_unregister_vport_reps | esw_offloads_cleanup |
| mlx5_eswitch_unregister_vport_reps | esw_offloads_unload_all_reps |
| __unload_reps_all_vport | __unload_reps_all_vport |
+--------------------------------------+--------------------------------+
These two flows will try to unload the same rep. Per original design,
once one flow unloads the rep, the state moves to REGISTERED. The 2nd
flow will no longer needs to do the unload and bails out. However, as
read and write of the state is not atomic, when 1st flow is doing the
unload, the state is still LOADED, 2nd flow is able to do the same
unload action. Kernel crash will happen.
To solve this, driver should do atomic test-and-set for the state. So
that only one flow can change the rep state from LOADED to REGISTERED,
and proceed to do the actual unloading.
Since the state is changing to atomic type, all other read/write should
be atomic action as well.
Fixes: f121e0ea9586 (net/mlx5: E-Switch, Add state to eswitch vport representors)
Signed-off-by: Bodong Wang <bodong@mellanox.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Vu Pham <vuhuong@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
2019-04-19 06:24:15 +07:00
|
|
|
atomic_t state;
|
2018-01-16 21:04:14 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct mlx5_eswitch_rep {
|
|
|
|
struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
|
|
|
|
u16 vport;
|
|
|
|
u8 hw_id[ETH_ALEN];
|
|
|
|
u16 vlan;
|
|
|
|
u32 vlan_refcount;
|
|
|
|
};
|
|
|
|
|
net/mlx5: E-Switch, Centralize repersentor reg/unreg to eswitch driver
Eswitch has two users: IB and ETH. They both register repersentors
when mlx5 interface is added, and unregister the repersentors when
mlx5 interface is removed. Ideally, each driver should only deal with
the entities which are unique to itself. However, current IB and ETH
drivers have to perform the following eswitch operations:
1. When registering, specify how many vports to register. This number
is the same for both drivers which is the total available vport
numbers.
2. When unregistering, specify the number of registered vports to do
unregister. Also, unload the repersentors which are already loaded.
It's unnecessary for eswitch driver to hands out the control of above
operations to individual driver users, as they're not unique to each
driver. Instead, such operations should be centralized to eswitch
driver. This consolidates eswitch control flow, and simplified IB and
ETH driver.
This patch doesn't change any functionality.
Signed-off-by: Bodong Wang <bodong@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
2019-02-01 06:42:57 +07:00
|
|
|
void mlx5_eswitch_register_vport_reps(struct mlx5_eswitch *esw,
|
|
|
|
struct mlx5_eswitch_rep_if *rep_if,
|
|
|
|
u8 rep_type);
|
|
|
|
void mlx5_eswitch_unregister_vport_reps(struct mlx5_eswitch *esw, u8 rep_type);
|
2018-01-16 21:04:14 +07:00
|
|
|
void *mlx5_eswitch_get_proto_dev(struct mlx5_eswitch *esw,
|
2019-04-05 13:07:19 +07:00
|
|
|
u16 vport_num,
|
2018-01-16 21:04:14 +07:00
|
|
|
u8 rep_type);
|
|
|
|
struct mlx5_eswitch_rep *mlx5_eswitch_vport_rep(struct mlx5_eswitch *esw,
|
2019-04-05 13:07:19 +07:00
|
|
|
u16 vport_num);
|
2018-01-16 21:04:14 +07:00
|
|
|
void *mlx5_eswitch_uplink_get_proto_dev(struct mlx5_eswitch *esw, u8 rep_type);
|
|
|
|
u8 mlx5_eswitch_mode(struct mlx5_eswitch *esw);
|
|
|
|
struct mlx5_flow_handle *
|
|
|
|
mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw,
|
2019-04-05 13:07:19 +07:00
|
|
|
u16 vport_num, u32 sqn);
|
2018-01-16 21:04:14 +07:00
|
|
|
#endif
|