Gomdol Kim

rousalome.egloos.com

포토로그



Workqueue(2) - kernel workqueue 종류 Workqueue

system_wq
보통 ISR 핸들러 및 notifier call에서 주로 쓰는 workqueue이며, 멀티 코어 환경에서 동작한다. 
crash> workqueue_struct.name,flags 0xed40cc00 -p
  name = "events\
  flags = 0
 
system_wq = $1 = (struct workqueue_struct *) 0xed40cc00 
system_wq workqueue를 접근하는 API는 아래와 같다. 
static inline bool schedule_work_on(int cpu, struct work_struct *work)
{
             return queue_work_on(cpu, system_wq, work);
}
static inline bool schedule_work(struct work_struct *work)
{
             return queue_work(system_wq, work);
}
 
static inline bool schedule_delayed_work_on(int cpu, struct delayed_work *dwork,
                                                                       unsigned long delay)
{
             return queue_delayed_work_on(cpu, system_wq, dwork, delay);
}
static inline bool schedule_delayed_work(struct delayed_work *dwork,
                                                                    unsigned long delay)
{
             return queue_delayed_work(system_wq, dwork, delay);
}

 


system_highpri_wq
가장 높은 nice 우선 순위 -20 워커들이 워크를 처리한다. 
보통 CPU Hotplug 동작으로 CPU off되기 직전 worker pool에서 돌던 work를 workqueue_cpu_down_callback() 함수에서 이 system_highpri_wq queue한다.  

crash> workqueue_struct.flags,name 0xed40ccc0 –p

  flags = 0x10  //<<-- WQ_HIGHPRI

  name = "events_highpri\000\000\000\000\000\000\000\000\000"

 

crash> p system_highpri_wq

system_highpri_wq = $30 = (struct workqueue_struct *) 0xed40ccc0


아래 코드 주석문을 잘 이해하자. 

static int workqueue_cpu_down_callback(struct notifier_block *nfb,...)

{

// ... skip ...

             switch (action & ~CPU_TASKS_FROZEN) {

             case CPU_DOWN_PREPARE:

                           /* unbinding per-cpu workers should happen on the local CPU */

                           INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn);

                           queue_work_on(cpu, system_highpri_wq, &unbind_work);


system_unbound_wq
특정 cpu로 등록되어 호출되지 않고, 동일한 액션으로 2개 이상 동시 처리하지 않는 성격의 작업에 사용한다.
한 번에 하나씩만 처리되므로 요청한 작업은 즉각 동작한다. 주의: max_active 제한까지 스레드 수가 커질 수 있음 
crash> p system_unbound_wq
system_unbound_wq = $2 = (struct workqueue_struct *) 0xed40a300
crash> workqueue_struct.name,flags 0xed40a300 -p
  name = "events_unbound\000\000\000\000\000\000\000\000\000"
  flags = 2  // WQ_UNBOUND


system_freezable_wq
system_wq과 유사하게 동작하는데, suspend되는 경우 freeze 가능한 작업로 쓴다.
작업 중 suspend 요청이 오면 다른 워크큐는 마저 다 처리하지만 이 워크큐는 그대로 freeze하고 복구(resume)한 후에 동작을 계속한다. suspend/resume 시 정확한 synchronize 동작을 위해 쓰인다.
system_freezable_wq = $3 = (struct workqueue_struct *) 0xed40ce40
crash> workqueue_struct.name,flags  0xed40ce40 -p
  name = "events_freezable\000\000\000\000\000\000\000"
  flags = 4 // WQ_FREEZABLE

system_power_efficient_wq
절전 목적으로 성능을 약간 희생하여도 되는 작업에 사용한다.
crash> p system_power_efficient_wq
system_power_efficient_wq = $4 = (struct workqueue_struct *) 0xed40cf00
 
crash> workqueue_struct.name,flags  0xed40cf00 -p
  name = "events_power_efficient\000"
  flags = 0x80  // WQ_POWER_EFFICIENT = 1 << 7,

덧글

댓글 입력 영역