new_sz = MLX5_MH_ACT_SZ * new_num_actions;
        old_sz = mod_hdr_acts->max_actions * MLX5_MH_ACT_SZ;
 
-       ret = krealloc(mod_hdr_acts->actions, new_sz, GFP_KERNEL);
+       if (mod_hdr_acts->is_static) {
+               ret = kzalloc(new_sz, GFP_KERNEL);
+               if (ret) {
+                       memcpy(ret, mod_hdr_acts->actions, old_sz);
+                       mod_hdr_acts->is_static = false;
+               }
+       } else {
+               ret = krealloc(mod_hdr_acts->actions, new_sz, GFP_KERNEL);
+               if (ret)
+                       memset(ret + old_sz, 0, new_sz - old_sz);
+       }
        if (!ret)
                return ERR_PTR(-ENOMEM);
 
-       memset(ret + old_sz, 0, new_sz - old_sz);
        mod_hdr_acts->actions = ret;
        mod_hdr_acts->max_actions = new_num_actions;
 
 void
 mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
 {
-       kfree(mod_hdr_acts->actions);
+       if (!mod_hdr_acts->is_static)
+               kfree(mod_hdr_acts->actions);
+
        mod_hdr_acts->actions = NULL;
        mod_hdr_acts->num_actions = 0;
        mod_hdr_acts->max_actions = 0;
 
 #include <linux/hashtable.h>
 #include <linux/mlx5/fs.h>
 
+#define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)
+
 struct mlx5e_mod_hdr_handle;
 
 struct mlx5e_tc_mod_hdr_acts {
        int num_actions;
        int max_actions;
+       bool is_static;
        void *actions;
 };
 
+#define DECLARE_MOD_HDR_ACTS_ACTIONS(name, len) \
+       u8 name[len][MLX5_MH_ACT_SZ] = {}
+
+#define DECLARE_MOD_HDR_ACTS(name, acts_arr) \
+       struct mlx5e_tc_mod_hdr_acts name = { \
+               .max_actions = ARRAY_SIZE(acts_arr), \
+               .is_static = true, \
+               .actions = acts_arr, \
+       }
+
 char *mlx5e_mod_hdr_alloc(struct mlx5_core_dev *mdev, int namespace,
                          struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
 void mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
 
 #define MLX5_CT_LABELS_BITS (mlx5e_tc_attr_to_reg_mappings[LABELS_TO_REG].mlen)
 #define MLX5_CT_LABELS_MASK GENMASK(MLX5_CT_LABELS_BITS - 1, 0)
 
+/* Statically allocate modify actions for
+ * ipv6 and port nat (5) + tuple fields (4) + nic mode zone restore (1) = 10.
+ * This will be increased dynamically if needed (for the ipv6 snat + dnat).
+ */
+#define MLX5_CT_MIN_MOD_ACTS 10
+
 #define ct_dbg(fmt, args...)\
        netdev_dbg(ct_priv->netdev, "ct_debug: " fmt "\n", ##args)
 
                                struct mlx5e_mod_hdr_handle **mh,
                                u8 zone_restore_id, bool nat)
 {
-       struct mlx5e_tc_mod_hdr_acts mod_acts = {};
+       DECLARE_MOD_HDR_ACTS_ACTIONS(actions_arr, MLX5_CT_MIN_MOD_ACTS);
+       DECLARE_MOD_HDR_ACTS(mod_acts, actions_arr);
        struct flow_action_entry *meta;
        u16 ct_state = 0;
        int err;