devlink: Set device as early as possible

All kernel devlink implementations call to devlink_alloc() during
initialization routine for specific device which is used later as
a parent device for devlink_register().

Such late device assignment causes to the situation which requires us to
call to device_register() before setting other parameters, but that call
opens devlink to the world and makes accessible for the netlink users.

Any attempt to move devlink_register() to be the last call generates the
following error due to access to the devlink->dev pointer.

[    8.758862]  devlink_nl_param_fill+0x2e8/0xe50
[    8.760305]  devlink_param_notify+0x6d/0x180
[    8.760435]  __devlink_params_register+0x2f1/0x670
[    8.760558]  devlink_params_register+0x1e/0x20

The simple change of API to set devlink device in the devlink_alloc()
instead of devlink_register() fixes all this above and ensures that
prior to call to devlink_register() everything already set.

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Leon Romanovsky
2021-08-08 21:57:43 +03:00
committed by David S. Miller
parent 94c0a6fbd5
commit 919d13a7e4
33 changed files with 91 additions and 94 deletions

View File

@@ -1544,13 +1544,15 @@ struct net *devlink_net(const struct devlink *devlink);
* Drivers that operate on real HW must use devlink_alloc() instead.
*/
struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
size_t priv_size, struct net *net);
size_t priv_size, struct net *net,
struct device *dev);
static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
size_t priv_size)
size_t priv_size,
struct device *dev)
{
return devlink_alloc_ns(ops, priv_size, &init_net);
return devlink_alloc_ns(ops, priv_size, &init_net, dev);
}
int devlink_register(struct devlink *devlink, struct device *dev);
int 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);