mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-30 21:40:37 -04:00
Merge branch 'devlink-reload-simplification'
Leon Romanovsky says: ==================== devlink reload simplification Simplify devlink reload APIs. ==================== Link: https://lore.kernel.org/r/cover.1634044267.git.leonro@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -119,8 +119,8 @@ int hclge_devlink_init(struct hclge_dev *hdev)
|
||||
priv->hdev = hdev;
|
||||
hdev->devlink = devlink;
|
||||
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,8 +128,6 @@ void hclge_devlink_uninit(struct hclge_dev *hdev)
|
||||
{
|
||||
struct devlink *devlink = hdev->devlink;
|
||||
|
||||
devlink_reload_disable(devlink);
|
||||
|
||||
devlink_unregister(devlink);
|
||||
|
||||
devlink_free(devlink);
|
||||
|
||||
@@ -121,8 +121,8 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev)
|
||||
priv->hdev = hdev;
|
||||
hdev->devlink = devlink;
|
||||
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,8 +130,6 @@ void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
|
||||
{
|
||||
struct devlink *devlink = hdev->devlink;
|
||||
|
||||
devlink_reload_disable(devlink);
|
||||
|
||||
devlink_unregister(devlink);
|
||||
|
||||
devlink_free(devlink);
|
||||
|
||||
@@ -4025,8 +4025,8 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto err_params_unregister;
|
||||
|
||||
pci_save_state(pdev);
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
|
||||
err_params_unregister:
|
||||
@@ -4135,7 +4135,6 @@ static void mlx4_remove_one(struct pci_dev *pdev)
|
||||
struct devlink *devlink = priv_to_devlink(priv);
|
||||
int active_vfs = 0;
|
||||
|
||||
devlink_reload_disable(devlink);
|
||||
devlink_unregister(devlink);
|
||||
|
||||
if (mlx4_is_slave(dev))
|
||||
|
||||
@@ -796,6 +796,7 @@ static void mlx5_devlink_traps_unregister(struct devlink *devlink)
|
||||
|
||||
int mlx5_devlink_register(struct devlink *devlink)
|
||||
{
|
||||
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
||||
int err;
|
||||
|
||||
err = devlink_params_register(devlink, mlx5_devlink_params,
|
||||
@@ -813,6 +814,9 @@ int mlx5_devlink_register(struct devlink *devlink)
|
||||
if (err)
|
||||
goto traps_reg_err;
|
||||
|
||||
if (!mlx5_core_is_mp_slave(dev))
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
|
||||
return 0;
|
||||
|
||||
traps_reg_err:
|
||||
|
||||
@@ -1538,8 +1538,6 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
pci_save_state(pdev);
|
||||
devlink_register(devlink);
|
||||
if (!mlx5_core_is_mp_slave(dev))
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
|
||||
err_init_one:
|
||||
@@ -1559,7 +1557,6 @@ static void remove_one(struct pci_dev *pdev)
|
||||
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
||||
struct devlink *devlink = priv_to_devlink(dev);
|
||||
|
||||
devlink_reload_disable(devlink);
|
||||
devlink_unregister(devlink);
|
||||
mlx5_crdump_disable(dev);
|
||||
mlx5_drain_health_wq(dev);
|
||||
|
||||
@@ -47,7 +47,6 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
|
||||
goto init_one_err;
|
||||
}
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
|
||||
init_one_err:
|
||||
@@ -62,10 +61,8 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
|
||||
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 devlink *devlink;
|
||||
struct devlink *devlink = priv_to_devlink(sf_dev->mdev);
|
||||
|
||||
devlink = priv_to_devlink(sf_dev->mdev);
|
||||
devlink_reload_disable(devlink);
|
||||
devlink_unregister(devlink);
|
||||
mlx5_uninit_one(sf_dev->mdev);
|
||||
iounmap(sf_dev->mdev->iseg);
|
||||
|
||||
@@ -19,7 +19,7 @@ struct mlxfw_dev {
|
||||
static inline
|
||||
struct device *mlxfw_dev_dev(struct mlxfw_dev *mlxfw_dev)
|
||||
{
|
||||
return mlxfw_dev->devlink->dev;
|
||||
return devlink_to_dev(mlxfw_dev->devlink);
|
||||
}
|
||||
|
||||
#define MLXFW_PRFX "mlxfw: "
|
||||
|
||||
@@ -2008,10 +2008,9 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
}
|
||||
|
||||
if (!reload) {
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_driver_init:
|
||||
@@ -2075,10 +2074,9 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
|
||||
{
|
||||
struct devlink *devlink = priv_to_devlink(mlxsw_core);
|
||||
|
||||
if (!reload) {
|
||||
devlink_reload_disable(devlink);
|
||||
if (!reload)
|
||||
devlink_unregister(devlink);
|
||||
}
|
||||
|
||||
if (devlink_is_reload_failed(devlink)) {
|
||||
if (!reload)
|
||||
/* Only the parts that were not de-initialized in the
|
||||
|
||||
@@ -1511,8 +1511,8 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
|
||||
goto err_psample_exit;
|
||||
|
||||
nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
|
||||
devlink_set_features(devlink, DEVLINK_F_RELOAD);
|
||||
devlink_register(devlink);
|
||||
devlink_reload_enable(devlink);
|
||||
return 0;
|
||||
|
||||
err_psample_exit:
|
||||
@@ -1566,9 +1566,7 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
|
||||
struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
|
||||
struct devlink *devlink = priv_to_devlink(nsim_dev);
|
||||
|
||||
devlink_reload_disable(devlink);
|
||||
devlink_unregister(devlink);
|
||||
|
||||
nsim_dev_reload_destroy(nsim_dev);
|
||||
|
||||
nsim_bpf_dev_exit(nsim_dev);
|
||||
|
||||
@@ -21,45 +21,7 @@
|
||||
#include <linux/xarray.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
|
||||
(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
|
||||
|
||||
struct devlink_dev_stats {
|
||||
u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
|
||||
u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
|
||||
};
|
||||
|
||||
struct devlink_ops;
|
||||
|
||||
struct devlink {
|
||||
u32 index;
|
||||
struct list_head port_list;
|
||||
struct list_head rate_list;
|
||||
struct list_head sb_list;
|
||||
struct list_head dpipe_table_list;
|
||||
struct list_head resource_list;
|
||||
struct list_head param_list;
|
||||
struct list_head region_list;
|
||||
struct list_head reporter_list;
|
||||
struct mutex reporters_lock; /* protects reporter_list */
|
||||
struct devlink_dpipe_headers *dpipe_headers;
|
||||
struct list_head trap_list;
|
||||
struct list_head trap_group_list;
|
||||
struct list_head trap_policer_list;
|
||||
const struct devlink_ops *ops;
|
||||
struct xarray snapshot_ids;
|
||||
struct devlink_dev_stats stats;
|
||||
struct device *dev;
|
||||
possible_net_t _net;
|
||||
struct mutex lock; /* Serializes access to devlink instance specific objects such as
|
||||
* port, sb, dpipe, resource, params, region, traps and more.
|
||||
*/
|
||||
u8 reload_failed:1,
|
||||
reload_enabled:1;
|
||||
refcount_t refcount;
|
||||
struct completion comp;
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
struct devlink;
|
||||
|
||||
struct devlink_port_phys_attrs {
|
||||
u32 port_number; /* Same value as "split group".
|
||||
@@ -1224,6 +1186,11 @@ enum devlink_trap_group_generic_id {
|
||||
.min_burst = _min_burst, \
|
||||
}
|
||||
|
||||
enum {
|
||||
/* device supports reload operations */
|
||||
DEVLINK_F_RELOAD = 1UL << 0,
|
||||
};
|
||||
|
||||
struct devlink_ops {
|
||||
/**
|
||||
* @supported_flash_update_params:
|
||||
@@ -1520,34 +1487,9 @@ struct devlink_ops {
|
||||
struct netlink_ext_ack *extack);
|
||||
};
|
||||
|
||||
static inline void *devlink_priv(struct devlink *devlink)
|
||||
{
|
||||
BUG_ON(!devlink);
|
||||
return &devlink->priv;
|
||||
}
|
||||
|
||||
static inline struct devlink *priv_to_devlink(void *priv)
|
||||
{
|
||||
BUG_ON(!priv);
|
||||
return container_of(priv, struct devlink, priv);
|
||||
}
|
||||
|
||||
static inline struct devlink_port *
|
||||
netdev_to_devlink_port(struct net_device *dev)
|
||||
{
|
||||
if (dev->netdev_ops->ndo_get_devlink_port)
|
||||
return dev->netdev_ops->ndo_get_devlink_port(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct devlink *netdev_to_devlink(struct net_device *dev)
|
||||
{
|
||||
struct devlink_port *devlink_port = netdev_to_devlink_port(dev);
|
||||
|
||||
if (devlink_port)
|
||||
return devlink_port->devlink;
|
||||
return NULL;
|
||||
}
|
||||
void *devlink_priv(struct devlink *devlink);
|
||||
struct devlink *priv_to_devlink(void *priv);
|
||||
struct device *devlink_to_dev(const struct devlink *devlink);
|
||||
|
||||
struct ib_device;
|
||||
|
||||
@@ -1566,10 +1508,9 @@ static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
|
||||
{
|
||||
return devlink_alloc_ns(ops, priv_size, &init_net, dev);
|
||||
}
|
||||
void devlink_set_features(struct devlink *devlink, u64 features);
|
||||
void devlink_register(struct devlink *devlink);
|
||||
void devlink_unregister(struct devlink *devlink);
|
||||
void devlink_reload_enable(struct devlink *devlink);
|
||||
void devlink_reload_disable(struct devlink *devlink);
|
||||
void devlink_free(struct devlink *devlink);
|
||||
int devlink_port_register(struct devlink *devlink,
|
||||
struct devlink_port *devlink_port,
|
||||
|
||||
@@ -21,9 +21,9 @@ TRACE_EVENT(devlink_hwmsg,
|
||||
TP_ARGS(devlink, incoming, type, buf, len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__field(bool, incoming)
|
||||
__field(unsigned long, type)
|
||||
__dynamic_array(u8, buf, len)
|
||||
@@ -31,9 +31,9 @@ TRACE_EVENT(devlink_hwmsg,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__entry->incoming = incoming;
|
||||
__entry->type = type;
|
||||
memcpy(__get_dynamic_array(buf), buf, len);
|
||||
@@ -55,17 +55,17 @@ TRACE_EVENT(devlink_hwerr,
|
||||
TP_ARGS(devlink, err, msg),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__field(int, err)
|
||||
__string(msg, msg)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__entry->err = err;
|
||||
__assign_str(msg, msg);
|
||||
),
|
||||
@@ -85,17 +85,17 @@ TRACE_EVENT(devlink_health_report,
|
||||
TP_ARGS(devlink, reporter_name, msg),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__string(reporter_name, msg)
|
||||
__string(msg, msg)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__assign_str(reporter_name, reporter_name);
|
||||
__assign_str(msg, msg);
|
||||
),
|
||||
@@ -116,18 +116,18 @@ TRACE_EVENT(devlink_health_recover_aborted,
|
||||
TP_ARGS(devlink, reporter_name, health_state, time_since_last_recover),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__string(reporter_name, reporter_name)
|
||||
__field(bool, health_state)
|
||||
__field(u64, time_since_last_recover)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__assign_str(reporter_name, reporter_name);
|
||||
__entry->health_state = health_state;
|
||||
__entry->time_since_last_recover = time_since_last_recover;
|
||||
@@ -150,17 +150,17 @@ TRACE_EVENT(devlink_health_reporter_state_update,
|
||||
TP_ARGS(devlink, reporter_name, new_state),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__string(reporter_name, reporter_name)
|
||||
__field(u8, new_state)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__assign_str(reporter_name, reporter_name);
|
||||
__entry->new_state = new_state;
|
||||
),
|
||||
@@ -181,9 +181,9 @@ TRACE_EVENT(devlink_trap_report,
|
||||
TP_ARGS(devlink, skb, metadata),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(bus_name, devlink->dev->bus->name)
|
||||
__string(dev_name, dev_name(devlink->dev))
|
||||
__string(driver_name, devlink->dev->driver->name)
|
||||
__string(bus_name, devlink_to_dev(devlink)->bus->name)
|
||||
__string(dev_name, dev_name(devlink_to_dev(devlink)))
|
||||
__string(driver_name, devlink_to_dev(devlink)->driver->name)
|
||||
__string(trap_name, metadata->trap_name)
|
||||
__string(trap_group_name, metadata->trap_group_name)
|
||||
__dynamic_array(char, input_dev_name, IFNAMSIZ)
|
||||
@@ -192,9 +192,9 @@ TRACE_EVENT(devlink_trap_report,
|
||||
TP_fast_assign(
|
||||
struct net_device *input_dev = metadata->input_dev;
|
||||
|
||||
__assign_str(bus_name, devlink->dev->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink->dev));
|
||||
__assign_str(driver_name, devlink->dev->driver->name);
|
||||
__assign_str(bus_name, devlink_to_dev(devlink)->bus->name);
|
||||
__assign_str(dev_name, dev_name(devlink_to_dev(devlink)));
|
||||
__assign_str(driver_name, devlink_to_dev(devlink)->driver->name);
|
||||
__assign_str(trap_name, metadata->trap_name);
|
||||
__assign_str(trap_group_name, metadata->trap_group_name);
|
||||
__assign_str(input_dev_name,
|
||||
|
||||
@@ -30,6 +30,63 @@
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/devlink.h>
|
||||
|
||||
#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
|
||||
(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
|
||||
|
||||
struct devlink_dev_stats {
|
||||
u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
|
||||
u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
|
||||
};
|
||||
|
||||
struct devlink {
|
||||
u32 index;
|
||||
struct list_head port_list;
|
||||
struct list_head rate_list;
|
||||
struct list_head sb_list;
|
||||
struct list_head dpipe_table_list;
|
||||
struct list_head resource_list;
|
||||
struct list_head param_list;
|
||||
struct list_head region_list;
|
||||
struct list_head reporter_list;
|
||||
struct mutex reporters_lock; /* protects reporter_list */
|
||||
struct devlink_dpipe_headers *dpipe_headers;
|
||||
struct list_head trap_list;
|
||||
struct list_head trap_group_list;
|
||||
struct list_head trap_policer_list;
|
||||
const struct devlink_ops *ops;
|
||||
u64 features;
|
||||
struct xarray snapshot_ids;
|
||||
struct devlink_dev_stats stats;
|
||||
struct device *dev;
|
||||
possible_net_t _net;
|
||||
/* Serializes access to devlink instance specific objects such as
|
||||
* port, sb, dpipe, resource, params, region, traps and more.
|
||||
*/
|
||||
struct mutex lock;
|
||||
u8 reload_failed:1;
|
||||
refcount_t refcount;
|
||||
struct completion comp;
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
void *devlink_priv(struct devlink *devlink)
|
||||
{
|
||||
return &devlink->priv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_priv);
|
||||
|
||||
struct devlink *priv_to_devlink(void *priv)
|
||||
{
|
||||
return container_of(priv, struct devlink, priv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(priv_to_devlink);
|
||||
|
||||
struct device *devlink_to_dev(const struct devlink *devlink)
|
||||
{
|
||||
return devlink->dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_to_dev);
|
||||
|
||||
static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
|
||||
{
|
||||
.name = "destination mac",
|
||||
@@ -95,6 +152,22 @@ static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_
|
||||
static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
|
||||
#define DEVLINK_REGISTERED XA_MARK_1
|
||||
|
||||
/* devlink instances are open to the access from the user space after
|
||||
* devlink_register() call. Such logical barrier allows us to have certain
|
||||
* expectations related to locking.
|
||||
*
|
||||
* Before *_register() - we are in initialization stage and no parallel
|
||||
* access possible to the devlink instance. All drivers perform that phase
|
||||
* by implicitly holding device_lock.
|
||||
*
|
||||
* After *_register() - users and driver can access devlink instance at
|
||||
* the same time.
|
||||
*/
|
||||
#define ASSERT_DEVLINK_REGISTERED(d) \
|
||||
WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
|
||||
#define ASSERT_DEVLINK_NOT_REGISTERED(d) \
|
||||
WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
|
||||
|
||||
/* devlink_mutex
|
||||
*
|
||||
* An overall lock guarding every operation coming from userspace.
|
||||
@@ -3959,9 +4032,6 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
|
||||
struct net *curr_net;
|
||||
int err;
|
||||
|
||||
if (!devlink->reload_enabled)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
|
||||
sizeof(remote_reload_stats));
|
||||
|
||||
@@ -4029,7 +4099,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
|
||||
u32 actions_performed;
|
||||
int err;
|
||||
|
||||
if (!devlink_reload_supported(devlink->ops))
|
||||
if (!(devlink->features & DEVLINK_F_RELOAD))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = devlink_resources_validate(devlink, NULL, info);
|
||||
@@ -8912,6 +8982,25 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* devlink_set_features - Set devlink supported features
|
||||
*
|
||||
* @devlink: devlink
|
||||
* @features: devlink support features
|
||||
*
|
||||
* This interface allows us to set reload ops separatelly from
|
||||
* the devlink_alloc.
|
||||
*/
|
||||
void devlink_set_features(struct devlink *devlink, u64 features)
|
||||
{
|
||||
ASSERT_DEVLINK_NOT_REGISTERED(devlink);
|
||||
|
||||
WARN_ON(features & DEVLINK_F_RELOAD &&
|
||||
!devlink_reload_supported(devlink->ops));
|
||||
devlink->features = features;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_set_features);
|
||||
|
||||
/**
|
||||
* devlink_alloc_ns - Allocate new devlink instance resources
|
||||
* in specific namespace
|
||||
@@ -9056,6 +9145,10 @@ static void devlink_notify_unregister(struct devlink *devlink)
|
||||
*/
|
||||
void devlink_register(struct devlink *devlink)
|
||||
{
|
||||
ASSERT_DEVLINK_NOT_REGISTERED(devlink);
|
||||
/* Make sure that we are in .probe() routine */
|
||||
device_lock_assert(devlink->dev);
|
||||
|
||||
mutex_lock(&devlink_mutex);
|
||||
xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
|
||||
devlink_notify_register(devlink);
|
||||
@@ -9070,53 +9163,20 @@ EXPORT_SYMBOL_GPL(devlink_register);
|
||||
*/
|
||||
void devlink_unregister(struct devlink *devlink)
|
||||
{
|
||||
ASSERT_DEVLINK_REGISTERED(devlink);
|
||||
/* Make sure that we are in .remove() routine */
|
||||
device_lock_assert(devlink->dev);
|
||||
|
||||
devlink_put(devlink);
|
||||
wait_for_completion(&devlink->comp);
|
||||
|
||||
mutex_lock(&devlink_mutex);
|
||||
WARN_ON(devlink_reload_supported(devlink->ops) &&
|
||||
devlink->reload_enabled);
|
||||
devlink_notify_unregister(devlink);
|
||||
xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
|
||||
mutex_unlock(&devlink_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_unregister);
|
||||
|
||||
/**
|
||||
* devlink_reload_enable - Enable reload of devlink instance
|
||||
*
|
||||
* @devlink: devlink
|
||||
*
|
||||
* Should be called at end of device initialization
|
||||
* process when reload operation is supported.
|
||||
*/
|
||||
void devlink_reload_enable(struct devlink *devlink)
|
||||
{
|
||||
mutex_lock(&devlink_mutex);
|
||||
devlink->reload_enabled = true;
|
||||
mutex_unlock(&devlink_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_reload_enable);
|
||||
|
||||
/**
|
||||
* devlink_reload_disable - Disable reload of devlink instance
|
||||
*
|
||||
* @devlink: devlink
|
||||
*
|
||||
* Should be called at the beginning of device cleanup
|
||||
* process when reload operation is supported.
|
||||
*/
|
||||
void devlink_reload_disable(struct devlink *devlink)
|
||||
{
|
||||
mutex_lock(&devlink_mutex);
|
||||
/* Mutex is taken which ensures that no reload operation is in
|
||||
* progress while setting up forbidded flag.
|
||||
*/
|
||||
devlink->reload_enabled = false;
|
||||
mutex_unlock(&devlink_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_reload_disable);
|
||||
|
||||
/**
|
||||
* devlink_free - Free devlink instance resources
|
||||
*
|
||||
@@ -9124,6 +9184,8 @@ EXPORT_SYMBOL_GPL(devlink_reload_disable);
|
||||
*/
|
||||
void devlink_free(struct devlink *devlink)
|
||||
{
|
||||
ASSERT_DEVLINK_NOT_REGISTERED(devlink);
|
||||
|
||||
mutex_destroy(&devlink->reporters_lock);
|
||||
mutex_destroy(&devlink->lock);
|
||||
WARN_ON(!list_empty(&devlink->trap_policer_list));
|
||||
@@ -11324,6 +11386,24 @@ static void __devlink_compat_running_version(struct devlink *devlink,
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
static struct devlink_port *netdev_to_devlink_port(struct net_device *dev)
|
||||
{
|
||||
if (!dev->netdev_ops->ndo_get_devlink_port)
|
||||
return NULL;
|
||||
|
||||
return dev->netdev_ops->ndo_get_devlink_port(dev);
|
||||
}
|
||||
|
||||
static struct devlink *netdev_to_devlink(struct net_device *dev)
|
||||
{
|
||||
struct devlink_port *devlink_port = netdev_to_devlink_port(dev);
|
||||
|
||||
if (!devlink_port)
|
||||
return NULL;
|
||||
|
||||
return devlink_port->devlink;
|
||||
}
|
||||
|
||||
void devlink_compat_running_version(struct net_device *dev,
|
||||
char *buf, size_t len)
|
||||
{
|
||||
@@ -11433,7 +11513,7 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
|
||||
if (!net_eq(devlink_net(devlink), net))
|
||||
goto retry;
|
||||
|
||||
WARN_ON(!devlink_reload_supported(devlink->ops));
|
||||
WARN_ON(!(devlink->features & DEVLINK_F_RELOAD));
|
||||
err = devlink_reload(devlink, &init_net,
|
||||
DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
|
||||
DEVLINK_RELOAD_LIMIT_UNSPEC,
|
||||
|
||||
Reference in New Issue
Block a user