return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)];
 }
 
-static inline void rps_lock(struct softnet_data *sd)
+static inline void rps_lock_irqsave(struct softnet_data *sd,
+                                   unsigned long *flags)
 {
-#ifdef CONFIG_RPS
-       spin_lock(&sd->input_pkt_queue.lock);
-#endif
+       if (IS_ENABLED(CONFIG_RPS))
+               spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags);
+       else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               local_irq_save(*flags);
 }
 
-static inline void rps_unlock(struct softnet_data *sd)
+static inline void rps_lock_irq_disable(struct softnet_data *sd)
 {
-#ifdef CONFIG_RPS
-       spin_unlock(&sd->input_pkt_queue.lock);
-#endif
+       if (IS_ENABLED(CONFIG_RPS))
+               spin_lock_irq(&sd->input_pkt_queue.lock);
+       else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               local_irq_disable();
+}
+
+static inline void rps_unlock_irq_restore(struct softnet_data *sd,
+                                         unsigned long *flags)
+{
+       if (IS_ENABLED(CONFIG_RPS))
+               spin_unlock_irqrestore(&sd->input_pkt_queue.lock, *flags);
+       else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               local_irq_restore(*flags);
+}
+
+static inline void rps_unlock_irq_enable(struct softnet_data *sd)
+{
+       if (IS_ENABLED(CONFIG_RPS))
+               spin_unlock_irq(&sd->input_pkt_queue.lock);
+       else if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               local_irq_enable();
 }
 
 static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev,
  * If yes, queue it to our IPI list and return 1
  * If no, return 0
  */
-static int rps_ipi_queued(struct softnet_data *sd)
+static int napi_schedule_rps(struct softnet_data *sd)
 {
-#ifdef CONFIG_RPS
        struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
 
+#ifdef CONFIG_RPS
        if (sd != mysd) {
                sd->rps_ipi_next = mysd->rps_ipi_list;
                mysd->rps_ipi_list = sd;
                return 1;
        }
 #endif /* CONFIG_RPS */
+       __napi_schedule_irqoff(&mysd->backlog);
        return 0;
 }
 
 
        sd = &per_cpu(softnet_data, cpu);
 
-       local_irq_save(flags);
-
-       rps_lock(sd);
+       rps_lock_irqsave(sd, &flags);
        if (!netif_running(skb->dev))
                goto drop;
        qlen = skb_queue_len(&sd->input_pkt_queue);
 enqueue:
                        __skb_queue_tail(&sd->input_pkt_queue, skb);
                        input_queue_tail_incr_save(sd, qtail);
-                       rps_unlock(sd);
-                       local_irq_restore(flags);
+                       rps_unlock_irq_restore(sd, &flags);
                        return NET_RX_SUCCESS;
                }
 
                /* Schedule NAPI for backlog device
                 * We can use non atomic operation since we own the queue lock
                 */
-               if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) {
-                       if (!rps_ipi_queued(sd))
-                               ____napi_schedule(sd, &sd->backlog);
-               }
+               if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state))
+                       napi_schedule_rps(sd);
                goto enqueue;
        }
 
 drop:
        sd->dropped++;
-       rps_unlock(sd);
-
-       local_irq_restore(flags);
+       rps_unlock_irq_restore(sd, &flags);
 
        atomic_long_inc(&skb->dev->rx_dropped);
        kfree_skb(skb);
        local_bh_disable();
        sd = this_cpu_ptr(&softnet_data);
 
-       local_irq_disable();
-       rps_lock(sd);
+       rps_lock_irq_disable(sd);
        skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
                if (skb->dev->reg_state == NETREG_UNREGISTERING) {
                        __skb_unlink(skb, &sd->input_pkt_queue);
                        input_queue_head_incr(sd);
                }
        }
-       rps_unlock(sd);
-       local_irq_enable();
+       rps_unlock_irq_enable(sd);
 
        skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
                if (skb->dev->reg_state == NETREG_UNREGISTERING) {
        struct softnet_data *sd = &per_cpu(softnet_data, cpu);
        bool do_flush;
 
-       local_irq_disable();
-       rps_lock(sd);
+       rps_lock_irq_disable(sd);
 
        /* as insertion into process_queue happens with the rps lock held,
         * process_queue access may race only with dequeue
         */
        do_flush = !skb_queue_empty(&sd->input_pkt_queue) ||
                   !skb_queue_empty_lockless(&sd->process_queue);
-       rps_unlock(sd);
-       local_irq_enable();
+       rps_unlock_irq_enable(sd);
 
        return do_flush;
 #endif
 
                }
 
-               local_irq_disable();
-               rps_lock(sd);
+               rps_lock_irq_disable(sd);
                if (skb_queue_empty(&sd->input_pkt_queue)) {
                        /*
                         * Inline a custom version of __napi_complete().
                        skb_queue_splice_tail_init(&sd->input_pkt_queue,
                                                   &sd->process_queue);
                }
-               rps_unlock(sd);
-               local_irq_enable();
+               rps_unlock_irq_enable(sd);
        }
 
        return work;