net: devlink: make sure that devlink_try_get() works with valid pointer during xarray...
authorJiri Pirko <jiri@nvidia.com>
Mon, 25 Jul 2022 08:29:14 +0000 (10:29 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 26 Jul 2022 20:50:50 +0000 (13:50 -0700)
commit30bab7cdb56da4819ff081ad658646f2df16c098
tree09aceb019193f4ecb67cb92ae460d122b3583a9d
parent35d099da41967f114c6472b838e12014706c26e7
net: devlink: make sure that devlink_try_get() works with valid pointer during xarray iteration

Remove dependency on devlink_mutex during devlinks xarray iteration.

The reason is that devlink_register/unregister() functions taking
devlink_mutex would deadlock during devlink reload operation of devlink
instance which registers/unregisters nested devlink instances.

The devlinks xarray consistency is ensured internally by xarray.
There is a reference taken when working with devlink using
devlink_try_get(). But there is no guarantee that devlink pointer
picked during xarray iteration is not freed before devlink_try_get()
is called.

Make sure that devlink_try_get() works with valid pointer.
Achieve it by:
1) Splitting devlink_put() so the completion is sent only
   after grace period. Completion unblocks the devlink_unregister()
   routine, which is followed-up by devlink_free()
2) During devlinks xa_array iteration, get devlink pointer from xa_array
   holding RCU read lock and taking reference using devlink_try_get()
   before unlock.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/devlink.c