読者です 読者をやめる 読者になる 読者になる

kernel

try_charge()めも2

前回の続き 前回はここの2238行目のpage_counter_try_charge()を読んだのでその下からです。 2236 if (!do_swap_account || 2237 !page_counter_try_charge(&memcg->memsw, batch, &counter)) { 2238 if (!page_counter_try_charge(&memcg->memory, batch, &…

try_charge()の処理めも(1)

chargeの処理としてはこの辺が重要だろうと思われる(要出典)try_charge()の処理を読みましょう。 早速処理を見ていきますが、まず対象のmemcgがルートのmemcgだった場合は何もしません。このチェックはmem_cgroup_is_root()で行えます。次にconsume_stock(…

mem_cgroup_try_charge()の処理めも

commitの前にmem_cgroup_try_charge()を呼んでいるので、commitの処理では重要な関数。 mem_cgroup_try_charge()自体はそんなに処理はなくて、メインなのはtry_charge()関数。mem_cgroup_try_charge()の処理は memcgが無効なら何もしないで終了。 5468 if (m…

Linux 4.11から入った参照カウンタのAPIめも

security things in Linux v4.11を読んでて参照カウンタ用のAPIが4.11に入ったとのことなので軽くめもです。 利用にはinclude/refcount.hをインクルードします。実装はlib/refcount.cです。 機能的には変数は実態はatomic_t型のrefcount_tという型が作られて…

memcgで実際に課金してるところめも

mm/memcontorl.cのmem_cgroup_charge_statistics()のとこです。カーネルは毎度ながら4.1.15。 mem_cgroup_charge_statistics()のコードはこんな感じです。見たままですね。 828 static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg, 829 str…

commit_charge()の処理

mem_cgroup_commit_charge()から呼ばれるcommit_charge()の処理のめも。 呼び出しはこうですね。mem_cgroup_commit_charge()で渡された引数がそのまま渡ります。 5522 void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, 5523 boo…

mem_cgroup_commit_charge()の処理

カーネルは4.1.15。mem_cgroup_commit_charge()はchargeの処理で呼ばれる関数。 今回はここで使われる関数の詳細は調べないで、大まかな流れを把握するのが目標。 LXRで検索するとmm/filemap.cとかmm/swapfile.c、mm/memory.cなんかから呼ばれてます。 mem_c…

mem_cgroup_charge_common()はだいぶ前に消えていた (; ・`д・´) ナ、ナンダッテー !! (`・д´・ (`・д´・ ;)

昨日の続きです。 4.10にあるドキュメントには課金の処理ではmem_cgroup_charge_common()を使うよーなんて書いてあったんですが、この関数はだいぶ昔になくなってました。 3.15で消えたようです。さらに言うと、このパッチで使用している__mem_cgroup_commit…

Documentation/cgroup-v1/memory.txtのめも

コードではなくてドキュメントもたまには読みましょうということで、Documentation/cgroup-v1/memory.txtです。 accounting == 課金です。以下のめもは本文を自分が分かれば良い程度に大雑把に意訳した感じです。 機械翻訳はとかしてないので安心ですね? 2.…

memory cgroupの初期化処理辺りを読む

誰得なめも。バージョンは4.1.15。 __initがついているのは以下の3関数。 mem_cgroup_init() enable_swap_account() mem_cgroup_swap_init() 当たり前だけど、__initがあるのでカーネル起動時の初期化で呼ばれる。 mem_cgroup_init()はこのような関数。 577…

cgroupのv1とv2の切り分け的なところ

cgroupはv1とv2という2つの実装(と言っていいのか?)があってそれらはkernel/cgroup.cで一つのコードベースにまとまっているのでコード読んでで混乱するなーというところで、誰得なめもを。 特に、4.1とかのカーネルだとv2のコードはまだ正式版となってな…

Linuxカーネルのコードネームの扱いが不憫なので/proc/sys/kernel/codenameで読めるようにした

たぶん、この辺の会話から Linuxカーネルのコードネームって気にした事無いな— int $0x03@SNS部 (@masami256) 2017年1月30日 この記事に繋がってたりするのかな?なんて思ったりということで、 さらに話を続けてみてですね、こんなpatchを書きました。4.10.0…

Linuxカーネルのライブパッチを使ってテスト用のstubを作る

この記事はLinux Advent Calendar 2016の1日目の記事です。 テストする時にstubって便利ですよね。最近はnodejsで仕事のコードを書いているのでsinon便利だなとか思ってます。じゃあ、Linuxカーネルでもstub作れたら便利だよねという思うわけです。そうする…

作成したファイル(struct dentry *)の読み書き用バッファをプロセス等固有に持たせるめも

たとえば、debugfsのディレクトリとファイルをプロセス毎に作って、ファイルの中身はプロセスごとに変えたいってことをしたい場合にどうするかというメモです。 foobarという機能がdebugfsのルートディレクトリにディレクトリを作成して、piyoというプロセス…

Linuxのカーネルモジュールがロードされるアドレス範囲

カーネルモジュールがロードされるアドレスって範囲決まってたはずだけど、自分で言っといてホントそうだったけ?とか思ったので確認。 @RKX1209 たしかmodule mapping spaceだと思った… https://t.co/4rH8h4G3rS— int $0x03 (@masami256) 2016年10月4日 調…

pid cgroupのコードを読む

この記事はLinuxカーネルもくもく会 #24 - connpassで書いてます。今日は前に追加されたcgroupsのpid管理のコードを読んでみます。 ファイルはcgroup_pids.cです。Linux 4.7のコードを対象にします。 最初にデータ構造です。pidの場合はpids_cgroup構造体が…

bccめも:bpf_probe_read()

bpf_probe_read()は3番目の引数を安全に読み出すためのものという認識で間違ってないとは思うけど。 linuxカーネルのsamples/bpf/bpf_helpers.hを見ると引数名はunsafe_ptrとかなってるし。strpcyとかだとinvalid opcode的なエラーになったので、この辺を使…

Linux 2.0.40の頃のkmalloc()

たまには古いカーネルでも読んでみましょう的なところで、Linux 2.0.40の頃はkmalloc()はどんな実装だったのかというところでも見てみましょう。最近のkmalloc()の実装は使用しているディストーションが採用しているスラブアローケータの__kmalloc()の実装を…

Linux 4.7の新機能「perf trace calls stack」めも

kernelnewbies.orgのLinux Changesを見てて良さげだなと思った「perf trace calls stack」のめもを。 基本的な使い方は説明が書かれているので、 perfでread、open、closeシステムコールを指定する場合。 masami@saga:~/tmp$ sudo perf trace -e read,open,c…

linux 4.7でライブパッチ用のカーネルモジュールにelfのセクションチェックが入ったのでめも

Linux 4.7からライブパッチ用のカーネルモジュールをロードする時にELFのセクションをチェックするようになりました。 このチェックが入ったこととで、今までのモジュールを再コンパイルするだけだと以下のようなエラーになってロードに失敗します。 [ 153.8…

linux kernelのlivepatchにライブパッチを適用する・しないの判断機能を入れて遊ぶ

2016年7月13日〜15日で行われたLinuxCon Japan 2016のセッションでカーネルハックの一環でカーネルのlivepatchの機能を使って、FreeBSDのバイナリをLinuxで動かすってセッションに参加して、そういう使い方もありだなと思ったのでちょっと試してみました。ア…

Linuxカーネルのコードを読んで勉強になったこと

Linuxカーネルのコードを読んでて、なるほど〜と思うことはよくあるけど、その中でも特に今までの考え方をぶち壊してくれたのはなんだっけと思ったところ、やっぱりリスト構造かなと言うところ。 c言語でリスト構造を作る場合、一般的な教科書方式だと↓のよ…

page cacheの検索と作成・登録

詳解Linuxカーネル読書会 - 詳解Linuxカーネル読書会 | Doorkeeperのもくもく結果。今日はページキャッシュの処理を調べました。 参考資料はUnderstanding Linux Kernelですが、長いので赤本と呼びます。 kernelは4.6を参照 buffer_head構造体の初期化。 buf…

free(1)のtotalとかusedなどの各項目をカーネルの方から見てみる

free(1)は/proc/meminfoを読みに行くので、Linuxカーネルでどのような変数を見せているのかを調べてみます。カーネルのバージョンは4.5です。あ、swapのほうは今回は見ません。 最初に見るのはfs/proc/meminfo.cで、このファイルが/proc/meminfoに対する操作…

Linuxカーネルのコマンドラインはブートローダーからどう渡されるのか?

先日参加した自作OSもくもく会で「Linuxカーネルのコマンドラインはブートローダーからどう渡されるのか?」のような話が聞こえたので、調べようと思い調べてみました。確認はLinux kernel v4.5とsystemd-bootの2016/05/02 23:00 JSTのコードです。 uefiじゃ…

systemptapでプロセスが所属する各pid名前空間におけるpid番号を取得

systemptapでプロセスが所属する各pid名前空間におけるpid番号を取得する方法のめも。 プロセスのPIDは普通に見れますが、そこで見えているPIDというのは自身が所属しているPID名前空間においてのものです。なので、あるプロセスがunshareなりでpid名前空間…

Linux: pid numberからtask_structの取得

pid numberからtask_structの取得のめも pid番号から直接task_structは取得できないので、pid構造体の取得 -> task_struct構造体の取得という流れになる。 pid名前空間を気しなくて良い場合は、find_get_pid()でpid構造体を取得し、pid_task()でtask_struct…

Linux netns: グローバルなNet Namespace

グローバルなnsproxyに設定するNet Namespaceの変数のinit_nsめも これはコンパイル時にはリストしか初期化していないので、その他のデータはカーネルの起動時に初期化してます。 35 struct net init_net = { 36 .dev_base_head = LIST_HEAD_INIT(init_net.d…

Linux net namespace: pernet_deviceめも

Linuxのnet namespaceにpernet_listというpernet_operation構造体のリストがあって、これがどのように設定されてるのかのめもです。 読んでるカーネルのバージョンは4.1です。 pernet_listを使ってるところは以前書いたこちらの記事にあります。 kernhack.ha…

exit(2)とpid namespaceめも

プロセスが終了するときにもpid namespaceが関係するので、その辺りのめもです。 流れとしてはこんな感じです。 do_exit()@kernel/exit.c -> exit_notify@kernel/exit.c -> forget_original_parent()@kernel/exit.c -> find_child_reaper()@kernel/exit.c ->…

perf-reportめも

Linux 4.5からperf reportのソート方針がちょっと変わっているので忘れないようにメモ。 こんな感じでprobeを設定し、 perf probe -a _do_fork こうやって実行する。 perf record -e probe:_do_fork -aR sleep 10 そして、perf reportを使った場合、 perf re…

kallsymsのめも

/proc/kallsymsをスクリプトで読むときにちょっとハマったので。 なにかというと、下の出力で、ext4_file_operationsはext4モジュールに含まれているというのがわかります。で、_do_forkのほうはモジュールにないので3カラム目まで。 masami@saga:~$ grep ex…

bccでuprobes

前回(LinuxのBPFとbccでデバッグする - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ)はbccを使ってkprobeでカーネル内の関数にprobeを設定したので今回はユーザーランドのほうでuprobesを使うメモ。 fork()が呼ばれたときにプロセス名、pid等を表示する。 …

LinuxのBPFとbccでデバッグする

最近公開されたスライドでLinuxのパフォーマンスチューニングとかDTraceで有名なBrendan GreggさんのLinux BPF Superpowersが面白かったのでBPFとbccに手を出してみました。 BPFはLinuxカーネルのパケットフィルタリングの機能で、その名の通りBerkeley Pack…

systemtapでカーネルの関数を呼ぶメモ

systemtapのスクリプトでカーネル関数を呼ぶのはどうやんだっけ?というところのメモです。 c言語の関数を作って、それを呼び出す形で実装しました。systemtapのマニュアル 3 Components of a SystemTap scriptの3.5~3.7にcの関数を組み込む方法の説明があり…

strncpy_from_user()を読んで見る

なんとなくLinuxカーネルのライブラリにあるstrncpy_from_user()を読んでみます。 ファイルはlib/strncpy_from_user.cです。 関数名から何をするかは想像つきますね。関数はこうなってます。 99 long strncpy_from_user(char *dst, const char __user *src, …

IPC名前空間を調べる(2)

IPC名前空間の初期化で、名前空間のリソース初期化をするこれらの関数は特にこれと言った処理はありません。 mq_init_ns() sem_init_ns() msg_init_ns() shm_init_ns() 各リソースがシステムコールが呼ばれた時にどのように使われるのか?というところに関し…

IPC名前空間を調べる(1)

IPC名前空間で使う構造体とか読んでいきます。まずは簡単に全体像を把握するところからです。 まずはipc_namespace構造体。ファイルはinclude/linux/ipc_namespace.hです。 21 struct ipc_namespace { 22 atomic_t count; 23 struct ipc_ids ids[3]; 24 25 i…

create_pid_namespace()の処理を読む。

最近はfork/clone時のプロセス番号の発行あたりを読んできたので、今回はPID名前空間の生成部分を読んでみます。 処理を行うのはcreate_pid_namespace()です。clone(2)の場合、ここに至る流れはこうなっています。 do_fork() -> copy_process() -> copy_name…

fork/clone時に返すpidの設定(2)

前回のfork/clone時に返すpidの設定(1) - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモの続きです。alloc_pid()を見ていきます。 その前に、pid構造体のnumbers変数はサイズ1の配列として宣言されていますが、pidの処理ではindex番号1とかそれ以上の場所にア…

fork/clone時に返すpidの設定(1)

fork/clone時にpidがどのように決まるのか見てみます。見ているのはカーネル v4.1です。今回はどういう流れで処理されているかを見ていきます。 pidの設定は数カ所でやっていて、copy_process()、copy_namespaces()、do_fork()内でcopy_process()をあります…

setnsの実装を読む

カーネル4.3でのsetnsの実装を読みます。 setns()はkernel/nsproxy.cにあり、30行程度の短い関数です。 流れとしてはこのようになります。 移動先の名前空間のfdからns_common構造体を取得 nsproxyの作成 移動先名前空間のinstall()を呼んで名前空間のほうに…

Linuxカーネルのデバッグでprintk(9)デバッグを卒業したいっ!

この記事はLinux Advent Calendar 2015の25日目の記事です。 Linuxカーネルのデバッグである意味一番手軽なのがprintk(9)によるデバッグだと思うんですが(ユーザランドのプログラムで言うところのprintf(3)デバッグ)、この場合h速いCPUを積んだマシンなら…

glibcのmalloc(3)とLinuxカーネルのovercommitとOOM

この記事はLinux Advent Calendar 2015の23日目です。 glibcのmalloc(3)とLinuxカーネルのovercommitとOOMの関連でも見てみようと思います。Linuxカーネルのシステムコールにはmalloc(3)的なものはないので、mmap(2)、brk(2)が使われます。 今回知りたかった…

Linux 4.0(x86_64)のメモリレイアウト

この記事はLinux Advent Calendar 2015の2日目の記事です。 今日は復習も兼ねてメモリレイアウトの確認です。 見るのはDocumentation/x86/x86_64/mm.txtです。見ているのは4.0ですが、4.3も同じでした。 で、メモリーマップですが下記のように説明されていま…

fedora カーネルパッケージのバージョンの付け方の謎

このタイトルだと謎とは何ぞや?となる人が多いと思います・・・ どういうことかというと、2015/11/12の時点ではカーネル 4.4のマージウィンドウが開いている段階で、カーネルのMakefileに書かれているバージョンは4.3です。 これを書いている時の最新のコミ…

Linuxのスケジューラのデータ構造めも

Linuxのスケジューラはランキューには赤黒木を使っていて〜というところは見聞きしたことありますが、実際にどんなデータを使っていて、それらの関係は?と思ったので調べてみました。 スケジューラに関連する構造体はこれらのものがあります。 struct sched…

sched_setscheduler(2)の挙動めも

ちょっとsched_setscheduler(2)の動作を調べていたのでそのメモを。 見ているのはlinux kernel 4.2。 sched_setscheduler(2)はkerne/sched/core.cにある。 ここは単なる入り口でpolicyが0以下の場合にエラーを返す程度で、その他の処理はdo_sched_setschedul…

kmem_cache_alloc_bulk()を試してみる

lwn.netの2015/09/10の記事でLinuxの4.3にkmem_cache_alloc_bulk()とkmem_cache_free_bulk()のスラブキャッシュをがっつり確保するための関数が入ったと書かれていたので試してみました。 最初のパッチはslab: infrastructure for bulk object allocation an…

PID名前空間で名前空間を普通の時と多段にしたときでgetpid(2)にかかる速度を見てみる

PID名前空間で名前空間をとくに使わない時(CONFIG_PID_NS=yな環境で特に分離させてない時)とPID名前空間の分離を多段でやってみた時で、getpid(2)に影響があるのかどうかというのを見てみました。 まず、getpid(2)の仕組みですが、これは以前書いたCLONE_N…