#include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
+#ifdef CONFIG_RFS_ACCEL
+#include <linux/cpu_rmap.h>
+#endif
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
        return IRQ_HANDLED;
 }
 
-/* This callback function is used to set affinity changes to the irq affinity
- * masks when the irq_set_affinity_notifier function is used.
- */
-static void hns3_nic_irq_affinity_notify(struct irq_affinity_notify *notify,
-                                        const cpumask_t *mask)
-{
-       struct hns3_enet_tqp_vector *tqp_vectors =
-               container_of(notify, struct hns3_enet_tqp_vector,
-                            affinity_notify);
-
-       tqp_vectors->affinity_mask = *mask;
-}
-
-static void hns3_nic_irq_affinity_release(struct kref *ref)
-{
-}
-
 static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv)
 {
        struct hns3_enet_tqp_vector *tqp_vectors;
                if (tqp_vectors->irq_init_flag != HNS3_VECTOR_INITED)
                        continue;
 
-               /* clear the affinity notifier and affinity mask */
-               irq_set_affinity_notifier(tqp_vectors->vector_irq, NULL);
+               /* clear the affinity mask */
                irq_set_affinity_hint(tqp_vectors->vector_irq, NULL);
 
                /* release the irq resource */
                        return ret;
                }
 
-               tqp_vectors->affinity_notify.notify =
-                                       hns3_nic_irq_affinity_notify;
-               tqp_vectors->affinity_notify.release =
-                                       hns3_nic_irq_affinity_release;
-               irq_set_affinity_notifier(tqp_vectors->vector_irq,
-                                         &tqp_vectors->affinity_notify);
                irq_set_affinity_hint(tqp_vectors->vector_irq,
                                      &tqp_vectors->affinity_mask);
 
        hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg);
 }
 
+static void hns3_free_rx_cpu_rmap(struct net_device *netdev)
+{
+#ifdef CONFIG_RFS_ACCEL
+       free_irq_cpu_rmap(netdev->rx_cpu_rmap);
+       netdev->rx_cpu_rmap = NULL;
+#endif
+}
+
+static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
+{
+#ifdef CONFIG_RFS_ACCEL
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hns3_enet_tqp_vector *tqp_vector;
+       int i, ret;
+
+       if (!netdev->rx_cpu_rmap) {
+               netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->vector_num);
+               if (!netdev->rx_cpu_rmap)
+                       return -ENOMEM;
+       }
+
+       for (i = 0; i < priv->vector_num; i++) {
+               tqp_vector = &priv->tqp_vector[i];
+               ret = irq_cpu_rmap_add(netdev->rx_cpu_rmap,
+                                      tqp_vector->vector_irq);
+               if (ret) {
+                       hns3_free_rx_cpu_rmap(netdev);
+                       return ret;
+               }
+       }
+#endif
+       return 0;
+}
+
 static int hns3_nic_net_up(struct net_device *netdev)
 {
        struct hns3_nic_priv *priv = netdev_priv(netdev);
        if (ret)
                return ret;
 
+       /* the device can work without cpu rmap, only aRFS needs it */
+       ret = hns3_set_rx_cpu_rmap(netdev);
+       if (ret)
+               netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret);
+
        /* get irq resource for all vectors */
        ret = hns3_nic_init_irq(priv);
        if (ret) {
                netdev_err(netdev, "hns init irq failed! ret=%d\n", ret);
-               return ret;
+               goto free_rmap;
        }
 
        clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
                hns3_vector_disable(&priv->tqp_vector[j]);
 
        hns3_nic_uninit_irq(priv);
-
+free_rmap:
+       hns3_free_rx_cpu_rmap(netdev);
        return ret;
 }
 
        if (ops->stop)
                ops->stop(priv->ae_handle);
 
+       hns3_free_rx_cpu_rmap(netdev);
+
        /* free irq resources */
        hns3_nic_uninit_irq(priv);
 
                hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
 
                if (tqp_vector->irq_init_flag == HNS3_VECTOR_INITED) {
-                       irq_set_affinity_notifier(tqp_vector->vector_irq,
-                                                 NULL);
                        irq_set_affinity_hint(tqp_vector->vector_irq, NULL);
                        free_irq(tqp_vector->vector_irq, tqp_vector);
                        tqp_vector->irq_init_flag = HNS3_VECTOR_NOT_INITED;