delayacct_init()

delayacct_init()

kernel/delayacct.c

void delayacct_init(void)
{
        delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC);
        delayacct_tsk_init(&init_task);
}

CONFIG_TASK_DELAY_ACCT 커널 옵션을 사용하는 경우 task에 대한 각종 지연 stat을 얻을 수 있다.

  • cpu, 동기 블록 입출력 완료 및 페이지 스와핑과 같은 시스템 자원을 기다리는 작업에 소요되는 시간에 대한 정보를 수집합니다.
  • “nodelayacct” 커널 파라메터를 사용하는 경우 delay accounting 기능을 disable한다.

 

__delayacct_tsk_init()

kernel/delayacct.c

void __delayacct_tsk_init(struct task_struct *tsk)
{
        tsk->delays = kmem_cache_zalloc(delayacct_cache, GFP_KERNEL);
        if (tsk->delays)
                spin_lock_init(&tsk->delays->lock);
}

요청 태스크의 delays 멤버에 delayacct_cache 구조체를 할당받은 후 초기화한다.

 

delayacct_setup_disable()

kernel/delayacct.c

int delayacct_on __read_mostly = 1;     /* Delay accounting turned on/off */
EXPORT_SYMBOL_GPL(delayacct_on);
struct kmem_cache *delayacct_cache;

static int __init delayacct_setup_disable(char *str)
{
        delayacct_on = 0;
        return 1;
}
__setup("nodelayacct", delayacct_setup_disable);

“nodelayacct” 커널 파라메터를 사용하는 경우 delay accounting 기능을 disable한다.

 

Per-task Delay Accounting

delayacct_freepages_start()

include/linux/delayacct.h

static inline void delayacct_freepages_start(void)
{
        if (current->delays)
                __delayacct_freepages_start();
}

태스크의 delay accounting에 사용하기 위해 현재 시작 clock을 기록한다.

 

__delayacct_blkio_start()

kernel/delayacct.c

void __delayacct_freepages_start(void)
{
        current->delays->freepages_start = ktime_get_ns();
}

태스크의 delay accounting에 사용하기 위해 현재 시작 clock을 기록한다.

 

delayacct_freepages_end()

include/linux/delayacct.h

static inline void delayacct_freepages_end(void)
{
        if (current->delays)
                __delayacct_freepages_end();
}

태스크의 delay accounting에 사용하기 위해 시작 clock에서 현재 clock을 빼서 기록한다.

 

__delayacct_freepages_end()

kernel/delayacct.c

void __delayacct_freepages_end(void)
{
        delayacct_end(&current->delays->freepages_start,
                        &current->delays->freepages_delay,
                        &current->delays->freepages_count);
}

태스크의 delay accounting에 사용하기 위해 현재 clock에서 freepages_start clock을 빼서 freepages_delay에 delay time을 추가하고 freepages_count를 증가시킨다.

 

delayacct_end()

kernel/delayacct.c

/*
 * Finish delay accounting for a statistic using its timestamps (@start),
 * accumalator (@total) and @count
 */
static void delayacct_end(u64 *start, u64 *total, u32 *count)
{
        s64 ns = ktime_get_ns() - *start;
        unsigned long flags;

        if (ns > 0) {
                spin_lock_irqsave(&current->delays->lock, flags);
                *total += ns;
                (*count)++;
                spin_unlock_irqrestore(&current->delays->lock, flags);
        }
}

delay accounting에 사용하기 위해 현재 clock에서 인수로 전달받은 start clock을 빼서 total에 추가 하고 count를 증가시킨다.

 

getdelays 유틸리티 빌드 및 사용

  • Documentation/accounting/getdelay.c를 컴파일하여 사용한다.
    • gcc -I/usr/src/linux/include getdelays.c -o getdelays

 

./getdelays 
getdelays [-dilv] [-w logfile] [-r bufsize] [-m cpumask] [-t tgid] [-p pid]
  -d: print delayacct stats
  -i: print IO accounting (works only with -p)
  -l: listen forever
  -v: debug on
  -C: container path

 

참고

 

 

댓글 남기기