Skip to content

Commit

Permalink
132nd
Browse files Browse the repository at this point in the history
  • Loading branch information
iamroot12a committed Oct 30, 2017
1 parent 6026cb2 commit b1833c6
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 9 deletions.
10 changes: 10 additions & 0 deletions arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ void (*arm_pm_idle)(void);

void arch_cpu_idle(void)
{
/* IAMROOT-12:
* -------------
* arm에서 cpuidle 드라이버 없이 idle 진입 하면 이 함수를 사용한다.
*
* armv7 -> cpu_v7_do_idle() 함수 호출
*/
if (arm_pm_idle)
arm_pm_idle();
else
Expand All @@ -149,6 +155,10 @@ void arch_cpu_idle(void)

void arch_cpu_idle_prepare(void)
{
/* IAMROOT-12:
* -------------
* arm에서는 fiq를 enable하고 idle 진입한다.
*/
local_fiq_enable();
}

Expand Down
5 changes: 5 additions & 0 deletions arch/arm/mm/proc-v7.S
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ ENDPROC(cpu_v7_reset)
*
* IRQs are already disabled.
*/

/* IAMROOT-12:
* -------------
* armv7에서 인터럽트가 들어올 때까지 클럭이 정지된다. (idle 진입 시 사용)
*/
ENTRY(cpu_v7_do_idle)
dsb @ WFI may enter a low-power mode
wfi
Expand Down
5 changes: 5 additions & 0 deletions drivers/cpuidle/cpuidle-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev,
int ret;

if (!idx) {

/* IAMROOT-12:
* -------------
* arm64의 wfi 명령을 호출하여 인터럽트가 올때까지 내부 cpu 클럭이 정지된다.
*/
cpu_do_idle();
return idx;
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/cpuidle/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)

#else

/* IAMROOT-12:
* -------------
* cpuidle 드라이버가 지정된다.
*/
static struct cpuidle_driver *cpuidle_curr_driver;

/**
Expand Down
19 changes: 13 additions & 6 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,11 @@ struct sched_domain {
unsigned int forkexec_idx;
unsigned int smt_gain;

/* IAMROOT-12:
* -------------
* nohz_idle:
* idle 진입 시 1로 설정된다.
*/
int nohz_idle; /* NOHZ IDLE status */
int flags; /* See SD_* */
int level;
Expand Down Expand Up @@ -1287,14 +1292,16 @@ struct sched_dl_entity {

/* IAMROOT-12:
* -------------
* 다음 3가지는 태스크에 주어지는 파라메터 값이다.
* 다음 3가지는 태스크에 주어지는 파라메터 값(ns 단위의 시간)이다.
* -----------------------------------------------
* dl_runtime:
* 최대 런타임 설정
* 최대 런타임 설정(WCET(Worst Case Execution Time)
* 이 시간이 지나면 dl 스케줄러가 강제로 해당 태스크를 스로틀(dequeue) 한다.
* dl_deadline:
* 상대 deadline
* 상대 deadline으로 태스크가 작업을 만료해야 하는 시간
* dl 태스크들 끼리 경쟁 시 우선 순위로 활용된다.
* dl_period:
* 주기
* dl 태스크가 깨어날 주기(우선 순위에 밀리면 보류된다)
*/
u64 dl_runtime; /* maximum runtime for each instance */
u64 dl_deadline; /* relative deadline of each instance */
Expand All @@ -1310,13 +1317,13 @@ struct sched_dl_entity {
/* IAMROOT-12:
* -------------
* runtime:
* 남은 런타임 잔량
* 남은 런타임 잔량(0 이하 시 스로틀)
*/
s64 runtime; /* remaining runtime for this instance */

/* IAMROOT-12:
* -------------
* clock이 포함된 deadline
* clock이 포함된 deadline (절대 시간, 이 값으로 RB 트리에서 정렬된다)
*/
u64 deadline; /* absolute deadline for this instance */
unsigned int flags; /* specifying the scheduler behaviour */
Expand Down
4 changes: 4 additions & 0 deletions include/linux/sched/deadline.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ static inline int dl_prio(int prio)
return 0;
}

/* IAMROOT-12:
* -------------
* prio가 0 이하 값이면 dl 태스크이다.
*/
static inline int dl_task(struct task_struct *p)
{
return dl_prio(p->prio);
Expand Down
8 changes: 8 additions & 0 deletions include/linux/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,20 @@ struct tick_sched {
/* IAMROOT-12:
* -------------
* nohz 모드(inactive, lowres, highres)
*
* inidle:
* idle 진입 시 1로 변경된다.
*/
enum tick_nohz_mode nohz_mode;
ktime_t last_tick;
int inidle;
int tick_stopped;
unsigned long idle_jiffies;

/* IAMROOT-12:
* -------------
* no_hz idle에 진입한 횟수
*/
unsigned long idle_calls;
unsigned long idle_sleeps;
int idle_active;
Expand Down
90 changes: 87 additions & 3 deletions kernel/sched/deadline.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se,

/* IAMROOT-12:
* -------------
* new dl 태스크인 경우에는 pi 태스크의 deadline을 상속받는다.
* (refill)
* new dl 태스크인 경우에는 dl_deadline 값을 사용하여 deadline을 설정한다.
* 만일 pi 발생된 경우 가장 우선 순위가 높은 pi 태스크의 dl_deadline을
* 사용하여 deadline을 설정한다.
*/
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
dl_se->runtime = pi_se->dl_runtime;
Expand Down Expand Up @@ -355,7 +356,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,

/* IAMROOT-12:
* -------------
* deadline 설정이 없는 경우에는
* deadline 설정이 0으로 된 경우 현재 시각으로 deadline을 설정한다.
* 그런데 pi boost 된 경우는 pi 태스크의 dl_deadline 값을 사용한다.
*/
if (dl_se->dl_deadline == 0) {
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
Expand Down Expand Up @@ -389,6 +391,12 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,
* resetting the deadline and the budget of the
* entity.
*/

/* IAMROOT-12:
* -------------
* deadline 만료된 경우 dl_deadline 값으로 재보충한다. (pi인 경우 ...)
* 런타임 잔량도 다시 dl_runtime으로 재보충한다.
*/
if (dl_time_before(dl_se->deadline, rq_clock(rq))) {
printk_deferred_once("sched: DL replenish lagged to much\n");
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
Expand Down Expand Up @@ -566,6 +574,10 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
unsigned long flags;
struct rq *rq;

/* IAMROOT-12:
* -------------
* deadline 타이머의 핸들러 시작 함수
*/
rq = task_rq_lock(p, &flags);

/*
Expand Down Expand Up @@ -602,11 +614,25 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
* We can be both throttled and !queued. Replenish the counter
* but do not enqueue -- wait for our wakeup to do that.
*/

/* IAMROOT-12:
* -------------
* 런타임 소진 후 태스크가 deactivate되는데 이 때부터 dl 타이머가 동작한다.
*
* 그런 후 타이머 만료에 의해 이 함수에 진입하게 된다.
*/
if (!task_on_rq_queued(p)) {
replenish_dl_entity(dl_se, dl_se);
goto unlock;
}

/* IAMROOT-12:
* -------------
* 현재 태스크보다 더 급한 태스크가 있는 경우 리스케줄한다.
*
* 이 타이머가 깨어났을 때 dl 태스크가 아닌 경우 그냥 리스케줄하여
* 무조건 dl 태스크가 동작하게 한다.
*/
enqueue_task_dl(rq, p, ENQUEUE_REPLENISH);
if (dl_task(rq->curr))
check_preempt_curr_dl(rq, p, 0);
Expand All @@ -617,6 +643,11 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
* Queueing this task back might have overloaded rq,
* check if we need to kick someone away.
*/

/* IAMROOT-12:
* -------------
* 오버로드된 pushable 태스크들을 다른 cpu로 보낸다.
*/
if (has_pushable_dl_tasks(rq))
push_dl_task(rq);
#endif
Expand Down Expand Up @@ -1180,13 +1211,24 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)

dl_rq = &rq->dl;

/* IAMROOT-12:
* -------------
* 기존 태스크가 dl 태스크인 경우(dl -> dl) 나보다 더 급한 dl 태스크를
* 가져온다.
*/
if (need_pull_dl_task(rq, prev)) {
pull_dl_task(rq);
/*
* pull_rt_task() can drop (and re-acquire) rq->lock; this
* means a stop task can slip in, in which case we need to
* re-start task selection.
*/

/* IAMROOT-12:
* -------------
* stop 스케줄러에 태스크가 발생하면 dl 보다 더 우선 순위를 가지므로
* 다시 스케줄러를 선택하게 한다.
*/
if (rq->stop && task_on_rq_queued(rq->stop))
return RETRY_TASK;
}
Expand All @@ -1201,17 +1243,35 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)
if (unlikely(!dl_rq->dl_nr_running))
return NULL;

/* IAMROOT-12:
* -------------
* 기존 태스크에 대한 것들을 정리한다.
*/
put_prev_task(rq, prev);


/* IAMROOT-12:
* -------------
* 현재 dl 런큐에서 가장 급한 태스크를 가져온다.
*/
dl_se = pick_next_dl_entity(rq, dl_rq);
BUG_ON(!dl_se);

p = dl_task_of(dl_se);
p->se.exec_start = rq_clock_task(rq);

/* Running task will never be pushed. */

/* IAMROOT-12:
* -------------
* 실행할 태스크가 pushable에 있으면 제거한다.
*/
dequeue_pushable_dl_task(rq, p);

/* IAMROOT-12:
* -------------
* 해당 dl 태스크의 runtime 잔량만큼 hrtick을 프로그램한다.
*/
if (hrtick_enabled(rq))
start_hrtick_dl(rq, p);

Expand Down Expand Up @@ -1296,6 +1356,10 @@ static struct task_struct *pick_next_earliest_dl_task(struct rq *rq, int cpu)
struct sched_dl_entity *dl_se;
struct task_struct *p = NULL;

/* IAMROOT-12:
* -------------
* 차순위 earliest 태스크를 알아온다.
*/
next_node:
next_node = rb_next(next_node);
if (next_node) {
Expand Down Expand Up @@ -1570,6 +1634,10 @@ static int pull_dl_task(struct rq *this_rq)
*/
smp_rmb();

/* IAMROOT-12:
* -------------
* 오버로드된 cpu들을 대상으로 순회한다.
*/
for_each_cpu(cpu, this_rq->rd->dlo_mask) {
if (this_cpu == cpu)
continue;
Expand All @@ -1580,6 +1648,11 @@ static int pull_dl_task(struct rq *this_rq)
* It looks racy, abd it is! However, as in sched_rt.c,
* we are fine with this.
*/

/* IAMROOT-12:
* -------------
* 현재 cpu에서 동작중인 dl의 만료시각보다 더 급한 태스크가 없으면 skip
*/
if (this_rq->dl.dl_nr_running &&
dl_time_before(this_rq->dl.earliest_dl.curr,
src_rq->dl.earliest_dl.next))
Expand All @@ -1595,13 +1668,24 @@ static int pull_dl_task(struct rq *this_rq)
if (src_rq->dl.dl_nr_running <= 1)
goto skip;

/* IAMROOT-12:
* -------------
* 오버로드된 cpu에서 차순위 dl 태스크를 알아온다.
*/
p = pick_next_earliest_dl_task(src_rq, this_cpu);

/*
* We found a task to be pulled if:
* - it preempts our current (if there's one),
* - it will preempt the last one we pulled (if any).
*/

/* IAMROOT-12:
* -------------
* 가장 급한(dmin: 오버로드된 cpu의 차순위 dl 태스크들 중 earliest deadline)
* 태스크를 찾는다. dmin을 갱신하면서 그 값보다 작은 태스크들을 다 현재
* cpu로 가져온다.
*/
if (p && dl_time_before(p->dl.deadline, dmin) &&
(!this_rq->dl.dl_nr_running ||
dl_time_before(p->dl.deadline,
Expand Down
9 changes: 9 additions & 0 deletions kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -8915,13 +8915,22 @@ void set_cpu_sd_state_idle(void)
struct sched_domain *sd;
int cpu = smp_processor_id();

/* IAMROOT-12:
* -------------
* 스케줄링 도메인에 현재 cpu가 idle로 진입함을 알린다.
*/
rcu_read_lock();
sd = rcu_dereference(per_cpu(sd_busy, cpu));

if (!sd || sd->nohz_idle)
goto unlock;
sd->nohz_idle = 1;

/* IAMROOT-12:
* -------------
* nr_busy_cpus:
* 스케줄링 그룹내에서 idle 상태가 아닌 cpu 수
*/
atomic_dec(&sd->groups->sgc->nr_busy_cpus);
unlock:
rcu_read_unlock();
Expand Down
Loading

0 comments on commit b1833c6

Please sign in to comment.