SlideShare une entreprise Scribd logo
1  sur  25
Télécharger pour lire hors ligne
Workqueueの話
2014/3/28
第109回、カーネル読書会
あなたは誰ですか?
● 吉田 茂
● ミラクル・リナックス
● Linuxサポートエンジニア
● カーネル素人
最初の貢献
commit 0515973ffb16c2852a1bb1df2ca1456556faaaa5
Author: Shigeru Yoshida <shigeru.yoshida@gmail.com>
Date: Sun Nov 17 12:12:36 2013 +0900
sched: Fix a trivial typo in comments
Fix a trivial typo in rq_attach_root().
Signed-off-by: Shigeru Yoshida <shigeru.yoshida@gmail.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20131117.121236.1990617639803941055.
shigeru.y
Signed-off-by: Ingo Molnar <mingo@kernel.org>
最初の貢献
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a1591ca..718730d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4762,7 +4762,7 @@ static void rq_attach_root(struct rq *rq, struct
root_doma
cpumask_clear_cpu(rq->cpu, old_rd->span);
/*
- * If we dont want to free the old_rt yet then
+ * If we dont want to free the old_rd yet then
* set old_rd to NULL to skip the freeing later
* in this function:
*/
Concurrency Managed Workqueue
● プロセスコンテキストで非同期に処理を実行
● 処理(コールバック関数)をキューに登録
● ワーカスレッドがキューに登録された処理を実
行
従来のWorkqueue
w0
w1
w2
10ms5ms 5ms
10ms5ms
10ms5ms
50ms
スレッド数=1
Documentation/workqueue.txt
CPUが遊ぶ
w0
w1
w2
10ms5ms 5ms
10ms5ms
10ms5ms
50ms
スレッド数=1
Concurrency Managed Workqueue
w0
w1
w2
10ms5ms 5ms
10ms5ms
10ms5ms
25ms
スレッド数>=3
スレッドプール
Thread
Thread
Thread
Thread Thread
CPU
Job Queue Thread Pool
CPUスケジューラ
ジョブスケジューラ
スレッドプールの悩みどころ
● より多くのJobを受け入れる
→スレッドが増えオーバヘッドが増える
● スレッドの数を制限する
→CPUが遊ぶ
● どのくらいのスレッド数にするか?
→動的にがんばる
2段スケジューラ
Thread
Thread
Thread
Thread Thread
CPU
Job Queue Thread Pool
CPUスケジューラ
ジョブスケジューラ
カーネル
ユーザ(ライブラリ)
すべてはカーネルが知っている
Thread
Thread
Thread
Thread Thread
CPU
Job Queue Thread Pool
CPUスケジューラ
ジョブスケジューラ
全部カーネル!!
APIを読む(1/2)
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func;
};
schedule_work(struct work_struct *work)
-> queue_work(system_wq, work)
-> queue_work_on(WORK_CPU_UNBOUND, wq, work)
-> __queue_work(cpu, wq, work)
-> insert_work(pwq, work, worklist, work_flags)
APIを読む(2/2)
static void insert_work(struct pool_workqueue *pwq,
struct work_struct *work, struct list_head *head,
unsigned int extra_flags)
{
struct worker_pool *pool = pwq->pool;
set_work_pwq(work, pwq, extra_flags);
list_add_tail(&work->entry, head); // キューにつなぐ
get_pwq(pwq);
smp_mb();
if (__need_more_worker(pool))
wake_up_worker(pool); // ワーカスレッドを起こす
}
ワーカスレッドを読む(1/4)
static int worker_thread(void *__worker)
{
struct worker *worker = __worker;
struct worker_pool *pool = worker->pool;
// ワーカスレッドには特別なフラグを立てる
worker->task->flags |= PF_WQ_WORKER;
woke_up:
spin_lock_irq(&pool->lock);
if (unlikely(worker->flags & WORKER_DIE)) {
spin_unlock_irq(&pool->lock);
worker->task->flags &= ~PF_WQ_WORKER;
return 0;
}
worker_leave_idle(worker); // idleスレッドの数を数える
ワーカスレッドを読む(2/4)
recheck:
if (!need_more_worker(pool))
goto sleep;
if (unlikely(!may_start_working(pool)) &&
manage_workers(worker))
goto recheck;
worker_clr_flags(worker, WORKER_PREP | WORKER_REBOUND);
ワーカスレッドを読む(3/4)
do {
struct work_struct *work =
list_first_entry(&pool->worklist,
struct work_struct, entry);
if (likely(!(*work_data_bits(work) & WORK_STRUCT_LINKED))) {
// ?????
/* optimization path, not strictly necessary */
process_one_work(worker, work);
if (unlikely(!list_empty(&worker->scheduled)))
process_scheduled_works(worker);
} else {
move_linked_works(work, &worker->scheduled, NULL);
process_scheduled_works(worker);
}
} while (keep_working(pool));
worker_set_flags(worker, WORKER_PREP, false);
ワーカスレッドを読む(4/4)
sleep:
if (unlikely(need_to_manage_workers(pool)) &&
manage_workers(worker))
goto recheck;
worker_enter_idle(worker); // idleスレッドの数を数える
// スリープ
__set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(&pool->lock);
schedule();
goto woke_up; // 起床したら関数のはじめへ
}
CPUスケジューラを読む
static void __sched __schedule(void)
{
... // 変数宣言
need_resched:
preempt_disable();
cpu = smp_processor_id();
rq = cpu_rq(cpu);
rcu_note_context_switch(cpu);
prev = rq->curr; // 現在のプロセスを選択
if (sched_feat(HRTICK))
hrtick_clear(rq);
CPUスケジューラを読む(1/3)
smp_mb__before_spinlock();
raw_spin_lock_irq(&rq->lock);
switch_count = &prev->nivcsw;
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
if (unlikely(signal_pending_state(prev->state, prev))) {
prev->state = TASK_RUNNING;
} else {
deactivate_task(rq, prev, DEQUEUE_SLEEP);
prev->on_rq = 0;
if (prev->flags & PF_WQ_WORKER) {
struct task_struct *to_wakeup;
to_wakeup = wq_worker_sleeping(prev, cpu);
if (to_wakeup)
try_to_wake_up_local(to_wakeup);
}
}
switch_count = &prev->nvcsw;
}
CPUスケジューラを読む(2/3)
pre_schedule(rq, prev);
if (unlikely(!rq->nr_running))
idle_balance(cpu, rq);
put_prev_task(rq, prev);
next = pick_next_task(rq); // 次のプロセスを選択
clear_tsk_need_resched(prev);
rq->skip_clock_update = 0;
if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count;
context_switch(rq, prev, next); // コンテキストスイッチ
cpu = smp_processor_id();
rq = cpu_rq(cpu);
} else
raw_spin_unlock_irq(&rq->lock);
CPUスケジューラを読む(3/3)
post_schedule(rq);
sched_preempt_enable_no_resched();
if (need_resched())
goto need_resched;
}
まとめ
Thread
Thread
Thread
Thread Thread
CPU
Workqueue Thread Pool
①work(仕事)をリストに追加
②ワーカスレッドがwork
(仕事)をこなす
③ワーカスレッドが
スリープ
④次のワーカスレッドにバ
トンタッチ!!
最後に…
『詳解Linuxカーネル 第3版』 2007, v2.6.11
『Linuxカーネル2.6解読室』 2006, v2.6.15
『Linux Kernel Architecture』 2008,
v2.6.24
『Linux Kernel Development』 2010, v2.6.34
おしまい

Contenu connexe

Tendances

Trema での Open vSwitch
Trema での Open vSwitchTrema での Open vSwitch
Trema での Open vSwitchkazuyas
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Mori Shingo
 
Windowsでも使えるシェル
Windowsでも使えるシェルWindowsでも使えるシェル
Windowsでも使えるシェルTetsuya Hasegawa
 
わたしを支える技術
わたしを支える技術わたしを支える技術
わたしを支える技術yoku0825
 
Docker+CoreOS+GCEで自動スケール分散レイトレ
Docker+CoreOS+GCEで自動スケール分散レイトレDocker+CoreOS+GCEで自動スケール分散レイトレ
Docker+CoreOS+GCEで自動スケール分散レイトレperyaudo
 
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題Makoto Setoh
 
ocsとselってコマンド作ったわよ
ocsとselってコマンド作ったわよocsとselってコマンド作ったわよ
ocsとselってコマンド作ったわよxztaityozx
 
ラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよnpsg
 
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 TokyoYoshiyuki Asaba
 
Apache Auroraの始めかた
Apache Auroraの始めかたApache Auroraの始めかた
Apache Auroraの始めかたMasahito Zembutsu
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するshigeki_ohtsu
 
How to backup your mroonga database?
How to backup your mroonga database?How to backup your mroonga database?
How to backup your mroonga database?yoku0825
 
Dive into dockerネットワーク
Dive into dockerネットワークDive into dockerネットワーク
Dive into dockerネットワークKazuyuki Mori
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
MySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLはMySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLはyoku0825
 
Nuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyNuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyogawatti
 
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーションイルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーションyoku0825
 

Tendances (20)

Trema での Open vSwitch
Trema での Open vSwitchTrema での Open vSwitch
Trema での Open vSwitch
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
Windowsでも使えるシェル
Windowsでも使えるシェルWindowsでも使えるシェル
Windowsでも使えるシェル
 
わたしを支える技術
わたしを支える技術わたしを支える技術
わたしを支える技術
 
Openresty
OpenrestyOpenresty
Openresty
 
Docker+CoreOS+GCEで自動スケール分散レイトレ
Docker+CoreOS+GCEで自動スケール分散レイトレDocker+CoreOS+GCEで自動スケール分散レイトレ
Docker+CoreOS+GCEで自動スケール分散レイトレ
 
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
 
ocsとselってコマンド作ったわよ
ocsとselってコマンド作ったわよocsとselってコマンド作ったわよ
ocsとselってコマンド作ったわよ
 
ラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよ
 
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
 
Apache Auroraの始めかた
Apache Auroraの始めかたApache Auroraの始めかた
Apache Auroraの始めかた
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
 
How to backup your mroonga database?
How to backup your mroonga database?How to backup your mroonga database?
How to backup your mroonga database?
 
Docker やってみた
Docker やってみたDocker やってみた
Docker やってみた
 
Dive into dockerネットワーク
Dive into dockerネットワークDive into dockerネットワーク
Dive into dockerネットワーク
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
Hello, systemd
Hello, systemdHello, systemd
Hello, systemd
 
MySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLはMySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLは
 
Nuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyNuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlify
 
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーションイルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
 

Similaire à Introduction to workqueue

コンテナ情報交換会2
コンテナ情報交換会2コンテナ情報交換会2
コンテナ情報交換会2Masahide Yamamoto
 
Docker調査20150704
Docker調査20150704Docker調査20150704
Docker調査20150704HommasSlide
 
OpenFlowで覚えるネットワーク
OpenFlowで覚えるネットワークOpenFlowで覚えるネットワーク
OpenFlowで覚えるネットワークM Hagiwara
 
MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2学 松崎
 
2012/03/31 Apacheスタートスクリプト読書会発表資料
2012/03/31 Apacheスタートスクリプト読書会発表資料2012/03/31 Apacheスタートスクリプト読書会発表資料
2012/03/31 Apacheスタートスクリプト読書会発表資料Yasutaka Hamada
 
第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西Masahide Yamamoto
 
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版今さら聞けない人のためのDocker超入門 CentOS 7.2対応版
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版VirtualTech Japan Inc.
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0Kiwamu Okabe
 
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002Takeshi Kuramochi
 
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月VirtualTech Japan Inc.
 
140607 lib o-mini_con-ryoon
140607 lib o-mini_con-ryoon140607 lib o-mini_con-ryoon
140607 lib o-mini_con-ryoonRyo ONODERA
 
(IDEユーザのための) ClojureのEmacs開発環境について
(IDEユーザのための) ClojureのEmacs開発環境について(IDEユーザのための) ClojureのEmacs開発環境について
(IDEユーザのための) ClojureのEmacs開発環境についてKazuhiro Hara
 
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
A story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kA story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kKenji Aoyama
 
LibreOffice を Windows 上でビルドする UPDATE2
LibreOffice を Windows 上でビルドする UPDATE2LibreOffice を Windows 上でビルドする UPDATE2
LibreOffice を Windows 上でビルドする UPDATE2Tomofumi Yagi
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試したy-uti
 
今さら聞けない人のためのDocker超入門
今さら聞けない人のためのDocker超入門今さら聞けない人のためのDocker超入門
今さら聞けない人のためのDocker超入門Toru Miyahara
 

Similaire à Introduction to workqueue (20)

コンテナ情報交換会2
コンテナ情報交換会2コンテナ情報交換会2
コンテナ情報交換会2
 
Docker調査20150704
Docker調査20150704Docker調査20150704
Docker調査20150704
 
OpenFlowで覚えるネットワーク
OpenFlowで覚えるネットワークOpenFlowで覚えるネットワーク
OpenFlowで覚えるネットワーク
 
MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2
 
2012/03/31 Apacheスタートスクリプト読書会発表資料
2012/03/31 Apacheスタートスクリプト読書会発表資料2012/03/31 Apacheスタートスクリプト読書会発表資料
2012/03/31 Apacheスタートスクリプト読書会発表資料
 
第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西
 
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版今さら聞けない人のためのDocker超入門 CentOS 7.2対応版
今さら聞けない人のためのDocker超入門 CentOS 7.2対応版
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002
OpenStack を NetApp Unified Driver と NFS Copy Offload を使って拡張する Vol.002
 
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月
今さら聞けない人のためのDocker超入門 – OpenStack最新情報セミナー 2015年4月
 
TripleO Deep Dive
TripleO Deep DiveTripleO Deep Dive
TripleO Deep Dive
 
140607 lib o-mini_con-ryoon
140607 lib o-mini_con-ryoon140607 lib o-mini_con-ryoon
140607 lib o-mini_con-ryoon
 
(IDEユーザのための) ClojureのEmacs開発環境について
(IDEユーザのための) ClojureのEmacs開発環境について(IDEユーザのための) ClojureのEmacs開発環境について
(IDEユーザのための) ClojureのEmacs開発環境について
 
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_walinspectについて調べてみた!(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
A story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kA story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88k
 
LibreOffice を Windows 上でビルドする UPDATE2
LibreOffice を Windows 上でビルドする UPDATE2LibreOffice を Windows 上でビルドする UPDATE2
LibreOffice を Windows 上でビルドする UPDATE2
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試した
 
Maatkitの紹介
Maatkitの紹介Maatkitの紹介
Maatkitの紹介
 
今さら聞けない人のためのDocker超入門
今さら聞けない人のためのDocker超入門今さら聞けない人のためのDocker超入門
今さら聞けない人のためのDocker超入門
 

Introduction to workqueue