mlxsw: spectrum: add "acl_region_rehash_interval" devlink param
authorJiri Pirko <jiri@mellanox.com>
Thu, 7 Feb 2019 11:22:55 +0000 (11:22 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Feb 2019 23:02:50 +0000 (15:02 -0800)
Expose new driver-specific "acl_region_rehash_interval" devlink param
which would allow user to alter default ACL region rehash interval.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/devlink-params-mlxsw.txt
drivers/net/ethernet/mellanox/mlxsw/core.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h

index 2c5c67a920c9fc89eba36857e445980beabebe0c..c63ea9fc7009077dfadd9e915c6c211026f9df3f 100644 (file)
@@ -1,2 +1,10 @@
 fw_load_policy         [DEVICE, GENERIC]
                        Configuration mode: driverinit
+
+acl_region_rehash_interval     [DEVICE, DRIVER-SPECIFIC]
+                       Sets an interval for periodic ACL region rehashes.
+                       The value is in milliseconds, minimal value is "3000".
+                       Value "0" disables the periodic work.
+                       The first rehash will be run right after value is set.
+                       Type: u32
+                       Configuration mode: runtime
index 4e114f35ee0dd3a3612ec2b7beb7c21d9153a46b..c8e16a3059690d6803c4a62647d72e856a41ca42 100644 (file)
@@ -394,4 +394,9 @@ static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
 
 #endif
 
+enum mlxsw_devlink_param_id {
+       MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+       MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
+};
+
 #endif
index 8dd808b7f9314a3c0cf73ac4a23afc16182af249..7c9745cecbbd5dbc498eb24fe95804c905c6109b 100644 (file)
@@ -4413,6 +4413,71 @@ static void mlxsw_sp_params_unregister(struct mlxsw_core *mlxsw_core)
                                  ARRAY_SIZE(mlxsw_sp_devlink_params));
 }
 
+static int
+mlxsw_sp_params_acl_region_rehash_intrvl_get(struct devlink *devlink, u32 id,
+                                            struct devlink_param_gset_ctx *ctx)
+{
+       struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
+       struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+
+       ctx->val.vu32 = mlxsw_sp_acl_region_rehash_intrvl_get(mlxsw_sp);
+       return 0;
+}
+
+static int
+mlxsw_sp_params_acl_region_rehash_intrvl_set(struct devlink *devlink, u32 id,
+                                            struct devlink_param_gset_ctx *ctx)
+{
+       struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
+       struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+
+       return mlxsw_sp_acl_region_rehash_intrvl_set(mlxsw_sp, ctx->val.vu32);
+}
+
+static const struct devlink_param mlxsw_sp2_devlink_params[] = {
+       DEVLINK_PARAM_DRIVER(MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
+                            "acl_region_rehash_interval",
+                            DEVLINK_PARAM_TYPE_U32,
+                            BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                            mlxsw_sp_params_acl_region_rehash_intrvl_get,
+                            mlxsw_sp_params_acl_region_rehash_intrvl_set,
+                            NULL),
+};
+
+static int mlxsw_sp2_params_register(struct mlxsw_core *mlxsw_core)
+{
+       struct devlink *devlink = priv_to_devlink(mlxsw_core);
+       union devlink_param_value value;
+       int err;
+
+       err = mlxsw_sp_params_register(mlxsw_core);
+       if (err)
+               return err;
+
+       err = devlink_params_register(devlink, mlxsw_sp2_devlink_params,
+                                     ARRAY_SIZE(mlxsw_sp2_devlink_params));
+       if (err)
+               goto err_devlink_params_register;
+
+       value.vu32 = 0;
+       devlink_param_driverinit_value_set(devlink,
+                                          MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
+                                          value);
+       return 0;
+
+err_devlink_params_register:
+       mlxsw_sp_params_unregister(mlxsw_core);
+       return err;
+}
+
+static void mlxsw_sp2_params_unregister(struct mlxsw_core *mlxsw_core)
+{
+       devlink_params_unregister(priv_to_devlink(mlxsw_core),
+                                 mlxsw_sp2_devlink_params,
+                                 ARRAY_SIZE(mlxsw_sp2_devlink_params));
+       mlxsw_sp_params_unregister(mlxsw_core);
+}
+
 static struct mlxsw_driver mlxsw_sp1_driver = {
        .kind                           = mlxsw_sp1_driver_name,
        .priv_size                      = sizeof(struct mlxsw_sp),
@@ -4461,8 +4526,8 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
        .sb_occ_tc_port_bind_get        = mlxsw_sp_sb_occ_tc_port_bind_get,
        .txhdr_construct                = mlxsw_sp_txhdr_construct,
        .resources_register             = mlxsw_sp2_resources_register,
-       .params_register                = mlxsw_sp_params_register,
-       .params_unregister              = mlxsw_sp_params_unregister,
+       .params_register                = mlxsw_sp2_params_register,
+       .params_unregister              = mlxsw_sp2_params_unregister,
        .txhdr_len                      = MLXSW_TXHDR_LEN,
        .profile                        = &mlxsw_sp2_config_profile,
        .res_query_enabled              = true,
index 3d17b4a368f42aba3603a5ed450e404d989fc90d..ceebc91f4f1ded7ff078882c38e6d008f9ef90e8 100644 (file)
@@ -690,6 +690,8 @@ struct mlxsw_sp_fid *mlxsw_sp_acl_dummy_fid(struct mlxsw_sp *mlxsw_sp);
 
 int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
+u32 mlxsw_sp_acl_region_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp);
+int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val);
 
 /* spectrum_acl_tcam.c */
 struct mlxsw_sp_acl_tcam;
index 38e02781539374da8ea6391e2e64357155d1e1f4..a146a44634e9d4cb97fbe7b9f3b7cdda2c0f5910 100644 (file)
@@ -912,3 +912,19 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp)
        mlxsw_afk_destroy(acl->afk);
        kfree(acl);
 }
+
+u32 mlxsw_sp_acl_region_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp)
+{
+       struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
+
+       return mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(mlxsw_sp,
+                                                          &acl->tcam);
+}
+
+int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val)
+{
+       struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
+
+       return mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(mlxsw_sp,
+                                                          &acl->tcam, val);
+}
index 9239ff4e94c45716d317787eeed8d63241fbc1b0..f2cb37c0d300f1f6fc5785620bcf2c5c9cc4b977 100644 (file)
@@ -24,6 +24,7 @@ size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp)
 }
 
 #define MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT 5000 /* ms */
+#define MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_MIN 3000 /* ms */
 
 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
                           struct mlxsw_sp_acl_tcam *tcam)
@@ -725,6 +726,41 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
        kfree(vregion);
 }
 
+u32 mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp,
+                                               struct mlxsw_sp_acl_tcam *tcam)
+{
+       const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+       u32 vregion_rehash_intrvl;
+
+       if (WARN_ON(!ops->region_rehash_hints_get))
+               return 0;
+       vregion_rehash_intrvl = tcam->vregion_rehash_intrvl;
+       return vregion_rehash_intrvl;
+}
+
+int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
+                                               struct mlxsw_sp_acl_tcam *tcam,
+                                               u32 val)
+{
+       const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+       struct mlxsw_sp_acl_tcam_vregion *vregion;
+
+       if (val < MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_MIN && val)
+               return -EINVAL;
+       if (WARN_ON(!ops->region_rehash_hints_get))
+               return -EOPNOTSUPP;
+       tcam->vregion_rehash_intrvl = val;
+       rtnl_lock();
+       list_for_each_entry(vregion, &tcam->vregion_list, tlist) {
+               if (val)
+                       mlxsw_core_schedule_dw(&vregion->rehash_dw, 0);
+               else
+                       cancel_delayed_work_sync(&vregion->rehash_dw);
+       }
+       rtnl_unlock();
+       return 0;
+}
+
 static int
 mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
                               struct mlxsw_sp_acl_tcam_group *group,
index 440a3483ed7bdcee9fb8c177dde863df282a251c..96bd42a9fbc33a14ff170c8b67628b8e40bbcf0c 100644 (file)
@@ -28,6 +28,11 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
                           struct mlxsw_sp_acl_tcam *tcam);
 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
                            struct mlxsw_sp_acl_tcam *tcam);
+u32 mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp,
+                                               struct mlxsw_sp_acl_tcam *tcam);
+int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
+                                               struct mlxsw_sp_acl_tcam *tcam,
+                                               u32 val);
 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
                                   struct mlxsw_sp_acl_rule_info *rulei,
                                   u32 *priority, bool fillup_priority);