Gomdol Kim

rousalome.egloos.com

포토로그



Workqueue(1) - 기본 설정 Flags Workqueue

[1]: WQ_UNBOUND
worker를 per-cpu로 등록하지 않고(pool workqueue 생성 안함) 현재 CPU로 work를 할당한다.

[2]: WQ_FREEZABLE
Power Consumption을 위해 suspend로 진입할 때 시스템 절전을 위해 suspend 상태로 빠지는 경우 플러싱을 한다.
이 때 기존 워크들이 다 처리되고 새로운 워크들을 등록하지 않고 suspend에 진입한다.

[3]: WQ_MEM_RECLAIM
메모리 부족으로 Page Reclaim에도 수행되는 동안에도 반드시 동작해야 할 경우 쓰인다.
idle 워커가 부족하여 새로운 워커를 할당 받아 동작해야 하는 경우 메모리 부족으로 인해 새로운 워커를 할당받지 못하는
 비상 상황에서 쓰기 위해 이 플래그가 사용되어 만들어둔 rescue 워커(함수: rescuer_thread)로 워크 실행을 의뢰한다.
(example): 등록  

static int ext4_fill_super(...)

{

           EXT4_SB(sb)->rsv_conversion_wq =

                      alloc_workqueue("ext4-rsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1); 

 

(example): rescuer_thread 등록 

           if (flags & WQ_MEM_RECLAIM) {

//snip

                      rescuer->rescue_wq = wq;

                      rescuer->task = kthread_create(rescuer_thread, rescuer, "%s", wq->name);

 

[4]: WQ_HIGH_PRI

각 workqueue의 worker_pool, 즉 struct worker_pool *cpu_pools[1]에 등록하여 다른 워크보다 더 빠른 우선 순위를 갖고 처리할 수 있게 한다.


[5]: WQ_CPU_INTENSIVE

워크들이 진입한 순서대로 빠르게 처리하는 WQ_HIGH_PRI와 달리 순서와 상관없이 빠르게 처리한다.

unbound 워크큐에 적합한 필드이다.


[6]: WQ_SYSFS

sysfs 인터페이스를 제공한다. 이 때 __WQ_ORDERED 필드와 ORing으로 등록하면 sysfs 등록이 안된다. 

crash> p &wq_subsys

$12 = (struct bus_type *) 0xc1817860 <wq_subsys>

crash> bus_type  0xc1817860

struct bus_type {

  name = 0xc14eac58 "workqueue",

  dev_name = 0x0,

//... skip...

  dev_groups = 0xc1817940 <wq_sysfs_groups>,;

 


[7]: WQ_POWER_EFFICIENT

절전 옵션에 따라 성능을 희생해도 되는 작업을 위해 사용된다.

CONFIG_WQ_POWER_EFFICIENT_DEFAULT 커널 옵션을 사용하거나 “power_efficient” 모듈 파라메터를 설정하는 경우 절전을 위해 언바운드 큐로 동작한다.


[8]: __WQ_ORDERED

WQ_HIGH_PRI 필드와 함께 쓰면 nice -20 값으로 우선순위가 설정[*1]된다.

워크풀에서 하나의 워커만 처리하도록 제한하여 워크의 FIFO 처리 순서를 보장한다.


소스 코드 

enum {

           WQ_UNBOUND             = 1 << 1, /* not bound to any cpu */  //<<--[1]

           WQ_FREEZABLE             = 1  << 2, /* freeze during suspend */ //<<--[2]

           WQ_MEM_RECLAIM                   = 1 << 3, /* may be used for memory reclaim */ //<<--[3]

           WQ_HIGHPRI                 = 1 << 4, /* high priority */ //<<--[4]

           WQ_CPU_INTENSIVE       = 1 << 5, /* cpu intensive workqueue */ //<<--[5]

           WQ_SYSFS                    = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */ //<<--[6]

           WQ_POWER_EFFICIENT    = 1 << 7,

 

           __WQ_DRAINING            = 1 << 16, /* internal: workqueue is draining */

           __WQ_ORDERED             = 1 << 17, /* internal: workqueue is ordered */

 

           WQ_MAX_ACTIVE                      = 512,     /* I like 512, better ideas? */

           WQ_MAX_UNBOUND_PER_CPU     = 4,        /* 4 * #cpus for unbound wq */

           WQ_DFL_ACTIVE            = WQ_MAX_ACTIVE / 2,

};

 


[Appendix]

[*1] 

crash> struct workqueue_attrs ordered_wq_attrs 2

struct workqueue_attrs {

  nice = 0xed422780, // 0x0

  cpumask = {{

      bits = {0xed422800}

    }},

  no_numa = 0x40

}

struct workqueue_attrs {

  nice = 0xed4227c0, // -20, 0xffffffec

  cpumask = {{

      bits = {0x0}

    }},

  no_numa = 0x0

}

(where)

crash> int 0xed422780

ed422780:  00000000                              ....

crash> int 0xed4227c0

ed4227c0:  ffffffec                              ....

 




덧글

댓글 입력 영역