- const struct net_device *netdev = fs->netdev;
- u32 prio = 0;
- int err;
-
- ct_matchers->ipv4_tcp = mlx5_ct_fs_smfs_matcher_create(fs, tbl, true, true, prio);
- if (IS_ERR(ct_matchers->ipv4_tcp)) {
- err = PTR_ERR(ct_matchers->ipv4_tcp);
- netdev_warn(netdev,
- "%s, failed to create ipv4 tcp matcher, err: %d\n",
- INIT_ERR_PREFIX, err);
- return err;
- }
-
- ++prio;
- ct_matchers->ipv4_udp = mlx5_ct_fs_smfs_matcher_create(fs, tbl, true, false, prio);
- if (IS_ERR(ct_matchers->ipv4_udp)) {
- err = PTR_ERR(ct_matchers->ipv4_udp);
- netdev_warn(netdev,
- "%s, failed to create ipv4 udp matcher, err: %d\n",
- INIT_ERR_PREFIX, err);
- goto err_matcher_ipv4_udp;
+ struct mlx5_ct_fs_smfs *fs_smfs = mlx5_ct_fs_priv(fs);
+ struct mlx5_ct_fs_smfs_matcher *m, *smfs_matcher;
+ struct mlx5_ct_fs_smfs_matchers *matchers;
+ struct mlx5dr_matcher *dr_matcher;
+ struct mlx5dr_table *tbl;
+ struct list_head *prev;
+ int prio;
+
+ matchers = nat ? &fs_smfs->matchers_nat : &fs_smfs->matchers;
+ smfs_matcher = &matchers->smfs_matchers[ipv4 * 2 + tcp];
+
+ if (refcount_inc_not_zero(&smfs_matcher->ref))
+ return smfs_matcher;
+
+ mutex_lock(&fs_smfs->lock);
+
+ /* Retry with lock, as another thread might have already created the relevant matcher
+ * till we acquired the lock
+ */
+ if (refcount_inc_not_zero(&smfs_matcher->ref))
+ goto out_unlock;
+
+ // Find next available priority in sorted used list
+ prio = 0;
+ prev = &matchers->used;
+ list_for_each_entry(m, &matchers->used, list) {
+ prev = &m->list;
+
+ if (m->prio == prio)
+ prio = m->prio + 1;
+ else
+ break;