nfp: flower: avoid rmmod nfp crash issues
[linux-2.6-microblaze.git] / drivers / net / ethernet / netronome / nfp / flower / conntrack.c
index 2643c4b..2967bab 100644 (file)
@@ -2131,8 +2131,6 @@ nfp_fl_ct_offload_nft_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_cls_offl
        struct nfp_fl_ct_flow_entry *ct_entry;
        struct netlink_ext_ack *extack = NULL;
 
-       ASSERT_RTNL();
-
        extack = flow->common.extack;
        switch (flow->command) {
        case FLOW_CLS_REPLACE:
@@ -2178,9 +2176,13 @@ int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb
 
        switch (type) {
        case TC_SETUP_CLSFLOWER:
-               rtnl_lock();
+               while (!mutex_trylock(&zt->priv->nfp_fl_lock)) {
+                       if (!zt->nft) /* avoid deadlock */
+                               return err;
+                       msleep(20);
+               }
                err = nfp_fl_ct_offload_nft_flow(zt, flow);
-               rtnl_unlock();
+               mutex_unlock(&zt->priv->nfp_fl_lock);
                break;
        default:
                return -EOPNOTSUPP;
@@ -2208,6 +2210,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
        struct nfp_fl_ct_flow_entry *ct_entry;
        struct nfp_fl_ct_zone_entry *zt;
        struct rhashtable *m_table;
+       struct nf_flowtable *nft;
 
        if (!ct_map_ent)
                return -ENOENT;
@@ -2226,8 +2229,12 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
                if (ct_map_ent->cookie > 0)
                        kfree(ct_map_ent);
 
-               if (!zt->pre_ct_count) {
-                       zt->nft = NULL;
+               if (!zt->pre_ct_count && zt->nft) {
+                       nft = zt->nft;
+                       zt->nft = NULL; /* avoid deadlock */
+                       nf_flow_table_offload_del_cb(nft,
+                                                    nfp_fl_ct_handle_nft_flow,
+                                                    zt);
                        nfp_fl_ct_clean_nft_entries(zt);
                }
                break;