sched: Make find_busiest_queue a method
Subsystems (4)
Commit-ID: 2a7910b97834876332e58713674cd8194b5c082c Gitweb: http://git.kernel.org/tip/2a7910b97834876332e58713674cd8194b5c082c Author: Peter Zijlstra <[email protected]> AuthorDate: Sat, 3 Mar 2012 16:56:25 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 18 May 2012 08:16:23 +0200
sched: Make find_busiest_queue a method
Its a bit awkward but it was the least painful means of modifying the queue selection. Used in a later patch to conditionally use a random queue.
--- include/linux/mm_types.h | 8 + include/linux/sched.h | 14 + init/Kconfig | 2 +- kernel/fork.c | 2 + kernel/sched/Makefile | 1 + kernel/sched/core.c | 22 ++- kernel/sched/debug.c | 3 + kernel/sched/fair.c | 257 +++++++++++++++-- kernel/sched/features.h | 12 + kernel/sched/numa.c | 741 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 34 +++ mm/init-mm.c | 10 + 12 files changed, 1079 insertions(+), 27 deletions(-)
include/linux/mm_types.h +8 -0
@@ -285,6 +285,13 @@ struct mm_rss_stat {atomic_long_t count[NR_MM_COUNTERS ]; }; +struct numa_entity { +#ifdef CONFIG_NUMA +int node;/* home node */ +struct list_head numa_entry;/* balance list */ +#endif +}; +struct mm_struct {struct vm_area_struct * mmap;/* list of VMAs */ struct rb_root mm_rb;
@@ -388,6 +395,7 @@ struct mm_struct {#ifdef CONFIG_CPUMASK_OFFSTACK struct cpumask cpumask_allocation;#endif +struct numa_entity numa; };static inline void mm_init_cpumask (struct mm_struct *mm)
include/linux/sched.h +14 -0
@@ -860,6 +860,7 @@ enum cpu_idle_type {#define SD_ASYM_PACKING 0x0800/* Place busy groups earlier in the domain */ #define SD_PREFER_SIBLING 0x1000/* Prefer to place tasks in a sibling domain */ #define SD_OVERLAP 0x2000/* sched_domains of this level overlap */ +#define SD_NUMA 0x4000/* cross-node balancing */ extern int __weak arch_sd_sibiling_asym_packing (void );
@@ -1233,6 +1234,11 @@ struct task_struct {struct sched_entity se;struct sched_rt_entity rt; +#ifdef CONFIG_NUMA +unsigned long numa_contrib; +int numa_remote; +#endif +#ifdef CONFIG_PREEMPT_NOTIFIERS /* list of struct preempt_notifier: */ struct hlist_head preempt_notifiers;
@@ -2781,6 +2787,14 @@ static inline unsigned long rlimit_max(unsigned int limit)return task_rlimit_max (current, limit); } +#ifdef CONFIG_NUMA +void mm_init_numa (struct mm_struct *mm); +void exit_numa (struct mm_struct *mm); +#else +static inline void mm_init_numa (struct mm_struct *mm) { } +static inline void exit_numa (struct mm_struct *mm) { } +#endif +#endif /* __KERNEL__ */ #endif
init/Kconfig +1 -1
@@ -866,7 +866,7 @@ config SCHED_AUTOGROUP upon task session. config MM_OWNER - bool + def_bool NUMA config SYSFS_DEPRECATED bool "Enable deprecated sysfs features to support old userspace tools"
kernel/fork.c +2 -0
@@ -527,6 +527,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) mm->cached_hole_size = ~0UL ;mm_init_aio (mm);mm_init_owner (mm, p); +mm_init_numa (mm);if (likely (!mm_alloc_pgd (mm))) { mm->def_flags =0 ;
@@ -595,6 +596,7 @@ void mmput(struct mm_struct *mm)might_sleep ();if (atomic_dec_and_test (&mm->mm_users)) { +exit_numa (mm);exit_aio (mm);ksm_exit (mm);khugepaged_exit (mm);/* must run before exit_mmap */
kernel/sched/Makefile +1 -0
@@ -16,3 +16,4 @@ obj-$(CONFIG_SMP) += cpupri.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o obj-$(CONFIG_SCHED_DEBUG) += debug.o +obj-$(CONFIG_NUMA) += numa.o
kernel/sched/core.c +20 -2
@@ -5859,7 +5859,9 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu) DEFINE_PER_CPU(struct sched_domain *, sd_llc);DEFINE_PER_CPU (int, sd_llc_id); -static void update_top_cache_domain (int cpu) +DEFINE_PER_CPU(struct sched_domain *, sd_node); + +static void update_domain_cache (int cpu) {struct sched_domain *sd;int id = cpu;
@@ -5870,6 +5872,15 @@ static void update_top_cache_domain(int cpu)rcu_assign_pointer (per_cpu (sd_llc, cpu), sd);per_cpu (sd_llc_id, cpu) = id; + +for_each_domain (cpu, sd) { +if (cpumask_equal (sched_domain_span (sd), +cpumask_of_node (cpu_to_node (cpu)))) + goto got_node; + } + sd =NULL ; +got_node: +rcu_assign_pointer (per_cpu (sd_node, cpu), sd); }/*
@@ -5912,7 +5923,7 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)rcu_assign_pointer (rq->sd, sd);destroy_sched_domains (tmp, cpu); -update_top_cache_domain (cpu); +update_domain_cache (cpu); }/* cpus with isolated domains */
@@ -6359,6 +6370,7 @@ sd_numa_init(struct sched_domain_topology_level *tl, int cpu) | 0*SD_SHARE_PKG_RESOURCES |1 *SD_SERIALIZE |0 *SD_PREFER_SIBLING + |1 *SD_NUMA |sd_local_flags (level) , .last_balance = jiffies,
@@ -7066,6 +7078,11 @@ void __init sched_init(void) rq->avg_idle =2 *sysctl_sched_migration_cost;INIT_LIST_HEAD (&rq->cfs_tasks); +#ifdef CONFIG_NUMA +INIT_LIST_HEAD (&rq->offnode_tasks); + rq->offnode_running =0 ; + rq->offnode_weight =0 ; +#endif rq_attach_root (rq, &def_root_domain);#ifdef CONFIG_NO_HZ
@@ -7115,6 +7132,7 @@ void __init sched_init(void)idle_thread_set_boot_cpu ();#endif init_sched_fair_class (); +init_sched_numa (); scheduler_running =1 ; }
kernel/sched/debug.c +3 -0
@@ -132,6 +132,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)SEQ_printf (m,"%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld" ,0LL ,0LL ,0LL ,0L ,0LL ,0L ,0LL ,0L );#endif +#ifdef CONFIG_NUMA +SEQ_printf (m," %d/%d" , p->node,cpu_to_node (task_cpu (p))); +#endif #ifdef CONFIG_CGROUP_SCHED SEQ_printf (m," %s" ,task_group_path (task_group (p)));#endif
kernel/sched/fair.c +233 -24
441 lines not on this page · raw message
kernel/sched/features.h +12 -0
@@ -69,3 +69,15 @@ SCHED_FEAT(TTWU_QUEUE, true) SCHED_FEAT(FORCE_SD_OVERLAP, false) SCHED_FEAT(RT_RUNTIME_SHARE, true) SCHED_FEAT(LB_MIN, false) + +#ifdef CONFIG_NUMA +SCHED_FEAT(NUMA_HOT, true) +SCHED_FEAT(NUMA_BIAS, true) +SCHED_FEAT(NUMA_PULL, true) +SCHED_FEAT(NUMA_PULL_BIAS, true) +SCHED_FEAT(NUMA_BALANCE, true) +SCHED_FEAT(NUMA_SELECT, true) +SCHED_FEAT(NUMA_SLOW, false) +SCHED_FEAT(NUMA_BALANCE_FILTER, false) +#endif +
kernel/sched/numa.c new file +741 -0
741 lines not on this page · raw message
kernel/sched/sched.h +34 -0
@@ -414,6 +414,12 @@ struct rq {struct list_head cfs_tasks; +#ifdef CONFIG_NUMA +unsigned long offnode_running; +unsigned long offnode_weight; +struct list_head offnode_tasks; +#endif +u64 rt_avg;u64 age_stamp;u64 idle_stamp;
@@ -465,6 +471,15 @@ struct rq {#endif }; +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +#ifdef CONFIG_NUMA +return &rq->offnode_tasks; +#else +return NULL ; +#endif +} +static inline int cpu_of (struct rq *rq) {#ifdef CONFIG_SMP
@@ -525,6 +540,7 @@ static inline struct sched_domain *highest_flag_domain(int cpu, int flag) DECLARE_PER_CPU(struct sched_domain *, sd_llc);DECLARE_PER_CPU (int, sd_llc_id); +DECLARE_PER_CPU(struct sched_domain *, sd_node);#endif /* CONFIG_SMP */
@@ -1163,7 +1179,25 @@ enum rq_nohz_flag_bits {#define nohz_flags (cpu) (&cpu_rq(cpu)->nohz_flags)#endif +unsigned long task_h_load (struct task_struct *p); + +#ifdef CONFIG_NUMA + +void sched_setnode (struct task_struct *p,int node); +void select_task_node (struct task_struct *p,struct mm_struct *mm,int sd_flags); +bool account_numa_enqueue (struct task_struct *p); +void account_numa_dequeue (struct task_struct *p); +void init_sched_numa (void ); + +#else /* CONFIG_NUMA */ +/* * Macro to avoid argument evaluation */ #define select_task_node (p, mm, sd_flags) do { } while (0) +static inline bool account_numa_enqueue (struct task_struct *p) {return false; } +static inline void account_numa_dequeue (struct task_struct *p) { } +static inline void init_sched_numa (void ) { } + +#endif /* CONFIG_NUMA */ +
mm/init-mm.c +10 -0
@@ -13,6 +13,15 @@#define INIT_MM_CONTEXT (name)#endif +#ifdef CONFIG_NUMA +# define INIT_MM_NUMA (mm) \ + .numa = { \ + .node = -1, \ + }, +#else +# define INIT_MM_NUMA (mm) +#endif +struct mm_struct init_mm = { .mm_rb =RB_ROOT , .pgd = swapper_pg_dir,
@@ -22,4 +31,5 @@ struct mm_struct init_mm = { .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(init_mm.mmlist), INIT_MM_CONTEXT(init_mm) + INIT_MM_NUMA(init_mm) };
Quoted 7 lines · tip-bot for Peter Zijlstra
sched: Make
find_busiest_queuea methodIts a bit awkward but it was the least painful means of modifying the queue selection. Used in a later patch to conditionally use a random queue.
Quoted 14 lines
--- include/linux/mm_types.h | 8 + include/linux/sched.h | 14 + init/Kconfig | 2 +- kernel/fork.c | 2 + kernel/sched/Makefile | 1 + kernel/sched/core.c | 22 ++- kernel/sched/debug.c | 3 + kernel/sched/fair.c | 257 +++++++++++++++-- kernel/sched/features.h | 12 + kernel/sched/numa.c | 741 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 34 +++ mm/init-mm.c | 10 + 12 files changed, 1079 insertions(+), 27 deletions(-)
Something went wrong here.. this were 3 patches:
Subject: sched: Make find_busiest_queue a method
Subject: sched: Implement home-node awareness
Subject: sched, numa: Numa balancer
Quoted 25 lines · Peter Zijlstra
Quoted 7 lines · tip-bot for Peter Zijlstra
sched: Make
find_busiest_queuea methodIts a bit awkward but it was the least painful means of modifying the queue selection. Used in a later patch to conditionally use a random queue.
Quoted 14 lines
--- include/linux/mm_types.h | 8 + include/linux/sched.h | 14 + init/Kconfig | 2 +- kernel/fork.c | 2 + kernel/sched/Makefile | 1 + kernel/sched/core.c | 22 ++- kernel/sched/debug.c | 3 + kernel/sched/fair.c | 257 +++++++++++++++-- kernel/sched/features.h | 12 + kernel/sched/numa.c | 741 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 34 +++ mm/init-mm.c | 10 + 12 files changed, 1079 insertions(+), 27 deletions(-)
Quoted 5 lines
Something went wrong here.. this were 3 patches:
Subject: sched: Make
find_busiest_queuea method
Subject: sched: Implement home-node awareness
Subject: sched, numa: Numa balancer
Oops, indeed, good spotting - that was the victim of a post-review, post-commit backmerge of a fixlet workflow hickup so it went unnoticed by me. I Hate Rebases (tm).
Will push it out shortly, after some testing.
Thanks,
Ingo