--- zzzz-none-000/linux-3.10.107/kernel/softirq.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/kernel/softirq.c 2021-11-10 11:53:56.000000000 +0000 @@ -8,6 +8,12 @@ * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903) */ +/** + * Some part of this file is modified by Ikanos Communications. + * + * Copyright (C) 2013-2014 Ikanos Communications. + */ + #include #include #include @@ -23,6 +29,13 @@ #include #include #include +#include +#if defined(CONFIG_AVM_SIMPLE_PROFILING) +#include +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + + +#include #define CREATE_TRACE_POINTS #include @@ -53,6 +66,11 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; +#if defined(CONFIG_AVM_SKB_CACHE_SPLIT) +static struct kmem_cache *skb_cache_per_swirq[NR_SOFTIRQS]; +static DEFINE_PER_CPU(struct kmem_cache *, actual_skb_cache); +#endif/*--- #if defined(CONFIG_AVM_SKB_CACHE_SPLIT) ---*/ + DEFINE_PER_CPU(struct task_struct *, ksoftirqd); char *softirq_to_name[NR_SOFTIRQS] = { @@ -60,6 +78,14 @@ "TASKLET", "SCHED", "HRTIMER", "RCU" }; +#if defined(CONFIG_AVM_SKB_CACHE_SPLIT) +/** + * if NULL you have to use skbuff_head_cache! + */ +struct kmem_cache *skb_swirq_context(void) { + return __this_cpu_read(actual_skb_cache); +} +#endif/*--- #if defined(CONFIG_AVM_SKB_CACHE_SPLIT) ---*/ /* * we cannot loop indefinitely here to avoid userspace starvation, * but we also don't want to introduce a worst case 1/HZ latency @@ -232,6 +258,7 @@ lockdep_softirq_enter(); cpu = smp_processor_id(); + avm_sum_softirq_enter(); restart: /* Reset the pending bitmask before enabling irqs */ set_softirq_pending(0); @@ -241,6 +268,8 @@ h = softirq_vec; do { + struct _runtime_stat *pts; + if (pending & 1) { unsigned int vec_nr = h - softirq_vec; int prev_count = preempt_count(); @@ -248,7 +277,21 @@ kstat_incr_softirqs_this_cpu(vec_nr); trace_softirq_entry(vec_nr); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_sw_irq_begin, (unsigned int)(h->action), (unsigned int)h); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ +#if defined(CONFIG_AVM_SKB_CACHE_SPLIT) + __this_cpu_write(actual_skb_cache, skb_cache_per_swirq[vec_nr]); +#endif/*--- #if defined(CONFIG_AVM_SKB_CACHE_SPLIT) ---*/ + pts = avm_softirq_enter(vec_nr); h->action(h); + avm_softirq_leave(pts); +#if defined(CONFIG_AVM_SKB_CACHE_SPLIT) + __this_cpu_write(actual_skb_cache, NULL); +#endif/*--- #if defined(CONFIG_AVM_SKB_CACHE_SPLIT) ---*/ +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_sw_irq_end, (unsigned int)(h->action), (unsigned int)h); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ trace_softirq_exit(vec_nr); if (unlikely(prev_count != preempt_count())) { printk(KERN_ERR "huh, entered softirq %u %s %p" @@ -275,7 +318,7 @@ wakeup_softirqd(); } - + avm_sum_softirq_leave(); lockdep_softirq_exit(); account_irq_exit_time(current); @@ -415,6 +458,13 @@ void open_softirq(int nr, void (*action)(struct softirq_action *)) { softirq_vec[nr].action = action; +#if defined(CONFIG_AVM_SKB_CACHE_SPLIT) + if(skb_cache_per_swirq[nr] == NULL) { + char symname[KSYM_NAME_LEN]; + lookup_symbol_name((unsigned long)action, symname); + skb_cache_per_swirq[nr] = skb_cache_create_per_swirq(symname); + } +#endif/*--- #if defined(CONFIG_AVM_SKB_CACHE_SPLIT) ---*/ } /* @@ -437,6 +487,9 @@ t->next = NULL; *__this_cpu_read(tasklet_vec.tail) = t; __this_cpu_write(tasklet_vec.tail, &(t->next)); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_begin, (unsigned int)(t->func), TASKLET_SOFTIRQ); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ raise_softirq_irqoff(TASKLET_SOFTIRQ); local_irq_restore(flags); } @@ -451,6 +504,9 @@ t->next = NULL; *__this_cpu_read(tasklet_hi_vec.tail) = t; __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_begin, (unsigned int)(t->func), HI_SOFTIRQ); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ raise_softirq_irqoff(HI_SOFTIRQ); local_irq_restore(flags); } @@ -479,6 +535,7 @@ local_irq_enable(); while (list) { + struct _runtime_stat *pfunc; struct tasklet_struct *t = list; list = list->next; @@ -487,7 +544,16 @@ if (!atomic_read(&t->count)) { if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_end, (unsigned int)(t->func), TASKLET_SOFTIRQ); + avm_simple_profiling_log(avm_profile_data_type_tasklet_begin, (unsigned int)(t->func), (unsigned int)(t->data)); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + pfunc = avm_taskletfunc_enter(t->func, TASKLET_SOFTIRQ); t->func(t->data); + avm_taskletfunc_leave(pfunc); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_tasklet_end, (unsigned int)(t->func), (unsigned int)(t->data)); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ tasklet_unlock(t); continue; } @@ -514,6 +580,7 @@ local_irq_enable(); while (list) { + struct _runtime_stat *pfunc; struct tasklet_struct *t = list; list = list->next; @@ -522,7 +589,16 @@ if (!atomic_read(&t->count)) { if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_trigger_tasklet_end, (unsigned int)(t->func), HI_SOFTIRQ); + avm_simple_profiling_log(avm_profile_data_type_hi_tasklet_begin, (unsigned int)(t->func), (unsigned int)(t->data)); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + pfunc = avm_taskletfunc_enter(t->func, HI_SOFTIRQ); t->func(t->data); + avm_taskletfunc_leave(pfunc); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_hi_tasklet_end, (unsigned int)(t->func), (unsigned int)(t->data)); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ tasklet_unlock(t); continue; } @@ -771,3 +847,15 @@ return 0; } #endif + +#if defined(CONFIG_FUSIV_MIPS_BASED_VOICE) | defined(CONFIG_FUSIV_KERNEL_PROFILER_MODULE) | defined(CONFIG_FUSIV_DSP_BASED_VOICE) +int is_softirqd(struct task_struct *currentTask) +{ + struct task_struct *tsk = __get_cpu_var(ksoftirqd); + if(tsk == currentTask) + return 1; + else + return 0; +} +EXPORT_SYMBOL(is_softirqd); +#endif