Skip to content

Commit 1b9c6b0

Browse files
Hadar Hen Ziondavem330
authored andcommitted
net/mlx4_core: Add resource tracking for device managed flow steering rules
As with other device resources, the resource tracker is needed for supporting device managed flow steering rules under SRIOV: make sure virtual functions delete only rules created by them, and clean all rules attached by a crashed VF. Signed-off-by: Hadar Hen Zion <[email protected]> Signed-off-by: Or Gerlitz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0ff1fb6 commit 1b9c6b0

File tree

2 files changed

+125
-8
lines changed

2 files changed

+125
-8
lines changed

drivers/net/ethernet/mellanox/mlx4/mlx4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ enum mlx4_resource {
149149
RES_VLAN,
150150
RES_EQ,
151151
RES_COUNTER,
152+
RES_FS_RULE,
152153
MLX4_NUM_OF_RESOURCE_TYPE
153154
};
154155

drivers/net/ethernet/mellanox/mlx4/resource_tracker.c

Lines changed: 124 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ struct res_xrcdn {
190190
int port;
191191
};
192192

193+
enum res_fs_rule_states {
194+
RES_FS_RULE_BUSY = RES_ANY_BUSY,
195+
RES_FS_RULE_ALLOCATED,
196+
};
197+
198+
struct res_fs_rule {
199+
struct res_common com;
200+
};
201+
193202
static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
194203
{
195204
struct rb_node *node = root->rb_node;
@@ -245,6 +254,7 @@ static const char *ResourceType(enum mlx4_resource rt)
245254
case RES_MAC: return "RES_MAC";
246255
case RES_EQ: return "RES_EQ";
247256
case RES_COUNTER: return "RES_COUNTER";
257+
case RES_FS_RULE: return "RES_FS_RULE";
248258
case RES_XRCD: return "RES_XRCD";
249259
default: return "Unknown resource type !!!";
250260
};
@@ -516,6 +526,20 @@ static struct res_common *alloc_xrcdn_tr(int id)
516526
return &ret->com;
517527
}
518528

529+
static struct res_common *alloc_fs_rule_tr(u64 id)
530+
{
531+
struct res_fs_rule *ret;
532+
533+
ret = kzalloc(sizeof *ret, GFP_KERNEL);
534+
if (!ret)
535+
return NULL;
536+
537+
ret->com.res_id = id;
538+
ret->com.state = RES_FS_RULE_ALLOCATED;
539+
540+
return &ret->com;
541+
}
542+
519543
static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
520544
int extra)
521545
{
@@ -549,6 +573,9 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
549573
case RES_XRCD:
550574
ret = alloc_xrcdn_tr(id);
551575
break;
576+
case RES_FS_RULE:
577+
ret = alloc_fs_rule_tr(id);
578+
break;
552579
default:
553580
return NULL;
554581
}
@@ -681,6 +708,16 @@ static int remove_xrcdn_ok(struct res_xrcdn *res)
681708
return 0;
682709
}
683710

711+
static int remove_fs_rule_ok(struct res_fs_rule *res)
712+
{
713+
if (res->com.state == RES_FS_RULE_BUSY)
714+
return -EBUSY;
715+
else if (res->com.state != RES_FS_RULE_ALLOCATED)
716+
return -EPERM;
717+
718+
return 0;
719+
}
720+
684721
static int remove_cq_ok(struct res_cq *res)
685722
{
686723
if (res->com.state == RES_CQ_BUSY)
@@ -722,6 +759,8 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
722759
return remove_counter_ok((struct res_counter *)res);
723760
case RES_XRCD:
724761
return remove_xrcdn_ok((struct res_xrcdn *)res);
762+
case RES_FS_RULE:
763+
return remove_fs_rule_ok((struct res_fs_rule *)res);
725764
default:
726765
return -EINVAL;
727766
}
@@ -2744,14 +2783,28 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
27442783
struct mlx4_cmd_mailbox *outbox,
27452784
struct mlx4_cmd_info *cmd)
27462785
{
2786+
int err;
2787+
27472788
if (dev->caps.steering_mode !=
27482789
MLX4_STEERING_MODE_DEVICE_MANAGED)
27492790
return -EOPNOTSUPP;
2750-
return mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
2751-
vhcr->in_modifier, 0,
2752-
MLX4_QP_FLOW_STEERING_ATTACH,
2753-
MLX4_CMD_TIME_CLASS_A,
2754-
MLX4_CMD_NATIVE);
2791+
2792+
err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
2793+
vhcr->in_modifier, 0,
2794+
MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
2795+
MLX4_CMD_NATIVE);
2796+
if (err)
2797+
return err;
2798+
2799+
err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0);
2800+
if (err) {
2801+
mlx4_err(dev, "Fail to add flow steering resources.\n ");
2802+
/* detach rule*/
2803+
mlx4_cmd(dev, vhcr->out_param, 0, 0,
2804+
MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
2805+
MLX4_CMD_NATIVE);
2806+
}
2807+
return err;
27552808
}
27562809

27572810
int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
@@ -2760,12 +2813,22 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
27602813
struct mlx4_cmd_mailbox *outbox,
27612814
struct mlx4_cmd_info *cmd)
27622815
{
2816+
int err;
2817+
27632818
if (dev->caps.steering_mode !=
27642819
MLX4_STEERING_MODE_DEVICE_MANAGED)
27652820
return -EOPNOTSUPP;
2766-
return mlx4_cmd(dev, vhcr->in_param, 0, 0,
2767-
MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
2768-
MLX4_CMD_NATIVE);
2821+
2822+
err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
2823+
if (err) {
2824+
mlx4_err(dev, "Fail to remove flow steering resources.\n ");
2825+
return err;
2826+
}
2827+
2828+
err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
2829+
MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
2830+
MLX4_CMD_NATIVE);
2831+
return err;
27692832
}
27702833

27712834
enum {
@@ -3177,6 +3240,58 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
31773240
spin_unlock_irq(mlx4_tlock(dev));
31783241
}
31793242

3243+
static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave)
3244+
{
3245+
struct mlx4_priv *priv = mlx4_priv(dev);
3246+
struct mlx4_resource_tracker *tracker =
3247+
&priv->mfunc.master.res_tracker;
3248+
struct list_head *fs_rule_list =
3249+
&tracker->slave_list[slave].res_list[RES_FS_RULE];
3250+
struct res_fs_rule *fs_rule;
3251+
struct res_fs_rule *tmp;
3252+
int state;
3253+
u64 base;
3254+
int err;
3255+
3256+
err = move_all_busy(dev, slave, RES_FS_RULE);
3257+
if (err)
3258+
mlx4_warn(dev, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n",
3259+
slave);
3260+
3261+
spin_lock_irq(mlx4_tlock(dev));
3262+
list_for_each_entry_safe(fs_rule, tmp, fs_rule_list, com.list) {
3263+
spin_unlock_irq(mlx4_tlock(dev));
3264+
if (fs_rule->com.owner == slave) {
3265+
base = fs_rule->com.res_id;
3266+
state = fs_rule->com.from_state;
3267+
while (state != 0) {
3268+
switch (state) {
3269+
case RES_FS_RULE_ALLOCATED:
3270+
/* detach rule */
3271+
err = mlx4_cmd(dev, base, 0, 0,
3272+
MLX4_QP_FLOW_STEERING_DETACH,
3273+
MLX4_CMD_TIME_CLASS_A,
3274+
MLX4_CMD_NATIVE);
3275+
3276+
spin_lock_irq(mlx4_tlock(dev));
3277+
rb_erase(&fs_rule->com.node,
3278+
&tracker->res_tree[RES_FS_RULE]);
3279+
list_del(&fs_rule->com.list);
3280+
spin_unlock_irq(mlx4_tlock(dev));
3281+
kfree(fs_rule);
3282+
state = 0;
3283+
break;
3284+
3285+
default:
3286+
state = 0;
3287+
}
3288+
}
3289+
}
3290+
spin_lock_irq(mlx4_tlock(dev));
3291+
}
3292+
spin_unlock_irq(mlx4_tlock(dev));
3293+
}
3294+
31803295
static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
31813296
{
31823297
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -3318,5 +3433,6 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
33183433
rem_slave_mtts(dev, slave);
33193434
rem_slave_counters(dev, slave);
33203435
rem_slave_xrcdns(dev, slave);
3436+
rem_slave_fs_rule(dev, slave);
33213437
mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
33223438
}

0 commit comments

Comments
 (0)