diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fork.c | 4 | ||||
| -rw-r--r-- | kernel/sched/Makefile | 2 | ||||
| -rw-r--r-- | kernel/sched/core.c | 675 | ||||
| -rw-r--r-- | kernel/sched/cputime.c | 530 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 81 | ||||
| -rw-r--r-- | kernel/sched/features.h | 10 | ||||
| -rw-r--r-- | kernel/sched/rt.c | 5 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 69 | ||||
| -rw-r--r-- | kernel/softirq.c | 6 | ||||
| -rw-r--r-- | kernel/sysctl.c | 6 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 3 |
11 files changed, 686 insertions, 705 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 2343c9eaaaf4..5a0e74d89a5a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1276,11 +1276,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1276 | #endif | 1276 | #endif |
| 1277 | #ifdef CONFIG_TRACE_IRQFLAGS | 1277 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 1278 | p->irq_events = 0; | 1278 | p->irq_events = 0; |
| 1279 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
| 1280 | p->hardirqs_enabled = 1; | ||
| 1281 | #else | ||
| 1282 | p->hardirqs_enabled = 0; | 1279 | p->hardirqs_enabled = 0; |
| 1283 | #endif | ||
| 1284 | p->hardirq_enable_ip = 0; | 1280 | p->hardirq_enable_ip = 0; |
| 1285 | p->hardirq_enable_event = 0; | 1281 | p->hardirq_enable_event = 0; |
| 1286 | p->hardirq_disable_ip = _THIS_IP_; | 1282 | p->hardirq_disable_ip = _THIS_IP_; |
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile index 173ea52f3af0..f06d249e103b 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile | |||
| @@ -11,7 +11,7 @@ ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) | |||
| 11 | CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer | 11 | CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer |
| 12 | endif | 12 | endif |
| 13 | 13 | ||
| 14 | obj-y += core.o clock.o idle_task.o fair.o rt.o stop_task.o | 14 | obj-y += core.o clock.o cputime.o idle_task.o fair.o rt.o stop_task.o |
| 15 | obj-$(CONFIG_SMP) += cpupri.o | 15 | obj-$(CONFIG_SMP) += cpupri.o |
| 16 | obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o | 16 | obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o |
| 17 | obj-$(CONFIG_SCHEDSTATS) += stats.o | 17 | obj-$(CONFIG_SCHEDSTATS) += stats.o |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3c4dec0594d6..c17747236438 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -740,126 +740,6 @@ void deactivate_task(struct rq *rq, struct task_struct *p, int flags) | |||
| 740 | dequeue_task(rq, p, flags); | 740 | dequeue_task(rq, p, flags); |
| 741 | } | 741 | } |
| 742 | 742 | ||
| 743 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | ||
| 744 | |||
| 745 | /* | ||
| 746 | * There are no locks covering percpu hardirq/softirq time. | ||
| 747 | * They are only modified in account_system_vtime, on corresponding CPU | ||
| 748 | * with interrupts disabled. So, writes are safe. | ||
| 749 | * They are read and saved off onto struct rq in update_rq_clock(). | ||
| 750 | * This may result in other CPU reading this CPU's irq time and can | ||
| 751 | * race with irq/account_system_vtime on this CPU. We would either get old | ||
| 752 | * or new value with a side effect of accounting a slice of irq time to wrong | ||
| 753 | * task when irq is in progress while we read rq->clock. That is a worthy | ||
| 754 | * compromise in place of having locks on each irq in account_system_time. | ||
| 755 | */ | ||
| 756 | static DEFINE_PER_CPU(u64, cpu_hardirq_time); | ||
| 757 | static DEFINE_PER_CPU(u64, cpu_softirq_time); | ||
| 758 | |||
| 759 | static DEFINE_PER_CPU(u64, irq_start_time); | ||
| 760 | static int sched_clock_irqtime; | ||
| 761 | |||
| 762 | void enable_sched_clock_irqtime(void) | ||
| 763 | { | ||
| 764 | sched_clock_irqtime = 1; | ||
| 765 | } | ||
| 766 | |||
| 767 | void disable_sched_clock_irqtime(void) | ||
| 768 | { | ||
| 769 | sched_clock_irqtime = 0; | ||
| 770 | } | ||
| 771 | |||
| 772 | #ifndef CONFIG_64BIT | ||
| 773 | static DEFINE_PER_CPU(seqcount_t, irq_time_seq); | ||
| 774 | |||
| 775 | static inline void irq_time_write_begin(void) | ||
| 776 | { | ||
| 777 | __this_cpu_inc(irq_time_seq.sequence); | ||
| 778 | smp_wmb(); | ||
| 779 | } | ||
| 780 | |||
| 781 | static inline void irq_time_write_end(void) | ||
| 782 | { | ||
| 783 | smp_wmb(); | ||
| 784 | __this_cpu_inc(irq_time_seq.sequence); | ||
| 785 | } | ||
| 786 | |||
| 787 | static inline u64 irq_time_read(int cpu) | ||
| 788 | { | ||
| 789 | u64 irq_time; | ||
| 790 | unsigned seq; | ||
| 791 | |||
| 792 | do { | ||
| 793 | seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu)); | ||
| 794 | irq_time = per_cpu(cpu_softirq_time, cpu) + | ||
| 795 | per_cpu(cpu_hardirq_time, cpu); | ||
| 796 | } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq)); | ||
| 797 | |||
| 798 | return irq_time; | ||
| 799 | } | ||
| 800 | #else /* CONFIG_64BIT */ | ||
| 801 | static inline void irq_time_write_begin(void) | ||
| 802 | { | ||
| 803 | } | ||
| 804 | |||
| 805 | static inline void irq_time_write_end(void) | ||
| 806 | { | ||
| 807 | } | ||
| 808 | |||
| 809 | static inline u64 irq_time_read(int cpu) | ||
| 810 | { | ||
| 811 | return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); | ||
| 812 | } | ||
| 813 | #endif /* CONFIG_64BIT */ | ||
| 814 | |||
| 815 | /* | ||
| 816 | * Called before incrementing preempt_count on {soft,}irq_enter | ||
| 817 | * and before decrementing preempt_count on {soft,}irq_exit. | ||
| 818 | */ | ||
| 819 | void account_system_vtime(struct task_struct *curr) | ||
| 820 | { | ||
| 821 | unsigned long flags; | ||
| 822 | s64 delta; | ||
| 823 | int cpu; | ||
| 824 | |||
| 825 | if (!sched_clock_irqtime) | ||
| 826 | return; | ||
| 827 | |||
| 828 | local_irq_save(flags); | ||
| 829 | |||
| 830 | cpu = smp_processor_id(); | ||
| 831 | delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time); | ||
| 832 | __this_cpu_add(irq_start_time, delta); | ||
| 833 | |||
| 834 | irq_time_write_begin(); | ||
| 835 | /* | ||
| 836 | * We do not account for softirq time from ksoftirqd here. | ||
| 837 | * We want to continue accounting softirq time to ksoftirqd thread | ||
| 838 | * in that case, so as not to confuse scheduler with a special task | ||
| 839 | * that do not consume any time, but still wants to run. | ||
| 840 | */ | ||
| 841 | if (hardirq_count()) | ||
| 842 | __this_cpu_add(cpu_hardirq_time, delta); | ||
| 843 | else if (in_serving_softirq() && curr != this_cpu_ksoftirqd()) | ||
| 844 | __this_cpu_add(cpu_softirq_time, delta); | ||
| 845 | |||
| 846 | irq_time_write_end(); | ||
| 847 | local_irq_restore(flags); | ||
| 848 | } | ||
| 849 | EXPORT_SYMBOL_GPL(account_system_vtime); | ||
| 850 | |||
| 851 | #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ | ||
| 852 | |||
| 853 | #ifdef CONFIG_PARAVIRT | ||
| 854 | static inline u64 steal_ticks(u64 steal) | ||
| 855 | { | ||
| 856 | if (unlikely(steal > NSEC_PER_SEC)) | ||
| 857 | return div_u64(steal, TICK_NSEC); | ||
| 858 | |||
| 859 | return __iter_div_u64_rem(steal, TICK_NSEC, &steal); | ||
| 860 | } | ||
| 861 | #endif | ||
| 862 | |||
| 863 | static void update_rq_clock_task(struct rq *rq, s64 delta) | 743 | static void update_rq_clock_task(struct rq *rq, s64 delta) |
| 864 | { | 744 | { |
| 865 | /* | 745 | /* |
| @@ -920,43 +800,6 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) | |||
| 920 | #endif | 800 | #endif |
| 921 | } | 801 | } |
| 922 | 802 | ||
| 923 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | ||
| 924 | static int irqtime_account_hi_update(void) | ||
| 925 | { | ||
| 926 | u64 *cpustat = kcpustat_this_cpu->cpustat; | ||
| 927 | unsigned long flags; | ||
| 928 | u64 latest_ns; | ||
| 929 | int ret = 0; | ||
| 930 | |||
| 931 | local_irq_save(flags); | ||
| 932 | latest_ns = this_cpu_read(cpu_hardirq_time); | ||
| 933 | if (nsecs_to_cputime64(latest_ns) > cpustat[CPUTIME_IRQ]) | ||
| 934 | ret = 1; | ||
| 935 | local_irq_restore(flags); | ||
| 936 | return ret; | ||
| 937 | } | ||
| 938 | |||
| 939 | static int irqtime_account_si_update(void) | ||
| 940 | { | ||
| 941 | u64 *cpustat = kcpustat_this_cpu->cpustat; | ||
| 942 | unsigned long flags; | ||
| 943 | u64 latest_ns; | ||
| 944 | int ret = 0; | ||
| 945 | |||
| 946 | local_irq_save(flags); | ||
| 947 | latest_ns = this_cpu_read(cpu_softirq_time); | ||
| 948 | if (nsecs_to_cputime64(latest_ns) > cpustat[CPUTIME_SOFTIRQ]) | ||
| 949 | ret = 1; | ||
| 950 | local_irq_restore(flags); | ||
| 951 | return ret; | ||
