Commit 4a66d709 authored by aumgn's avatar aumgn
Browse files

[cleanup] Add build/linux.deb directory

parent df7108d4
CORES=$(shell nproc)
KERNEL_VERSION=4.9.9
KERNEL_STAMP:=$(shell python -c 'import uuid; print(str(uuid.uuid1())[0:8])')
EXECUTABLES = tar curl make fakeroot make-kpkg
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH (required $(EXECUTABLES))")))
FLAVORS=vanilla wastedcores schedprofiler tptracepoint
.PHONY: all
all: ubuntu
linux-$(KERNEL_VERSION).tar.xz:
@echo "Downloading kernel source code"
@curl -OL 'http://kernel.org/pub/linux/kernel/v4.x/linux-$(KERNEL_VERSION).tar.xz'
SOURCES-$(KERNEL_VERSION):
curl -L http://kernel.ubuntu.com/~kernel-ppa/mainline/v$(KERNEL_VERSION)/SOURCES -o $@
linux-$(KERNEL_VERSION)-ubuntu: linux-$(KERNEL_VERSION).tar.xz SOURCES-$(KERNEL_VERSION)
@echo "Uncompressing source code for $@"
@mkdir $@
@tar xf $< -C $@ --strip-components 1
@echo "Patching $@ with ubuntu patches"
cd $@; for patch in $$(tail -n +2 ../SOURCES-$(KERNEL_VERSION)); do \
curl -OL http://kernel.ubuntu.com/~kernel-ppa/mainline/v$(KERNEL_VERSION)/$$patch; \
patch -p1 <$$patch; \
done
@cd $@; if ! test -f REPORTING-BUGS; then \
echo "Removed" > REPORTING-BUGS; \
fi
linux-$(KERNEL_VERSION)-vanilla-$(KERNEL_STAMP): linux-$(KERNEL_VERSION)-ubuntu
@echo "Copying $< for $@"
@cp -r $< $@
linux-$(KERNEL_VERSION)-%-$(KERNEL_STAMP): linux-$(KERNEL_VERSION)-ubuntu
@echo "Copying $< for $@"
@cp -r $< $@
@echo "Patching $@ with $* patches"
@cd $@; for patch in ../$*/$(KERNEL_VERSION)/*.patch; do \
patch -p1 <$$patch; \
done
linux-image-$(KERNEL_VERSION)-%-$(KERNEL_STAMP)_2_amd64.deb: linux-$(KERNEL_VERSION)-%-$(KERNEL_STAMP)
@echo "Cleaning $<"
make -C$< distclean
make -C$< mrproper
cd $<; make-kpkg clean
@echo "Configuring $<"
@cp /boot/config-$$(uname -r) $</.config
make -C$< olddefconfig
@echo "Building $<"
cd $<; make-kpkg \
--rootcmd fakeroot \
--jobs $(CORES) \
--append-to-version -$*-$(KERNEL_STAMP) \
--revision 2 \
--initrd kernel_image kernel_headers
.PHONY: $(FLAVORS)
$(FLAVORS): %: linux-image-$(KERNEL_VERSION)-%-$(KERNEL_STAMP)_2_amd64.deb
4.1.x
\ No newline at end of file
diff -uprNw -X linux-4.1.vanilla/Documentation/dontdiff '--exclude=*tools*' '--exclude=install*' linux-4.1.vanilla/kernel/sched/core.c linux-4.1.sched_profiler/kernel/sched/core.c
--- linux-4.1.vanilla/kernel/sched/core.c 2015-06-21 22:05:43.000000000 -0700
+++ linux-4.1.sched_profiler/kernel/sched/core.c 2016-04-30 08:58:54.803760696 -0700
@@ -1700,6 +1700,8 @@ try_to_wake_up(struct task_struct *p, un
}
#endif /* CONFIG_SMP */
+ sp_record_scheduling_event(SP_TRY_TO_WAKE_UP, p->wake_cpu, cpu);
+
ttwu_queue(p, cpu);
stat:
ttwu_stat(p, cpu, wake_flags);
@@ -2078,6 +2080,7 @@ void wake_up_new_task(struct task_struct
{
unsigned long flags;
struct rq *rq;
+ int dst_cpu;
raw_spin_lock_irqsave(&p->pi_lock, flags);
#ifdef CONFIG_SMP
@@ -2086,12 +2089,15 @@ void wake_up_new_task(struct task_struct
* - cpus_allowed can change in the fork path
* - any previously selected cpu might disappear through hotplug
*/
- set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));
+ set_task_cpu(p, dst_cpu = select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));
#endif
/* Initialize new task's runnable average */
init_task_runnable_average(p);
rq = __task_rq_lock(p);
+
+ sp_record_scheduling_event(SP_WAKE_UP_NEW_TASK, 255, dst_cpu);
+
activate_task(rq, p, 0);
p->on_rq = TASK_ON_RQ_QUEUED;
trace_sched_wakeup_new(p, true);
@@ -2423,6 +2429,9 @@ void sched_exec(void)
struct migration_arg arg = { p, dest_cpu };
raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+
+ sp_record_scheduling_event(SP_SCHED_EXEC, task_cpu(p), dest_cpu);
+
stop_one_cpu(task_cpu(p), migration_cpu_stop, &arg);
return;
}
diff -uprNw -X linux-4.1.vanilla/Documentation/dontdiff '--exclude=*tools*' '--exclude=install*' linux-4.1.vanilla/kernel/sched/fair.c linux-4.1.sched_profiler/kernel/sched/fair.c
--- linux-4.1.vanilla/kernel/sched/fair.c 2015-06-21 22:05:43.000000000 -0700
+++ linux-4.1.sched_profiler/kernel/sched/fair.c 2016-04-30 09:37:44.287653280 -0700
@@ -35,6 +35,121 @@
#include "sched.h"
+#include <linux/module.h>
+
+/******************************************************************************/
+/* Wrappers */
+/******************************************************************************/
+struct rq *sp_cpu_rq(int cpu) {
+ return cpu_rq(cpu);
+}
+
+EXPORT_SYMBOL(sp_cpu_rq);
+
+/******************************************************************************/
+/* Hook type definitions */
+/******************************************************************************/
+typedef void (*set_nr_running_t)(int *, int, int);
+typedef void (*record_scheduling_event_t)(int, int, int);
+typedef void (*record_scheduling_event_extra_t)(int, char, char, char, char,
+ char, char, char, char);
+typedef void (*record_balancing_event_t)(int, int, uint64_t);
+typedef void (*record_load_change_t)(unsigned long, int);
+
+/******************************************************************************/
+/* Hooks */
+/******************************************************************************/
+__read_mostly volatile set_nr_running_t sp_module_set_nr_running = NULL;
+__read_mostly volatile record_scheduling_event_t
+ sp_module_record_scheduling_event = NULL;
+__read_mostly volatile record_scheduling_event_extra_t
+ sp_module_record_scheduling_event_extra = NULL;
+__read_mostly volatile record_balancing_event_t
+ sp_module_record_balancing_event = NULL;
+__read_mostly volatile record_load_change_t
+ sp_module_record_load_change = NULL;
+
+/******************************************************************************/
+/* Default hook implementations */
+/******************************************************************************/
+void sp_set_nr_running(int *nr_running_p, int new_nr_running, int dst_cpu)
+{
+ if (sp_module_set_nr_running)
+ (*sp_module_set_nr_running)(nr_running_p, new_nr_running, dst_cpu);
+ else
+ *nr_running_p = new_nr_running;
+}
+
+void sp_record_scheduling_event(int event_type, int src_cpu, int dst_cpu)
+{
+ if (sp_module_record_scheduling_event)
+ (*sp_module_record_scheduling_event)(event_type, src_cpu, dst_cpu);
+}
+
+void sp_record_scheduling_event_extra(int event_type,
+ char data1, char data2, char data3, char data4,
+ char data5, char data6, char data7, char data8)
+{
+ if (sp_module_record_scheduling_event_extra)
+ (*sp_module_record_scheduling_event_extra)(event_type,
+ data1, data2, data3, data4, data5, data6, data7, data8);
+}
+
+void sp_record_balancing_event(int event_type, int cpu, uint64_t data)
+{
+ if (sp_module_record_balancing_event)
+ (*sp_module_record_balancing_event)(event_type, cpu, data);
+}
+
+void sp_record_load_change(unsigned long load, int cpu)
+{
+ if (sp_module_record_load_change)
+ (*sp_module_record_load_change)(load, cpu);
+}
+
+/******************************************************************************/
+/* Hook setters */
+/******************************************************************************/
+void set_sp_module_set_nr_running(set_nr_running_t __sp_module_set_nr_running)
+{
+ sp_module_set_nr_running = __sp_module_set_nr_running;
+
+}
+
+void set_sp_module_record_scheduling_event
+ (record_scheduling_event_t __sp_module_record_scheduling_event)
+{
+ sp_module_record_scheduling_event = __sp_module_record_scheduling_event;
+}
+
+void set_sp_module_record_scheduling_event_extra
+ (record_scheduling_event_extra_t __sp_module_record_scheduling_event_extra)
+{
+ sp_module_record_scheduling_event_extra =
+ __sp_module_record_scheduling_event_extra;
+}
+
+void set_sp_module_record_balancing_event
+ (record_balancing_event_t __sp_module_record_balancing_event)
+{
+ sp_module_record_balancing_event = __sp_module_record_balancing_event;
+}
+
+void set_sp_module_record_load_change
+ (record_load_change_t __sp_module_record_load_change)
+{
+ sp_module_record_load_change = __sp_module_record_load_change;
+}
+
+/******************************************************************************/
+/* Symbols */
+/******************************************************************************/
+EXPORT_SYMBOL(set_sp_module_set_nr_running);
+EXPORT_SYMBOL(set_sp_module_record_scheduling_event);
+EXPORT_SYMBOL(set_sp_module_record_scheduling_event_extra);
+EXPORT_SYMBOL(set_sp_module_record_balancing_event);
+EXPORT_SYMBOL(set_sp_module_record_load_change);
+
/*
* Targeted preemption latency for CPU-bound tasks:
* (default: 6ms * (1 + ilog(ncpus)), units: nanoseconds)
@@ -666,7 +781,7 @@ static u64 sched_vslice(struct cfs_rq *c
}
#ifdef CONFIG_SMP
-static int select_idle_sibling(struct task_struct *p, int cpu);
+static int select_idle_sibling(struct task_struct *p, int cpu, int prev_cpu);
static unsigned long task_h_load(struct task_struct *p);
static inline void __update_task_entity_contrib(struct sched_entity *se);
@@ -1386,7 +1501,7 @@ balance:
* Call select_idle_sibling to maybe find a better one.
*/
if (!cur)
- env->dst_cpu = select_idle_sibling(env->p, env->dst_cpu);
+ env->dst_cpu = select_idle_sibling(env->p, env->dst_cpu, -1);
assign:
task_numa_assign(env, cur, imp);
@@ -2291,7 +2406,10 @@ account_entity_enqueue(struct cfs_rq *cf
{
update_load_add(&cfs_rq->load, se->load.weight);
if (!parent_entity(se))
+ {
update_load_add(&rq_of(cfs_rq)->load, se->load.weight);
+ sp_record_load_change(rq_of(cfs_rq)->load.weight, rq_of(cfs_rq)->cpu);
+ }
#ifdef CONFIG_SMP
if (entity_is_task(se)) {
struct rq *rq = rq_of(cfs_rq);
@@ -2308,7 +2426,10 @@ account_entity_dequeue(struct cfs_rq *cf
{
update_load_sub(&cfs_rq->load, se->load.weight);
if (!parent_entity(se))
+ {
update_load_sub(&rq_of(cfs_rq)->load, se->load.weight);
+ sp_record_load_change(rq_of(cfs_rq)->load.weight, rq_of(cfs_rq)->cpu);
+ }
if (entity_is_task(se)) {
account_numa_dequeue(rq_of(cfs_rq), task_of(se));
list_del_init(&se->group_node);
@@ -4646,6 +4767,7 @@ find_idlest_group(struct sched_domain *s
unsigned long min_load = ULONG_MAX, this_load = 0;
int load_idx = sd->forkexec_idx;
int imbalance = 100 + (sd->imbalance_pct-100)/2;
+ uint64_t considered_cores = 0;
if (sd_flag & SD_BALANCE_WAKE)
load_idx = sd->wake_idx;
@@ -4667,6 +4789,8 @@ find_idlest_group(struct sched_domain *s
avg_load = 0;
for_each_cpu(i, sched_group_cpus(group)) {
+ considered_cores |= (uint64_t)1 << i;
+
/* Bias balancing toward cpus of our domain */
if (local_group)
load = source_load(i, load_idx);
@@ -4687,6 +4811,9 @@ find_idlest_group(struct sched_domain *s
}
} while (group = group->next, group != sd->groups);
+ sp_record_balancing_event(SP_CONSIDERED_CORES_FIG, this_cpu,
+ considered_cores);
+
if (!idlest || 100*this_load < imbalance*min_load)
return NULL;
return idlest;
@@ -4704,9 +4831,12 @@ find_idlest_cpu(struct sched_group *grou
int least_loaded_cpu = this_cpu;
int shallowest_idle_cpu = -1;
int i;
+ uint64_t considered_cores = 0;
/* Traverse only the allowed CPUs */
for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) {
+ considered_cores |= (uint64_t)1 << i;
+
if (idle_cpu(i)) {
struct rq *rq = cpu_rq(i);
struct cpuidle_state *idle = idle_get_state(rq);
@@ -4738,26 +4868,43 @@ find_idlest_cpu(struct sched_group *grou
}
}
+ sp_record_balancing_event(SP_CONSIDERED_CORES_FIC, this_cpu,
+ considered_cores);
+
return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu;
}
/*
* Try and locate an idle CPU in the sched_domain.
*/
-static int select_idle_sibling(struct task_struct *p, int target)
+static int select_idle_sibling(struct task_struct *p, int target, int prev_cpu)
{
struct sched_domain *sd;
struct sched_group *sg;
int i = task_cpu(p);
+ uint64_t considered_cores = 0;
+ considered_cores |= (uint64_t)1 << target;
if (idle_cpu(target))
+ {
+ if (prev_cpu > 0)
+ sp_record_balancing_event(SP_CONSIDERED_CORES_SIS, prev_cpu,
+ considered_cores);
return target;
+ }
+
+ considered_cores |= (uint64_t)1 << i;
/*
* If the prevous cpu is cache affine and idle, don't be stupid.
*/
if (i != target && cpus_share_cache(i, target) && idle_cpu(i))
+ {
+ if (prev_cpu > 0)
+ sp_record_balancing_event(SP_CONSIDERED_CORES_SIS, prev_cpu,
+ considered_cores);
return i;
+ }
/*
* Otherwise, iterate the domains and find an elegible idle cpu.
@@ -4771,6 +4918,8 @@ static int select_idle_sibling(struct ta
goto next;
for_each_cpu(i, sched_group_cpus(sg)) {
+ considered_cores |= (uint64_t)1 << i;
+
if (i == target || !idle_cpu(i))
goto next;
}
@@ -4783,6 +4932,11 @@ next:
} while (sg != sd->groups);
}
done:
+
+ if (prev_cpu > 0)
+ sp_record_balancing_event(SP_CONSIDERED_CORES_SIS, prev_cpu,
+ considered_cores);
+
return target;
}
/*
@@ -4833,6 +4987,7 @@ select_task_rq_fair(struct task_struct *
int new_cpu = cpu;
int want_affine = 0;
int sync = wake_flags & WF_SYNC;
+ int __prev_cpu = prev_cpu;
if (sd_flag & SD_BALANCE_WAKE)
want_affine = cpumask_test_cpu(cpu, tsk_cpus_allowed(p));
@@ -4860,7 +5015,7 @@ select_task_rq_fair(struct task_struct *
prev_cpu = cpu;
if (sd_flag & SD_BALANCE_WAKE) {
- new_cpu = select_idle_sibling(p, prev_cpu);
+ new_cpu = select_idle_sibling(p, prev_cpu, __prev_cpu);
goto unlock;
}
@@ -5638,13 +5793,19 @@ int can_migrate_task(struct task_struct
/*
* detach_task() -- detach the task for the migration specified in env
*/
-static void detach_task(struct task_struct *p, struct lb_env *env)
+static void detach_task(struct task_struct *p, struct lb_env *env,
+ int event_type)
{
lockdep_assert_held(&env->src_rq->lock);
deactivate_task(env->src_rq, p, 0);
p->on_rq = TASK_ON_RQ_MIGRATING;
set_task_cpu(p, env->dst_cpu);
+ if (event_type >= 0)
+ /* Otherwise we're coming from active_load_balance_cpu_stop and the
+ event was registered already. */
+ sp_record_scheduling_event(event_type, cpu_of(env->src_rq),
+ env->dst_cpu);
}
/*
@@ -5663,7 +5824,7 @@ static struct task_struct *detach_one_ta
if (!can_migrate_task(p, env))
continue;
- detach_task(p, env);
+ detach_task(p, env, -1);
/*
* Right now, this is only the second place where
@@ -5685,7 +5846,7 @@ static const unsigned int sched_nr_migra
*
* Returns number of detached tasks if successful and 0 otherwise.
*/
-static int detach_tasks(struct lb_env *env)
+static int detach_tasks(struct lb_env *env, int event_type)
{
struct list_head *tasks = &env->src_rq->cfs_tasks;
struct task_struct *p;
@@ -5723,7 +5884,7 @@ static int detach_tasks(struct lb_env *e
if ((load / 2) > env->imbalance)
goto next;
- detach_task(p, env);
+ detach_task(p, env, event_type);
list_add(&p->se.group_node, &env->tasks);
detached++;
@@ -6262,12 +6423,15 @@ static inline void update_sg_lb_stats(st
{
unsigned long load;
int i;
+ uint64_t considered_cores = 0;
memset(sgs, 0, sizeof(*sgs));
for_each_cpu_and(i, sched_group_cpus(group), env->cpus) {
struct rq *rq = cpu_rq(i);
+ considered_cores |= (uint64_t)1 << i;
+
/* Bias balancing toward cpus of our domain */
if (local_group)
load = target_load(i, load_idx);
@@ -6290,6 +6454,9 @@ static inline void update_sg_lb_stats(st
sgs->idle_cpus++;
}
+ sp_record_balancing_event(SP_CONSIDERED_CORES_USLS, env->dst_cpu,
+ considered_cores);
+
/* Adjust by relative CPU capacity of the group */
sgs->group_capacity = group->sgc->capacity;
sgs->avg_load = (sgs->group_load*SCHED_CAPACITY_SCALE) / sgs->group_capacity;
@@ -6761,11 +6928,14 @@ static struct rq *find_busiest_queue(str
struct rq *busiest = NULL, *rq;
unsigned long busiest_load = 0, busiest_capacity = 1;
int i;
+ uint64_t considered_cores = 0;
for_each_cpu_and(i, sched_group_cpus(group), env->cpus) {
unsigned long capacity, wl;
enum fbq_type rt;
+ considered_cores |= (uint64_t)1 << i;
+
rq = cpu_rq(i);
rt = fbq_classify_rq(rq);
@@ -6822,6 +6992,9 @@ static struct rq *find_busiest_queue(str
}
}
+ sp_record_balancing_event(SP_CONSIDERED_CORES_FBQ, env->dst_cpu,
+ considered_cores);
+
return busiest;
}
@@ -6907,7 +7080,7 @@ static int should_we_balance(struct lb_e
*/
static int load_balance(int this_cpu, struct rq *this_rq,
struct sched_domain *sd, enum cpu_idle_type idle,
- int *continue_balancing)
+ int *continue_balancing, int event_type)
{
int ld_moved, cur_ld_moved, active_balance = 0;
struct sched_domain *sd_parent = sd->parent;
@@ -6982,7 +7155,7 @@ more_balance:
* cur_ld_moved - load moved in current iteration
* ld_moved - cumulative load moved across iterations
*/
- cur_ld_moved = detach_tasks(&env);
+ cur_ld_moved = detach_tasks(&env, event_type + SP_MOVE_TASKS);
/*
* We've detached some tasks from busiest_rq. Every
@@ -7104,6 +7277,9 @@ more_balance:
raw_spin_unlock_irqrestore(&busiest->lock, flags);
if (active_balance) {
+ sp_record_scheduling_event
+ (event_type + SP_ACTIVE_LOAD_BALANCE_CPU_STOP,
+ cpu_of(busiest), this_cpu);
stop_one_cpu_nowait(cpu_of(busiest),
active_load_balance_cpu_stop, busiest,
&busiest->active_balance_work);
@@ -7250,7 +7426,7 @@ static int idle_balance(struct rq *this_
pulled_task = load_balance(this_cpu, this_rq,
sd, CPU_NEWLY_IDLE,
- &continue_balancing);
+ &continue_balancing, SP_IDLE_BALANCE);
domain_cost = sched_clock_cpu(this_cpu) - t0;
if (domain_cost > sd->max_newidle_lb_cost)
@@ -7583,7 +7759,8 @@ static void rebalance_domains(struct rq
}
if (time_after_eq(jiffies, sd->last_balance + interval)) {
- if (load_balance(cpu, rq, sd, idle, &continue_balancing)) {
+ if (load_balance(cpu, rq, sd, idle, &continue_balancing,
+ SP_REBALANCE_DOMAINS)) {
/*
* The LBF_DST_PINNED logic could have changed
* env->dst_cpu, so we can't know our idle
diff -uprNw -X linux-4.1.vanilla/Documentation/dontdiff '--exclude=*tools*' '--exclude=install*' linux-4.1.vanilla/kernel/sched/sched.h linux-4.1.sched_profiler/kernel/sched/sched.h
--- linux-4.1.vanilla/kernel/sched/sched.h 2015-06-21 22:05:43.000000000 -0700
+++ linux-4.1.sched_profiler/kernel/sched/sched.h 2016-04-30 09:34:32.047662144 -0700
@@ -14,6 +14,29 @@
#include "cpudeadline.h"
#include "cpuacct.h"
+extern void sp_set_nr_running(int *nr_running_p, int nr_running, int dst_cpu);
+extern void sp_record_scheduling_event(int event_type, int src_cpu,
+ int dst_cpu);
+extern void sp_record_scheduling_event_extra(int event_type,
+ char data1, char data2, char data3, char data4,
+ char data5, char data6, char data7, char data8);
+extern void sp_record_load_change(unsigned long load, int cpu);
+
+enum {
+ SP_SCHED_EXEC = 0,
+ SP_TRY_TO_WAKE_UP,
+ SP_WAKE_UP_NEW_TASK,
+ SP_IDLE_BALANCE,
+ SP_REBALANCE_DOMAINS,
+ SP_MOVE_TASKS = 10,
+ SP_ACTIVE_LOAD_BALANCE_CPU_STOP = 20,
+ SP_CONSIDERED_CORES_SIS = 200,
+ SP_CONSIDERED_CORES_USLS,
+ SP_CONSIDERED_CORES_FBQ,
+ SP_CONSIDERED_CORES_FIG,
+ SP_CONSIDERED_CORES_FIC
+};
+
struct rq;
struct cpuidle_state;
@@ -1306,7 +1329,7 @@ static inline void add_nr_running(struct
{
unsigned prev_nr = rq->nr_running;
- rq->nr_running = prev_nr + count;
+ sp_set_nr_running(&rq->nr_running, prev_nr + count, cpu_of(rq));
if (prev_nr < 2 && rq->nr_running >= 2) {
#ifdef CONFIG_SMP
@@ -1332,7 +1355,7 @@ static inline void add_nr_running(struct
static inline void sub_nr_running(struct rq *rq, unsigned count)
{
- rq->nr_running -= count;
+ sp_set_nr_running(&rq->nr_running, rq->nr_running - count, cpu_of(rq));
}
static inline void rq_last_tick_reset(struct rq *rq)
4.9.x/
\ No newline at end of file
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e9c009dc3a4a..7687f5ca8eb6 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -3474,7 +3474,30 @@ static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
}