mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 12:16:41 +00:00
devlink: bump the instance index directly when iterating
xa_find_after() is designed to handle multi-index entries correctly. If a xarray has two entries one which spans indexes 0-3 and one at index 4 xa_find_after(0) will return the entry at index 4. Having to juggle the two callbacks, however, is unnecessary in case of the devlink xarray, as there is 1:1 relationship with indexes. Always use xa_find() and increment the index manually. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6b754d7bd0
commit
d772781964
@ -91,16 +91,13 @@ void devlink_put(struct devlink *devlink)
|
|||||||
call_rcu(&devlink->rcu, __devlink_put_rcu);
|
call_rcu(&devlink->rcu, __devlink_put_rcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct devlink *
|
struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp)
|
||||||
devlinks_xa_find_get(struct net *net, unsigned long *indexp,
|
|
||||||
void * (*xa_find_fn)(struct xarray *, unsigned long *,
|
|
||||||
unsigned long, xa_mark_t))
|
|
||||||
{
|
{
|
||||||
struct devlink *devlink;
|
struct devlink *devlink = NULL;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
retry:
|
retry:
|
||||||
devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
|
devlink = xa_find(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
|
||||||
if (!devlink)
|
if (!devlink)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
@ -109,31 +106,21 @@ devlinks_xa_find_get(struct net *net, unsigned long *indexp,
|
|||||||
* This prevents live-lock of devlink_unregister() wait for completion.
|
* This prevents live-lock of devlink_unregister() wait for completion.
|
||||||
*/
|
*/
|
||||||
if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING))
|
if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING))
|
||||||
goto retry;
|
goto next;
|
||||||
|
|
||||||
/* For a possible retry, the xa_find_after() should be always used */
|
|
||||||
xa_find_fn = xa_find_after;
|
|
||||||
if (!devlink_try_get(devlink))
|
if (!devlink_try_get(devlink))
|
||||||
goto retry;
|
goto next;
|
||||||
if (!net_eq(devlink_net(devlink), net)) {
|
if (!net_eq(devlink_net(devlink), net)) {
|
||||||
devlink_put(devlink);
|
devlink_put(devlink);
|
||||||
goto retry;
|
goto next;
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return devlink;
|
return devlink;
|
||||||
}
|
|
||||||
|
|
||||||
struct devlink *
|
next:
|
||||||
devlinks_xa_find_get_first(struct net *net, unsigned long *indexp)
|
(*indexp)++;
|
||||||
{
|
goto retry;
|
||||||
return devlinks_xa_find_get(net, indexp, xa_find);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct devlink *
|
|
||||||
devlinks_xa_find_get_next(struct net *net, unsigned long *indexp)
|
|
||||||
{
|
|
||||||
return devlinks_xa_find_get(net, indexp, xa_find_after);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,18 +82,9 @@ extern struct genl_family devlink_nl_family;
|
|||||||
* in loop body in order to release the reference.
|
* in loop body in order to release the reference.
|
||||||
*/
|
*/
|
||||||
#define devlinks_xa_for_each_registered_get(net, index, devlink) \
|
#define devlinks_xa_for_each_registered_get(net, index, devlink) \
|
||||||
for (index = 0, \
|
for (index = 0; (devlink = devlinks_xa_find_get(net, &index)); index++)
|
||||||
devlink = devlinks_xa_find_get_first(net, &index); \
|
|
||||||
devlink; devlink = devlinks_xa_find_get_next(net, &index))
|
|
||||||
|
|
||||||
struct devlink *
|
struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp);
|
||||||
devlinks_xa_find_get(struct net *net, unsigned long *indexp,
|
|
||||||
void * (*xa_find_fn)(struct xarray *, unsigned long *,
|
|
||||||
unsigned long, xa_mark_t));
|
|
||||||
struct devlink *
|
|
||||||
devlinks_xa_find_get_first(struct net *net, unsigned long *indexp);
|
|
||||||
struct devlink *
|
|
||||||
devlinks_xa_find_get_next(struct net *net, unsigned long *indexp);
|
|
||||||
|
|
||||||
/* Netlink */
|
/* Netlink */
|
||||||
#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
|
#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
|
||||||
@ -135,7 +126,7 @@ struct devlink_gen_cmd {
|
|||||||
*/
|
*/
|
||||||
#define devlink_dump_for_each_instance_get(msg, state, devlink) \
|
#define devlink_dump_for_each_instance_get(msg, state, devlink) \
|
||||||
for (; (devlink = devlinks_xa_find_get(sock_net(msg->sk), \
|
for (; (devlink = devlinks_xa_find_get(sock_net(msg->sk), \
|
||||||
&state->instance, xa_find)); \
|
&state->instance)); \
|
||||||
state->instance++, state->idx = 0)
|
state->instance++, state->idx = 0)
|
||||||
|
|
||||||
extern const struct genl_small_ops devlink_nl_ops[56];
|
extern const struct genl_small_ops devlink_nl_ops[56];
|
||||||
|
Loading…
Reference in New Issue
Block a user