--- zzzz-none-000/linux-4.1.52/kernel/softirq.c 2018-05-28 02:26:45.000000000 +0000 +++ bcm63-7530ax-731/linux-4.1.52/kernel/softirq.c 2022-03-02 11:37:13.000000000 +0000 @@ -26,9 +26,14 @@ #include #include #include +#include +#include #define CREATE_TRACE_POINTS #include +#if defined(CONFIG_BCM_KF_BUZZZ) && defined(CONFIG_BUZZZ_KEVT) +#include +#endif /* - No shared variables, all the data are CPU local. @@ -77,6 +82,19 @@ wake_up_process(tsk); } +#if defined(CONFIG_BCM_KF_ARM_BCM963XX) && defined(CONFIG_BCM947189) +/* + * If ksoftirqd is scheduled, we do not want to process pending softirqs + * right now. Let ksoftirqd handle this at its own rate, to get fairness. + */ +static bool ksoftirqd_running(void) +{ + struct task_struct *tsk = __this_cpu_read(ksoftirqd); + + return tsk && (tsk->state == TASK_RUNNING); +} +#endif + /* * preempt_count and SOFTIRQ_OFFSET usage: * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving @@ -249,6 +267,7 @@ __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET); in_hardirq = lockdep_softirq_start(); + avm_sum_softirq_enter(); restart: /* Reset the pending bitmask before enabling irqs */ @@ -259,6 +278,7 @@ h = softirq_vec; while ((softirq_bit = ffs(pending))) { + struct _runtime_stat *pts; unsigned int vec_nr; int prev_count; @@ -269,9 +289,21 @@ kstat_incr_softirqs_this_cpu(vec_nr); + avm_simple_profiling_log(avm_profile_data_type_sw_irq_begin, + (unsigned long)(h->action), (unsigned int)h); trace_softirq_entry(vec_nr); + pts = avm_softirq_enter(vec_nr); +#if defined(CONFIG_BCM_KF_BUZZZ) && defined(CONFIG_BUZZZ_KEVT) + BUZZZ_KNL3(SIRQ_ENT, 0, h->action); +#endif h->action(h); +#if defined(CONFIG_BCM_KF_BUZZZ) && defined(CONFIG_BUZZZ_KEVT) + BUZZZ_KNL3(SIRQ_EXT, 0, h->action); +#endif + avm_softirq_leave(pts); trace_softirq_exit(vec_nr); + avm_simple_profiling_log(avm_profile_data_type_sw_irq_end, + (unsigned long)(h->action), (unsigned int)h); if (unlikely(prev_count != preempt_count())) { pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n", vec_nr, softirq_to_name[vec_nr], h->action, @@ -294,6 +326,7 @@ wakeup_softirqd(); } + avm_sum_softirq_leave(); lockdep_softirq_end(in_hardirq); account_irq_exit_time(current); __local_bh_enable(SOFTIRQ_OFFSET); @@ -312,8 +345,11 @@ local_irq_save(flags); pending = local_softirq_pending(); - +#if defined(CONFIG_BCM_KF_ARM_BCM963XX) && defined(CONFIG_BCM947189) + if (pending && !ksoftirqd_running()) +#else if (pending) +#endif do_softirq_own_stack(); local_irq_restore(flags); @@ -340,6 +376,10 @@ static inline void invoke_softirq(void) { +#if defined(CONFIG_BCM_KF_ARM_BCM963XX) && defined(CONFIG_BCM947189) + if (ksoftirqd_running()) + return; +#endif if (!force_irqthreads) { #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK /* @@ -454,6 +494,8 @@ t->next = NULL; *__this_cpu_read(tasklet_vec.tail) = t; __this_cpu_write(tasklet_vec.tail, &(t->next)); + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_begin, + (unsigned long)(t->func), TASKLET_SOFTIRQ); raise_softirq_irqoff(TASKLET_SOFTIRQ); local_irq_restore(flags); } @@ -467,6 +509,8 @@ t->next = NULL; *__this_cpu_read(tasklet_hi_vec.tail) = t; __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_begin, + (unsigned long)(t->func), HI_SOFTIRQ); raise_softirq_irqoff(HI_SOFTIRQ); local_irq_restore(flags); } @@ -493,6 +537,7 @@ local_irq_enable(); while (list) { + struct _runtime_stat *pfunc_stat; struct tasklet_struct *t = list; list = list->next; @@ -502,7 +547,16 @@ if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_end, + (unsigned long)(t->func), TASKLET_SOFTIRQ); + avm_simple_profiling_log(avm_profile_data_type_tasklet_begin, + (unsigned long)(t->func), (unsigned int)(t->data)); + pfunc_stat = avm_taskletfunc_enter(t->func, TASKLET_SOFTIRQ); t->func(t->data); + avm_taskletfunc_leave(pfunc_stat); + avm_simple_profiling_log(avm_profile_data_type_tasklet_end, + (unsigned long)(t->func), (unsigned int)(t->data)); + tasklet_unlock(t); continue; } @@ -529,6 +583,7 @@ local_irq_enable(); while (list) { + struct _runtime_stat *pfunc_stat; struct tasklet_struct *t = list; list = list->next; @@ -538,7 +593,15 @@ if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_end, + (unsigned long)(t->func), HI_SOFTIRQ); + avm_simple_profiling_log(avm_profile_data_type_hi_tasklet_begin, + (unsigned long)(t->func), (unsigned int)(t->data)); + pfunc_stat = avm_taskletfunc_enter(t->func, HI_SOFTIRQ); t->func(t->data); + avm_taskletfunc_leave(pfunc_stat); + avm_simple_profiling_log(avm_profile_data_type_hi_tasklet_end, + (unsigned long)(t->func), (unsigned int)(t->data)); tasklet_unlock(t); continue; }