{"id":4622,"date":"2021-05-23T22:22:20","date_gmt":"2021-05-23T13:22:20","guid":{"rendered":"https:\/\/now0930.pe.kr\/wordpress\/?p=4622"},"modified":"2021-05-23T22:22:53","modified_gmt":"2021-05-23T13:22:53","slug":"linux-kernel-%ec%a4%91-container_of-%ec%9d%b4%ed%95%b4%ec%99%80-%ec%82%ac%ec%9a%a9","status":"publish","type":"post","link":"https:\/\/now0930.pe.kr\/wordpress\/linux-kernel-%ec%a4%91-container_of-%ec%9d%b4%ed%95%b4%ec%99%80-%ec%82%ac%ec%9a%a9\/","title":{"rendered":"linux kernel \uc911 container_of \uc774\ud574\uc640 \uc0ac\uc6a9"},"content":{"rendered":"\n<p>container_of\ub97c \uc0ac\uc6a9\ud558\uc5ec double linked list\ub85c \uc5f0\uacb0\ub41c task_struct\uac00 \uac00\uc9c4 \ub2e4\ub978 \uba64\ubc84\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub2e4. \uc790\uc138\ud55c \uc6d0\ub9ac\ub294 \ubaa8\ub974\uaca0\uc9c0\ub9cc, \ucef4\ud30c\uc77c\ub7ec\uac00 offset\uc744 \uace0\uc815\uc2dc\ud0a4\ub294\ub370, \uad6c\uc870\uccb4\ub97c \ubbf8\ub9ac \uc54c\uace0 \uc788\uae30\ub54c\ubb38\uc5d0, \uac70\uafb8\ub85c \uc138\uc5b4 \ub098\uac00\ub294 \uc6d0\ub9ac\uc778 \ub4ef \ud558\ub2e4. \uc774\uac83\uc740 \uae30\uc220\uc778\uac00? \uc794\uba38\ub9ac\uc778\uac00? \ub450 \ubc88 \ud0d0\uc0c9\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\uae30 \ub54c\ubb38\uc5d0 \ub9ce\uc740 \ubd80\ubd84\uc5d0\uc11c \uc0ac\uc6a9\ub41c\ub2e4 \ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc720\uc800 \ud504\ub85c\uc138\uc2a4 raspbian_proc\uac00 printf\ub85c \uae00\uc790\ub97c \ucd9c\ub825\ud558\uace0, sleep\uc73c\ub85c 3\ucd08\ub3d9\uc548 \ub300\uae30\ud55c\ub2e4. \ud504\ub9b0\ud2b8 \ub420 \ub54c wake_up_process \ud568\uc218\ub97c \uc2e4\ud589\ud55c\ub2e4. \uc774 \ubd80\ubd84\uc5d0\uc11c list_head\ub85c \uc5f0\uacb0\ub41c next, prev task_struct\ub97c \ubcf4\uae30\ub85c \ud588\ub2e4. \uc798 \uc548\ub41c\ub2e4.<\/p>\n\n\n\n<p>\uc2f1\uae00 \ud3ec\uc778\ud130\ub97c \uc0ac\uc6a9\ud558\uba74 next \uad6c\uc870\uccb4\ub85c \uc811\uadfc\ud560 \uc218 \uc5c6\ub2e4. double \ud3ec\uc778\ud130\ub85c \uc5b4\ub5bb\uac8c \uc5b4\ub5bb\uac8c \uc798 \uad6c\ud574\ub0b4\uc57c \ud55c\ub2e4. \ucee4\ub110 \ud328\uce58\ub97c \ud558\ub2e4\ud558\ub2e4 \uc548\ub418\uc5b4, \uc784\uc2dc\ub85c \ud504\ub85c\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uc5b4 gdb\ub85c \ud30c \ubcf4\uc558\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;stddef.h>\n\n\/\/ Copied from linux\/kernel.h\n#define container_of(ptr, type, member) ({                      \\\n\t\tconst typeof( ((type *)0)->member ) *__mptr = (ptr);    \\\n\t\t(type *)( (char *)__mptr - offsetof(type,member) );})\n\n\nstruct myStruct { int a, b; struct myStruct *next; struct myStruct *prev;char name[10];};\n\n\n\n\/\/struct myStruct { int a, b; };\n\nint main()\n{\n\n\t\/\/.\uc740 \uad6c\uc870\uccb4 \ub0b4\ubd80 \uba64\ubc84\ub97c \uc9c0\uce6d.\n\tstruct myStruct var = {.a = 0, .b = 0, .next=NULL, .prev=NULL, .name=\"first\"}; \n\tstruct myStruct var2 = {.a = 2, .b = 2, .next=NULL, .prev=NULL, .name=\"second\"}; \n\tstruct myStruct var3 = {.a = 3, .b = 3, .next=NULL, .prev=NULL, .name=\"third\"}; \n\n\n\t\/\/ next\ub85c \uae30\ubcf8 \uac12 \ub418\ub294 \ub4ef.\n\t\/*\n\tvar.ptr = (struct list_head*)&amp;(var2.ptr);\n\tvar2.ptr = (struct list_head*)&amp;(var3.ptr);\n\tvar3.ptr = (struct list_head*)&amp;(var.ptr);\n\t*\/\n\n\tvar.next = &amp;(var2);\n\tvar2.next = &amp;(var3);\n\tvar3.next = &amp;(var);\n\n\tvar.prev = &amp;(var3);\n\tvar2.prev = &amp;(var);\n\tvar3.prev = &amp;(var2);\n\n\n\t\/\/var.ptr->prev = (struct list_head*)&amp;(var3.ptr);\n\t\/\/var2.ptr->prev = (struct list_head*)&amp;(var.ptr);\n\t\/\/var3.ptr->prev = (struct list_head*)&amp;(var2.ptr);\n\n\n\t\/\/var2.ptr->prev= var3.ptr;\n\t\/\/\n\tstruct myStruct* target;\n\tstruct myStruct** tmp;\n\ttmp = &amp;(var2.next);\n\ttmp = &amp;(*tmp)->next;\n\tprintf(\"test name: %s, var address %p, a value = %d\\n\", (*tmp)->name, *tmp, (*tmp)->a);\n\t\/\/var2.next\ub97c \uac00\ub9ac\ud0a4\ub294  var3\n\ttarget=container_of((struct myStruct**)tmp, struct myStruct, next); \n\tprintf(\"test2 name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\n\ttarget=container_of(&amp;var.next, struct myStruct, next); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\ttarget=container_of(&amp;var2.next, struct myStruct, next); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\ttarget=container_of(&amp;var3.next, struct myStruct, next); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\n\t\/\/prev\ub85c \uac80\uc0c9.\n\ttarget=container_of(&amp;var.prev, struct myStruct, prev); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\ttarget=container_of(&amp;var2.prev, struct myStruct, prev); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\ttarget=container_of(&amp;var3.prev, struct myStruct, prev); \n\tprintf(\"name: %s, var address %p, a value = %d\\n\", target->name, target, target->a);\n\n\n\t\/\/int *memberPointer = &amp;var.b;\n\/\/\n\/\/\tint *memberPointer = &amp;var.a;\n\/\/\n\/\/\tprintf(\"Struct addr=%p\\n\", &amp;var);\n\/\/\n\/\/\tstruct myStruct *newSp = container_of(memberPointer, struct myStruct, b); \n\/\/\n\/\/\tprintf(\"Struct addr new=%p\\n\", newSp);\n\/\/\n\/\/\tif(newSp == &amp;var)\n\/\/\t{   \n\/\/\t\tprintf(\"It's equal.\\n\");\n\/\/\t}   \n\/\/\n\treturn 0;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pi@raspberrypi:~\/RaspberryDebug\/taskAddress $ .\/a.out \ntest name: first, var address 0xbef413e0, a value = 0\ntest2 name: third, var address 0xbef413a8, a value = 3\nname: first, var address 0xbef413e0, a value = 0\nname: second, var address 0xbef413c4, a value = 2\nname: third, var address 0xbef413a8, a value = 3\nname: first, var address 0xbef413e0, a value = 0\nname: second, var address 0xbef413c4, a value = 2\nname: third, var address 0xbef413a8, a value = 3<\/pre>\n\n\n\n<p>struct myStruct** tmp;<br>tmp = &amp;(var2.next);<br>tmp = &amp;(*tmp)->next; <\/p>\n\n\n\n<p>tmp\uac19\uc774 \uc774\uc911 \ud3ec\uc778\ud130\ub85c \uc811\uadfc\ud574\uc57c var2.next\uc5d0 \ud574\ub2f9\ud558\ub294 var3\uc744 target\uc73c\ub85c \ubc1b\uc744 \uc218 \uc788\ub2e4. \ud3ec\uc778\ud130 \uc5f0\uc0b0\uc790 \uc6b0\uc120\uc21c\uc704\ub3c4 \uc880 \uc2e0\uacbd\uc368\uc57c \ud574\uc11c, (*tmp)\ub97c \uba3c\uc800 \uc4f0\uace0 -> \ub85c next\uc5d0 \uc811\uadfc\ud574\uc57c \ud55c\ub2e4. \ub108\ubb34 \ud5f7\uac08\ub9b0\ub2e4. list_head* next, prev\ub3c4 \ub354\ube14 \ud3ec\uc778\ud130\ub2e4. \uc774\ub97c gdb\ub85c \uaca8\uc6b0 \uc54c\uc544\ub0b4\uace0, \ucee4\ub110 core.c \ucf54\ub4dc\ub97c \uc880 \uc218\uc815\ud588\ub2e4. \ucee4\ub110\uc744 \ub514\ubc84\uadf8\ud558\uba74 \uc88b\uc73c\ub098, \uadf8\ub7f0 \ubc29\ubc95\uc740 \uc5c6\uace0, trace32\ub098 kgdb\ub4f1 \ubc29\ubc95\uc744 \ucc3e\uc544\uc57c \ub41c\ub2e4. \ube44\uc2f8\uac70\ub098 \ud798\ub4e4\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[21:52:04]>cat linux\/kernel\/sched\/core.c  | head -2180 | tail -50\n\t\tttwu_activate(rq, p, ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK);\n\t}\n\n\tttwu_do_wakeup(rq, p, 0, rf);\n\tttwu_stat(p, smp_processor_id(), 0);\nout:\n\traw_spin_unlock(&amp;p->pi_lock);\n}\n\n\/**\n * wake_up_process - Wake up a specific process\n * @p: The process to be woken up.\n *\n * Attempt to wake up the nominated process and move it to the set of runnable\n * processes.\n *\n * Return: 1 if the process was woken up, 0 if it was already running.\n *\n * This function executes a full memory barrier before accessing the task state.\n *\/\nint wake_up_process(struct task_struct *p)\n{\n\t\/\/2021. 5. 23\ucd94\uac00\n\tstruct task_struct* tmp;\n\tstruct list_head **tmp2;\n\tif ( !strcmp (p->comm, \"raspbian_proc\")) {\n\t\t\/\/printk(\"[+]test activated\\n\");\n\t\ttmp2 = (struct list_head**)(p->tasks.next);\n\t\ttmp = container_of(tmp2, struct task_struct, tasks.next);\n\t\tprintk(\"[=]pid[%d], [%s] point %p at %p \\n\",\n\t\t\t\tp->pid, p->comm, p->tasks.next, &amp;p->tasks.next);\n\t\tprintk(\"[+]%s point %p at %p\\n\", tmp->comm, tmp->tasks.next, &amp;tmp->tasks.next);\n\t\tprintk(\"[-]%s point %p at %p\\n\", tmp->comm, tmp->tasks.prev, &amp;tmp->tasks.prev);\n\t\t\/\/printk(\"[==]p->task.next: %p, p: %p\\n\", &amp;p->tasks.next, &amp;p);\n\t\t\/\/\n\n\t}\n\n\t\/\/2021. 5. 16\ucd94\uac00\n\n\n\treturn try_to_wake_up(p, TASK_NORMAL, 0);\n}\nEXPORT_SYMBOL(wake_up_process);\n\nint wake_up_state(struct task_struct *p, unsigned int state)\n{\n\treturn try_to_wake_up(p, state, 0);\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pi@raspberrypi:~\/RaspberryDebug\/process $ .\/raspbian_proc \nraspbian tracing \nraspbian tracing \nraspbian tracing <\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[   12.482776] Bluetooth: BNEP (Ethernet Emulation) ver 1.3\n[   12.482790] Bluetooth: BNEP filters: protocol multicast\n[   12.482811] Bluetooth: BNEP socket layer initialized\n[   12.602761] Bluetooth: hci0: unexpected event for opcode 0x0c52\n[   43.549185] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 \n[   43.549191] [+]kworker\/2:4 point 1d830555 at fb675b81\n[   43.549195] [-]kworker\/2:4 point e45574a0 at 71182716\n[   46.549300] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 \n[   46.549309] [+]kworker\/2:4 point 1d830555 at fb675b81\n[   46.549317] [-]kworker\/2:4 point e45574a0 at 71182716\n[   49.549442] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 \n[   49.549452] [+]kworker\/2:4 point 1d830555 at fb675b81\n[   49.549460] [-]kworker\/2:4 point e45574a0 at 71182716<\/pre>\n\n\n\n<p>\uc5ec\ub7ec \uc0ac\uc774\ud2b8\ub97c \ucc38\uc870 \ud588\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/kamang-it.tistory.com\/entry\/Cclangcontainerof%EC%99%80-offsetof%EB%A1%9C-%EB%A9%A4%EB%B2%84-%EB%B3%80%EC%88%98%EB%A1%9C-%ED%95%B4%EB%8B%B9-%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/digiconfactory.tistory.com\/entry\/C%EC%96%B8%EC%96%B4-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-Doubly-Linked-List-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/stackoverflow.com\/questions\/21398105\/accessing-structure-elements-via-double-pointers-in-c\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/doomsodradek.blogspot.com\/2017\/06\/c-struct-warning-assignment-from.html\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>container_of\ub97c \uc0ac\uc6a9\ud558\uc5ec double linked list\ub85c \uc5f0\uacb0\ub41c task_struct\uac00 \uac00\uc9c4 \ub2e4\ub978 \uba64\ubc84\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub2e4. \uc790\uc138\ud55c \uc6d0\ub9ac\ub294 \ubaa8\ub974\uaca0\uc9c0\ub9cc, \ucef4\ud30c\uc77c\ub7ec\uac00 offset\uc744 \uace0\uc815\uc2dc\ud0a4\ub294\ub370, \uad6c\uc870\uccb4\ub97c \ubbf8\ub9ac \uc54c\uace0 \uc788\uae30\ub54c\ubb38\uc5d0, \uac70\uafb8\ub85c \uc138\uc5b4 \ub098\uac00\ub294 \uc6d0\ub9ac\uc778 \ub4ef \ud558\ub2e4. \uc774\uac83\uc740 \uae30\uc220\uc778\uac00? \uc794\uba38\ub9ac\uc778\uac00? \ub450 \ubc88 \ud0d0\uc0c9\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\uae30 \ub54c\ubb38\uc5d0 \ub9ce\uc740 \ubd80\ubd84\uc5d0\uc11c \uc0ac\uc6a9\ub41c\ub2e4 \ud55c\ub2e4.<\/p>\n","protected":false},"author":1,"featured_media":4625,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[12],"tags":[915,53,798,912],"class_list":["post-4622","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-12","tag-container_of","tag-linux","tag-raspberry","tag-912"],"jetpack_featured_media_url":"https:\/\/now0930.pe.kr\/wordpress\/wp-content\/uploads\/2021\/05\/kernel_core.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4622","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/comments?post=4622"}],"version-history":[{"count":3,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4622\/revisions"}],"predecessor-version":[{"id":4626,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4622\/revisions\/4626"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/media\/4625"}],"wp:attachment":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/media?parent=4622"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/categories?post=4622"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/tags?post=4622"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}