void *type_data)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
+       struct flow_block_offload *f = type_data;
 
        switch (type) {
 #ifdef CONFIG_MLX5_ESWITCH
        case TC_SETUP_BLOCK:
+               f->unlocked_driver_cb = true;
                return flow_block_cb_setup_simple(type_data,
                                                  &mlx5e_block_cb_list,
                                                  mlx5e_setup_tc_block_cb,
 
        if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
                return -EOPNOTSUPP;
 
+       f->unlocked_driver_cb = true;
        f->driver_block_list = &mlx5e_block_cb_list;
 
        switch (f->command) {
                              void *type_data)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
+       struct flow_block_offload *f = type_data;
 
        switch (type) {
        case TC_SETUP_BLOCK:
+               f->unlocked_driver_cb = true;
                return flow_block_cb_setup_simple(type_data,
                                                  &mlx5e_rep_block_cb_list,
                                                  mlx5e_rep_setup_tc_cb,
 
        enum flow_block_command command;
        enum flow_block_binder_type binder_type;
        bool block_shared;
+       bool unlocked_driver_cb;
        struct net *net;
        struct flow_block *block;
        struct list_head cb_list;
 
        bool keep_dst;
        atomic_t offloadcnt; /* Number of oddloaded filters */
        unsigned int nooffloaddevcnt; /* Number of devs unable to do offload */
+       unsigned int lockeddevcnt; /* Number of devs that require rtnl lock. */
        struct {
                struct tcf_chain *chain;
                struct list_head filter_chain_list;
 
                                                  bo->extack);
                if (err)
                        goto err_unroll;
+               if (!bo->unlocked_driver_cb)
+                       block->lockeddevcnt++;
 
                i++;
        }
                                                    block_cb->cb_priv, false,
                                                    tcf_block_offload_in_use(block),
                                                    NULL);
+                       if (!bo->unlocked_driver_cb)
+                               block->lockeddevcnt--;
                }
                flow_block_cb_free(block_cb);
        }
                                            NULL);
                list_del(&block_cb->list);
                flow_block_cb_free(block_cb);
+               if (!bo->unlocked_driver_cb)
+                       block->lockeddevcnt--;
        }
 }