Merge tag 'irq-core-2020-12-23' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / kernel / softirq.c
index 617009c..d5bfd5e 100644 (file)
@@ -315,10 +315,10 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
        current->flags &= ~PF_MEMALLOC;
 
        pending = local_softirq_pending();
-       account_irq_enter_time(current);
 
        __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
        in_hardirq = lockdep_softirq_start();
+       account_softirq_enter(current);
 
 restart:
        /* Reset the pending bitmask before enabling irqs */
@@ -365,8 +365,8 @@ restart:
                wakeup_softirqd();
        }
 
+       account_softirq_exit(current);
        lockdep_softirq_end(in_hardirq);
-       account_irq_exit_time(current);
        __local_bh_enable(SOFTIRQ_OFFSET);
        WARN_ON_ONCE(in_interrupt());
        current_restore_flags(old_flags, PF_MEMALLOC);
@@ -377,16 +377,12 @@ restart:
  */
 void irq_enter_rcu(void)
 {
-       if (is_idle_task(current) && !in_interrupt()) {
-               /*
-                * Prevent raise_softirq from needlessly waking up ksoftirqd
-                * here, as softirq will be serviced on return from interrupt.
-                */
-               local_bh_disable();
+       __irq_enter_raw();
+
+       if (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET))
                tick_irq_enter();
-               _local_bh_enable();
-       }
-       __irq_enter();
+
+       account_hardirq_enter(current);
 }
 
 /**
@@ -418,7 +414,7 @@ static inline void __irq_exit_rcu(void)
 #else
        lockdep_assert_irqs_disabled();
 #endif
-       account_irq_exit_time(current);
+       account_hardirq_exit(current);
        preempt_count_sub(HARDIRQ_OFFSET);
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();