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

buddy allocator: compatctionの処理 compaction_suitable()

compaction_suitable()はcompact_zone()の最初に使う関数で、コンパクションしようとしているzoneをコンパクションするかどうか判断する。 compaction_suitable()自体はたいした処理はなく、__compaction_suitable()が実際にチェックをする。 1259 unsigned …

buddy allocatorの__zone_watermark_ok()めも

Linuxのbuddy allocatorでpage数のwatermarkをチェックしているのは__zone_watermark_ok()。そんなわけで、今日はその辺りの動作を見てみる。 __zone_watermark_ok()は他のファイルから直接呼べないので、zone_watermark_ok()を使う。例えば、mm/compaction.…

buddy allocator: compactionのざっくりとした流れ

__alloc_pages_slowpath()でcompactionの処理をする場合のざっくりとした流れをc⌒っ゚д゚)っφ メモメモ... __alloc_pages_slowpath()では__alloc_pages_direct_compact()をこのように呼んでpageの確保を試みる。 2700 /* 2701 * Try direct compaction. The first…

user_ns: task_structからuser_nsの取得めも

誰得なめも。task_structからuser_nsの取得の方法。 名前空間はstruct nsproxyで管理されているけど、user namespaceはstruct credが管理していて、user namespace以外の名前空間はその構造体にuser namespaceへのポインタを持っている。 このポインタがどう…

Linux: inodeからtask_struct構造体を取得

Namespace周りのコードを読んでいたらinodeからtask_struct構造体を取得をしているところがあって、こんなことできるんだ〜などと思ったのでどんな方法で取得するのか見てみます。 使ってた場所はproc_ns_follow_link()とかです。 ↓のように。 37 struct tas…

buddy system: __alloc_pages_slowpath()のざっくりとした流れ。

LinuxのPage Allocatorで __alloc_pages_slowpath()の流れをメモ程度に。 読んでいるカーネルのversionは4.0。 __alloc_pages_nodemask()でget_page_from_freelist()を呼んだ時にpageの確保ができなかった場合に呼ばれるのが __alloc_pages_slowpath()。 get…

buddy allocator: __rmqueue_fallback()を調べる

前回の記事では__rmqueue_smallest()を見たので、今回は __rmqueue_fallback()を見ていきます。 この関数の呼び出し元は__rmqueue()で、__rmqueue_smallest()でメモリを確保できなかった場合に実行されます。 では、処理を見ていきましょう。 __rmqueue_fall…

buddy allocator: __rmqueue_smallest()を調べる

前回の「buffered_rmqueue()めも - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ」続きとして、__rmqueue_smallest()を読みます。 これは割と分かりやすい感じです。 では、見ていきます。 関数のプロトタイプはこうなっていて、引数はpageを確保する対象のzo…

buffered_rmqueue()めも

今日はLinuxカーネルもくもく会 #12 を利用してbuffered_rmqueue()から読んでく。 buffered_rmqueue() 最初の大きな分岐はページ確保のorderが0(1page)かどうかで処理が変わる まずは1page分の場合から見ていく if文には1pageにlikelyが使われいるのでこっ…

get_page_from_freelist()の処理

前回は__alloc_pages_nodemask()を見たので、今回はそこから呼ばれ、実際にallocationを行う部分の get_page_from_freelist()を見ていきます。 基本的な流れは、 boolの変数consider_zone_dirtyにalloc_flagsとgfpフラグの値から真偽値を決める ここでgfpフ…

linux: page allocatorの辺りを読んでいこう

Linuxのpage単位のallocatorを理解したいなーというところで、mm/page_alloc.cの __alloc_pages_nodemask()を起点にコードを読み始める。 __alloc_pages_nodemask()はalloc_pages()なんかから呼ばれるところですね。 __alloc_pages_nodemask()の細かいところ…

livepatchでftraceのハンドラでセットしたInstruction Pointerがどう使われるのか調べた

Linuxのlivepatchはftraceを使って古い関数へのアクセスをフックして新しい関数を呼ぶようにしているというのは以前の記事で調べたんですが、 じゃあ、セットしたIP(Instruction Pointer)をどのように使って新しい関数に飛ばしているのか?というのが知りた…

linux: livepatchめも klp_find_object_symbol()でpatch対象関数のアドレスを探すところ

前のlinux: livepatchコードリーディングめも1 〜 patch側のデータ設定とpatchの登録まで - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモではさらっと流したklp_find_object_symbol()でpatch対象関数のアドレスを探すところを見てみる。 呼んでいる場所として…

linux: livepatchめも 新たに関数が追加れされる場合

livepatchはftraceを使って既存の関数のアドレスにフィルターをセットして、フィルターにセットしたハンドラがripを新しい関数のアドレスに置き換えて実行を継続するというのは前回の記事で分かったんだけど、新しい関数を追加する場合はどうすんだろ?と思…

linux: livepatchコードリーディングめも2 〜 patchのenable

前回の記事(linux: livepatchコードリーディングめも1 〜 patch側のデータ設定とpatchの登録まで - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ)はpatchを登録するを見たので今回はpatchを有効にする部分を見てきます。 まず、livepatch-sample.cでpatchを…

linux: livepatchコードリーディングめも1 〜 patch側のデータ設定とpatchの登録まで

Linuxカーネルもくもく会 #11でやったことです。Linux kernel 4.0 のlivepatchを調べてみる。patchとなるsamples/livepatch/にあるlivepatch-sample.cからスタートして読んでいきましょう。livepatchモジュールにpatchを登録するまでを見ていきます。 まずは…

perf probeで関数の引数も記録する

perf probeで引数とかもログ取れる?と思って確認したらできることが分かったのでその辺のめも。 例えばlong do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)の引数を記録するのはこんな感じ。filename引数は文字列として扱う…

linux: slub code reading

最近調べていたslubのkmem_cache_alloc()、kmem_cache_free()のまとめですm( )m Slub alloc and_free from Masami Ichikawa Slub alloc and_free Amazon Web Services 基礎からのネットワーク&サーバー構築作者: 玉川憲,片山暁雄,今井雄太出版社/メーカー: …

Linuxのthis_cpu_cmpxchg_double()によるpercpuなデータの交換

Linux kernelでpercpuなデータの入れ替えに使用されるthis_cpu_cmpxchg_double()のメモ。見ているカーネルは3.18。 これはマクロでlinux/include/percpu-defs.hにて下記のように定義されています。 507 #define this_cpu_cmpxchg_double(pcp1, pcp2, oval1, …

slub: [sg]et_freepointer()めも

slubのkmem_cache_alloc()、kmem_cache_free()時の[sg]et_freepointer()の動きを確かめるというめもですが、チラ裏ですm(__)m kmem_cache_alloc()を呼ぶとslubではslab_alloc_node()が呼ばれて、slabがすでにある場合はelseの方に入る。ここでget_freepointe…

slubで/sys/kernel/slab/<slab name>/以下にstruct kmem_cacheの変数をexportさせるメモ

slubでstruct kmem_cacheの各変数の値を見るのに/sys/kernel/slab//にexportさせる場合のメモ。俺得用。 見るだけなら 変数名 + _show という形で関数を作って、SLAB_ATTR_ROマクロに見たい変数名を渡す。それとslab_attrsに 変数名 + _attr.attr という形で…

slub: slabでslab名の:at-とか:t-なんかのprefixの意味

slabinfoとか/sys/kernel/slabを見た時にslab名が:で始まるものがあって、これらの意味は何なのか?というめも。 このprefixをつけているのはslub.cにあるcreate_unique_id()のこの部分。設定されているフラグの中で一部のものについてprefixが付く模様。 50…

slub: struct kmem_cache_nodeの使われ方

SLUBの場合のstruct kmem_cacheでstruct kmem_cache_node *node[MAX_NUMNODES];がどのように使われているのかというメモ。 kernelのバージョンは3.18。 struct kmem_cache_nodeはSLAB・SLUBの場合分けがifdefでされていて、debugオプション無しのSLUBの場合…

slub: freelist用にpage確保してからstruct kmem_cache_cpuを設定する辺りのメモ

new_slab_objects()がfreelistを確保するためにnew_slab()を呼んで、それが戻ってきたらという辺りのメモです。 大まかにはslub:slab objectの作成処理を見ていく - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモで書いたりしているんだけど流れが見えてきた…

Linux Kernel Hack入門編

この記事はLinux Advent Calendar 2014の25日目ですヽ(=´▽`=)ノ 今回はLinux Kernel Hack入門編ということで入門的なことを書いてみたいと思います。 まず使用する環境ですけど最近出たばっかのFedora 21のWorkstationにしました。まあ、今回の内容的にはディ…

slub: kmem_cache構造体とslab object作成時のめも

slabを作る時とallocするときで似たようなパスを通ってちょっと混乱してしまったのでその辺のメモです。 slabを作るときはkmem_cache_create()が呼ばれて、そこから呼ばれるdo_kmem_cache_create()がメイン処理。 まずslabキャッシュの作り方の復習。slabキ…

slub: objectのsize設定

slubでオブジェクト管理する上で使うサイズ等の管理のメモ。見ているカーネルはv3.17です。今回はcalculate_sizes()を見るのがメインかな。 struct kmem_cacheの中でサイズに関連するのはこの辺り。 62 struct kmem_cache { 〜略〜 67 int size; /* The size…

Linuxカーネルで見る最適化の技

この記事はLinux Advent Calendar 2014の13日目です。 LWNのACCESS_ONCE() and compiler bugsを読んでなるほどねーと思ったのでその辺について書いてみたいと思います。 最適化の技と言いつつ実際は最適化させすぎない技なんですが\(^o^)/ まずACCESS_ONCE…

slub: allocate_slabでslab object用のページ確保

この記事はLinux Advent Calendar 2014の10日目の記事です。 今回は前回の「slub:slab objectの作成処理を見ていく」で詳細を見なかったnew_slab()でpageを確保するところを見ていきます。 new_slab()では下記のようにallocate_slab()にてページの確保を行…

slub:slab objectの作成処理を見ていく

この記事はLinux Advent Calendar 2014の6日目の記事です。 今回は前回の続きではなくて(といっても流れ的には続きになるんですが)slab objectの作成部分です。 slab objectの作成はnew_slab_objects()にて行います。この関数の呼び出し元は__slab_alloc()…

Linuxカーネルでsystem callのhook

この記事はLinux Advent Calendar 2014の5日目の記事です。 Linuxカーネルのシステムコールをhookしたい場合にどうやるかという話です。試したカーネルは3.18.0-rc6です。 まずシステムコールですが、これはテーブルで管理されていて、各要素はNR_システムコ…

slubのコードを読む:__memcg_kmem_get_cacheの処理を読む

この記事はLinux Advent Calendar 2014の3日目の記事です。 kmem_cache_zalloc()、名前だけ見ると単純そうな気がするけど割とそうでもないのでした。この関数は最初のほうは別の関数へのラッパー程度になっていますが、memcg_kmem_get_cache()、__memcg_kmem…

Linuxのプロセス切り替え処理

この記事はLinux Advent Calendar 2014 1日目の記事です。 switch_toはプロセス切り替え時の処理ですね。ここを読んでみます。基本的にはアセンブラで__switch_toがcの関数となってます。 まずはプロトタイプから。引数は3個でprev,、next、 lastの3個。型は…

kmem_cache_create()のざっくりとした流れのめも

Linuxでスラブキャッシュを新しく作成する場合はkmem_cache_create()を使用する。これのラッパーとしてKMEM_CACHE()というマクロもあって、これは構造体の型名とメモリ確保時に使用するフラグ(GFP_KERNEL等)を渡すだけの便利マクロ。 処理の流れは下記の通…

Linux 3.18のrc版でiptablesが起動できなかったという話

Linux 3.18のrc(自分が気付いたのは3.18-rc2)でiptablesが動かないからkvm環境等々が動かせなくて悩んでたんだけど、とりあえずはpatchを見つけたので解決。 パッチは(nf_reject_ipv4: module license 'unspecified' taints kernel - Patchwork)です。 i…

Linux SystemV IPC: semctl()の実装を読む

semctl()を読むのは良いけどフラグによって操作が違うのでshmctl()の時と同じくIPC_RMIDの場合を読みます。 まずはsemctl()からでshmctl()と同じくIPC_SETとIPC_RMIDは同じ関数が使われます。 1569 SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, c…

Linux SystemV IPC: semop()の実装を読む

今日はsemop()の実装を。システムコール的にはsemop(2)とsemtimedop(2)の2つの関数がありますが、カーネルのsemop()側はsemtimedop(semid, sops, nsops, NULL);と呼び出してるだけなので、実体は一つです。 では、semop(2)とsemtimedop(2)の共通実装部分、と…

Linux SystemV IPC: semgetを読む

semget()は以前のエントリ(Linuxカーネル:SystemV IPC get系操作の共通実装部分を読む - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ)で書いたようにSystemV IPC共通部分と機能固有部分に分かれていて、semget()の場合はnewary()が使われます。 というわけ…

Linux SystemV IPC: shmctl()でIPC_RMIDの処理

shmctl()はセグメントの削除だけ見ておけば良いかなというところで。 shmctl()はipc()よりsys_shmctl()の呼び出しという形で呼ばれます。 そして、shmctl()の第二引数にあたるcmdの値を使ったswitchがあり、IPC_RMIDとIPC_SETの場合はshmctl_down()が呼ばれ…

Linux SystemV IPC: shmatとshmdtを読む

今日はshmat()とshmdt()を読んでみます。 shmat()はshmget()、shmdt()、shmctl()と違ってsyscall_defineは使われていなくて、ipc()からdo_shmat()を呼び出しています。 では、do_shmat()を見ていきます。 最初は変数定義が並んでいるだけなので飛ばします。 …

Linux SystemV IPC: shmgetの実装を読む

今日はipc/shm.cにあるshmget()の実装部分であるnewseg()を読んでみる。昨日の「 Linuxカーネル:SystemV IPC get系操作の共通実装部分を読む - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ」でも書いた通りSystemV IPCのxxxget()はipcget()という共通関数を…

Linuxカーネル:SystemV IPC get系操作の共通実装部分を読む

LinuxカーネルのSystemV IPC実装で共有メモリ、セマフォ、メッセージキューのget操作はある程度共通化されているのでその辺を読んでみます。 と、その前にまずはglibc側をちょっと見てます。glibcの中でLinuxのシステムコールはsysdeps/unix/sysv/linux/にあ…

linux namespace: mnt_nsが最初に作られる流れ

mnt_nsはinit_nsproxyにあるデータの中で唯一コンパイル時に値が入っていないので、どのようデータが設定されていくのかを見てみる。mnt_nsの作成はcreate_mnt_ns()で実施していて、以前のエントリー「φ(・・*)ゞ ウーン mount namespaceめも - φ(・・*)ゞ ウーン …

3.17-rc4:Kconfigのnat周りの項目に変更があったようなのでメモ

つい最新のものを使ってしまう人以外には多分関係ないだろうメモ書き。ディストリビューションのカーネルならこの辺のチェックはちゃんとしているだろうし。 Linux 3.17-rc4でnat周りの設定が変わってipv4のnatとかmasquradeを使うにはCONFIG_IP_NF_NATをyか…

user namespaceめも

user namespace以外のnamespaceはcreate_new_namespaces()で作るけどuser namespaceだけは別ルートになっているのでその辺のめも。 見ているのはLinux 3.16。 user namespaceの場合copy_creds()の処理中に以下のような形で呼ばれる。 339 if (clone_flags & …

φ(・・*)ゞ ウーン mount namespaceめも

mount namespaceを作成するカーネル側の関数としてはcreate_mnt_ns()とcopy_mnt_ns()の2つがあるんだけどcreate_mnt_ns()のほうはbtrfsとnfs4しか使っていない模様。 これら2個のコールフローは以下のような流れ。 btrfsの場合はサブボリュームをマウントす…

Linux:実行中プロセスの名前空間切り替え

Linuxで名前空間に関して設定できるのはclone(2)、unshare(2)、setns(2)で、このうち実行中のプロセスの名前空間を変更できるのは後者の2個なんですが、カーネル側ではkernel/nsproxy.cにあるswitch_task_namespaces()が実際の処理を行ってます。そんなわけ…

CLONE_NEWPIDを調べる:getpid()とpid namespace

CLONE_NEWPIDをclone(2)のflagsに付けて新しいプロセスを親プロセスと別のpid namaspaceで動かすことができますね。この時にどうやってpidを正しくプロセスに見せているのか知りたかったのでgetpid()を見てみました。 まずこんなコードを動かしてみます。あ…

Linux: コンテナ型の仮想化サポートとkuid_t、kgid_t

前回の日記でふと思ったuser_namespace構造体とは何?というのを調べているんだけどその過程で出てきたkuid_tとkgid_tのメモ。 定義自体はinclude/linux/uidgid.hにあって、このような形でとくに面白いものでもない。 20 typedef struct { 21 uid_t val; 22 …

create_new_namespaces()めも

軽くめも。fork(2)の場合は親プロセスの名前空間を引き継ぐけど、clone(2)、unshare(2)、set_ns(2)などは名前空間に関するフラグが設定でき、これはカーネル内だとcreate_new_namespaces()にて行われる。 create_new_namespaces()の処理内容としてはcreate_n…