티스토리 뷰

운영체제/스케줄러

CFS Bandwidth

로또_ 2019. 9. 14. 01:43

CFS Bandwidth

테스크 그룹별로 shares 값을 설정하여 cfs 태스크의 스케줄 할당 비율을 조절할 수 있습니다. 여기서 또 다른 cfs 태스크의 스케줄 할당 비율을 조절할 수 있는 cfs bandwidth 방법을 소개합니다.

 

테스크 그룹에 매 cfs_period_us 기간 마다 cfs_quota_us 기간 만큼 런타임을 할당하여 사용한다. 소진되어 런타임 잔량이 0이하가 되면 다음 period가 오기 전까지 남는 시간은 스로틀링 한다. 즉 해당 그룹을 대표하는 스케줄 엔티티가 상위 cfs 런큐로부터 dequeue되어 활동을 잠시 정지하게 된다. 이렇게 하여 다른 태스크 그룹에게 시간 할당을 양보한다.

 

  •  cfs_period_us
    • bandwidth 기간 (us)
  • cfs_quota_us
    • bandwidth 할당 쿼터 (us)
    • 디폴트 값으로 -1(무제한)이 설정되어 있으며, 이 때에는 cfs bandwidth가 동작하지 않는다.

 

다음은 루트 태스크 그룹에 설정된 cfs_period_us와 cfs_quota_us 값을 보여줍니다. 디폴트로 cfs_quota_us 값이 -1이 설정되어 cfs bandwidth가 활성화되어 있지 않음을 알 수 있습니다.

 


 

다음 용어들이 빈번이 나오므로 먼저 요약합니다.

 

  • cfs runtime
    • cfs 런큐에 태스크가 스케줄되어 동작한 시간
  • 스로틀
    • period 기간동안 quota 만큼 다 소진하면 나머지 시간을 해당 태스크 그룹에 해당하는 스케줄 엔티티를 dequeue 하여 타임할당을 받지 않는다.
    • 스로틀 후 period 시각이 되면 다시 태스크 그룹에 해당하는 스케줄 엔티티를 엔큐한다.
  • quota 정수 비율 (normalize cfs quota)
    • period 기간에 대한 quota 기간의 비율을 정수로 변환한 값이다.
    • 100%=1M(1,048,576)이다.
    • 예 1) period=10ms, quota=5ms인 경우 50%이며 이 비율을 quota 정수 비율로 표현하면 524,288이다.
    • 예 2) period=10ms, quota=20ms인 경우 200%이며 이 비율을 quota 정수 비율로 표현하면 2,097,152이다.

 


 

 

bandwidth가 적용된 사례 3개를 확인하려고 합니다.

 

사례 1) 다음 그림은 20ms 주기마다 10ms quota 만큼 cfs 스케줄되는 모습을 보여줍니다. 남는 시간은 스로틀링 합니다.

  • 범례 설명
  • cfs running
    • 해당 태스크 그룹에 소속된 cfs 태스크들이 사용한 런타임 구간입니다.
  • cfs 스로틀
    • 해당 태스크 그룹이 dequeue되고 해당 태스크 그룹 외의 다른 cfs 태스크들이 동작하는 구간입니다.
    • 동작할 태스크가 하나도 없는 경우 idle 합니다.
  • other 스케줄러
    • 해당 태스크 그룹의 스케줄 엔티티가 아닌 태스크들이 먼저 스케줄되어 동작하는 경우입니다.
    • 물론 다른 태스크 그룹의 cfs 태스크 이외에도 dl 이나 rt 태스크는 cfs 태스크보다 우선 순위가 더 빠르기 때문에 언제든지 other 스케줄러 표시에 들어갈 수 있습니다.

 

  • 1 번째 period 구간은 해당 그룹이 먼저 동작하고 주어진 quota 만큼의 런타임을 다 소진하고 스로틀링 하여 다른 태스크들에게 스케줄링을 넘겼습니다.
  • 2 번째 period 구간이 되면서 다시 quota 만큼 런타임을 재충전(refill) 받아 다시 모두 사용하고 또 스로틀링하였습니다.
  • 3 번째 period 구간에서 other(stop, rt, dl) 스케줄러가 먼저 할당되어 동작하고 끝나면서 해당 그룹의 cfs 태스크가 수행됨을 알 수 있습니다.
  • 9 번째 period 구간과 같이 어쩔 수 없이 해당 태스크 그룹이 사용할 수 있는 10ms quota 만큼의 런타임을 소진하지 못하는 경우도 있음을 알 수 있습니다.

 

 

사례 2) 다음 그림은 20ms 주기마다 2개의 cpu에 총 20ms quota 만큼 cfs 스케줄합니다.

 

  • period와 quota가 같은 경우 2개의 cpu가 주어지면 일반적으로 매 period 마다 2 개의 cpu가 번갈아 가면서 런타임이 소진됩니다.
  • cpu가 두 개라 period와 quota 기간이 같아도 절반의 여유가 있음을 확인할 수 있습니다.
  • 가능하면 스로틀링한 cpu에 런타임을 우선 할당하여 스로틀링이 교대로 됨을 알 수 있습니다.
  • 8 번째 period 구간의 경우 해당 태스크 그룹은 한 번도 런타임 소진을 못한 경우입니다.

 

 

사례 3) 다음 그림은 20ms 주기마다 2개의 cpu에 총 30ms quota 만큼 cfs 스케줄합니다.

  • 해당 태스크 그룹은 최대 75%의 cfs 런타임 할당을 받는 것을 확인할 수 있습니다.

 

 

다음 그림은 G1 태스크 그룹에 period, quota=25의 밴드위드를 설정하여 동작시켰을 때의 이해를 돕기 위해 더 자세히 표현하였다.

  • 다만 다음 항목들은 적용하지 않았습니다.
    • G1 그룹에 대한 엔티티 로드 weight 값에 tg_weight 비율을 적용하지 않고 그냥 shares를 사용하였습니다.
    • 태스크 6개 모두 idle 코드가 없다고 가정하였습니다.

 

주요 전역 변수 값

  • sysctl_sched_cfs_bandwidth_slice
    • 디폴트 값은 5000 (us) = 5 (ms)
    • “/sys/fs/kernel/sched_cfs_bandwidth_slice_us” 파일로 설정
    • 로컬 풀의 요구에 따라 글로벌 풀(tg)로부터 로컬(per cfs_rq) 풀로 런타임을 빌려와서 할당해주는 기간
  • min_cfs_rq_runtime
    • 디폴트 값은 1,000,000 (ns) = 1 (ms)
    • 로컬 풀에서 최소 할당 받을 런타임
  • min_bandwidth_expiration
    • 디폴트 값은 2,000,000 (ns) = 2 (ms)
    • 최소 남은 period 만료 시각으로 이 기간 내에서는 slack 타이머를 활성화시키지 않는다.
  • cfs_bandwidth_slack_period
    • 디폴트 값은 5,000,000 (ns) = 5 (ms)
    • slack 타이머 주기

 

CFS Runtime

그룹내에서 CFS bandwidth를 사용 시 스로틀링을 위해 남은 quota(runtime) 산출에 사용했던 CFS runtime의 구현 방법들은 다음과 같이 진화하였다.

  • 1) cfs hard limits: cfs bandwidth 적용 초기에 구현된 방법
  • 2) hybrid global pool: 현재 커널에서 구현된 방법으로 cfs bandwidth v4에서 소개되었다.

나머지는 다음에...

반응형