diff options
| author | Gal Pressman <galp@mellanox.com> | 2017-11-28 04:58:51 -0500 |
|---|---|---|
| committer | Saeed Mahameed <saeedm@mellanox.com> | 2017-12-28 17:43:52 -0500 |
| commit | 9b93ab981e3bf62ff95a8cbb6faf652cd400decd (patch) | |
| tree | 34e27bb7871cc59e32d92c0d721d5d386c02db74 | |
| parent | 4484e2994887cf57815c8e55ac1f9eaf0036928e (diff) | |
net/mlx5: Separate ingress/egress namespaces for each vport
Each vport has its own root flow table for the ACL flow tables and root
flow table is per namespace, therefore we should create a namespace for
each vport.
Fixes: efdc810ba39d ("net/mlx5: Flow steering, Add vport ACL support")
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 10 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 145 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 4 | ||||
| -rw-r--r-- | include/linux/mlx5/fs.h | 4 |
4 files changed, 133 insertions, 30 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index cdf65ed8714c..7649e36653d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | |||
| @@ -867,9 +867,10 @@ static int esw_vport_enable_egress_acl(struct mlx5_eswitch *esw, | |||
| 867 | esw_debug(dev, "Create vport[%d] egress ACL log_max_size(%d)\n", | 867 | esw_debug(dev, "Create vport[%d] egress ACL log_max_size(%d)\n", |
| 868 | vport->vport, MLX5_CAP_ESW_EGRESS_ACL(dev, log_max_ft_size)); | 868 | vport->vport, MLX5_CAP_ESW_EGRESS_ACL(dev, log_max_ft_size)); |
| 869 | 869 | ||
| 870 | root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS); | 870 | root_ns = mlx5_get_flow_vport_acl_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS, |
| 871 | vport->vport); | ||
| 871 | if (!root_ns) { | 872 | if (!root_ns) { |
| 872 | esw_warn(dev, "Failed to get E-Switch egress flow namespace\n"); | 873 | esw_warn(dev, "Failed to get E-Switch egress flow namespace for vport (%d)\n", vport->vport); |
| 873 | return -EOPNOTSUPP; | 874 | return -EOPNOTSUPP; |
| 874 | } | 875 | } |
| 875 | 876 | ||
| @@ -984,9 +985,10 @@ static int esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw, | |||
| 984 | esw_debug(dev, "Create vport[%d] ingress ACL log_max_size(%d)\n", | 985 | esw_debug(dev, "Create vport[%d] ingress ACL log_max_size(%d)\n", |
| 985 | vport->vport, MLX5_CAP_ESW_INGRESS_ACL(dev, log_max_ft_size)); | 986 | vport->vport, MLX5_CAP_ESW_INGRESS_ACL(dev, log_max_ft_size)); |
| 986 | 987 | ||
| 987 | root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS); | 988 | root_ns = mlx5_get_flow_vport_acl_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS, |
| 989 | vport->vport); | ||
| 988 | if (!root_ns) { | 990 | if (!root_ns) { |
| 989 | esw_warn(dev, "Failed to get E-Switch ingress flow namespace\n"); | 991 | esw_warn(dev, "Failed to get E-Switch ingress flow namespace for vport (%d)\n", vport->vport); |
| 990 | return -EOPNOTSUPP; | 992 | return -EOPNOTSUPP; |
| 991 | } | 993 | } |
| 992 | 994 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5e786e29f93a..45e75b1010f7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
| @@ -2014,16 +2014,6 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, | |||
| 2014 | return &steering->fdb_root_ns->ns; | 2014 | return &steering->fdb_root_ns->ns; |
| 2015 | else | 2015 | else |
| 2016 | return NULL; | 2016 | return NULL; |
| 2017 | case MLX5_FLOW_NAMESPACE_ESW_EGRESS: | ||
| 2018 | if (steering->esw_egress_root_ns) | ||
| 2019 | return &steering->esw_egress_root_ns->ns; | ||
| 2020 | else | ||
| 2021 | return NULL; | ||
| 2022 | case MLX5_FLOW_NAMESPACE_ESW_INGRESS: | ||
| 2023 | if (steering->esw_ingress_root_ns) | ||
| 2024 | return &steering->esw_ingress_root_ns->ns; | ||
| 2025 | else | ||
| 2026 | return NULL; | ||
| 2027 | case MLX5_FLOW_NAMESPACE_SNIFFER_RX: | 2017 | case MLX5_FLOW_NAMESPACE_SNIFFER_RX: |
| 2028 | if (steering->sniffer_rx_root_ns) | 2018 | if (steering->sniffer_rx_root_ns) |
| 2029 | return &steering->sniffer_rx_root_ns->ns; | 2019 | return &steering->sniffer_rx_root_ns->ns; |
| @@ -2054,6 +2044,33 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, | |||
| 2054 | } | 2044 | } |
| 2055 | EXPORT_SYMBOL(mlx5_get_flow_namespace); | 2045 | EXPORT_SYMBOL(mlx5_get_flow_namespace); |
| 2056 | 2046 | ||
| 2047 | struct mlx5_flow_namespace *mlx5_get_flow_vport_acl_namespace(struct mlx5_core_dev *dev, | ||
| 2048 | enum mlx5_flow_namespace_type type, | ||
| 2049 | int vport) | ||
| 2050 | { | ||
| 2051 | struct mlx5_flow_steering *steering = dev->priv.steering; | ||
| 2052 | |||
| 2053 | if (!steering || vport >= MLX5_TOTAL_VPORTS(dev)) | ||
| 2054 | return NULL; | ||
| 2055 | |||
| 2056 | switch (type) { | ||
| 2057 | case MLX5_FLOW_NAMESPACE_ESW_EGRESS: | ||
| 2058 | if (steering->esw_egress_root_ns && | ||
| 2059 | steering->esw_egress_root_ns[vport]) | ||
| 2060 | return &steering->esw_egress_root_ns[vport]->ns; | ||
| 2061 | else | ||
| 2062 | return NULL; | ||
| 2063 | case MLX5_FLOW_NAMESPACE_ESW_INGRESS: | ||
| 2064 | if (steering->esw_ingress_root_ns && | ||
| 2065 | steering->esw_ingress_root_ns[vport]) | ||
| 2066 | return &steering->esw_ingress_root_ns[vport]->ns; | ||
| 2067 | else | ||
| 2068 | return NULL; | ||
| 2069 | default: | ||
| 2070 | return NULL; | ||
| 2071 | } | ||
| 2072 | } | ||
| 2073 | |||
| 2057 | static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, | 2074 | static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, |
| 2058 | unsigned int prio, int num_levels) | 2075 | unsigned int prio, int num_levels) |
| 2059 | { | 2076 | { |
| @@ -2331,13 +2348,41 @@ static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns) | |||
| 2331 | clean_tree(&root_ns->ns.node); | 2348 | clean_tree(&root_ns->ns.node); |
| 2332 | } | 2349 | } |
| 2333 | 2350 | ||
| 2351 | static void cleanup_egress_acls_root_ns(struct mlx5_core_dev *dev) | ||
| 2352 | { | ||
| 2353 | struct mlx5_flow_steering *steering = dev->priv.steering; | ||
| 2354 | int i; | ||
| 2355 | |||
| 2356 | if (!steering->esw_egress_root_ns) | ||
| 2357 | return; | ||
| 2358 | |||
| 2359 | for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) | ||
| 2360 | cleanup_root_ns(steering->esw_egress_root_ns[i]); | ||
| 2361 | |||
| 2362 | kfree(steering->esw_egress_root_ns); | ||
| 2363 | } | ||
| 2364 | |||
| 2365 | static void cleanup_ingress_acls_root_ns(struct mlx5_core_dev *dev) | ||
| 2366 | { | ||
| 2367 | struct mlx5_flow_steering *steering = dev->priv.steering; | ||
| 2368 | int i; | ||
| 2369 | |||
| 2370 | if (!steering->esw_ingress_root_ns) | ||
| 2371 | return; | ||
| 2372 | |||
| 2373 | for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) | ||
| 2374 | cleanup_root_ns(steering->esw_ingress_root_ns[i]); | ||
| 2375 | |||
| 2376 | kfree(steering->esw_ingress_root_ns); | ||
| 2377 | } | ||
| 2378 | |||
| 2334 | void mlx5_cleanup_fs(struct mlx5_core_dev *dev) | 2379 | void mlx5_cleanup_fs(struct mlx5_core_dev *dev) |
| 2335 | { | 2380 | { |
| 2336 | struct mlx5_flow_steering *steering = dev->priv.steering; | 2381 | struct mlx5_flow_steering *steering = dev->priv.steering; |
| 2337 | 2382 | ||
| 2338 | cleanup_root_ns(steering->root_ns); | 2383 | cleanup_root_ns(steering->root_ns); |
| 2339 | cleanup_root_ns(steering->esw_egress_root_ns); | 2384 | cleanup_egress_acls_root_ns(dev); |
| 2340 | cleanup_root_ns(steering->esw_ingress_root_ns); | 2385 | cleanup_ingress_acls_root_ns(dev); |
| 2341 | cleanup_root_ns(steering->fdb_root_ns); | 2386 | cleanup_root_ns(steering->fdb_root_ns); |
| 2342 | cleanup_root_ns(steering->sniffer_rx_root_ns); | 2387 | cleanup_root_ns(steering->sniffer_rx_root_ns); |
| 2343 | cleanup_root_ns(steering->sniffer_tx_root_ns); | 2388 | cleanup_root_ns(steering->sniffer_tx_root_ns); |
| @@ -2406,34 +2451,86 @@ out_err: | |||
| 2406 | return PTR_ERR(prio); | 2451 | return PTR_ERR(prio); |
| 2407 | } | 2452 | } |
| 2408 | 2453 | ||
| 2409 | static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering) | 2454 | static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering, int vport) |
| 2410 | { | 2455 | { |
| 2411 | struct fs_prio *prio; | 2456 | struct fs_prio *prio; |
| 2412 | 2457 | ||
| 2413 | steering->esw_egress_root_ns = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL); | 2458 | steering->esw_egress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL); |
| 2414 | if (!steering->esw_egress_root_ns) | 2459 | if (!steering->esw_egress_root_ns[vport]) |
| 2415 | return -ENOMEM; | 2460 | return -ENOMEM; |
| 2416 | 2461 | ||
| 2417 | /* create 1 prio*/ | 2462 | /* create 1 prio*/ |
| 2418 | prio = fs_create_prio(&steering->esw_egress_root_ns->ns, 0, | 2463 | prio = fs_create_prio(&steering->esw_egress_root_ns[vport]->ns, 0, 1); |
| 2419 | MLX5_TOTAL_VPORTS(steering->dev)); | ||
| 2420 | return PTR_ERR_OR_ZERO(prio); | 2464 | return PTR_ERR_OR_ZERO(prio); |
| 2421 | } | 2465 | } |
| 2422 | 2466 | ||
| 2423 | static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering) | 2467 | static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering, int vport) |
| 2424 | { | 2468 | { |
| 2425 | struct fs_prio *prio; | 2469 | struct fs_prio *prio; |
| 2426 | 2470 | ||
| 2427 | steering->esw_ingress_root_ns = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL); | 2471 | steering->esw_ingress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL); |
| 2428 | if (!steering->esw_ingress_root_ns) | 2472 | if (!steering->esw_ingress_root_ns[vport]) |
| 2429 | return -ENOMEM; | 2473 | return -ENOMEM; |
| 2430 | 2474 | ||
| 2431 | /* create 1 prio*/ | 2475 | /* create 1 prio*/ |
| 2432 | prio = fs_create_prio(&steering->esw_ingress_root_ns->ns, 0, | 2476 | prio = fs_create_prio(&steering->esw_ingress_root_ns[vport]->ns, 0, 1); |
| 2433 | MLX5_TOTAL_VPORTS(steering->dev)); | ||
| 2434 | return PTR_ERR_OR_ZERO(prio); | 2477 | return PTR_ERR_OR_ZERO(prio); |
| 2435 | } | 2478 | } |
| 2436 | 2479 | ||
| 2480 | static int init_egress_acls_root_ns(struct mlx5_core_dev *dev) | ||
| 2481 | { | ||
| 2482 | struct mlx5_flow_steering *steering = dev->priv.steering; | ||
| 2483 | int err; | ||
| 2484 | int i; | ||
| 2485 | |||
| 2486 | steering->esw_egress_root_ns = kcalloc(MLX5_TOTAL_VPORTS(dev), | ||
| 2487 | sizeof(*steering->esw_egress_root_ns), | ||
| 2488 | GFP_KERNEL); | ||
| 2489 | if (!steering->esw_egress_root_ns) | ||
| 2490 | return -ENOMEM; | ||
| 2491 | |||
| 2492 | for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) { | ||
| 2493 | err = init_egress_acl_root_ns(steering, i); | ||
| 2494 | if (err) | ||
| 2495 | goto cleanup_root_ns; | ||
| 2496 | } | ||
| 2497 | |||
| 2498 | return 0; | ||
| 2499 | |||
| 2500 | cleanup_root_ns: | ||
| 2501 | for (i--; i >= 0; i--) | ||
| 2502 | cleanup_root_ns(steering->esw_egress_root_ns[i]); | ||
| 2503 | kfree(steering->esw_egress_root_ns); | ||
| 2504 | return err; | ||
| 2505 | } | ||
| 2506 | |||
| 2507 | static int init_ingress_acls_root_ns(struct mlx5_core_dev *dev) | ||
| 2508 | { | ||
| 2509 | struct mlx5_flow_steering *steering = dev->priv.steering; | ||
| 2510 | int err; | ||
| 2511 | int i; | ||
| 2512 | |||
| 2513 | steering->esw_ingress_root_ns = kcalloc(MLX5_TOTAL_VPORTS(dev), | ||
| 2514 | sizeof(*steering->esw_ingress_root_ns), | ||
| 2515 | GFP_KERNEL); | ||
| 2516 | if (!steering->esw_ingress_root_ns) | ||
| 2517 | return -ENOMEM; | ||
| 2518 | |||
| 2519 | for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) { | ||
| 2520 | err = init_ingress_acl_root_ns(steering, i); | ||
| 2521 | if (err) | ||
| 2522 | goto cleanup_root_ns; | ||
| 2523 | } | ||
| 2524 | |||
| 2525 | return 0; | ||
| 2526 | |||
| 2527 | cleanup_root_ns: | ||
| 2528 | for (i--; i >= 0; i--) | ||
| 2529 | cleanup_root_ns(steering->esw_ingress_root_ns[i]); | ||
| 2530 | kfree(steering->esw_ingress_root_ns); | ||
| 2531 | return err; | ||
| 2532 | } | ||
| 2533 | |||
| 2437 | int mlx5_init_fs(struct mlx5_core_dev *dev) | 2534 | int mlx5_init_fs(struct mlx5_core_dev *dev) |
| 2438 | { | 2535 | { |
| 2439 | struct mlx5_flow_steering *steering; | 2536 | struct mlx5_flow_steering *steering; |
| @@ -2476,12 +2573,12 @@ int mlx5_init_fs(struct mlx5_core_dev *dev) | |||
| 2476 | goto err; | 2573 | goto err; |
| 2477 | } | 2574 | } |
| 2478 | if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) { | 2575 | if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) { |
| 2479 | err = init_egress_acl_root_ns(steering); | 2576 | err = init_egress_acls_root_ns(dev); |
| 2480 | if (err) | 2577 | if (err) |
| 2481 | goto err; | 2578 | goto err; |
| 2482 | } | 2579 | } |
| 2483 | if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) { | 2580 | if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) { |
| 2484 | err = init_ingress_acl_root_ns(steering); | 2581 | err = init_ingress_acls_root_ns(dev); |
| 2485 | if (err) | 2582 | if (err) |
| 2486 | goto err; | 2583 | goto err; |
| 2487 | } | 2584 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h index 397d24a621a4..3e571045626f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | |||
| @@ -71,8 +71,8 @@ struct mlx5_flow_steering { | |||
| 71 | struct kmem_cache *ftes_cache; | 71 | struct kmem_cache *ftes_cache; |
| 72 | struct mlx5_flow_root_namespace *root_ns; | 72 | struct mlx5_flow_root_namespace *root_ns; |
| 73 | struct mlx5_flow_root_namespace *fdb_root_ns; | 73 | struct mlx5_flow_root_namespace *fdb_root_ns; |
| 74 | struct mlx5_flow_root_namespace *esw_egress_root_ns; | 74 | struct mlx5_flow_root_namespace **esw_egress_root_ns; |
| 75 | struct mlx5_flow_root_namespace *esw_ingress_root_ns; | 75 | struct mlx5_flow_root_namespace **esw_ingress_root_ns; |
| 76 | struct mlx5_flow_root_namespace *sniffer_tx_root_ns; | 76 | struct mlx5_flow_root_namespace *sniffer_tx_root_ns; |
| 77 | struct mlx5_flow_root_namespace *sniffer_rx_root_ns; | 77 | struct mlx5_flow_root_namespace *sniffer_rx_root_ns; |
| 78 | }; | 78 | }; |
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h index b25e7baa273e..a0b48afcb422 100644 --- a/include/linux/mlx5/fs.h +++ b/include/linux/mlx5/fs.h | |||
| @@ -95,6 +95,10 @@ struct mlx5_flow_destination { | |||
| 95 | struct mlx5_flow_namespace * | 95 | struct mlx5_flow_namespace * |
| 96 | mlx5_get_flow_namespace(struct mlx5_core_dev *dev, | 96 | mlx5_get_flow_namespace(struct mlx5_core_dev *dev, |
| 97 | enum mlx5_flow_namespace_type type); | 97 | enum mlx5_flow_namespace_type type); |
| 98 | struct mlx5_flow_namespace * | ||
| 99 | mlx5_get_flow_vport_acl_namespace(struct mlx5_core_dev *dev, | ||
| 100 | enum mlx5_flow_namespace_type type, | ||
| 101 | int vport); | ||
| 98 | 102 | ||
| 99 | struct mlx5_flow_table * | 103 | struct mlx5_flow_table * |
| 100 | mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns, | 104 | mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns, |
