diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index bea1c3f..8f6b96b 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -4663,6 +4663,9 @@ dp_netdev_queue_batches(struct dp_packet *pkt,
     packet_batch_per_flow_update(batch, pkt, mf);
 }
 
+/* Threshold to skip EMC for recirculated packets. */
+#define EMC_RECIRCT_NO_INSERT_THRESHOLD 0xFFFFF000
+
 /* Try to process all ('cnt') the 'packets' using only the exact match cache
  * 'pmd->flow_cache'. If a flow is not found for a packet 'packets[i]', the
  * miniflow is copied into 'keys' and the packet pointer is moved at the
@@ -4714,8 +4717,36 @@ emc_processing(struct dp_netdev_pmd_thread *pmd,
         key->len = 0; /* Not computed yet. */
         key->hash = dpif_netdev_packet_get_rss_hash(packet, &key->mf);
 
-        /* If EMC is disabled skip emc_lookup */
-        flow = (cur_min == 0) ? NULL: emc_lookup(flow_cache, key);
+        /*
+         * EMC lookup is skipped when one or both of the following
+         * two cases occurs:
+         *
+         *    - EMC is disabled.  This is detected from cur_min.
+         *
+         *    - The EMC occupancy exceeds EMC_RECIRCT_NO_INSERT_THRESHOLD and
+         *      the packet to be classified is being recirculated.  When this
+         *      happens also EMC insertions are skipped for recirculated
+         *      packets.  So that EMC is used just to store entries which
+         *      are hit from the 'original' packets.  This way the EMC
+         *      thrashing is mitigated with a benefit on performance.
+         */
+        if (OVS_LIKELY(cur_min)) {
+            if (!md_is_valid) {
+                flow = emc_lookup(flow_cache, key);
+            } else {
+                /* Recirculated packet. */
+                if (flow_cache->n_entries & EMC_RECIRCT_NO_INSERT_THRESHOLD) {
+                    /* EMC occupancy is over the threshold.  We skip EMC
+                     * lookup for recirculated packets. */
+                    flow = NULL;
+                } else {
+                    flow = emc_lookup(flow_cache, key);
+                }
+            }
+        } else {
+            flow = NULL;
+        }
+
         if (OVS_LIKELY(flow)) {
             dp_netdev_queue_batches(packet, flow, &key->mf, batches,
                                     n_batches);
@@ -4800,7 +4831,20 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
                                              add_actions->size);
         }
         ovs_mutex_unlock(&pmd->flow_mutex);
-        emc_probabilistic_insert(pmd, key, netdev_flow);
+        /* EMC insertion can be skipped by a probabilistic criteria or
+         * - in case of recirculated packets - depending on the number of
+         * EMC entries. */
+        if (!packet->md.recirc_id) {
+            emc_probabilistic_insert(pmd, key, netdev_flow);
+        } else {
+            /* Recirculated packets.  When EMC occupancy goes over
+             * a threshold we avoid inserting new entries. */
+            if (!(pmd->flow_cache.n_entries &
+                    EMC_RECIRCT_NO_INSERT_THRESHOLD)) {
+                /* Still under the threshold. */
+                emc_probabilistic_insert(pmd, key, netdev_flow);
+            }
+        }
     }
 }
 
@@ -4893,7 +4937,20 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
 
         flow = dp_netdev_flow_cast(rules[i]);
 
-        emc_probabilistic_insert(pmd, &keys[i], flow);
+        /* EMC insertion can be skipped by a probabilistic criteria or
+         * - in case of recirculated packets - depending on the number of
+         * EMC entries. */
+        if (!packet->md.recirc_id) {
+            emc_probabilistic_insert(pmd, &keys[i], flow);
+        } else {
+            /* Recirculated packets.  When EMC occupancy goes over
+             * a threshold we avoid inserting new entries. */
+            if (!(pmd->flow_cache.n_entries &
+                    EMC_RECIRCT_NO_INSERT_THRESHOLD)) {
+                /* Still under the threshold. */
+                emc_probabilistic_insert(pmd, &keys[i], flow);
+            }
+        }
         dp_netdev_queue_batches(packet, flow, &keys[i].mf, batches, n_batches);
     }
 
