Skip to content

Commit

Permalink
net/mlx5: Remove counter from idr after removing it from list
Browse files Browse the repository at this point in the history
Fs_counters list can temporary become unsorted when new counters are
created/deleted concurrently. Idr is used to quickly lookup position to
insert new counter in logarithmic time. However, if new flows are
concurrently inserted during time window when flows with adjacent ids are
already removed from idr but are still present in counters list,
mlx5_fc_stats_work() observes counters list in inconsistent state, which
results following warning:

[ 1839.561955] mlx5_core 0000:81:00.0: mlx5_cmd_fc_bulk_get:587:(pid 729): Flow counter id (0x102d5) out of range (0x1c0a8..0x1c10b). Counter ignored.

Move idr_remove() call to be executed synchronously with counter deletion
from list. Extract this code to mlx5_fc_stats_remove() helper function that
is called by workqueue job handler mlx5_fc_stats_work().

Fixes: 12d6066 ("net/mlx5: Add flow counters idr")
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
  • Loading branch information
Vlad Buslov authored and Saeed Mahameed committed Oct 18, 2018
1 parent fd33071 commit 2a4c429
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ static void mlx5_fc_stats_insert(struct mlx5_core_dev *dev,
list_add_tail(&counter->list, next);
}

static void mlx5_fc_stats_remove(struct mlx5_core_dev *dev,
struct mlx5_fc *counter)
{
struct mlx5_fc_stats *fc_stats = &dev->priv.fc_stats;

list_del(&counter->list);

spin_lock(&fc_stats->counters_idr_lock);
WARN_ON(!idr_remove(&fc_stats->counters_idr, counter->id));
spin_unlock(&fc_stats->counters_idr_lock);
}

/* The function returns the last counter that was queried so the caller
* function can continue calling it till all counters are queried.
*/
Expand Down Expand Up @@ -195,7 +207,7 @@ static void mlx5_fc_stats_work(struct work_struct *work)
mlx5_fc_stats_insert(dev, counter);

llist_for_each_entry_safe(counter, tmp, dellist, dellist) {
list_del(&counter->list);
mlx5_fc_stats_remove(dev, counter);

mlx5_free_fc(dev, counter);
}
Expand Down Expand Up @@ -275,10 +287,6 @@ void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter)
return;

if (counter->aging) {
spin_lock(&fc_stats->counters_idr_lock);
WARN_ON(!idr_remove(&fc_stats->counters_idr, counter->id));
spin_unlock(&fc_stats->counters_idr_lock);

llist_add(&counter->dellist, &fc_stats->dellist);
mod_delayed_work(fc_stats->wq, &fc_stats->work, 0);
return;
Expand Down

0 comments on commit 2a4c429

Please sign in to comment.