4780 lines
389 KiB
JSON
4780 lines
389 KiB
JSON
{
|
|
"schemaVersion": 4,
|
|
"project": "virtualization",
|
|
"ssot": "final/document.md",
|
|
"ssotSha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
|
|
"sourceRevision": "no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다",
|
|
"generatedAt": "2026-09-09",
|
|
"sourceRepository": {
|
|
"name": "없음 — 코드 저장소를 분석해 쓴 문서가 아니다",
|
|
"path": "/home/donghyeon/workspace/chat-gpt-container/document-haness/docs/virtualization/final/document.md",
|
|
"revision": null,
|
|
"verified": "이 프로젝트에는 분석한 저장소가 없다. 출발점은 사용자가 밖에서 쓴 문서 한 편이고, 체크아웃이 아니라 반입한 파일이 근거를 고정한다. 그래서 path 는 그 문서의 현재 자리인 final/document.md 다. 반입할 때의 원본(절 23개 · sha256 2b7b386de841f3e7b408066b39efaf183804b3d158d78d88e7fa0b7e00e08d69)은 source/kvm-cpu-virtualization-ssot.md 에 두었다가, 사용자가 §24~§28 을 더해 final/document.md 가 그 상위 집합이 된 뒤 지웠다 — heading marker 를 뺀 본문을 대조해 지워진 문장이 없음을 확인했다. 코드를 읽고 쓴 글이 아니라 고정할 커밋이 없어 revision 은 null 로 둔다. 지어내지 않는다."
|
|
},
|
|
"candidateScope": {
|
|
"document": "final/document.md",
|
|
"sections": [
|
|
"2. 전체 구조",
|
|
"3. 각 구성요소의 역할",
|
|
"4. vCPU와 vCPU Thread",
|
|
"5. Host Linux Scheduler와 실제 CPU",
|
|
"6. KVM_RUN과 Guest 실행",
|
|
"7. VM Entry와 VM Exit",
|
|
"8. 무엇이 실제로 VM Exit을 발생시키는가",
|
|
"9. VM Exit 이후 처리",
|
|
"10. Guest가 idle이면 물리 CPU는 어떻게 되는가",
|
|
"11. VM의 4 vCPU는 정확히 무엇을 의미하는가",
|
|
"12. CPU contention과 overcommit",
|
|
"13. Steal Time",
|
|
"14. 실제 Linux에서 확인할 수 있는 것",
|
|
"15. CPU 가상화 관점에서 장애를 보는 방법",
|
|
"16. 현재 Keycloak/K3s 실험과의 관계",
|
|
"17. 동시성 테스트와 부하 테스트를 분리해야 한다",
|
|
"18. Bare-metal K3s와 VM 기반 K3s의 차이",
|
|
"19. 이 SSOT에서 파생될 CONCEPT",
|
|
"20. 이 CONCEPT에서 파생되는 OPEN QUESTION",
|
|
"21. OPEN QUESTION에서 CASE가 만들어지는 흐름",
|
|
"22. 현재 단계의 핵심 Claim",
|
|
"23. 다음 단계",
|
|
"24. CPU 가상화 계층에서 발생할 수 있는 문제",
|
|
"25. CPU 문제를 계층별로 구분하는 진단표",
|
|
"26. 현재 Keycloak 실험에서 CPU 문제를 오판하지 않기 위한 기준",
|
|
"27. 문제 영역에서 파생되는 추가 OPEN QUESTION",
|
|
"28. CONCEPT -> OPEN QUESTION -> CASE 적용 기준",
|
|
"29. 이 문서에서 먼저 고정할 전체 구조",
|
|
"30. 일반 Linux의 Virtual Memory부터 시작한다",
|
|
"31. Page와 Physical Frame",
|
|
"32. Virtual Address = Page + Offset",
|
|
"33. Guest Page Table",
|
|
"34. MMU: 실제 주소 변환을 수행하는 CPU 하드웨어",
|
|
"35. TLB: 주소 변환 결과의 CPU Cache",
|
|
"36. Bare Metal과 VM의 차이",
|
|
"37. EPT(Extended Page Tables)",
|
|
"38. 왜 EPT가 필요한가",
|
|
"39. Shadow Page Table과 EPT의 의미",
|
|
"40. QEMU는 Guest RAM을 어떻게 준비하는가",
|
|
"41. KVM_SET_USER_MEMORY_REGION",
|
|
"42. Configured Memory와 실제 Physical RAM 사용량은 같지 않을 수 있다",
|
|
"43. Guest Page Table 자체도 메모리에 있다",
|
|
"44. 정상 Memory Access는 매번 VM Exit하지 않는다",
|
|
"45. Guest Page Fault",
|
|
"46. Page Fault의 대표적인 원인",
|
|
"47. EPT Violation",
|
|
"48. Guest Page Fault와 EPT Violation 비교",
|
|
"49. Host Page Fault도 별도로 존재한다",
|
|
"50. Huge Page가 필요한 이유",
|
|
"51. Huge Page와 TLB Coverage",
|
|
"52. VM에서 Huge Page를 볼 때 주의할 점",
|
|
"53. THP: Transparent Huge Pages",
|
|
"54. THP의 Trade-off",
|
|
"55. HugeTLB",
|
|
"56. THP와 HugeTLB 비교",
|
|
"57. Memory Overcommit",
|
|
"58. CPU Overcommit과 Memory Overcommit의 차이",
|
|
"59. Host Memory Pressure와 Reclaim",
|
|
"60. Host Swap이 VM에 미치는 영향",
|
|
"61. Guest Swap과 Host Swap",
|
|
"62. Memory Pressure와 Storage Contention의 연결",
|
|
"63. Swap Used만 보고 장애를 판단하면 안 된다",
|
|
"64. Ballooning이 필요한 이유",
|
|
"65. virtio-balloon 구조",
|
|
"66. Balloon Inflate",
|
|
"67. Balloon Page 반환의 의미",
|
|
"68. Balloon Deflate",
|
|
"69. Ballooning을 과도하게 하면 Guest가 압박을 받는다",
|
|
"70. Ballooning과 Memory Hotplug",
|
|
"71. OOM",
|
|
"72. Guest OOM과 Host OOM",
|
|
"73. NUMA",
|
|
"74. Local Memory와 Remote Memory",
|
|
"75. vCPU와 NUMA의 연결",
|
|
"76. vCPU Pinning만으로는 NUMA 최적화가 끝나지 않는다",
|
|
"77. Guest NUMA",
|
|
"78. NUMA는 실제 장비 topology부터 확인한다",
|
|
"79. 전체 Memory Virtualization 실행 경로",
|
|
"80. 전체 Memory Virtualization 관리 경로",
|
|
"81. CPU / Network / Storage / Memory 연결",
|
|
"82. 핵심 Claim Registry",
|
|
"83. 실제 환경에서 확인할 OPEN QUESTION",
|
|
"84. 권장 실험 순서",
|
|
"85. 실험 시 반드시 같이 기록할 것",
|
|
"86. 문제를 진단할 때의 분류",
|
|
"87. 최종 기준 그림",
|
|
"88. 결론",
|
|
"89. 문서 목적",
|
|
"90. virsh / libvirt / virtio 구분",
|
|
"91. virtio-net은 정확히 어디에 있는가",
|
|
"92. Frontend와 Backend",
|
|
"93. Guest OS는 왜 QEMU가 아니라 virtio-net을 사용하는가",
|
|
"94. 전체 네트워크 계층",
|
|
"95. Physical NIC의 역할",
|
|
"96. Linux Bridge의 역할",
|
|
"97. Routing의 역할",
|
|
"98. NAT의 역할",
|
|
"99. TAP의 역할",
|
|
"100. virtqueue의 역할",
|
|
"101. Guest TCP/IP Stack의 역할",
|
|
"102. Packet이 Keycloak까지 올라오는 과정",
|
|
"103. QEMU virtio Device Model의 역할",
|
|
"104. 왜 `TAP → vhost-net → QEMU → virtqueue`라고 일반화하면 안 되는가",
|
|
"105. Control Path와 Data Path",
|
|
"106. QEMU가 Userspace인데 packet이 QEMU를 안 거칠 수 있는 이유",
|
|
"107. vhost-net 최적화",
|
|
"108. vhost-net은 QEMU를 제거하지 않는다",
|
|
"109. Fast Path와 Slow/Control Path",
|
|
"110. Data Copy 최적화",
|
|
"111. Interrupt / Notification 최적화",
|
|
"112. Multi-Queue 최적화",
|
|
"113. Offload 최적화",
|
|
"114. Linux Bridge가 항상 Host TCP/IP Stack을 거치는 것은 아니다",
|
|
"115. Host Physical NIC로 나갈 때 virtio를 다시 거치지 않는다",
|
|
"116. 현재 Keycloak/K3s 테스트 환경과 연결",
|
|
"117. 이 구조에서 발생할 수 있는 문제",
|
|
"118. 실제 Linux에서 확인할 명령어",
|
|
"119. 실제 packet path 추적",
|
|
"120. Keycloak Refresh Token 실험과의 관계",
|
|
"121. 이 SSOT에서 파생될 CONCEPT",
|
|
"122. OPEN QUESTION",
|
|
"123. OPEN QUESTION → CASE",
|
|
"124. 핵심 Claim",
|
|
"125. 최종 기준 구조",
|
|
"126. 다음 실습 순서",
|
|
"127. 문서 목적",
|
|
"128. 전체 구조",
|
|
"129. Guest Application: `read()` / `write()`에서 시작",
|
|
"130. VFS: 공통 파일 인터페이스 계층",
|
|
"131. Filesystem(ext4/XFS): 파일 세계를 block 공간에 배치",
|
|
"132. inode",
|
|
"133. Page Cache: `write()`가 바로 SSD write는 아니다",
|
|
"134. Guest Block I/O Layer",
|
|
"135. `/dev/vda`: Guest가 보는 가상 Block Device",
|
|
"136. `/dev/vda`와 Filesystem 관계",
|
|
"137. virtio-blk: Guest의 가상 Block Device Driver",
|
|
"138. virtio-blk와 virtqueue",
|
|
"139. virtqueue의 실제 의미",
|
|
"140. VM Boundary를 넘으면 QEMU가 등장",
|
|
"141. QEMU가 물리 SSD를 직접 제어하는 것은 아니다",
|
|
"142. qcow2: Host에서는 파일, Guest에서는 디스크",
|
|
"143. qcow2 Virtual Size와 실제 Host 사용량",
|
|
"144. RAW Image",
|
|
"145. Host Block Device를 직접 backend로 사용 가능",
|
|
"146. 실제 연결 확인",
|
|
"147. VM에서는 Page Cache가 두 번 나타날 수 있다",
|
|
"148. `write()` 완료와 영속화는 다르다",
|
|
"149. Direct I/O",
|
|
"150. `fsync()`가 필요한 이유",
|
|
"151. FLUSH",
|
|
"152. 가장 위험한 상황: 거짓 완료",
|
|
"153. QEMU Cache Mode",
|
|
"154. `cache=none`",
|
|
"155. `cache=writeback`",
|
|
"156. `writeback = 위험`이라고 단정하면 안 되는 이유",
|
|
"157. Device-side Cache",
|
|
"158. Host Block Layer",
|
|
"159. 여러 VM이 하나의 NVMe를 공유하면",
|
|
"160. blk-mq: Multi-Queue Block Layer",
|
|
"161. I/O Scheduler",
|
|
"162. `none`",
|
|
"163. 실제 I/O Scheduler 확인",
|
|
"164. NVMe Driver와 Physical Device",
|
|
"165. NVMe와 SSD 구분",
|
|
"166. Storage I/O Completion",
|
|
"167. Storage Contention",
|
|
"168. CPU가 정상이어도 Storage 때문에 느릴 수 있다",
|
|
"169. Storage 관측 명령어",
|
|
"170. PostgreSQL 예시: WAL과 Durability",
|
|
"171. 성능과 Durability의 Trade-off",
|
|
"172. Storage Virtualization Canonical Flow",
|
|
"173. Network Virtualization과 비교",
|
|
"174. 핵심 Claim",
|
|
"175. 실제 테스트 서버에서 확인할 Open Questions",
|
|
"176. 권장 실습 흐름",
|
|
"177. 최종 요약"
|
|
],
|
|
"excluded": [
|
|
"1. 이 문서의 범위"
|
|
],
|
|
"excludedAnchorPattern": "#1-이-문서의-범위$",
|
|
"note": "접어 넣은 분석이 아니라 처음부터 한 편으로 쓴 개념 문서라 제2부·제3부가 없다. 대신 이 문서 자신이 네 부다 — 제1부 CPU 가상화(§1~§28) · 제2부 메모리 가상화(§29~§88) · 제3부 네트워크 가상화(§89~§126) · 제4부 스토리지 가상화(§127~§177). 네 부 모두가 후보를 찾는 범위이고 sections 는 그 절 제목을 부 순서대로 적는다. 지금 sections 에 있는 것은 제1부 §2~§28 과 제2부 §29~§88 이고, 제3부와 제4부는 그 부를 분해할 때 같은 형식으로 뒤에 덧붙인다. §1 은 이 문서가 무엇을 다루고 무엇을 안 다루는지를 선언한 자리라 후보가 나오는 곳이 아니다 — 글감이 그 선언을 근거로 인용할 수는 있어서 concept 노드의 source 에는 들어 있고, excludedAnchorPattern 은 §1 만 가리키는 앵커로 올라온 글감을 막는다. 앵커 형식은 `final/document.md#<h2 절 제목 슬러그>` 하나로 통일한다. ── 제3부(네트워크 가상화 §89~§126)를 분해하면서 그 절 제목 38개를 sections 뒤에 덧붙였다. ── 제4부(스토리지 가상화 §127~§177)를 분해하면서 그 절 제목 51개를 다시 뒤에 덧붙였다. 이제 sections 에는 네 부가 모두 들어 있다 — 제1부 §2~§28 · 제2부 §29~§88 · 제3부 §89~§126 · 제4부 §127~§177, 합쳐 176개이고 남은 부는 없다. excluded 와 excludedAnchorPattern 은 §1 그대로다."
|
|
},
|
|
"assetLedger": {
|
|
"note": "final/assets/diagrams/ 의 그림 아홉 장. 부마다 개념 기록이 한 장씩 받았고, 배정되지 않은 그림은 없다. 개념 열하나 가운데 셋은 그림을 안 받았다 — huge-pages-in-a-vm 과 qemu-block-backend-forms 는 본문의 비교표가 답해 3단계가 청구하지 않았고, memory-pressure-reclaim-swap-oom 은 4단계가 근거 절 §62 로 그리려다 멈췄다(그 절이 「Guest와 Host가 동시에 memory pressure를 겪으면」이라고 적어 순서가 없는데, techviz 가 그 문맥에서 허용하는 profile 이 순서를 요구하는 sequence 하나뿐이었다. 순서를 지어내야 그려진다).",
|
|
"assigned": [
|
|
"vm-exit-handling-cycle",
|
|
"guest-memory-address-translation-path",
|
|
"page-fault-layers-in-a-vm",
|
|
"virtio-balloon-inflate-deflate",
|
|
"numa-vcpu-and-memory-placement",
|
|
"packet-control-and-data-paths",
|
|
"guest-block-io-to-virtqueue",
|
|
"write-completion-boundaries",
|
|
"vms-sharing-one-nvme"
|
|
],
|
|
"unassigned": []
|
|
},
|
|
"contract": {
|
|
"decomposition": [
|
|
"글감을 찾는 입력은 final/document.md 하나다. 거기에 없는 근거는 먼저 SSOT 에 넣는다.",
|
|
"후보 전부는 candidates 에 처분과 함께 남고 PROMOTE 만 topics 로 올라간다.",
|
|
"없애고 관련 Case 나 Concept 의 한 절로 넣어도 이해·결정·재사용성이 그대로라면 독립 기록으로 만들지 않는다.",
|
|
"Topic 은 독자 질문 하나다. 그 물음에 답하지 않는 글감은 다른 Topic 으로 옮긴다.",
|
|
"Concept 은 Case·Decision·Question 을 먼저 고른 뒤 그것을 이해하는 데 필요한 것만 거꾸로 더한다."
|
|
],
|
|
"anchorStyle": "final/document.md#<h2 절 제목 슬러그>. 제목에서 ` * ( ) , : · — ? . / 를 공백으로 바꾸고 연속 공백을 - 로 접고 소문자로 내린 것이다.",
|
|
"readinessValues": [
|
|
"READY",
|
|
"OPEN",
|
|
"NEEDS_EVIDENCE",
|
|
"NEEDS_DECISION",
|
|
"BLOCKED"
|
|
],
|
|
"dispositionValues": {
|
|
"PROMOTE": "독립 Tech Log 로 쓴다",
|
|
"MERGE_INTO": "다른 기록의 한 절·표 행으로 흡수한다",
|
|
"KEEP_IN_SSOT": "분석에는 남기고 독립 기록으로 만들지 않는다 — 정상적인 성공 결과다",
|
|
"NEEDS_EVIDENCE": "주장에 아직 검증이 없다. 측정한 뒤에 다시 판정한다",
|
|
"NEEDS_DECISION": "방향이 그럴듯하지만 프로젝트가 정하지 않았다",
|
|
"BLOCKED": "원본이 불완전하거나 서로 어긋난다"
|
|
}
|
|
},
|
|
"note": "프로젝트 virtualization 의 SSOT 는 네 부다 — CPU(§1~§28) · 메모리(§29~§88) · 네트워크(§89~§126) · 스토리지(§127~§177). 네 부를 모두 분해했고 지금 주제는 넷, 글감은 57개다 — cpu-virtualization 13 · memory-virtualization 20 · network-virtualization 10 · storage-virtualization 14. 네 주제 모두 case 와 decision 이 0 이고 이유는 하나다 — 이 SSOT 에는 이 테스트 Host 에서 잰 값이 하나도 없고 측정이 없으면 Case 가 아니다. 아래는 부마다 무엇을 어떻게 판단했는지를 분해한 순서대로 이어 적은 기록이다. ── 제1부(CPU 가상화 §1~§28)는 주제 하나에 concept 하나로 내려앉았다. 하나로 둔 근거는 SSOT 자신이다 — §19 가 이 실행 경로를 하나의 CONCEPT 로 관리하고 여러 문서로 과도하게 분할하지 않는다고 적었고, §28 이 CONCEPT 에서 확정할 범위를 「구조적으로 어떤 문제가 발생할 수 있는가 · 어떤 지표로 의심할 수 있는가 · 어느 계층에서 확인해야 하는가」로 그었다. 검사기는 그 시점에 「Topic 에 노드가 하나뿐이다」를 warn 으로 냈다. 그것이 그때 이 프로젝트의 상태였고 노드를 늘려서 지우지 않았다 — 뒤에 §20·§27 을 재판정해 question 열둘을 올리면서 그 warn 이 사라졌다. 이 SSOT 에는 이 테스트 Host 에서 잰 값이 하나도 없다. 그 상태에서 §20·§27 의 OPEN QUESTION 열둘을 question 글감으로 올렸다 — Question 은 아직 닫히지 않은 판단을 적는 종류라 측정이 없다는 것이 올리지 못할 이유가 아니고, 값이 나오면 그때 Case 가 된다. OQ 하나에 글감 하나이고 열둘의 known 에는 SSOT 가 서술한 것만 적었다. 측정이 필요한 Claim(SSOT-22-claims-12-13)은 그대로 NEEDS_EVIDENCE 다 — 그것은 「이 환경에서 실제로 그러하다」는 주장이라 재기 전에는 Case 도 Question 도 아니다. Topic 은 하나로 두었다. 열둘이 전부 「구조적으로 가능한 문제가 이 Host 에서 실제로 일어나는가」를 묻고 있어 cpu-virtualization 의 독자 질문 뒷부분(어느 계층의 문제인지 무엇을 보고 가르는가)에 그대로 걸린다. 주제를 나누면 개념과 그 개념이 낳은 물음이 갈라진다. final/assets 의 첫 그림은 vm-exit-handling-cycle 한 장이고 assetLedger 에 배정으로 적었다 — §9 가 그린 VM Exit 이후 제어권 경로다. 이 단계에서 final/document.md 의 frontmatter 를 떼고 heading 단계를 맞췄다 — 절이 h1 이면 앵커가 가리킬 절이 없다. 절을 h2, 그 아래를 h3·h4 로 내렸고 본문 문장은 한 글자도 바꾸지 않았다. ── 제2부(메모리 가상화 §29~§88)는 절 60개이고 주제 하나 (memory-virtualization) 에 글감 20개로 내려앉았다 — concept 여섯 · reference 둘 · question 열둘, case 와 decision 은 0 이다. concept 을 여섯으로 나눈 것은 절을 훑어서가 아니라 §83 의 OPEN QUESTION 을 먼저 고른 뒤 그 물음들이 읽히려면 무엇을 미리 알아야 하는지를 거꾸로 물어서다 — 주소 변환(OQ-2·3 이 필요로 한다) · page fault 세 계층(OQ-13·14) · huge page(OQ-4·5) · 메모리 압박(OQ-6·7·14) · ballooning(OQ-8·9) · NUMA(OQ-11·12) 여섯이 그렇게 나왔고 남는 개념은 없다. CPU 부가 §19 의 「하나의 CONCEPT 로 관리하고 여러 문서로 과도하게 분할하지 않는다」를 근거로 한 편으로 묶은 것과 달리 제2부에는 그런 지시가 없고, §52·§58·§61·§70·§72 처럼 「A 와 B 는 같지 않다」로 경계를 긋는 절이 계속 나와 한 편으로 묶으면 그 경계들이 한 글의 각주가 된다. case 가 0 인 이유는 제2부에도 이 테스트 Host 에서 잰 값이 하나도 없기 때문이다 — 측정이 없으면 Case 가 아니다. §82 의 CLAIM-MEM-01~18 은 전부 메커니즘 서술이라(「~할 수 있다」·「A 와 B 는 다르다」) 여섯 개념에 나눠 흡수했고, CPU 부의 Claim 12·13 처럼 「이 환경에서 실제로 그러하다」고 주장한 것이 없어 NEEDS_EVIDENCE 로 남길 것도 없었다. §83 의 OQ 열넷 가운데 열둘만 올렸다 — OQ-1(Host NUMA topology)과 OQ-10(vCPU 가 어느 Host CPU 에 있는가)은 CPU 부의 question:host-numa-topology 가 이미 묻고 있고 그 unknown 이 「두 VM 의 vCPU 와 memory 가 어느 node 에 배치되어 있는지」를 그대로 담고 있어 MERGE_INTO 로 두었다. 같은 한 번의 측정으로 닫히는 물음을 두 편으로 만들지 않는다. 그 질문이 「SSOT 는 이 확인에 쓸 명령을 적지 않았다」고 남긴 자리에 §83 이 적은 `lscpu` · `numactl --hardware` · `virsh vcpuinfo`/`vcpupin` 이 들어간다. 넘겨받은 쪽은 OQ-11(QEMU memory 가 어느 node 에 있는가 — `numastat -p` 는 CPU 부 어디에도 없다)과 OQ-12(remote access 가 latency 를 바꾸는가)다. reference 둘은 §85 와 §86 에서 나왔다 — 열두 Question 전부에 같이 걸리는 규칙이라 각 글에 되풀이하는 대신 한 편씩으로 두었다. 제2부의 그림은 아직 없다 — assetLedger 는 그대로다. ── 제3부(네트워크 가상화 §89~§126)를 분해했다. 절 38개이고 주제 하나(network-virtualization)에 글감 10개로 내려앉았다 — concept 하나 · reference 둘 · question 일곱, case 와 decision 은 0 이다. concept 을 하나로 둔 근거는 §121 이다. 그 절이 virsh 부터 Packet tracing 까지 스물한 요소를 한 목록으로 묶고 「이 요소들이 하나의 packet 실행 경로를 설명하므로 하나의 CONCEPT 로 관리한다」고 적었다. 제1부의 §19 가 CPU 실행 경로에 대해 같은 지시를 했고 그 부도 개념 하나였다. 제2부를 여섯으로 나눈 것은 거기에 그런 지시가 없었기 때문이지 절 수가 많아서가 아니다. 넷으로 쪼개는 안 — 경로 · backend 주체(§103~§109) · Host 쪽 배선(§95~§99·§114) · 최적화(§110~§113) — 을 놓고 봤지만 SSOT 가 반대로 적은 것을 뒤집을 근거를 SSOT 안에서 찾지 못해 기각했다. case 가 0 인 이유는 제3부에도 이 테스트 Host 에서 잰 값이 하나도 없기 때문이다 — 측정이 없으면 Case 가 아니다. §124 의 Claim 1~16 은 전부 메커니즘 서술이라 개념에 흡수했고, 「이 환경에서 실제로 그러하다」고 주장한 것은 §116 하나뿐이라 그것만 NEEDS_EVIDENCE 로 남겼다 — Host Nginx 아래 VM 두 대라는 앞부분은 §89 가 밝힌 실험 구성이지만 TAP → vhost-net → virtqueue 로 펼친 뒷부분은 OQ-1·2·3·6 이 답하기 전의 가정이다. CPU 부의 SSOT-22-claims-12-13 과 같은 처분이다. §122 의 OQ 일곱은 전부 올렸다 — 다른 부의 question 이 같은 측정으로 닫는 물음이 하나도 없었다. 가장 가까운 것이 OQ-7 과 CPU 부의 question:virtualization-layer-saturation-during-refresh 인데, OQ-7 이 재라고 적은 vhost thread 와 softirq 는 제1부·제2부 어디에도 나오지 않는다(§81 의 그림에 vhost 라는 낱말이 한 번 나올 뿐이다). 두 물음은 같은 실험 구간에서 서로 다른 스레드를 재므로 relations 로만 이었다. reference 둘은 §119 와 §120 에서 나왔다. §119 는 네 지점의 capture O/X 로 끊긴 구간을 좁히는 절차이고 §120 은 그것이 network 문제인지 애플리케이션·저장소 문제인지를 가르는 귀속 규칙이라 답하는 물음이 다르다. 둘 다 적용 조건과 예외를 SSOT 가 스스로 대 준다 — §113·§114 가 앞의 예외를, §102·§116 이 뒤의 예외를 댄다. 제1부에서 §14(명령 목록)와 §15(계층 분리)를 개념으로 흡수한 것과 판단이 갈리는데, 그때 적은 이유는 「붙일 Reference 가 없다」였고 제2부가 §85·§86 으로 기준을 바꿨다. 여기서는 제2부 쪽을 따랐고 §118 의 명령 목록은 §119 의 Reference 본문 표로 들어간다. 제3부의 그림은 아직 없다 — assetLedger 는 그대로다. ── 제4부(스토리지 가상화 §127~§177)를 분해했다. 절 51개이고 주제 하나(storage-virtualization)에 글감 14개로 내려앉았다 — concept 넷 · reference 셋 · question 일곱, case 와 decision 은 0 이다. concept 을 넷으로 나눈 것은 절을 훑어서가 아니라 §175 의 OQ 여덟을 먼저 고른 뒤 그 물음들이 읽히려면 무엇을 미리 알아야 하는지를 거꾸로 물어서다 — Guest 쪽 경로(OQ-1·OQ-8 이 필요로 한다) · backend 형태(OQ-1·OQ-2·OQ-3·OQ-5) · 완료의 네 가지 뜻(OQ-4·OQ-8) · Host block stack 과 경쟁(OQ-5·OQ-6·OQ-7) 넷이 그렇게 나왔고 남는 개념은 없다. 제1부와 제3부는 §19 와 §121 이 「하나의 CONCEPT 로 관리하고 여러 문서로 과도하게 분할하지 않는다」고 적어 한 편으로 묶었지만 제4부에는 그런 지시가 없고, §144·§148·§149·§152·§156·§157·§162·§165·§167·§168·§171 처럼 「A 는 B 가 아니다」로 경계를 긋는 절이 계속 나와 한 편으로 묶으면 그 경계들이 한 글의 각주가 된다 — 제2부를 여섯으로 나눈 것과 같은 이유다. 경로를 한 장으로 그린 §128·§172·§177 은 첫 개념에 흡수했다. 네 개념이 나눠 설명하는 지도라 어느 하나가 소유하지 않지만, 경로가 시작하는 글이 그림을 열고 나머지 셋이 자기 구간을 가리키는 편이 그림 하나를 다섯 번째 기록으로 만드는 것보다 낫다 — 제2부가 §79·§87 을 같은 이유로 첫 개념에 넣었다. case 가 0 인 이유는 제4부에도 이 테스트 Host 에서 잰 값이 하나도 없기 때문이다. §143 의 100 GB/3GB 도 §168 의 CPU 30%/latency 2초 도 SSOT 가 예시로 든 값이지 이 장비에서 잰 값이 아니다. §174 의 Claim 1~6 은 전부 메커니즘 서술이라(「~할 수 있다」·「A 와 B 는 같은 의미가 아니다」) 개념 둘과 Reference 하나에 나눠 흡수했고, 제1부의 Claim 12·13 이나 제3부의 §116 처럼 「이 환경에서 실제로 그러하다」고 주장한 절이 없어 NEEDS_EVIDENCE 로 남길 것도 없었다. §175 의 OQ 여덟 가운데 일곱만 올렸다 — OQ-2(qcow2 인가 RAW 인가)는 OQ-3 과 같은 한 번의 `qemu-img info` 출력으로 닫히고 형식은 그 출력의 첫 줄이라 MERGE_INTO 로 두었다. 제2부가 OQ-1 과 OQ-10 을 합친 것과 같은 판단이다. 다른 부의 question 과는 하나도 겹치지 않았다 — 가장 가까운 둘이 OQ-7 과 제1부의 question:vcpu-contention-under-two-vm-load, OQ-8 과 제2부의 question:host-major-fault-vs-storage-latency 인데 앞의 짝은 부하 형태가 같을 뿐 재는 자원이 CPU 와 storage 로 다르고, 뒤의 짝은 한쪽이 memory pressure 로 유도한 major fault 를 보고 다른 쪽이 애플리케이션의 `fsync()` 를 보므로 유도 방법도 계열도 다르다. 둘 다 relations 로만 이었다. reference 셋은 §168·§171·§145 에서 나왔다. §168 은 지연을 CPU 로 귀속하기 전에 storage 를 따로 재라는 자원 귀속 규칙이고, §171 은 빨라진 구성이 durability contract 를 지운 것은 아닌지 가르라는 평가 규칙이고, §145 는 Guest 안에서 본 disk 로 backend 를 단정하지 말라는 확정 규칙이라 셋이 답하는 물음이 다르다. 셋 다 적용 조건과 예외를 SSOT 가 스스로 대 준다 — §167·§169·§177 이 첫째의, §149·§154·§157 이 둘째의, §143·§144 가 셋째의 예외를 댄다. NEEDS_DECISION 하나를 남겼다 — cache mode 를 무엇으로 둘 것인가는 §153~§156 이 두 설정의 뜻만 갈라 놓고 방향을 정하지 않았고, 현재 값이 무엇인지도 OQ-4 가 아직 확인하지 않았다. 제4부의 그림은 아직 없다 — assetLedger 는 그대로다.",
|
|
"topics": {
|
|
"cpu-virtualization": {
|
|
"topic": "cpu-virtualization",
|
|
"title": "CPU 가상화 — vCPU 가 물리 CPU 에서 실행되기까지",
|
|
"readerQuestion": "VM 에 준 vCPU 는 Host 의 어느 CPU 에서 언제 실행되고, Guest 안이 느릴 때 그것이 어느 계층의 문제인지 무엇을 보고 가르는가?",
|
|
"kinds": {
|
|
"case": [],
|
|
"concept": [
|
|
{
|
|
"title": "KVM 에서 vCPU 가 물리 CPU 에서 실행되기까지",
|
|
"kind": "concept",
|
|
"slug": "kvm-vcpu-to-physical-cpu",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#1-이-문서의-범위",
|
|
"final/document.md#2-전체-구조",
|
|
"final/document.md#3-각-구성요소의-역할",
|
|
"final/document.md#4-vcpu와-vcpu-thread",
|
|
"final/document.md#5-host-linux-scheduler와-실제-cpu",
|
|
"final/document.md#6-kvm_run과-guest-실행",
|
|
"final/document.md#7-vm-entry와-vm-exit",
|
|
"final/document.md#8-무엇이-실제로-vm-exit을-발생시키는가",
|
|
"final/document.md#9-vm-exit-이후-처리",
|
|
"final/document.md#10-guest가-idle이면-물리-cpu는-어떻게-되는가",
|
|
"final/document.md#11-vm의-4-vcpu는-정확히-무엇을-의미하는가",
|
|
"final/document.md#12-cpu-contention과-overcommit",
|
|
"final/document.md#13-steal-time",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것",
|
|
"final/document.md#15-cpu-가상화-관점에서-장애를-보는-방법",
|
|
"final/document.md#16-현재-keycloak-k3s-실험과의-관계",
|
|
"final/document.md#18-bare-metal-k3s와-vm-기반-k3s의-차이",
|
|
"final/document.md#19-이-ssot에서-파생될-concept",
|
|
"final/document.md#22-현재-단계의-핵심-claim",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제",
|
|
"final/document.md#25-cpu-문제를-계층별로-구분하는-진단표",
|
|
"final/document.md#26-현재-keycloak-실험에서-cpu-문제를-오판하지-않기-위한-기준",
|
|
"final/document.md#28-concept-->-open-question-->-case-적용-기준"
|
|
],
|
|
"basis-version": "x86_64 Intel VMX(VT-x) · Linux KVM(`kvm` · `kvm_intel`) · QEMU/libvirt · VM 안의 K3s cgroup CPU limit. SSOT 가 커널·QEMU·libvirt 버전을 한 번도 적지 않아 특정 버전에 고정하지 않는다 — 여기 적힌 것은 이 문서가 서술한 구성이고, 버전이 바뀌어 서술이 낡았는지는 §23 의 검증을 실제 Host 에서 돌릴 때 드러난다. AMD 는 `kvm_amd`/SVM 로 대응한다는 사실까지만 SSOT 에 있다.",
|
|
"classification": "§19 가 이 실행 경로를 하나의 CONCEPT 로 관리하고 여러 문서로 과도하게 분할하지 않는다고 적었다. virsh 에서 물리 CPU 까지가 한 인과 흐름이라 절 단위로 쪼개면 어느 조각도 혼자 서지 않는다 — vCPU thread 를 빼면 Host Scheduler 절이 무엇을 스케줄링하는지 말할 수 없고, VM Exit 을 빼면 Guest idle 이 왜 CPU 를 놓는지 말할 수 없다. §24 의 문제 열하나와 §25 의 진단표도 같은 경로 위의 자리들이라 이 글이 그 경로를 설명한 뒤라야 읽힌다. 근거는 문서가 서술한 메커니즘이고, 이 Host 에서 잰 값은 없다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. VM Exit 분포도, steal time 도, vCPU thread 가 실제로 logical CPU 사이를 옮겨 다니는지도 재지 않았다. §28 이 그은 경계대로 이 글은 「구조적으로 어떤 문제가 가능한가 · 어떤 지표로 의심하나 · 어느 계층에서 확인하나」까지만 말하고, 현재 서버에서 실제로 일어나는지는 사실로 확정하지 않는다. 재야 할 것은 §20·§27 의 OPEN QUESTION 열둘에 적혀 있고, 그 열둘은 이제 이 주제의 Question 글감 열둘이 되어 무엇을 재면 닫히는지를 각각 따로 적고 있다.",
|
|
"relations": [
|
|
"question:vcpu-thread-migration-without-pinning",
|
|
"question:vm-exit-distribution-by-workload",
|
|
"question:vcpu-contention-under-two-vm-load",
|
|
"question:throttling-vs-contention",
|
|
"question:is-production-on-a-hypervisor",
|
|
"question:host-numa-topology"
|
|
],
|
|
"ssot-assets": [
|
|
"vm-exit-handling-cycle"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/concept/concept-kvm-vcpu-to-physical-cpu.md",
|
|
"status": "초안",
|
|
"studioId": "5bcae89b-0873-4a2b-af4a-10e5234c085b",
|
|
"assets": [
|
|
"vm-exit-handling-cycle"
|
|
],
|
|
"assetFiles": [
|
|
"vm-exit-handling-cycle"
|
|
],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"reference": [],
|
|
"question": [
|
|
{
|
|
"title": "가상 머신 두 대에 동시에 부하를 주면 이 호스트에서 vCPU 경쟁이 실제로 생기는가",
|
|
"kind": "question",
|
|
"slug": "vcpu-contention-under-two-vm-load",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-1",
|
|
"final/document.md#12-cpu-contention과-overcommit",
|
|
"final/document.md#16-현재-keycloak-k3s-실험과의-관계"
|
|
],
|
|
"known": "§12 는 Host 12 logical CPU 에 8 vCPU VM 넷을 올린 예를 들어, 총 32 vCPU thread 가 12 logical CPU 위에서 Host CPU 시간을 두고 경쟁할 수 있고 그때 Guest application 이 느려진 원인이 application 이 아니라 Host CPU contention 일 수 있다고 적었다. §16 이 서술한 테스트 환경은 Physical Host 아래 Host Nginx 와 VM 두 대이고 각 VM 이 K3s 노드와 Keycloak 을 돌린다. §20 은 이 물음의 확인 대상으로 Host logical CPU 수 · 각 VM vCPU 수 · QEMU vCPU thread CPU 사용량 · Host run queue · Guest steal time 다섯을 적었다. 이 Host 의 logical CPU 수도 두 VM 의 vCPU 수도 SSOT 어디에도 적혀 있지 않다.",
|
|
"unknown": "이 Host 의 logical CPU 수와 두 VM 의 vCPU 합, 그리고 그 합이 logical CPU 를 넘는지. 넘든 넘지 않든 두 VM 에 동시에 부하를 걸었을 때 QEMU vCPU thread 사용량과 Host run queue 와 각 Guest 의 steal time 이 실제로 어떻게 움직이는지.",
|
|
"next-verification": "§20 의 확인 대상 다섯 가운데 정적인 둘 — Host logical CPU 수와 각 VM vCPU 수 — 을 먼저 적는다. 그 다음 VM 1 과 VM 2 에 동시에 CPU 부하를 걸고, 부하 전과 부하 중 두 시점에 Host 에서 `ps -eLo pid,tid,psr,pcpu,comm | grep qemu` (§14.7) 로 QEMU vCPU thread 의 CPU 사용량을, Host run queue 를, 각 Guest 에서 `top` (§14.8) 으로 `%st` 를 같은 시각에 기록한다.",
|
|
"decision-criterion": "두 VM 의 vCPU 합이 Host logical CPU 이하이고 동시 부하에서도 Guest `%st` 와 Host run queue 가 부하 전과 다르지 않으면, 이 Host 구성에서는 contention 이 관측되지 않는다고 적고 닫는다. `%st` 나 run queue 가 움직이면 그 부하 전후 표가 Case 가 되고 이 질문은 그 Case 가 닫는다. vCPU 수를 줄일지 VM 배치를 바꿀지는 그 Case 가 나온 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:steal-time-increase-under-two-cpu-bound-vms"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-vcpu-contention-under-two-vm-load.md",
|
|
"status": "초안",
|
|
"studioId": "eba4a877-276a-4050-9a97-d32614546c71",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Keycloak 동시 refresh 실험 중 CPU 가상화 계층이 결과를 흔들 만큼 포화되는가",
|
|
"kind": "question",
|
|
"slug": "virtualization-layer-saturation-during-refresh",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-2",
|
|
"final/document.md#16-현재-keycloak-k3s-실험과의-관계",
|
|
"final/document.md#26-현재-keycloak-실험에서-cpu-문제를-오판하지-않기-위한-기준"
|
|
],
|
|
"known": "§16 은 Keycloak 실험 구조 아래에 KVM 계층이 하나 더 붙는다고 적고, 결과를 해석할 때 분리해야 할 원인으로 Keycloak refresh/session 동시성 · PostgreSQL contention/locking · Redis 상태 관리 · K3s resource scheduling · VM vCPU scheduling · Host CPU saturation · Nginx/LB 를 들었다. §26 은 같은 것을 Application/Auth · Storage · K3s · Guest · Virtualization · Host 여섯 경계로 다시 그렸다. §20 은 이 물음에서 Host CPU · Guest CPU · steal time · Keycloak latency · DB/Redis latency 를 동시에 관찰하라고 적었고 그 목적이 refresh 경쟁과 Host resource contention 을 분리하는 것이라고 밝혔다.",
|
|
"unknown": "refresh 경쟁 실험을 돌리는 동안 그 다섯 지표가 실제로 어떤 값을 갖는지, 그리고 가상화 계층 쪽 지표(Host CPU · steal time)가 실험 결과를 다르게 읽어야 할 만큼 움직이는지.",
|
|
"next-verification": "refresh 경쟁 실험을 돌리면서 §20 이 적은 다섯 지표를 같은 시각에 기록한다 — Guest 의 steal time 은 `top` (§14.8), Host 쪽 QEMU vCPU thread 는 `ps -eLo pid,tid,psr,pcpu,comm | grep qemu` (§14.7), Keycloak 과 DB/Redis latency 는 실험이 이미 재는 값을 그대로 쓴다. 실험을 걸기 전 같은 다섯을 한 번 찍어 기준값으로 둔다.",
|
|
"decision-criterion": "실험 구간의 Host CPU 와 steal time 이 기준값과 다르지 않으면, 그 실험 결과를 application/storage 문제로 읽어도 된다고 적고 닫는다. 둘 중 하나라도 움직이면 §26 의 여섯 경계를 분리해 다시 재고, refresh 경쟁 실험을 CPU 여유 상태에서 따로 돌릴지는 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:vcpu-contention-under-two-vm-load",
|
|
"question:throttling-vs-contention"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-virtualization-layer-saturation-during-refresh.md",
|
|
"status": "초안",
|
|
"studioId": "da3a7b56-5691-4a9f-90c5-3a1a5d0f0013",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "게스트가 유휴 상태일 때 vCPU 스레드는 이 테스트 환경에서 어떻게 보이는가",
|
|
"kind": "question",
|
|
"slug": "idle-vcpu-thread-appearance",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-3",
|
|
"final/document.md#10-guest가-idle이면-물리-cpu는-어떻게-되는가",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것-14-6"
|
|
],
|
|
"known": "§10 은 Guest 가 idle 이면 vCPU thread 가 block/sleep 상태로 들어가고 Host 는 그 CPU 시간을 다른 workload 에 쓸 수 있다고 적었다. §14.6 은 `ps -T -p <QEMU_PID>` 와 `top -H -p <QEMU_PID>` 로 vCPU 관련 thread 를 Host 에서 관찰할 수 있다고 하면서, 환경과 QEMU 버전에 따라 thread 이름이 다를 수 있다는 단서를 함께 달았다. §20 은 Guest idle 상태와 CPU workload 상태를 비교하라고 적고 확인 명령으로 `top -H -p <QEMU_PID>` 와 `ps -eLo pid,tid,psr,pcpu,stat,comm` 둘을 들었다.",
|
|
"unknown": "이 환경에서 QEMU 의 vCPU thread 가 어떤 이름으로 보이는지, idle 과 부하 상태에서 그 thread 의 `pcpu` 와 `stat` 가 실제로 어떻게 갈리는지.",
|
|
"next-verification": "VM 을 idle 로 둔 채 `top -H -p <QEMU_PID>` 와 `ps -eLo pid,tid,psr,pcpu,stat,comm` 을 찍는다. 같은 VM 에 CPU workload 를 걸고 같은 두 명령을 다시 찍어 두 출력을 나란히 둔다 (§20 이 적은 확인 명령 그대로).",
|
|
"decision-criterion": "idle 에서 vCPU thread 의 `pcpu` 가 0 에 가깝고 `stat` 가 sleep 계열이며 부하에서 실행 상태로 바뀌면, §10 의 서술이 이 환경에서도 성립하는 것으로 개념의 확인 사례에 흡수하고 닫는다. 두 상태에서 출력이 갈리지 않거나 §10 과 반대로 나오면 그 출력이 Case 가 된다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:vcpu-thread-migration-without-pinning"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-idle-vcpu-thread-appearance.md",
|
|
"status": "초안",
|
|
"studioId": "4a2d3332-81c3-44fa-a4fb-216a41abb504",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "실제 작업에서 주로 발생하는 VM Exit 은 무엇인가",
|
|
"kind": "question",
|
|
"slug": "vm-exit-distribution-by-workload",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-4",
|
|
"final/document.md#8-무엇이-실제로-vm-exit을-발생시키는가",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것-14-9"
|
|
],
|
|
"known": "§8 은 VM Exit 을 일으키는 동작으로 HLT · I/O Port 접근 · CPUID · Control Register 접근 · MSR 접근 · Exception · External Interrupt 를 들고, 무엇이 Exit 을 일으킬지는 root 권한이 아니라 VMCS 의 VM-Execution Control 설정과 동작 종류가 정한다고 적었다. §14.9 는 `sudo perf kvm stat live` 를 예로 들면서 지원되는 명령과 표시되는 Exit reason 이 kernel · perf 버전 · CPU architecture 및 설정에 따라 다를 수 있으니 `perf kvm --help` 를 함께 확인하고 필요하면 KVM tracepoint tracing 도 검토하라고 적었다. §20 의 비교 후보는 idle · CPU-bound workload · I/O-heavy workload · Keycloak 정상 요청 · Keycloak 부하 테스트 다섯이다.",
|
|
"unknown": "이 Host 에서 `perf kvm` 또는 KVM tracepoint 가 실제로 열리는지, 열린다면 §20 이 든 다섯 workload 의 Exit reason 분포가 서로 얼마나 다른지.",
|
|
"next-verification": "먼저 `perf kvm --help` 로 이 환경이 지원하는 하위 명령을 확인한다. 열리면 `sudo perf kvm stat live` 로 §20 의 비교 후보 다섯을 각각 돌리며 Exit reason 분포를 받아 적는다. 열리지 않으면 §14.9 가 말한 KVM tracepoint tracing 을 검토하고 그 결과도 기록한다.",
|
|
"decision-criterion": "다섯 workload 의 Exit reason 분포를 한 표로 놓을 수 있으면 그 표가 Case 가 되고 닫는다. `perf kvm` 도 tracepoint 도 이 환경에서 열리지 않으면, 「이 Host 에서는 Exit 분포를 관측할 수 없다」를 그대로 적고 §24.9 의 확인 항목에서 Exit reason 을 빼는 근거로 남긴 뒤 닫는다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:exit-distribution-for-keycloak-workload"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-vm-exit-distribution-by-workload.md",
|
|
"status": "초안",
|
|
"studioId": "61b7486f-5dab-41df-8f4f-e8fc21d88617",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "pinning 없이 vCPU 스레드는 호스트 논리 CPU 사이를 옮겨 다니는가",
|
|
"kind": "question",
|
|
"slug": "vcpu-thread-migration-without-pinning",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-5",
|
|
"final/document.md#5-host-linux-scheduler와-실제-cpu",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것-14-7"
|
|
],
|
|
"known": "§5 는 vCPU thread 도 다른 Host thread 와 같이 Linux Scheduler 가 실행할 logical CPU 를 정한다고 적었다. §14.7 은 `ps -eLo pid,tid,psr,pcpu,comm | grep qemu` 의 `PSR` 로 thread 가 최근 실행된 logical CPU 를 관찰할 수 있고, 이것이 vCPU 가 물리 CPU 에 영구 고정되어 있다는 뜻은 아니며 pinning 을 하지 않았다면 스케줄링에 따라 달라질 수 있다고 적었다. §20 은 `PSR` 과 scheduler tracing 으로 관찰하라고만 적었다.",
|
|
"unknown": "이 Host 에서 pinning 없이 같은 vCPU thread 의 `PSR` 이 시간에 따라 실제로 바뀌는지, 바뀐다면 부하가 있을 때와 없을 때가 다른지. 현재 두 VM 에 affinity 가 걸려 있는지도 SSOT 에 적혀 있지 않다.",
|
|
"next-verification": "`ps -eLo pid,tid,psr,pcpu,comm | grep qemu` 를 일정 간격으로 여러 번 찍어 같은 tid 의 `PSR` 이 바뀌는지 본다. Guest 가 idle 일 때와 CPU 부하가 있을 때를 나눠 각각 찍고, 같은 실행에서 그 VM 에 affinity 설정이 있는지도 함께 적는다 (§14.7 · §20).",
|
|
"decision-criterion": "관측 구간에서 같은 tid 의 `PSR` 이 바뀌면 이동한다는 사실을 개념의 확인 사례로 흡수하고 닫는다 — 그 이동이 성능에 영향을 주는지는 OQ-10 이 받는다. `PSR` 이 고정으로 나오면 affinity 설정을 먼저 확인하고, 설정이 없는데도 고정이면 그 관측이 Case 가 된다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:pinning-before-and-after",
|
|
"question:idle-vcpu-thread-appearance"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-vcpu-thread-migration-without-pinning.md",
|
|
"status": "초안",
|
|
"studioId": "cd58d35d-3a93-4682-82b8-b64ce3a8813c",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "운영 서버는 CPU 가상화 계층의 영향을 받는 구조인가",
|
|
"kind": "question",
|
|
"slug": "is-production-on-a-hypervisor",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question-oq-6",
|
|
"final/document.md#18-bare-metal-k3s와-vm-기반-k3s의-차이",
|
|
"final/document.md#25-cpu-문제를-계층별로-구분하는-진단표"
|
|
],
|
|
"known": "§18 은 bare-metal K3s 가 Host scheduler 로 바로 가는 것과 달리 VM 기반 K3s 에는 vCPU · QEMU thread · KVM/VMX 계층이 더 붙는다고 적었다. §20 은 두 경로를 `K3s -> Host Scheduler -> Physical CPU` 와 `K3s -> Guest -> vCPU -> Hypervisor -> Physical CPU` 로 나란히 적고, 구조에 따라 진단 지표가 달라진다고 밝혔다. §25 의 진단표에는 Virtualization·Host 계층에만 있는 행이 따로 있다. 운영 서버가 둘 중 어느 쪽인지는 SSOT 에 적혀 있지 않다.",
|
|
"unknown": "운영 서버가 bare-metal Host 에 직접 K3s 를 설치한 것인지, 상위 Hypervisor 나 Cloud VM 위에 있는지.",
|
|
"next-verification": "운영 서버의 구성 기록이나 도입 경로로 bare-metal 인지 Hypervisor/Cloud VM 위인지 확인한다. 서버에 붙을 수 있으면 §14.1~§14.3 의 `grep -E 'vmx|svm' /proc/cpuinfo` · `lsmod | grep kvm` · `ls -l /dev/kvm` 으로 그 장비가 VM 을 직접 돌리는 Host 인지부터 적고, Guest 안에서 `top` 의 `%st` (§14.8) 가 관측되는지를 함께 본다.",
|
|
"decision-criterion": "운영 서버가 bare-metal 로 확인되면 §25 의 Virtualization·Host 행을 운영 진단에서 빼도 된다고 적고 닫는다. Hypervisor 나 Cloud VM 위로 확인되면 그 사실이 운영 진단의 전제가 되고, §25 의 어느 행을 운영에서 쓸지는 그 뒤 Decision 이 정한다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-is-production-on-a-hypervisor.md",
|
|
"status": "초안",
|
|
"studioId": "2acec7d5-3eaf-4115-9d61-45647c4ec01e",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "가상 머신 두 대를 CPU-bound 로 만들면 게스트 steal time 은 얼마나 오르는가",
|
|
"kind": "question",
|
|
"slug": "steal-time-increase-under-two-cpu-bound-vms",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-7",
|
|
"final/document.md#13-steal-time",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-4"
|
|
],
|
|
"known": "§13 은 steal time 이 Guest vCPU 에 실행할 작업이 있는데 다른 workload 때문에 즉시 실행되지 못하는 상황을 가리키는 단서이며, 그것 하나만으로 원인을 확정하지 말고 Host CPU saturation · run queue · affinity · workload 를 함께 확인해야 한다고 적었다. §24.4 는 steal time 증가를 Guest 에서 관측되는 문제로 놓고 우선 확인할 것을 `%st` 와 Host contention 으로 적었다. §27 은 이 물음에서 Host CPU utilization · run queue · QEMU vCPU thread · 각 Guest 의 `%st` 를 함께 측정하라고 적었다. 이 Host 에서 `%st` 를 실제로 잰 값은 없다.",
|
|
"unknown": "두 VM 을 동시에 CPU-bound 로 만들었을 때 각 Guest 의 `%st` 가 부하 전 대비 얼마나 오르는지, 그 증가가 Host run queue 와 같은 방향으로 움직이는지.",
|
|
"next-verification": "부하 전에 Host CPU utilization 과 run queue, `ps -eLo pid,tid,psr,pcpu,comm | grep qemu` (§14.7) 의 QEMU vCPU thread 사용량, 각 Guest 의 `top` (§14.8) `%st` 를 기준값으로 남긴다. 그 다음 VM 두 대를 동시에 CPU-bound 로 만들고 같은 네 항목을 같은 시각에 다시 기록한다 (§27 이 적은 측정 항목 그대로).",
|
|
"decision-criterion": "부하 전후의 `%st` 와 Host run queue 를 한 표로 놓을 수 있으면 그 표가 Case 가 되고 닫는다. `%st` 가 부하 전과 다르지 않으면 이 Host 구성에서는 두 VM 동시 부하가 steal time 으로 나타나는 경쟁을 만들지 않는다고 적고 OQ-1 과 함께 닫는다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:vcpu-contention-under-two-vm-load",
|
|
"question:throughput-vs-vcpu-count"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-steal-time-increase-under-two-cpu-bound-vms.md",
|
|
"status": "초안",
|
|
"studioId": "2d058fb5-01f1-4be8-80bb-0e377868573c",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "vCPU 를 늘릴수록 이 호스트에서 Keycloak 처리량도 계속 오르는가",
|
|
"kind": "question",
|
|
"slug": "throughput-vs-vcpu-count",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-8",
|
|
"final/document.md#11-vm의-4-vcpu는-정확히-무엇을-의미하는가",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-6"
|
|
],
|
|
"known": "§11 은 4 vCPU 가 실행 컨텍스트 4개이지 물리 CPU 4개를 영구히 예약한 것이 아니라고 적었다. §24.6 은 vCPU 를 많이 준다고 항상 빨라지는 것은 아니며, Guest workload 가 그만큼의 병렬성을 쓰지 못하거나 Host 전체 CPU 에 비해 지나치게 많은 vCPU 를 주면 scheduling 대상만 늘 수 있으니 실제 workload 의 병렬성과 Host capacity 를 함께 확인해야 한다고 적었다. §27 은 비교 구성으로 2 vCPU / 4 vCPU / 8 vCPU 를 들었다.",
|
|
"unknown": "이 Host 에서 vCPU 를 2 → 4 → 8 로 올렸을 때 Keycloak 처리량과 latency 가 어디서부터 더 좋아지지 않는지. 좋아지지 않는다면 그것이 workload 의 병렬성 부족 때문인지 Host capacity 부족 때문인지.",
|
|
"next-verification": "VM 구성을 2 vCPU · 4 vCPU · 8 vCPU 로 바꿔 가며 같은 Keycloak 부하를 걸고 처리량과 latency 를 각각 기록한다. 세 실행 모두에서 Host logical CPU 수 대비 총 vCPU 와 Guest 의 `top` `%st` (§14.8) 를 함께 남겨, §24.6 이 말한 병렬성 부족과 Host capacity 부족을 갈라 둔다 (§27 이 든 비교 구성 그대로).",
|
|
"decision-criterion": "처리량이 더 오르지 않기 시작하는 vCPU 수가 나오면 그 지점을 이 workload 의 상한으로 적고 그 세 실행이 Case 가 된다. 세 구성이 모두 같은 방향으로 오르면 이 Host 에서는 상한에 닿지 않았다고 적고 닫는다. 어느 vCPU 수로 운영할지는 그 뒤 Decision 이 정한다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:steal-time-increase-under-two-cpu-bound-vms"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-throughput-vs-vcpu-count.md",
|
|
"status": "초안",
|
|
"studioId": "723d8930-9e82-4552-8376-038a6446ec71",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "cgroup CPU 제한과 호스트 vCPU 경쟁을 지표로 가를 수 있는가",
|
|
"kind": "question",
|
|
"slug": "throttling-vs-contention",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-9",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-8",
|
|
"final/document.md#25-cpu-문제를-계층별로-구분하는-진단표"
|
|
],
|
|
"known": "§24.8 은 Host CPU 에 여유가 있어도 container cgroup 의 CPU limit 때문에 Keycloak Pod 실행이 제한될 수 있다고 적고, 「Host CPU 를 받지 못함」과 「Pod 가 자신의 CPU quota 를 초과함」을 구분해야 한다고 밝혔다. throttling 자체는 KVM 문제가 아니지만 VM 안에서 K3s 를 운영하는 지금 실험에서는 같은 application latency 로 관찰될 수 있어 진단 경계에 포함한다고도 적었다. §25 의 진단표는 CPU throttling 의 우선 확인 항목을 CPU limit · throttled time 으로, CPU contention 은 Host CPU · run queue · per-CPU usage 로 갈라 적었다. §27 은 둘을 의도적으로 재현해 Guest/Host/K3s 지표 차이를 비교하라고 적었다.",
|
|
"unknown": "같은 크기의 application latency 증가를 두 원인으로 각각 재현했을 때 §25 가 갈라 놓은 지표들이 실제로 갈리는지, 갈린다면 어느 지표가 가장 먼저 갈리는지.",
|
|
"next-verification": "같은 크기의 Keycloak latency 증가를 두 번 만든다 — 한 번은 Keycloak Pod 의 cgroup CPU limit 을 낮춰서, 한 번은 다른 VM 에 CPU 부하를 걸어서. 두 실행에서 Pod 의 throttled time 과 CPU limit, Guest CPU 와 `top` `%st` (§14.8), Host CPU 와 run queue 를 같은 항목으로 받아 적고 나란히 놓는다 (§27 · §25 의 두 행).",
|
|
"decision-criterion": "두 재현에서 지표 조합이 갈리면 그 대조표가 Case 가 되고, §25 의 두 행을 어떤 순서로 보는지를 정하는 근거가 된다. 갈리지 않으면 「이 지표들로는 두 원인이 구분되지 않는다」를 적고, 무엇을 더 봐야 하는지를 새 Question 으로 낸 뒤 이 질문은 닫는다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:virtualization-layer-saturation-during-refresh"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-throttling-vs-contention.md",
|
|
"status": "초안",
|
|
"studioId": "116b806c-b176-401c-9363-1489fffb721c",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "CPU pinning 전후로 Keycloak 지연과 vCPU 스케줄링 변동이 달라지는가",
|
|
"kind": "question",
|
|
"slug": "pinning-before-and-after",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-10",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-7",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것-14-7"
|
|
],
|
|
"known": "§24.7 은 CPU pinning 이 특정 vCPU thread 를 특정 Host logical CPU 에 제한하는 것이고, 적절히 쓰면 scheduling 변동을 줄일 수 있지만 잘못 설정하면 특정 CPU 에 workload 가 집중될 수 있다고 적었다. 그래서 pinning 여부만 보지 말고 실제 per-CPU utilization 과 affinity 를 함께 확인해야 한다고 밝혔다. §14.7 은 `PSR` 이 thread 가 최근 실행된 logical CPU 를 보여 주고 pinning 을 하지 않았다면 스케줄링에 따라 달라질 수 있다고 적었다. §27 은 pinning 이 현재 workload 에서 실제 이점을 주는지는 실험으로 확인한다고 적었다.",
|
|
"unknown": "pinning 전후로 Keycloak latency 가 달라지는지, `PSR` 변동이 실제로 줄어드는지, 줄어드는 대신 §24.7 이 말한 대로 특정 CPU 로 workload 가 몰리는지.",
|
|
"next-verification": "pinning 없이 Keycloak 부하를 걸어 latency 와 `ps -eLo pid,tid,psr,pcpu,comm | grep qemu` (§14.7) 의 `PSR` 변동과 per-CPU 사용량을 남긴다. vCPU thread 를 고정한 뒤 같은 부하를 다시 걸어 같은 세 가지를 남기고 두 실행을 나란히 놓는다 (§27 · §24.7).",
|
|
"decision-criterion": "pinning 뒤 latency 가 좋아지고 per-CPU 사용량이 특정 CPU 로 몰리지 않으면, pinning 을 쓸지 말지를 Decision 으로 넘긴다 — 그 Decision 이 감수할 비용은 §24.7 이 적은 「잘못 설정하면 특정 CPU 에 workload 가 집중된다」이다. 두 실행에서 latency 차이가 없으면 이 workload 에서는 pinning 이 이점을 주지 않는다고 적고 닫는다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:vcpu-thread-migration-without-pinning"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-pinning-before-and-after.md",
|
|
"status": "초안",
|
|
"studioId": "62319064-17ef-4b2f-bf8b-e363cd0e36a6",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Keycloak 작업의 VM Exit 분포는 idle · CPU-bound · I/O-bound 와 어떻게 다른가",
|
|
"kind": "question",
|
|
"slug": "exit-distribution-for-keycloak-workload",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-11",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-9",
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것-14-9"
|
|
],
|
|
"known": "§24.9 는 VM Exit 이 정상적인 가상화 동작이라 존재한다는 것 자체는 문제가 아니고, 특정 workload 에서 Exit 이 지나치게 빈번하고 처리 비용이 커질 때 성능에 영향을 줄 수 있다고 적었다. 볼 때는 Exit 횟수만이 아니라 Exit reason · workload 종류 · 처리 위치가 KVM 인지 QEMU userspace 인지 · application latency 와 Exit 증가가 함께 나타나는지를 같이 보라고 적었다. §14.9 는 지원되는 명령과 표시되는 Exit reason 이 kernel · perf 버전 · CPU architecture 및 설정에 따라 다를 수 있다고 단서를 달았다. §27 은 가능하면 `perf kvm` 또는 KVM tracepoint 로 Exit reason 분포를 비교하라고 적었다.",
|
|
"unknown": "Keycloak workload 구간의 Exit reason 분포가 idle · CPU-bound · I/O-bound 구간과 얼마나 다른지, 그 차이가 같은 구간의 Keycloak latency 와 같이 움직이는지.",
|
|
"next-verification": "OQ-4 에서 `perf kvm` 또는 KVM tracepoint 가 이 환경에서 열린다는 것을 먼저 확인한다. 열리면 idle · CPU-bound · I/O-bound · Keycloak 정상 요청 · Keycloak 부하 다섯 구간의 Exit reason 분포를 받고, 같은 구간의 Keycloak latency 를 나란히 적는다 (§27 · §24.9 가 함께 보라고 한 네 항목).",
|
|
"decision-criterion": "Keycloak 구간의 Exit 분포가 다른 구간과 다르고 그 차이가 latency 와 같이 움직이면 그 측정이 Case 가 되고 닫는다. 분포가 다르지 않거나 latency 와 따로 움직이면, 이 workload 에서 Exit overhead 는 조사 대상이 아니라고 적고 §25 의 「과도한 VM Exit」 행을 뒤로 미루는 근거로 남긴 뒤 닫는다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:vm-exit-distribution-by-workload"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-exit-distribution-for-keycloak-workload.md",
|
|
"status": "초안",
|
|
"studioId": "d103bb81-45df-402f-86e5-e41d66ed7f8d",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 호스트의 NUMA 토폴로지는 가상 머신 성능을 고려해야 할 구조인가",
|
|
"kind": "question",
|
|
"slug": "host-numa-topology",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-12",
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-11"
|
|
],
|
|
"known": "§24.11 은 멀티소켓 또는 NUMA 구조 Host 에서 vCPU 가 실행되는 NUMA node 와 VM memory 가 위치한 node 의 관계가 성능에 영향을 줄 수 있다고 적고, vCPU 가 Node 0 에서 실행되는데 필요한 memory 가 주로 Node 1 에 배치되어 있으면 remote memory access 가 발생할 수 있다는 예를 들었다. 같은 절이 이 문서에서는 문제의 존재와 CPU affinity 와의 관계까지만 기록하고 상세한 memory placement 와 NUMA tuning 은 메모리 가상화 CONCEPT 에서 다룬다고 범위를 그었다. §27 은 이 물음의 종료 기준을 스스로 적었다 — 단일 NUMA node 면 현재 실험에서 우선순위를 낮추고, 다중 NUMA node 면 vCPU/memory placement 를 별도 CASE 후보로 올린다.",
|
|
"unknown": "이 Host 가 단일 NUMA node 인지 다중 NUMA node 인지, 다중이라면 두 VM 의 vCPU 와 memory 가 어느 node 에 배치되어 있는지.",
|
|
"next-verification": "Host 의 NUMA topology 를 확인해 node 수를 적는다. 다중으로 나오면 §24.11 이 말한 vCPU 가 실행되는 node 와 VM memory 가 배치된 node 의 관계까지 같이 적는다 (§27 OQ-12). SSOT 는 이 확인에 쓸 명령을 적지 않았으므로 쓰는 명령과 그 출력을 함께 증거로 남긴다.",
|
|
"decision-criterion": "단일 NUMA node 로 나오면 §27 이 적은 대로 현재 실험에서 우선순위를 낮추고 닫는다. 다중 NUMA node 로 나오면 vCPU/memory placement 를 별도 CASE 후보로 올리고, 이 프로젝트가 메모리 가상화 SSOT 를 가질 때 §24.11 과 함께 그쪽으로 넘긴다.",
|
|
"relations": [
|
|
"concept:kvm-vcpu-to-physical-cpu"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "cpu-virtualization/question/question-host-numa-topology.md",
|
|
"status": "초안",
|
|
"studioId": "688c6c02-c1bd-4cd2-a615-2396db145386",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"decision": []
|
|
}
|
|
},
|
|
"memory-virtualization": {
|
|
"topic": "memory-virtualization",
|
|
"title": "메모리 가상화 — VM 에 준 RAM 이 실제로 있는 곳",
|
|
"readerQuestion": "VM 에 준 RAM 은 실제로 어디에 어떻게 있고, Guest 가 느리거나 죽을 때 그것이 어느 계층의 메모리 문제인지 무엇을 보고 가르는가?",
|
|
"kinds": {
|
|
"case": [],
|
|
"concept": [
|
|
{
|
|
"title": "Guest 메모리 주소가 물리 RAM 에 닿기까지 — GVA · GPA · HPA",
|
|
"kind": "concept",
|
|
"slug": "guest-memory-address-translation",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#29-이-문서에서-먼저-고정할-전체-구조",
|
|
"final/document.md#30-일반-linux의-virtual-memory부터-시작한다",
|
|
"final/document.md#31-page와-physical-frame",
|
|
"final/document.md#32-virtual-address-=-page-+-offset",
|
|
"final/document.md#33-guest-page-table",
|
|
"final/document.md#34-mmu-실제-주소-변환을-수행하는-cpu-하드웨어",
|
|
"final/document.md#35-tlb-주소-변환-결과의-cpu-cache",
|
|
"final/document.md#36-bare-metal과-vm의-차이",
|
|
"final/document.md#37-ept-extended-page-tables",
|
|
"final/document.md#38-왜-ept가-필요한가",
|
|
"final/document.md#39-shadow-page-table과-ept의-의미",
|
|
"final/document.md#40-qemu는-guest-ram을-어떻게-준비하는가",
|
|
"final/document.md#41-kvm_set_user_memory_region",
|
|
"final/document.md#42-configured-memory와-실제-physical-ram-사용량은-같지-않을-수-있다",
|
|
"final/document.md#43-guest-page-table-자체도-메모리에-있다",
|
|
"final/document.md#44-정상-memory-access는-매번-vm-exit하지-않는다",
|
|
"final/document.md#79-전체-memory-virtualization-실행-경로",
|
|
"final/document.md#80-전체-memory-virtualization-관리-경로",
|
|
"final/document.md#82-핵심-claim-registry",
|
|
"final/document.md#87-최종-기준-그림",
|
|
"final/document.md#88-결론"
|
|
],
|
|
"basis-version": "x86-64 Intel EPT(second-level address translation) · AMD 는 NPT 계열로 대응 · Linux KVM 의 `KVM_SET_USER_MEMORY_REGION` · QEMU/libvirt · 기본 page 4 KiB. SSOT 가 커널·QEMU·libvirt 버전을 한 번도 적지 않아 특정 버전에 고정하지 않는다 — 여기 적힌 것은 이 문서가 서술한 구성이고, 버전이 바뀌어 서술이 낡았는지는 §83 의 확인을 실제 Host 에서 돌릴 때 드러난다.",
|
|
"classification": "§29 가 이 부에서 먼저 고정할 구조로 GVA → GPA → HPA 를 놓았고 §87 이 같은 그림을 최종 기준으로 다시 그렸다. 이 경로는 제2부의 다른 다섯 글이 서는 바닥이다 — fault 가 어느 계층에서 났는지도, huge page 가 두 변환 단계 중 어디에 걸리는지도, NUMA 배치가 무엇을 옮기는지도 이 경로를 먼저 그려야 말이 된다. 실행 경로(§79)와 관리 경로(§80)를 갈라 놓는 것도 이 글의 일이다 — QEMU 가 backing 을 마련하고 KVM 이 region 을 등록하지만 매 접근을 처리하는 것은 CPU MMU 라는 것이 §41 과 §44 의 결론이다. 근거는 문서가 서술한 메커니즘이고 이 Host 에서 잰 값은 없다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. 이 글에 대해서는 §83 OQ-2 와 OQ-3 이 재는 것 — VM 의 configured/current memory 와 QEMU process 의 Host resident memory — 이 §42 가 말한 세 값의 차이를 이 Host 에서 확정한다.",
|
|
"relations": [
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"concept:huge-pages-in-a-vm",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"concept:numa-locality-for-vcpu-and-memory",
|
|
"question:vm-configured-vs-current-memory",
|
|
"question:qemu-resident-memory-distribution",
|
|
"reference:memory-symptom-needs-layer-separation",
|
|
"concept:kvm-vcpu-to-physical-cpu"
|
|
],
|
|
"ssot-assets": [
|
|
"guest-memory-address-translation-path"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-guest-memory-address-translation.md",
|
|
"status": "초안",
|
|
"studioId": "2f2ffafc-91ff-4971-a6a8-7c0e7d844ca2",
|
|
"assets": [
|
|
"guest-memory-address-translation-path"
|
|
],
|
|
"assetFiles": [
|
|
"guest-memory-address-translation-path"
|
|
],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "VM 에서 page fault 는 세 계층에서 따로 일어난다",
|
|
"kind": "concept",
|
|
"slug": "page-fault-layers-in-a-vm",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#35-tlb-주소-변환-결과의-cpu-cache",
|
|
"final/document.md#45-guest-page-fault",
|
|
"final/document.md#46-page-fault의-대표적인-원인",
|
|
"final/document.md#47-ept-violation",
|
|
"final/document.md#48-guest-page-fault와-ept-violation-비교",
|
|
"final/document.md#49-host-page-fault도-별도로-존재한다",
|
|
"final/document.md#82-핵심-claim-registry",
|
|
"final/document.md#86-문제를-진단할-때의-분류"
|
|
],
|
|
"basis-version": "x86-64 Intel EPT 기준의 second-stage translation · Linux Guest/Host kernel 의 page fault 처리 · AMD 는 NPT 계열로 대응. SSOT 가 커널 버전을 적지 않아 특정 버전에 고정하지 않는다.",
|
|
"classification": "§48 의 비교표와 §49 의 세 갈래(Guest Page Fault · Host Page Fault · EPT 관련 사건)는 제2부에서 가장 여러 번 다시 쓰이는 구분이다 — §86 의 진단 분류가 그 위에 서 있고, §83 의 OQ-13 과 OQ-14 가 각각 Guest 쪽과 Host 쪽 fault 를 재라고 말한다. 정상 경로를 그리는 글과 갈라 둔 이유는 물음이 다르기 때문이다 — 그쪽은 정상일 때 무엇이 일어나는가를, 이쪽은 접근이 완료되지 않을 때 어느 계층이 그것을 받는가를 말한다. §35 가 TLB Miss 와 Page Fault 를 먼저 갈라 놓은 것도 여기 들어간다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. Guest 쪽 fault 지표도 Host 쪽 major fault 도 재지 않았다. §46 의 다섯 원인 중 무엇이 이 환경에서 실제로 일어나는지는 OQ-13 이, Host 쪽과 storage latency 의 상관은 OQ-14 가 받는다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"question:guest-page-fault-vs-workload",
|
|
"question:host-major-fault-vs-storage-latency",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"ssot-assets": [
|
|
"page-fault-layers-in-a-vm"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-page-fault-layers-in-a-vm.md",
|
|
"status": "초안",
|
|
"studioId": "e80853fa-98b8-4cc3-a2df-427c7147794b",
|
|
"assets": [
|
|
"page-fault-layers-in-a-vm"
|
|
],
|
|
"assetFiles": [
|
|
"page-fault-layers-in-a-vm"
|
|
],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Huge Page 를 VM 에서 볼 때 갈라지는 세 자리",
|
|
"kind": "concept",
|
|
"slug": "huge-pages-in-a-vm",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#50-huge-page가-필요한-이유",
|
|
"final/document.md#51-huge-page와-tlb-coverage",
|
|
"final/document.md#52-vm에서-huge-page를-볼-때-주의할-점",
|
|
"final/document.md#53-thp-transparent-huge-pages",
|
|
"final/document.md#54-thp의-trade-off",
|
|
"final/document.md#55-hugetlb",
|
|
"final/document.md#56-thp와-hugetlb-비교",
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"basis-version": "Linux THP(`/sys/kernel/mm/transparent_hugepage/enabled`) · HugeTLB pool · x86-64 의 4 KiB / 2 MiB / 1 GiB page. §53 이 THP 정책은 kernel·distribution·Host 설정에 따라 다르므로 실제 시스템에서 확인하라고 적었고 SSOT 는 그 버전을 적지 않았다. §51 의 예시 숫자는 특정 CPU 의 실제 TLB 용량이 아니라는 단서가 원문에 붙어 있다.",
|
|
"classification": "§52 가 세운 세 자리 — Guest page table 단계 · Host backing · EPT 매핑 — 가 이 글이 존재하는 이유다. 「Huge Page 를 쓴다」는 말 하나로는 셋 중 어디를 말하는지 정해지지 않고, 그 구분이 없으면 OQ-4 가 읽은 THP 정책 값도 OQ-5 가 본 backing 설정도 무엇에 대한 값인지 말할 수 없다. THP 와 HugeTLB 의 비교(§56)와 THP 의 감수 비용(§54)도 같은 물음 아래 있어 함께 둔다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. 이 Host 의 THP 정책도 HugePages_Total 도 VM 의 memory backing 설정도 읽지 않았다. §54 가 말한 compaction latency 영향은 측정이 필요하다고 원문이 직접 적었다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"question:host-thp-policy",
|
|
"question:vm-ram-backed-by-hugetlb",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-huge-pages-in-a-vm.md",
|
|
"status": "초안",
|
|
"studioId": "efce9a6e-5f5d-45ec-86e5-056d8cb1b8d2",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Host 메모리 압박이 Guest 와 스토리지까지 내려가는 경로",
|
|
"kind": "concept",
|
|
"slug": "memory-pressure-reclaim-swap-oom",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#57-memory-overcommit",
|
|
"final/document.md#58-cpu-overcommit과-memory-overcommit의-차이",
|
|
"final/document.md#59-host-memory-pressure와-reclaim",
|
|
"final/document.md#60-host-swap이-vm에-미치는-영향",
|
|
"final/document.md#61-guest-swap과-host-swap",
|
|
"final/document.md#62-memory-pressure와-storage-contention의-연결",
|
|
"final/document.md#71-oom",
|
|
"final/document.md#72-guest-oom과-host-oom",
|
|
"final/document.md#81-cpu-network-storage-memory-연결",
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"basis-version": "Linux memory reclaim(file-backed clean page · anonymous page) · swap · OOM Killer · cgroup memory limit · QEMU 의 Guest RAM backing. SSOT 가 커널 버전도 Host RAM 도 적지 않는다.",
|
|
"classification": "§58 이 이 부에서 가장 오해되기 쉬운 자리를 앞에 세웠다 — CPU 가 모자라면 scheduler 가 시간을 나누지만 RAM 이 모자라면 「지금 존재해야 하는 page 를 어디에 둘 것인가」가 남는다. 그 답이 reclaim · swap · ballooning · OOM 이고, §60 이 그 결과로 Guest 의 단순한 memory load 가 Host 의 swap-in I/O 대기로 바뀔 수 있다고 적었다. §62 와 §81 은 그 사슬을 storage contention 과 application latency 까지 이었다. OQ-6 · OQ-7 · OQ-14 셋이 이 경로 위에서만 읽힌다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. 이 Host 의 RAM 도 swap 설정도 두 VM 의 configured memory 합도 SSOT 에 없다. 따라서 이 환경이 overcommit 상태인지조차 아직 사실이 아니다 — OQ-2 가 그 값을 받고, 압박이 실제로 Guest latency 를 밀어 올리는지는 OQ-7 이 받는다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"concept:virtio-balloon-memory-reclaim",
|
|
"question:swap-activity-in-guest-and-host",
|
|
"question:host-memory-pressure-vs-guest-latency",
|
|
"question:vm-configured-vs-current-memory",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-memory-pressure-reclaim-swap-oom.md",
|
|
"status": "초안",
|
|
"studioId": "647d6d11-5bb2-4028-a530-b10c8925aa11",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "virtio-balloon 이 Guest 메모리를 회수하고 돌려주는 방식",
|
|
"kind": "concept",
|
|
"slug": "virtio-balloon-memory-reclaim",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#64-ballooning이-필요한-이유",
|
|
"final/document.md#65-virtio-balloon-구조",
|
|
"final/document.md#66-balloon-inflate",
|
|
"final/document.md#67-balloon-page-반환의-의미",
|
|
"final/document.md#68-balloon-deflate",
|
|
"final/document.md#69-ballooning을-과도하게-하면-guest가-압박을-받는다",
|
|
"final/document.md#70-ballooning과-memory-hotplug",
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"basis-version": "virtio-balloon — Guest kernel 쪽 driver 와 QEMU 쪽 device 가 virtqueue 로 맞물린 구성 · libvirt 의 balloon target 설정. §67 이 Host 쪽 실제 release 동작은 QEMU/KVM 버전과 backing 종류·설정에 따라 달라질 수 있다고 적었고 SSOT 는 그 버전을 적지 않았다. `virtio-mem` 같은 다른 동적 memory 관리 방식이 있다는 사실까지만 §70 에 있다.",
|
|
"classification": "Host 는 Guest 안에서 어느 memory 가 중요한지 모른다는 것이 §64 의 출발점이고, 그래서 무작정 swap-out 하는 대신 Guest kernel 과 협력해 회수한다는 것이 이 장치의 존재 이유다. Guest 안의 driver 와 QEMU 쪽 device 가 virtqueue 로 맞물린 별도 메커니즘이라 압박 경로 안의 한 절로 넣으면 inflate 와 deflate 의 방향조차 놓을 자리가 없다. OQ-8 과 OQ-9 가 이 글을 필요로 한다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. 이 프로젝트의 VM 에 virtio-balloon 이 붙어 있는지조차 SSOT 에 적혀 있지 않다 — 그것을 OQ-8 이 받고, target 을 바꿨을 때 Guest 가 쓸 수 있는 메모리가 어떻게 따라 움직이는지는 OQ-9 가 받는다. §67 이 남긴 「Host-side release 는 버전과 설정에 따라 다를 수 있다」도 재지 않았다.",
|
|
"relations": [
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"question:virtio-balloon-configured",
|
|
"question:balloon-target-vs-guest-available-memory",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"ssot-assets": [
|
|
"virtio-balloon-inflate-deflate"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-virtio-balloon-memory-reclaim.md",
|
|
"status": "초안",
|
|
"studioId": "ebdf93d7-2dcb-4fc8-91b9-2364ac8196e6",
|
|
"assets": [
|
|
"virtio-balloon-inflate-deflate"
|
|
],
|
|
"assetFiles": [
|
|
"virtio-balloon-inflate-deflate"
|
|
],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "NUMA 에서는 vCPU 배치와 메모리 배치를 함께 본다",
|
|
"kind": "concept",
|
|
"slug": "numa-locality-for-vcpu-and-memory",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#73-numa",
|
|
"final/document.md#74-local-memory와-remote-memory",
|
|
"final/document.md#75-vcpu와-numa의-연결",
|
|
"final/document.md#76-vcpu-pinning만으로는-numa-최적화가-끝나지-않는다",
|
|
"final/document.md#77-guest-numa",
|
|
"final/document.md#78-numa는-실제-장비-topology부터-확인한다",
|
|
"final/document.md#81-cpu-network-storage-memory-연결",
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"basis-version": "multi-socket NUMA x86-64 · Linux `lscpu` 와 `numactl --hardware` · `numastat -p <QEMU_PID>` · libvirt `virsh vcpupin` 과 `virsh vcpuinfo`. SSOT 가 이 Host 의 NUMA node 수도 커널 버전도 적지 않아 topology 는 측정 전까지 미정이다.",
|
|
"classification": "CPU 부의 개념이 vCPU 가 QEMU vCPU thread 로 Host scheduler 위에서 돈다는 데까지 갔고, 그 문서의 question:host-numa-topology 가 「상세한 memory placement 와 NUMA tuning 은 메모리 가상화 CONCEPT 에서 다룬다」고 범위를 넘겼다. 넘겨받은 자리가 여기다 — §75 가 thread 가 도는 node 와 backing page 가 있는 node 를 잇고, §76 이 vCPU pinning 만으로는 끝나지 않는다는 결론을 낸다. 주소 변환 개념과 갈라 둔 이유는 이것이 변환 방식이 아니라 배치 문제이고, 재는 명령도 종료 조건도 다르기 때문이다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. SSOT 제2부는 개념 서술이고 §83 이 OQ-1~OQ-14 로 아직 돌리지 않은 확인 목록을 적어 두었다. §88 이 그은 경계대로 이 글은 구조가 어떻게 동작하는지까지만 말하고 이 서버에서 실제로 어떤 값이 나오는지는 사실로 확정하지 않는다. 이 Host 가 단일 node 인지 다중 node 인지가 정해지지 않았고, 그것이 정해지기 전에는 §76 이 말한 어긋남이 이 환경에서 성립하는지조차 알 수 없다. topology 는 CPU 부의 question:host-numa-topology 가 받고, QEMU 메모리가 어느 node 에 있는지는 OQ-11 이, remote access 가 latency 를 바꾸는지는 OQ-12 가 받는다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"concept:kvm-vcpu-to-physical-cpu",
|
|
"question:host-numa-topology",
|
|
"question:qemu-memory-numa-placement",
|
|
"question:numa-remote-access-vs-workload-latency",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"ssot-assets": [
|
|
"numa-vcpu-and-memory-placement"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/concept/concept-numa-locality-for-vcpu-and-memory.md",
|
|
"status": "초안",
|
|
"studioId": "68811272-5352-4409-aa20-7e22e601ede8",
|
|
"assets": [
|
|
"numa-vcpu-and-memory-placement"
|
|
],
|
|
"assetFiles": [
|
|
"numa-vcpu-and-memory-placement"
|
|
],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"reference": [
|
|
{
|
|
"title": "메모리 실험 결과에는 Host · VM · Workload 조건을 함께 남긴다",
|
|
"kind": "reference",
|
|
"slug": "record-the-conditions-with-every-memory-experiment",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#85-실험-시-반드시-같이-기록할-것",
|
|
"final/document.md#84-권장-실험-순서",
|
|
"final/document.md#83-실제-환경에서-확인할-open-question"
|
|
],
|
|
"classification": "§85 가 실험마다 남길 조건을 Host · VM · Workload 세 묶음으로 못박았다. 이유도 함께 적혀 있다 — 조건을 남기지 않으면 「Memory pressure 에서 느려졌다」는 결과를 다른 환경에 재사용하기 어렵다. 제2부의 열두 Question 전부가 같은 규칙에 걸리므로 각 글에 조건 목록을 되풀이하지 않고 여기 한 편으로 두고 가리킨다. 원 사건의 이름을 지워도 규칙이 남는다는 점에서 Case 요약이 아니다.",
|
|
"scope": "메모리 관련 측정을 남기는 모든 실험. Host 는 CPU model · core/thread 수 · RAM · NUMA topology · swap 설정 · kernel version · THP policy · physical storage, VM 은 vCPU · configured RAM · current RAM · memory backing 설정 · balloon device · guest swap · guest kernel, Workload 는 application · heap/memory 설정 · request concurrency · DB workload · 측정 시간을 적는다.",
|
|
"exceptions": "단일 값을 한 번 읽고 끝나는 확인(예: THP 정책 문자열 하나)에는 Workload 묶음이 비어 있어도 된다. 반대로 baseline 과 부하 구간을 비교하는 실험에서는 세 묶음을 두 시점 모두에 남긴다. SSOT 는 이 조건 목록을 이 프로젝트의 실제 장비 값으로 채운 적이 없다 — 목록이 규칙이고 값은 아직 없다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"concept:huge-pages-in-a-vm",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"reference:memory-symptom-needs-layer-separation",
|
|
"question:host-memory-pressure-vs-guest-latency",
|
|
"question:numa-remote-access-vs-workload-latency"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/reference/reference-record-the-conditions-with-every-memory-experiment.md",
|
|
"status": "초안",
|
|
"studioId": "ded41b52-ec08-4231-a54c-86d6c80d38f0",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "메모리 증상 하나로 계층을 단정하지 않는다",
|
|
"kind": "reference",
|
|
"slug": "memory-symptom-needs-layer-separation",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#86-문제를-진단할-때의-분류",
|
|
"final/document.md#63-swap-used만-보고-장애를-판단하면-안-된다",
|
|
"final/document.md#78-numa는-실제-장비-topology부터-확인한다",
|
|
"final/document.md#88-결론",
|
|
"final/document.md#61-guest-swap과-host-swap",
|
|
"final/document.md#72-guest-oom과-host-oom"
|
|
],
|
|
"classification": "§86 은 memory latency 나 OOM 을 보고 한 번에 「메모리 부족」이라고 결론내지 말고 Guest Virtual Memory · Virtualization Translation · Host Memory · Dynamic Memory · NUMA 다섯 갈래로 먼저 가르라고 적었다. 같은 규칙이 SSOT 안에서 세 번 더 나온다 — §63 은 Swap Used 값 하나로, §78 은 topology 만 보고, §88 은 Guest 하나의 `free -h` 만 보고 판단하지 말라고 한다. 다섯 갈래는 이 주제의 여섯 개념을 가로지르는 라우팅이라 어느 개념 안에 넣어도 나머지 넷을 가리키지 못한다.",
|
|
"scope": "메모리 증상(latency 증가 · swap 관측 · OOM · fault 증가)을 원인으로 옮기려는 모든 판독. 가르는 축은 다섯이다 — Guest Virtual Memory(page fault · guest reclaim · guest swap · guest OOM), Virtualization Translation(EPT 관련 사건 · TLB pressure · huge-page/mapping 특성), Host Memory(host reclaim · host swap · host major fault · host OOM), Dynamic Memory(balloon target · guest pressure · hotplug/virtio-mem 여부), NUMA(vCPU placement · memory placement · remote access).",
|
|
"exceptions": "cgroup memory limit 이 걸린 환경에서는 Host 전체 RAM 이 남아 있어도 그 경계에서 OOM 이 나므로 「Host Memory 갈래가 아니다」로 바로 넘기면 안 된다(§72). 단일 NUMA node Host 에서는 NUMA 갈래의 우선순위를 낮춰도 된다고 §78 이 적었지만, 그것도 topology 를 잰 뒤의 이야기다. 이 규칙은 어느 갈래인지를 좁힐 뿐 원인을 확정하지 않는다 — 확정은 §85 의 조건을 남긴 측정이 한다.",
|
|
"relations": [
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"concept:virtio-balloon-memory-reclaim",
|
|
"concept:numa-locality-for-vcpu-and-memory",
|
|
"reference:record-the-conditions-with-every-memory-experiment",
|
|
"question:swap-activity-in-guest-and-host",
|
|
"question:guest-page-fault-vs-workload"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/reference/reference-memory-symptom-needs-layer-separation.md",
|
|
"status": "초안",
|
|
"studioId": "63fa33e5-9957-4d28-8d3c-c75735a73bd6",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"question": [
|
|
{
|
|
"title": "이 호스트의 가상 머신들은 설정한 메모리와 지금 잡고 있는 메모리가 얼마나 다른가",
|
|
"kind": "question",
|
|
"slug": "vm-configured-vs-current-memory",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-2",
|
|
"final/document.md#42-configured-memory와-실제-physical-ram-사용량은-같지-않을-수-있다",
|
|
"final/document.md#57-memory-overcommit"
|
|
],
|
|
"known": "§42 는 VM 에 16 GiB 를 설정했다고 해서 시작 순간 Host RAM 16 GiB 가 반드시 즉시 물리적으로 점유되는 것은 아니라고 적고, configured memory · Guest 가 현재 실제 사용하는 memory · Host 에서 현재 resident 한 physical memory 셋이 같지 않을 수 있다고 밝혔다. 그 차이를 만드는 것으로 Host 의 demand paging · backing 종류 · HugeTLB · memory locking · preallocation · overcommit 정책을 들었다. §57 은 configured 총량이 Host physical RAM 을 넘는 구성이 가능한 이유를 configured capacity 와 현재 working set/resident memory 가 같지 않을 수 있다는 데서 찾았다. §83 OQ-2 는 확인 명령으로 Host 쪽 `virsh dominfo <VM_NAME>` · `virsh dumpxml <VM_NAME>` · `virsh dommemstat <VM_NAME>` 와 Guest 쪽 `free -h` · `cat /proc/meminfo` 를 적고 Host 의 QEMU process 상태와 비교하라고 했다. 이 Host 의 physical RAM 도 VM 들의 configured memory 도 SSOT 어디에도 적혀 있지 않다.",
|
|
"unknown": "이 Host 의 physical RAM 과 각 VM 의 configured memory, 그리고 그 합이 Host RAM 을 넘는지. 넘든 넘지 않든 지금 각 Guest 가 실제로 쓰고 있는 memory 와 Host 에서 그 VM 몫으로 resident 한 memory 가 configured 값과 얼마나 벌어져 있는지.",
|
|
"next-verification": "각 VM 에 대해 Host 에서 `virsh dominfo <VM_NAME>` 로 configured/current memory 를, `virsh dumpxml <VM_NAME>` 로 memory backing 설정을, `virsh dommemstat <VM_NAME>` 로 balloon 계열 값을 적는다. 같은 시각에 각 Guest 에서 `free -h` 와 `cat /proc/meminfo` 를 찍고 Host 의 `free -h` 도 함께 남긴다 (§83 OQ-2). QEMU process 쪽 RSS 는 question:qemu-resident-memory-distribution 이 받는다. 기록할 조건은 reference:record-the-conditions-with-every-memory-experiment 를 따른다.",
|
|
"decision-criterion": "세 값(configured · Guest 사용량 · Host resident)을 VM 마다 한 표로 적으면 닫는다 — §42 가 말한 차이가 이 Host 에서 얼마인지가 답이다. configured 합이 Host RAM 을 넘으면 이 환경이 overcommit 상태라는 사실을 확정한 것이 되고, 그 상태에서 무엇이 일어나는지는 question:swap-activity-in-guest-and-host 와 question:host-memory-pressure-vs-guest-latency 가 받는다. 넘지 않으면 §57 의 시나리오는 이 환경에 적용되지 않는다고 적고 닫는다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"question:qemu-resident-memory-distribution",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-vm-configured-vs-current-memory.md",
|
|
"status": "초안",
|
|
"studioId": "67285d51-7eaf-4540-9577-cfd0b273b40e",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "QEMU 프로세스가 실제로 붙잡고 있는 호스트 메모리는 얼마이고 어떻게 나뉘어 있는가",
|
|
"kind": "question",
|
|
"slug": "qemu-resident-memory-distribution",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-3",
|
|
"final/document.md#40-qemu는-guest-ram을-어떻게-준비하는가",
|
|
"final/document.md#41-kvm_set_user_memory_region",
|
|
"final/document.md#42-configured-memory와-실제-physical-ram-사용량은-같지-않을-수-있다"
|
|
],
|
|
"known": "§40 은 QEMU 가 Host userspace process 이고 Guest RAM 도 자신의 Host Virtual Address Space 에 마련한다고 적었다 — RAM 하드웨어에 「물리 주소 X 부터 8 GiB 를 달라」고 요구하는 것이 아니라 QEMU HVA → Host Page Table → HPA 로 관리된다. §41 은 그 영역과 Guest GPA 범위의 대응을 `KVM_SET_USER_MEMORY_REGION` 으로 KVM 에 등록한다고 적었다. §83 OQ-3 은 확인 명령으로 `ps -ef | grep qemu` 와 `ps -o pid,rss,vsz,cmd -p <QEMU_PID>` 를, 필요하면 `cat /proc/<QEMU_PID>/status` 와 `cat /proc/<QEMU_PID>/smaps_rollup` 을 적고 configured memory 와 RSS/anonymous/huge-page 상태를 비교하라고 했다.",
|
|
"unknown": "각 VM 의 QEMU process 가 지금 Host 에서 얼마나 resident 한지(RSS)와 virtual size(VSZ)가 얼마인지, 그 값이 configured memory 와 얼마나 벌어져 있는지, 그리고 그 backing 이 anonymous 인지 huge page 인지.",
|
|
"next-verification": "실행 중인 VM 마다 `ps -ef | grep qemu` 로 PID 를 찾고 `ps -o pid,rss,vsz,cmd -p <QEMU_PID>` 를 찍는다. 이어서 `cat /proc/<QEMU_PID>/status` 와 `cat /proc/<QEMU_PID>/smaps_rollup` 을 남겨 anonymous 와 huge page 항목을 본다 (§83 OQ-3). 같은 실행에서 question:vm-configured-vs-current-memory 가 적은 configured 값을 옆에 놓고 비교한다.",
|
|
"decision-criterion": "VM 마다 configured · RSS · VSZ 와 anonymous/huge-page 구성이 한 표에 적히면 닫는다. RSS 가 configured 에 크게 못 미치면 §42 가 말한 「configured ≠ resident」를 이 Host 에서 확인한 것이 되어 concept:guest-memory-address-translation 의 확인 사례로 흡수한다. huge page backing 이 보이면 question:vm-ram-backed-by-hugetlb 로 넘긴다.",
|
|
"relations": [
|
|
"concept:guest-memory-address-translation",
|
|
"question:vm-configured-vs-current-memory",
|
|
"question:vm-ram-backed-by-hugetlb",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-qemu-resident-memory-distribution.md",
|
|
"status": "초안",
|
|
"studioId": "fa5b3782-9fcf-4113-8f51-a55c8023b2db",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 호스트의 THP 정책과 huge page 상태는 무엇인가",
|
|
"kind": "question",
|
|
"slug": "host-thp-policy",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-4",
|
|
"final/document.md#53-thp-transparent-huge-pages",
|
|
"final/document.md#56-thp와-hugetlb-비교"
|
|
],
|
|
"known": "§53 은 THP 정책을 `cat /sys/kernel/mm/transparent_hugepage/enabled` 로 읽고 출력이 `always [madvise] never` 같은 꼴이라고 적으면서, 현재 정책은 kernel·distribution·Host 설정에 따라 다르므로 실제 시스템에서 확인하라고 했다. §56 은 Host 확인 명령으로 `grep -i huge /proc/meminfo` 와 같은 THP 파일을 들고 `AnonHugePages` 와 `HugePages_Total` 이 같은 의미가 아니라고 적었다. §83 OQ-4 는 확인 항목으로 THP policy · AnonHugePages · HugePages_Total · HugePages_Free · Hugepagesize 다섯을 적었다.",
|
|
"unknown": "이 Host 의 THP 정책이 always 인지 madvise 인지 never 인지, 그리고 다섯 항목의 실제 값. HugeTLB pool 이 잡혀 있는지(HugePages_Total 이 0 인지)도 아직 모른다.",
|
|
"next-verification": "Host 에서 `cat /sys/kernel/mm/transparent_hugepage/enabled` 와 `grep -i huge /proc/meminfo` 를 찍어 §83 OQ-4 의 다섯 항목을 그대로 적는다. 같은 명령을 각 Guest 에서도 찍어 Guest 쪽 정책과 구분한다 — §52 가 Guest 단계와 Host backing 을 하나의 설정으로 취급하지 말라고 적었다.",
|
|
"decision-criterion": "다섯 항목의 값이 Host 와 Guest 각각에 대해 적히면 닫는다. HugePages_Total 이 0 이 아니면 그 pool 을 VM 이 쓰고 있는지를 question:vm-ram-backed-by-hugetlb 로 넘긴다. THP 가 always 인데 latency-sensitive workload 를 돌리고 있으면 §54 가 말한 compaction 영향을 측정할지 여부를 Decision 으로 넘긴다 — 이 질문 자체는 정책 값을 확정하는 데서 끝난다.",
|
|
"relations": [
|
|
"concept:huge-pages-in-a-vm",
|
|
"question:vm-ram-backed-by-hugetlb",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-host-thp-policy.md",
|
|
"status": "초안",
|
|
"studioId": "50730203-df5f-4604-8535-7e93ab6fb724",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "가상 머신 RAM 이 HugeTLB 로 명시적으로 backing 되어 있는가",
|
|
"kind": "question",
|
|
"slug": "vm-ram-backed-by-hugetlb",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-5",
|
|
"final/document.md#55-hugetlb",
|
|
"final/document.md#52-vm에서-huge-page를-볼-때-주의할-점"
|
|
],
|
|
"known": "§55 는 HugeTLB 를 관리자가 미리 준비한 명시적 Huge Page pool 을 VM 이나 application 이 명시적으로 쓰는 방식으로 적고, 사전 확보로 예측 가능성을 높이는 대신 일반 memory allocation 의 유연성이 줄어드는 trade-off 가 있다고 밝혔다. §52 는 VM 에 변환 단계가 둘이라 Guest page-table 단계 · Host backing · EPT 매핑을 구분해야 하고 Guest 와 Host 의 page-size 선택을 하나의 설정으로 취급하면 안 된다고 적었다. §83 OQ-5 는 `virsh dumpxml <VM_NAME>` 로 libvirt memory backing 설정을 확인하고 Host `/proc/meminfo` 및 QEMU `smaps` 계열과 교차 검증하라고 했다.",
|
|
"unknown": "각 VM 의 libvirt 설정에 memory backing 항목이 있는지, 있다면 HugeTLB 를 가리키는지. 그리고 그것이 Host `/proc/meminfo` 의 HugePages 사용량 및 QEMU smaps 의 huge-page 항목과 맞는지.",
|
|
"next-verification": "VM 마다 `virsh dumpxml <VM_NAME>` 를 남기고 memory backing 관련 요소를 그대로 인용한다. 같은 시각에 Host `grep -i huge /proc/meminfo` 와 `cat /proc/<QEMU_PID>/smaps_rollup` 을 찍어 세 자료를 나란히 놓는다 (§83 OQ-5).",
|
|
"decision-criterion": "세 자료가 서로 맞으면 이 환경의 backing 종류를 확정하고 닫는다. 설정에 backing 이 없고 HugePages_Total 도 0 이면 이 VM 들은 명시적 HugeTLB backing 을 쓰지 않는다고 적고 닫는다 — 그 경우 §54 의 THP 쪽 특성만 남는다. 설정과 Host 값이 어긋나면 그 어긋남이 Case 가 된다.",
|
|
"relations": [
|
|
"concept:huge-pages-in-a-vm",
|
|
"question:host-thp-policy",
|
|
"question:qemu-resident-memory-distribution",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-vm-ram-backed-by-hugetlb.md",
|
|
"status": "초안",
|
|
"studioId": "f460e9a2-35ef-46ff-81cf-b36627a1b231",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "지금 게스트와 호스트에서 swap 이 실제로 오가고 있는가",
|
|
"kind": "question",
|
|
"slug": "swap-activity-in-guest-and-host",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-6",
|
|
"final/document.md#63-swap-used만-보고-장애를-판단하면-안-된다",
|
|
"final/document.md#61-guest-swap과-host-swap"
|
|
],
|
|
"known": "§63 은 Swap Used 값 하나로 memory pressure 가 심하다고 단정할 수 없고 과거에 swap-out 된 cold page 가 남아 있을 수도 있다고 적으면서, 더 중요한 물음으로 지금 swap-in/out 이 지속되는가 · reclaim pressure 가 증가하는가 · major fault 가 증가하는가 · storage latency 가 같이 증가하는가 넷을 들고 Guest 와 Host 를 동시에 확인하라고 했다. 확인 명령은 `free -h` 와 `vmstat 1` 이다. §61 은 Guest Swap 이 Guest kernel 에서 `/dev/vda` 로 내려가는 경로이고 Host Swap 은 QEMU memory backing 이 Host kernel 에 눌리는 경로라 둘이 다르며, Guest 가 여유 있어 보이는데 Host 에서 swap/reclaim 이 심할 수도 있다고 적었다. §83 OQ-6 도 같은 두 명령을 Guest 와 Host 양쪽에 적었다.",
|
|
"unknown": "지금 이 환경에서 swap-in/out 이 실제로 오가고 있는지, 오간다면 Guest 쪽인지 Host 쪽인지 둘 다인지. Swap Used 가 0 이 아니더라도 그것이 남아 있는 cold page 인지 진행 중인 활동인지.",
|
|
"next-verification": "Guest 와 Host 양쪽에서 같은 시각에 `free -h` 를 한 번 찍고 `vmstat 1` 을 일정 시간 돌려 `si`/`so` 열이 계속 0 인지 본다 (§83 OQ-6 · §63). Guest 는 VM 마다 따로 찍는다. 같은 창에서 §63 이 든 나머지 셋 — reclaim pressure · major fault · storage latency — 도 함께 남긴다.",
|
|
"decision-criterion": "관측 구간 내내 Guest 와 Host 모두 `si`/`so` 가 0 이면 지금은 swap 이 오가지 않는다고 적고 닫는다 — Swap Used 값이 0 이 아니어도 그렇게 적는다. 한쪽에서 swap 이 오가면 그 방향(§61 의 두 경로 중 어느 쪽인지)을 적고 그 구간의 storage latency 및 Guest latency 와 함께 놓아 question:host-memory-pressure-vs-guest-latency 로 넘긴다.",
|
|
"relations": [
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"question:host-memory-pressure-vs-guest-latency",
|
|
"question:host-major-fault-vs-storage-latency",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-swap-activity-in-guest-and-host.md",
|
|
"status": "초안",
|
|
"studioId": "d3e8501f-e1b5-4f8f-aa9a-89f9c89a308e",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "호스트 메모리 압박이 게스트 애플리케이션 지연을 실제로 밀어 올리는가",
|
|
"kind": "question",
|
|
"slug": "host-memory-pressure-vs-guest-latency",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-7",
|
|
"final/document.md#59-host-memory-pressure와-reclaim",
|
|
"final/document.md#60-host-swap이-vm에-미치는-영향",
|
|
"final/document.md#62-memory-pressure와-storage-contention의-연결"
|
|
],
|
|
"known": "§59 는 Host RAM 수요가 available physical memory 에 가까워지면 reclaim 이 돌고, file-backed clean page 는 버렸다 다시 읽으면 되지만 anonymous page 는 swap 같은 backing 이 필요하다고 적었다. §60 은 Guest 가 단순히 RAM 에 접근한다고 생각하는 사이에 Host 쪽에서는 backing page 가 RAM 에 없어 Host Page Fault → swap-in I/O → RAM 복원 → Guest 실행 계속으로 바뀔 수 있다고 적었다. §62 는 그 결과 Guest swap I/O · Host swap I/O · DB I/O · filesystem writeback 이 한 물리 장치로 몰려 storage contention 과 application latency 로 이어질 수 있고, CPU 사용률이 낮다고 memory/storage 문제가 없는 것은 아니라고 밝혔다. §83 OQ-7 은 실험 개념을 baseline → Guest latency 측정 → Host memory pressure 유도 → Host reclaim/swap 관측 → Guest latency 재측정으로 적고 CPU 와 storage 도 동시에 관측하라고 했다.",
|
|
"unknown": "이 Host 에서 memory pressure 를 유도했을 때 reclaim 과 swap 이 실제로 도는지, 돈다면 같은 구간의 Guest application latency 가 baseline 대비 얼마나 달라지는지, 그리고 그 변화가 CPU 쪽이 아니라 memory/storage 쪽 지표와 같은 방향으로 움직이는지.",
|
|
"next-verification": "baseline 구간에서 Guest application latency 와 Host `vmstat 1` · storage latency · CPU 를 같은 시각에 기록한다. 그 다음 Host 에 memory pressure 를 유도하고 같은 네 가지를 다시 기록한 뒤, pressure 를 걷고 세 번째 구간을 찍는다 (§83 OQ-7). 세 구간 모두에 reference:record-the-conditions-with-every-memory-experiment 의 Host · VM · Workload 조건을 남긴다. Guest 쪽 swap 은 question:swap-activity-in-guest-and-host 와 같은 방법으로 함께 찍는다.",
|
|
"decision-criterion": "pressure 구간에서 Host reclaim/swap 이 돌았는데도 Guest latency 가 baseline 과 다르지 않으면, 이 구성에서는 그 정도의 압박이 Guest 까지 오지 않는다고 적고 닫는다. latency 가 오르면 그 세 구간 표가 Case 가 되고 이 질문은 그 Case 가 닫는다. 압박을 어디까지 허용할지 — swappiness 를 바꿀지, VM 배치를 바꿀지, balloon 을 쓸지 — 는 그 Case 가 나온 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"question:swap-activity-in-guest-and-host",
|
|
"question:host-major-fault-vs-storage-latency",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-host-memory-pressure-vs-guest-latency.md",
|
|
"status": "초안",
|
|
"studioId": "a05fe2a6-eb7c-4bcc-a7da-58e729436468",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 가상 머신들에 virtio-balloon 이 붙어 있는가",
|
|
"kind": "question",
|
|
"slug": "virtio-balloon-configured",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-8",
|
|
"final/document.md#65-virtio-balloon-구조",
|
|
"final/document.md#64-ballooning이-필요한-이유"
|
|
],
|
|
"known": "§65 는 virtio-balloon 을 Guest kernel 쪽 driver 와 QEMU 쪽 device 가 virtqueue 로 맞물린 구성으로 그리고, Guest RAM 자체를 제공하는 장치가 아니라 이미 있는 backing 을 Host 와 Guest 가 협력해 회수·반환하는 데 쓰는 가상 장치라고 적었다. §64 는 Host 가 Guest 안에서 어느 memory 가 중요한지 완전히 알지 못하므로 무작정 swap-out 하기보다 Guest kernel 과 협력하는 편이 유리할 수 있다는 것을 이 장치의 존재 이유로 들었다. §83 OQ-8 은 `virsh dumpxml <VM_NAME>` 로 확인하고 Guest 에서도 관련 driver/device 상태를 확인하라고 하면서, 환경에 따라 driver 이름과 표시 방식이 달라질 수 있으니 실제 장비에서 검증하라는 단서를 달았다.",
|
|
"unknown": "각 VM 의 libvirt 설정에 balloon device 가 있는지, 있다면 Guest 안에서 해당 driver 가 실제로 올라와 있는지. 이 환경에서 그 driver 가 어떤 이름으로 보이는지도 SSOT 에 없다.",
|
|
"next-verification": "VM 마다 `virsh dumpxml <VM_NAME>` 를 남기고 balloon 관련 요소를 그대로 인용한다. 각 Guest 에서 balloon 관련 driver/device 상태를 확인해 실제로 보이는 이름과 함께 적는다 (§83 OQ-8). `virsh dommemstat <VM_NAME>` 출력도 같이 남긴다 — question:vm-configured-vs-current-memory 가 같은 명령을 찍으므로 한 번에 받는다.",
|
|
"decision-criterion": "설정과 Guest 쪽 상태가 둘 다 적히면 닫는다. 붙어 있지 않으면 이 환경에서는 ballooning 이 동작하지 않는다고 적고 question:balloon-target-vs-guest-available-memory 는 열지 않은 채로 둔다 — 장치가 없으면 그 실험이 성립하지 않는다. 붙어 있으면 그 질문으로 넘긴다.",
|
|
"relations": [
|
|
"concept:virtio-balloon-memory-reclaim",
|
|
"question:balloon-target-vs-guest-available-memory",
|
|
"question:vm-configured-vs-current-memory"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-virtio-balloon-configured.md",
|
|
"status": "초안",
|
|
"studioId": "63aef96b-03ef-4dbd-9ba6-9e61c6e695e1",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "balloon target 을 바꾸면 게스트가 쓸 수 있는 메모리는 어떻게 따라 움직이는가",
|
|
"kind": "question",
|
|
"slug": "balloon-target-vs-guest-available-memory",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-9",
|
|
"final/document.md#66-balloon-inflate",
|
|
"final/document.md#68-balloon-deflate",
|
|
"final/document.md#69-ballooning을-과도하게-하면-guest가-압박을-받는다"
|
|
],
|
|
"known": "§66 은 inflate 하면 Guest 안의 balloon 이 커져 Guest usable memory 가 줄고 Host 가 회수할 수 있는 backing 이 는다고 적었고, §68 은 target 을 줄이면 balloon page 가 반환되어 Guest usable memory 가 는다고 적었다. §69 는 working set 이 큰데 과도하게 inflate 하면 Guest available memory 감소 → Guest memory pressure → reclaim → page cache 회수 → Guest swap → 심하면 Guest OOM 으로 이어질 수 있고, Host RAM 을 확보하려는 조치가 Guest storage I/O 와 application latency 를 올릴 수 있다고 밝혔다. §83 OQ-9 는 Host/libvirt memory setting → Guest `free -h` / `/proc/meminfo` → Guest reclaim/swap 변화 순으로 관측하고 과도한 ballooning 시의 latency/swap/OOM 가능성은 별도 실험으로 보라고 했다.",
|
|
"unknown": "이 환경에서 balloon target 을 바꿨을 때 Guest 의 available memory 가 얼마나 따라 움직이는지, 그 반영이 즉시인지 지연이 있는지, 그리고 어느 지점부터 Guest reclaim/swap 이 시작되는지.",
|
|
"next-verification": "question:virtio-balloon-configured 가 balloon 이 붙어 있다고 확정한 뒤에 연다. baseline 에서 Guest `free -h` 와 `/proc/meminfo` 와 `vmstat 1` 을 찍고, Host 에서 balloon target 을 한 단계 낮춘 뒤 같은 셋을 다시 찍는다. 단계를 몇 번 반복해 target 과 Guest available memory 의 대응을 표로 만든다 (§83 OQ-9). 과도 inflate 구간은 §69 가 경고한 대로 별도 실험으로 분리하고 Guest application latency 를 같이 잰다.",
|
|
"decision-criterion": "target 값과 Guest available memory 가 표로 대응되고 reclaim/swap 이 시작되는 지점이 적히면 닫는다. Guest swap 이나 OOM 까지 갔으면 그 구간이 Case 가 되고, 운영에서 balloon 을 쓸지와 target 하한을 얼마로 둘지는 그 Case 가 나온 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:virtio-balloon-memory-reclaim",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"question:virtio-balloon-configured",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-balloon-target-vs-guest-available-memory.md",
|
|
"status": "초안",
|
|
"studioId": "6a60abe7-ea2c-46c2-bb9f-8281bfbe9644",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "QEMU 메모리는 vCPU 가 도는 NUMA node 와 같은 node 에 있는가",
|
|
"kind": "question",
|
|
"slug": "qemu-memory-numa-placement",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-11",
|
|
"final/document.md#75-vcpu와-numa의-연결",
|
|
"final/document.md#76-vcpu-pinning만으로는-numa-최적화가-끝나지-않는다",
|
|
"final/document.md#78-numa는-실제-장비-topology부터-확인한다"
|
|
],
|
|
"known": "§75 는 Guest vCPU 가 Host 에서 QEMU vCPU thread 이고, VM 의 vCPU thread 가 Node 0 CPU 에서 실행되는데 그 VM 의 Host physical backing page 가 Node 1 에 있으면 Guest 에서는 단순한 memory load 인 것이 실제 하드웨어에서는 NUMA interconnect 를 건널 수 있다고 적었다. §76 은 vCPU 를 pinning 해도 memory 가 다른 node 에 배치되어 있으면 remote access 가 많아질 수 있으므로 vCPU placement 와 memory placement/binding 을 함께 봐야 한다고 밝혔다. §78 은 `numastat -p <QEMU_PID>` 로 QEMU process 별 memory distribution 을, `virsh vcpupin` 과 `virsh vcpuinfo` 로 vCPU placement 를 본다고 적었다. §83 OQ-11 은 `numastat -p <QEMU_PID>` 결과를 vCPU placement 와 비교해 vCPU → Node 0 / Memory → Node 0 인지 vCPU → Node 0 / Memory → Node 1 인지 확인하라고 했다.",
|
|
"unknown": "이 Host 에서 각 VM 의 QEMU memory 가 어느 NUMA node 에 얼마나 나뉘어 있는지, 그리고 그 분포가 그 VM 의 vCPU thread 가 도는 node 와 맞는지 어긋나는지. Host 가 다중 NUMA node 인지 자체가 아직 확정되지 않았고 그것은 CPU 부의 question:host-numa-topology 가 받는다.",
|
|
"next-verification": "question:host-numa-topology 가 이 Host 를 다중 NUMA node 로 확정한 뒤에 연다. VM 마다 `numastat -p <QEMU_PID>` 로 node 별 memory 분포를 찍고, 같은 시각에 `virsh vcpuinfo <VM_NAME>` 와 `virsh vcpupin <VM_NAME>` 로 vCPU 배치를 적어 나란히 놓는다 (§78 · §83 OQ-11).",
|
|
"decision-criterion": "node 별 memory 분포와 vCPU 배치가 VM 마다 한 표로 적히면 닫는다. 둘이 같은 node 로 모여 있으면 §76 이 말한 어긋남이 이 환경에 없다고 적고 닫는다. 어긋나 있으면 그 표가 Case 가 되고, 그 어긋남이 실제 latency 를 바꾸는지는 question:numa-remote-access-vs-workload-latency 가 받는다. memory binding 을 걸지 여부는 그 뒤 Decision 으로 넘긴다. 단일 NUMA node 로 나오면 이 질문은 이 환경에 적용되지 않는다고 적고 닫는다.",
|
|
"relations": [
|
|
"concept:numa-locality-for-vcpu-and-memory",
|
|
"question:host-numa-topology",
|
|
"question:numa-remote-access-vs-workload-latency",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-qemu-memory-numa-placement.md",
|
|
"status": "초안",
|
|
"studioId": "1b59e6de-16f1-42b2-81bb-01d6198e34bf",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "NUMA remote access 가 이 작업의 지연을 실제로 바꾸는가",
|
|
"kind": "question",
|
|
"slug": "numa-remote-access-vs-workload-latency",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-12",
|
|
"final/document.md#74-local-memory와-remote-memory",
|
|
"final/document.md#77-guest-numa"
|
|
],
|
|
"known": "§74 는 remote access 가 local access 와 동일한 비용이라고 가정할 수 없으며 추가 latency/bandwidth 비용이 있을 수 있다고 적었다. §77 은 큰 VM 에서는 Guest 에게 NUMA topology 를 노출하고 가능하면 Guest 가 인식하는 topology 와 실제 Host placement 가 합리적으로 대응되도록 구성할 수 있다고 적었다. §83 OQ-12 는 NUMA node 가 2개 이상인 경우에만 우선순위를 높이라고 하면서 실험을 local placement baseline → latency/throughput/memory metrics → remote-heavy placement → 동일 workload 비교로 적고, 단순 topology 만 보고 성능 문제라고 단정하지 말라는 단서를 달았다.",
|
|
"unknown": "이 Host 에서 local placement 와 remote-heavy placement 를 각각 구성했을 때 같은 workload 의 latency 와 throughput 이 실제로 다른지, 다르다면 얼마나 다른지. Guest NUMA 를 노출한 구성인지도 SSOT 에 적혀 있지 않다.",
|
|
"next-verification": "question:host-numa-topology 가 다중 node 로 확정하고 question:qemu-memory-numa-placement 가 현재 배치를 적은 뒤에 연다. local placement 로 맞춘 구성에서 같은 workload 를 돌려 latency · throughput · memory 지표를 기록하고, remote-heavy placement 로 바꿔 같은 workload 를 같은 조건으로 다시 돌린다 (§83 OQ-12). 두 구간 모두에 reference:record-the-conditions-with-every-memory-experiment 의 세 묶음을 남긴다.",
|
|
"decision-criterion": "두 배치의 latency/throughput 이 측정 오차 안에서 다르지 않으면 이 workload 에서는 NUMA locality 가 우선순위가 아니라고 적고 닫는다. 차이가 나면 그 비교표가 Case 가 되고, vCPU pinning 과 memory binding 을 운영 구성으로 채택할지는 그 Case 가 나온 뒤 Decision 으로 넘긴다. 단일 NUMA node 로 나오면 §83 이 적은 대로 우선순위를 낮추고 닫는다.",
|
|
"relations": [
|
|
"concept:numa-locality-for-vcpu-and-memory",
|
|
"question:qemu-memory-numa-placement",
|
|
"question:host-numa-topology",
|
|
"reference:record-the-conditions-with-every-memory-experiment"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-numa-remote-access-vs-workload-latency.md",
|
|
"status": "초안",
|
|
"studioId": "380d4975-3be5-451d-aede-2e24c5a2a09e",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "게스트 page fault 증가는 workload 변화를 따라가는가",
|
|
"kind": "question",
|
|
"slug": "guest-page-fault-vs-workload",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-13",
|
|
"final/document.md#45-guest-page-fault",
|
|
"final/document.md#46-page-fault의-대표적인-원인"
|
|
],
|
|
"known": "§45 는 Guest Page Fault 가 GVA → GPA 단계에서 접근을 완료할 수 없을 때 나고 Guest Kernel 이 page 를 확보해 매핑을 갱신한 뒤 instruction 을 재시도한다고 적으면서, Page Fault 자체가 프로그램 오류를 뜻하지 않는다고 밝혔다. §46 은 대표 원인으로 demand paging · swap-in · permission fault · copy-on-write · invalid access 다섯을 들고 Page Fault 와 Segmentation Fault 가 다르다고 적었다. §83 OQ-13 은 Guest 에서 page-fault 관련 지표를 관측하되 정상 demand paging 인지 · COW 인지 · Guest swap-in 인지 · application working-set 증가인지를 분리하고, Page Fault 증가만으로 오류라고 판단하지 말라고 했다.",
|
|
"unknown": "이 환경의 Guest 에서 workload 가 늘 때 page fault 지표가 실제로 함께 오르는지, 오른다면 minor 인지 major 인지, 그리고 §46 의 다섯 원인 중 어느 쪽으로 설명되는지.",
|
|
"next-verification": "Guest 에서 idle 구간과 workload 구간을 나눠 page-fault 관련 지표를 같은 방법으로 기록한다 — `vmstat 1` 로 시간에 따른 변화를 보고 프로세스 수준은 `/proc/<PID>/stat` 계열로 minor/major 를 가른다. 같은 구간에 Guest 의 swap 활동(question:swap-activity-in-guest-and-host 와 같은 방법)과 application 의 working set 을 함께 남겨 §83 OQ-13 이 든 네 갈래를 분리한다.",
|
|
"decision-criterion": "workload 구간의 fault 증가가 minor 위주이고 swap-in 이 없으면 정상 demand paging 으로 설명된다고 적고 닫는다 — §45 가 말한 대로 그것은 오류가 아니다. major fault 가 함께 오르면 Guest swap-in 을 의심하고 그 구간을 question:swap-activity-in-guest-and-host 로 넘긴다. 어느 쪽으로도 설명되지 않으면 그 관측이 Case 가 된다.",
|
|
"relations": [
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"question:swap-activity-in-guest-and-host",
|
|
"question:host-major-fault-vs-storage-latency",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-guest-page-fault-vs-workload.md",
|
|
"status": "초안",
|
|
"studioId": "074a1cb4-cea8-4dad-bc4c-899692ff9aa9",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "호스트 major fault 와 스토리지 지연은 같은 시간축에서 함께 움직이는가",
|
|
"kind": "question",
|
|
"slug": "host-major-fault-vs-storage-latency",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-14",
|
|
"final/document.md#49-host-page-fault도-별도로-존재한다",
|
|
"final/document.md#62-memory-pressure와-storage-contention의-연결"
|
|
],
|
|
"known": "§49 는 QEMU 도 Host 의 일반 userspace process 이므로 QEMU memory backing 에 Host virtual-memory 관리가 적용되고 demand allocation·reclaim/swap 때문에 Host 쪽에서도 page fault 가 날 수 있다고 적으면서, VM 메모리 분석에서는 Guest Page Fault · Host Page Fault · EPT 관련 사건을 적어도 셋으로 구분해야 한다고 밝혔다. §62 는 Guest swap I/O · Host swap I/O · DB I/O · filesystem writeback 이 한 물리 장치로 몰릴 수 있고 Host memory pressure → reclaim/swap → storage I/O 증가 → storage contention → DB latency → application latency 로 이어질 수 있다고 적었다. §83 OQ-14 는 Host memory pressure 실험 시 Host fault · swap activity · storage latency · Guest application latency 를 같은 시간축으로 비교하라고 했다.",
|
|
"unknown": "Host 에 memory pressure 가 걸린 구간에서 Host major fault 와 swap activity 와 storage latency 가 실제로 같은 방향으로 움직이는지, 그리고 그 움직임이 Guest application latency 와 시간적으로 겹치는지.",
|
|
"next-verification": "question:host-memory-pressure-vs-guest-latency 의 실험과 같은 실행에서 받는다 — baseline · pressure · 회복 세 구간 각각에 Host 의 major fault 와 swap 활동(`vmstat 1`), storage latency, Guest application latency 를 같은 타임스탬프로 남긴다 (§83 OQ-14). 네 계열을 한 시간축에 놓고 본다.",
|
|
"decision-criterion": "네 계열이 같은 구간에서 함께 오르면 §62 가 그린 사슬이 이 환경에서 이어진다는 것을 확인한 것이 되고 그 시계열이 Case 가 된다. major fault 는 오르는데 storage latency 가 따라 오르지 않으면 이 장치 구성에서는 그 사슬이 여기서 끊긴다고 적고 닫는다. 어느 쪽이든 storage 쪽 대응 — 장치 분리나 swap 위치 변경 — 은 그 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:page-fault-layers-in-a-vm",
|
|
"concept:memory-pressure-reclaim-swap-oom",
|
|
"question:host-memory-pressure-vs-guest-latency",
|
|
"question:swap-activity-in-guest-and-host",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "memory-virtualization/question/question-host-major-fault-vs-storage-latency.md",
|
|
"status": "초안",
|
|
"studioId": "a2cbc828-59ab-4e70-916a-d053e71960ae",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"decision": []
|
|
}
|
|
},
|
|
"network-virtualization": {
|
|
"topic": "network-virtualization",
|
|
"title": "네트워크 가상화 — Guest 의 packet 이 Host Physical NIC 까지 가는 길",
|
|
"readerQuestion": "Guest 애플리케이션이 보낸 packet 은 어느 계층을 거쳐 Host Physical NIC 까지 가고, 요청이 느리거나 닿지 않을 때 그것이 network 가상화의 어느 자리 문제인지 무엇을 보고 가르는가?",
|
|
"kinds": {
|
|
"case": [],
|
|
"concept": [
|
|
{
|
|
"title": "Guest 의 packet 이 Host Physical NIC 에 닿기까지 — virtio-net · virtqueue · vhost-net · TAP · Bridge",
|
|
"kind": "concept",
|
|
"slug": "guest-packet-path-to-physical-nic",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#94-전체-네트워크-계층",
|
|
"final/document.md#121-이-ssot에서-파생될-concept",
|
|
"final/document.md#125-최종-기준-구조",
|
|
"final/document.md#89-문서-목적",
|
|
"final/document.md#90-virsh-libvirt-virtio-구분",
|
|
"final/document.md#91-virtio-net은-정확히-어디에-있는가",
|
|
"final/document.md#92-frontend와-backend",
|
|
"final/document.md#93-guest-os는-왜-qemu가-아니라-virtio-net을-사용하는가",
|
|
"final/document.md#95-physical-nic의-역할",
|
|
"final/document.md#96-linux-bridge의-역할",
|
|
"final/document.md#97-routing의-역할",
|
|
"final/document.md#98-nat의-역할",
|
|
"final/document.md#99-tap의-역할",
|
|
"final/document.md#100-virtqueue의-역할",
|
|
"final/document.md#101-guest-tcp-ip-stack의-역할",
|
|
"final/document.md#102-packet이-keycloak까지-올라오는-과정",
|
|
"final/document.md#103-qemu-virtio-device-model의-역할",
|
|
"final/document.md#104-왜-tap-→-vhost-net-→-qemu-→-virtqueue-라고-일반화하면-안-되는가",
|
|
"final/document.md#105-control-path와-data-path",
|
|
"final/document.md#106-qemu가-userspace인데-packet이-qemu를-안-거칠-수-있는-이유",
|
|
"final/document.md#107-vhost-net-최적화",
|
|
"final/document.md#108-vhost-net은-qemu를-제거하지-않는다",
|
|
"final/document.md#109-fast-path와-slow-control-path",
|
|
"final/document.md#110-data-copy-최적화",
|
|
"final/document.md#111-interrupt-notification-최적화",
|
|
"final/document.md#112-multi-queue-최적화",
|
|
"final/document.md#113-offload-최적화",
|
|
"final/document.md#114-linux-bridge가-항상-host-tcp-ip-stack을-거치는-것은-아니다",
|
|
"final/document.md#115-host-physical-nic로-나갈-때-virtio를-다시-거치지-않는다",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-4",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-5",
|
|
"final/document.md#124-핵심-claim"
|
|
],
|
|
"basis-version": "Linux KVM/QEMU/libvirt 의 virtio-net frontend + vhost-net kernel backend + TAP + Linux Bridge 구성. §94 가 「가장 기본적인 구조」로 잡은 것이 이 조합이고, 같은 절이 실제 환경은 Bridge · NAT · Routed Network · macvtap · SR-IOV · VFIO passthrough · Open vSwitch · Kubernetes CNI 에 따라 달라질 수 있다고 적었으므로 이 글은 그 조합 안에서만 유효하다. SSOT 가 커널·QEMU·libvirt 버전을 한 번도 적지 않아 특정 버전에 고정하지 않는다 — 여기 적힌 것은 이 문서가 서술한 구성이고, 버전이 바뀌어 서술이 낡았는지는 §122 의 확인을 실제 Host 에서 돌릴 때 드러난다. §110 이 copy 동작을 kernel version · QEMU version · vhost configuration · offload · NIC capability 에 따라 달라진다고 못박은 것이 그 경계다.",
|
|
"classification": "§121 이 virsh · libvirt · QEMU · virtio · virtio-net · Frontend/Backend · virtqueue · QEMU virtio Device Model · vhost-net · TAP · Linux Bridge · Routing · NAT · Physical NIC · Guest TCP/IP Stack · Socket · Data Path/Control Path · Fast Path · Multi-Queue · Offload · Packet tracing 을 한 목록으로 묶고 「이 요소들이 하나의 packet 실행 경로를 설명하므로 하나의 CONCEPT 로 관리한다」고 적었다. 제1부의 §19 가 CPU 실행 경로에 대해 같은 지시를 했고 그 부도 개념 하나로 내려앉았다. 경로 중간을 잘라 내면 인과가 끊긴다 — virtqueue 만 떼면 무엇과 무엇 사이의 queue 인지 말할 수 없고, vhost-net 만 떼면 무엇을 우회하는지 말할 수 없다. 이 글이 확정하는 것은 구조가 어떻게 동작하는가와 그 구조에서 어긋날 수 있는 자리(§117.4·§117.5)까지다. §103 이 나눈 두 역할(장치 관리 · packet 처리)이 이 글의 척추이고, §104 · §108 · §114 · §115 는 그 척추를 잘못 일반화한 그림 넷을 차례로 지운다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. 제3부는 개념 서술이고 §122 가 OQ-1~OQ-7 로 아직 돌리지 않은 확인 목록을 적어 두었다. 이 Host 의 network 가 Bridge 인지 NAT 인지(OQ-1), TAP 이 무엇인지(OQ-2), vhost-net 을 실제로 쓰는지(OQ-3), multi-queue 가 켜져 있는지(OQ-5)를 확인하기 전까지 이 글은 「이 구조에서는 이렇게 동작한다」까지만 말하고 「이 서버가 그 구조다」라고는 말하지 않는다. §116 이 이 테스트 환경에 얹어 그린 펼친 경로도 같은 이유로 확인 대상이며, 후보 대장에 SSOT-116-test-environment-packet-path 로 NEEDS_EVIDENCE 를 적어 두었다.",
|
|
"relations": [
|
|
"reference:bisect-the-packet-path-with-capture-points",
|
|
"reference:verify-the-network-path-before-blaming-the-application",
|
|
"question:vm-network-mode-bridge-nat-or-routed",
|
|
"question:tap-interface-to-vm-mapping",
|
|
"question:is-vhost-net-actually-in-use",
|
|
"question:qemu-backend-vs-vhost-net-on-this-host",
|
|
"question:virtio-net-multi-queue-enabled",
|
|
"question:actual-packet-path-nginx-to-keycloak",
|
|
"question:network-virtualization-cpu-cost-under-load",
|
|
"concept:kvm-vcpu-to-physical-cpu"
|
|
],
|
|
"ssot-assets": [
|
|
"packet-control-and-data-paths"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/concept/concept-guest-packet-path-to-physical-nic.md",
|
|
"status": "초안",
|
|
"studioId": "5b1de31c-0495-4226-8607-73ed7284b314",
|
|
"assets": [
|
|
"packet-control-and-data-paths"
|
|
],
|
|
"assetFiles": [
|
|
"packet-control-and-data-paths"
|
|
],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"reference": [
|
|
{
|
|
"title": "packet 이 어디서 끊겼는지는 계층마다 capture 해서 가른다",
|
|
"kind": "reference",
|
|
"slug": "bisect-the-packet-path-with-capture-points",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#119-실제-packet-path-추적",
|
|
"final/document.md#118-실제-linux에서-확인할-명령어",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-1",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-2",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-3",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-6",
|
|
"final/document.md#113-offload-최적화",
|
|
"final/document.md#114-linux-bridge가-항상-host-tcp-ip-stack을-거치는-것은-아니다",
|
|
"final/document.md#99-tap의-역할"
|
|
],
|
|
"classification": "§119 가 Host 의 physical NIC · bridge · tap/vnet 과 Guest 의 interface 에 각각 `tcpdump -ni` 를 걸고 어디까지 보이는지로 의심 구간을 좁히는 절차를 적었다. 세 가지 판독을 예로 들었다 — Physical NIC O · Bridge O · TAP X 이면 Host Bridge/TAP mapping 을, TAP O · Guest NIC X 이면 virtio/vhost/Guest NIC 계층을, Guest NIC O · Socket X 이면 Guest routing/firewall/listen 상태를 의심한다. §117.1~.3 이 그 절차가 다루는 증상(연결 오류 · routing 오류 · NAT/firewall 오류)을 대고 §118 이 각 지점에서 무엇을 실행할지를 댄다. 원 프로젝트의 이름을 지워도 규칙이 남는다는 점에서 Case 요약이 아니고, OQ-1 · OQ-2 · OQ-6 셋이 모두 이 규칙 위에서 돌아가므로 세 글에 되풀이하지 않고 한 편으로 두고 가리킨다.",
|
|
"scope": "KVM/QEMU/libvirt 로 만든 VM 이 밖과 통신하지 못하거나 특정 구간에서만 실패할 때, 그리고 실제 packet 경로를 처음 확인할 때. capture 지점은 Host 쪽 physical NIC · bridge · tap/vnet 과 Guest 쪽 interface 넷이고, 그 이름은 `ip link` · `bridge link` · `ip tuntap show` · `virsh domiflist <domain>` · `virsh net-list --all` · `virsh net-dumpxml <network>` · `ip route` · `ip rule` 로 먼저 확정한다(§118). 판독은 어느 지점까지 보였는가로만 하고, 보이지 않은 첫 지점의 앞 구간을 의심 구간으로 삼는다.",
|
|
"exceptions": "offload(GSO · GRO · TSO · Checksum offload)가 켜져 있으면 tcpdump 에 보이는 packet size 와 checksum 이 실제 wire 와 다르게 보일 수 있다(§113 · §117.6) — 크기와 checksum 이 이상하다는 이유만으로 결함으로 읽지 않는다. Bridge 가 단순 L2 forwarding 만 하는 구성에서는 frame 이 Host 의 L3 TCP/IP stack 을 거치지 않으므로 Host 쪽 L3 관측에서 안 보이는 것이 정상이다(§114). 네 지점이 모두 보이는데도 느린 경우는 이 규칙이 답하지 않는다 — 그때는 reference:verify-the-network-path-before-blaming-the-application 으로 넘긴다. 이 저장소에는 아직 이 절차를 실제로 돌린 출력이 없어 규칙은 SSOT 가 서술한 것이고 이 Host 의 출력으로 확인된 것이 아니다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:verify-the-network-path-before-blaming-the-application",
|
|
"question:vm-network-mode-bridge-nat-or-routed",
|
|
"question:tap-interface-to-vm-mapping",
|
|
"question:actual-packet-path-nginx-to-keycloak"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/reference/reference-bisect-the-packet-path-with-capture-points.md",
|
|
"status": "초안",
|
|
"studioId": "68a848c7-eaff-4421-ad25-de21673ca40c",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Keycloak 실험 결과를 애플리케이션 원인으로 읽기 전에 network 계층을 따로 검증한다",
|
|
"kind": "reference",
|
|
"slug": "verify-the-network-path-before-blaming-the-application",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#120-keycloak-refresh-token-실험과의-관계",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-7",
|
|
"final/document.md#124-핵심-claim",
|
|
"final/document.md#89-문서-목적",
|
|
"final/document.md#116-현재-keycloak-k3s-테스트-환경과-연결",
|
|
"final/document.md#102-packet이-keycloak까지-올라오는-과정"
|
|
],
|
|
"classification": "§120 은 Refresh Token 경쟁 자체는 virtio-net 문제가 아니지만 Client → Nginx → VM1/VM2 → K3s → Keycloak → PostgreSQL/Redis 경로를 공유하므로 network virtualization 문제가 실험 결과에 영향을 줄 수 있다고 적고, Node1 요청만 지연 · VM2 packet loss · Host bridge misconfiguration · NAT/conntrack issue · Host CPU contention 으로 인한 vhost 처리 지연을 Refresh Token 경쟁이나 DB lock 으로 오해하지 않도록 network path 를 별도로 검증하라고 못박았다. §124 의 Claim 17 이 같은 것을 한 줄로 적었고, §117.7 은 반대 방향까지 덧붙였다 — vhost-net · QEMU thread · softirq 도 Host CPU 를 쓰므로 network 문제처럼 보이는 것이 CPU scheduling 문제일 수도 있다. reference:bisect-the-packet-path-with-capture-points 가 network 안에서 어느 hop 인지를 가른다면 이 규칙은 그것이 network 인지 아닌지를 가르므로 둘은 다른 물음에 답한다.",
|
|
"scope": "여러 노드가 같은 network path 를 공유하는 실험의 결과를 원인에 귀속할 때. 특히 노드별로만 나타나는 지연, 특정 VM 에서만 나는 실패, 부하 구간에서만 커지는 latency 를 애플리케이션 동시성이나 저장소 lock 으로 결론내기 전에 적용한다. 검증 순서는 경로가 무엇인지(question:actual-packet-path-nginx-to-keycloak) · 그 경로가 끊기지 않았는지(reference:bisect-the-packet-path-with-capture-points) · network 처리가 Host CPU 를 얼마나 쓰는지(question:network-virtualization-cpu-cost-under-load) 셋이고, 셋을 애플리케이션 실험과 같은 시간축에 기록한다.",
|
|
"exceptions": "Keycloak 은 virtqueue · vhost-net · TAP · Bridge · Physical NIC 를 직접 알지 못하고 Guest socket 위에서만 동작하므로(§102) 애플리케이션 로그만으로는 이 계층이 원인인지 아닌지를 가를 수 없다 — 이 규칙은 애플리케이션 쪽 관측을 늘려서는 적용되지 않는다. 반대로 network 계층이 깨끗해도 이 규칙이 애플리케이션 결함을 배제해 주지는 않는다. §116 이 그린 이 환경의 경로는 아직 확인된 것이 아니라 기준 구조를 얹은 그림이고, K3s 안의 CNI · Service · Pod network 는 §116 이 별도 계층으로 미뤄 두어 이 규칙의 범위 밖이다. 이 저장소에는 이 규칙으로 원인을 실제로 가른 실험이 아직 없다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:bisect-the-packet-path-with-capture-points",
|
|
"question:actual-packet-path-nginx-to-keycloak",
|
|
"question:network-virtualization-cpu-cost-under-load",
|
|
"question:virtualization-layer-saturation-during-refresh"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/reference/reference-verify-the-network-path-before-blaming-the-application.md",
|
|
"status": "초안",
|
|
"studioId": "ca36f0db-9028-4761-91a8-afb7eb30f2b9",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"question": [
|
|
{
|
|
"title": "이 호스트의 가상 머신 네트워크는 Bridge 인가 NAT 인가 Routing 인가",
|
|
"kind": "question",
|
|
"slug": "vm-network-mode-bridge-nat-or-routed",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-1",
|
|
"final/document.md#96-linux-bridge의-역할",
|
|
"final/document.md#97-routing의-역할",
|
|
"final/document.md#98-nat의-역할",
|
|
"final/document.md#114-linux-bridge가-항상-host-tcp-ip-stack을-거치는-것은-아니다",
|
|
"final/document.md#94-전체-네트워크-계층"
|
|
],
|
|
"known": "§96 은 Linux Bridge 를 Host Kernel 안의 L2 software switch 로, Destination MAC 을 보고 port 를 고르며 MAC learning 을 한다고 적었다. §97 은 Routing 을 L3·IP 기반으로 서로 다른 IP network 를 잇는 것으로, §98 은 NAT 을 packet 의 IP/Port 를 바꾸는 것으로 놓고 VM 이 private subnet 을 쓰면 Host 가 NAT gateway 처럼 동작할 수 있다는 예(192.168.122.10 → 203.0.113.10)를 들었다. 그 셋을 두고 §98 은 VM network 를 분석할 때 Bridge 기반인가 · Routing 기반인가 · NAT 기반인가를 먼저 구분하라고 적었다. §114 는 Bridge 가 단순 L2 forwarding 을 하면 frame 이 Host 의 L3 stack 을 반드시 거치는 것은 아니고 Routing · NAT · Host-local termination · Firewall 이 걸릴 때 L3/Netfilter 경로가 개입한다고 밝혔다. §94 는 이 문서가 기준으로 삼은 구조가 virtio-net + vhost-net + TAP + Linux Bridge 이고 실제 환경은 Bridge · NAT · Routed Network · macvtap · SR-IOV · VFIO passthrough · Open vSwitch · Kubernetes CNI 에 따라 달라질 수 있다고 적었다. 이 Host 의 network 구성이 셋 중 무엇인지는 SSOT 어디에도 적혀 있지 않다.",
|
|
"unknown": "이 Host 의 VM network 가 Bridge 기반인지 NAT 기반인지 Routing 기반인지, libvirt virtual network 로 정의되어 있는지 Host 의 bridge 에 직접 붙어 있는지, 그리고 그 구성에서 VM 을 떠난 frame 이 Host 의 L3/Netfilter 경로를 지나는지 지나지 않는지.",
|
|
"next-verification": "§122 OQ-1 이 적은 다섯을 그대로 돌린다 — `virsh net-list --all` 로 정의된 virtual network 를 열거하고, 나온 이름마다 `virsh net-dumpxml <network>` 로 forward mode 와 bridge 이름을 읽고, `ip link` 로 interface 목록을, `bridge link` 로 어떤 interface 가 어느 bridge 에 enslave 되어 있는지를, `ip route` 로 routing table 을 적는다. 출력은 그대로 증거로 남긴다.",
|
|
"decision-criterion": "세 구성 중 무엇인지가 출력으로 확정되면 닫는다. Bridge 로 나오면 §96 과 §114 의 L2 forwarding 서술이 이 Host 에 적용된다고 적고, NAT 으로 나오면 §98 의 주소 변환이 경로에 들어간다고 적고, Routing 이면 §97 의 L3 결정이 들어간다고 적는다. 어느 쪽이든 그 결과가 question:actual-packet-path-nginx-to-keycloak 의 capture 지점을 정하고, §94 가 기준으로 삼은 구조와 다르면 이 부의 서술 가운데 어느 절이 이 Host 에 적용되지 않는지를 함께 적는다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:bisect-the-packet-path-with-capture-points",
|
|
"question:tap-interface-to-vm-mapping",
|
|
"question:actual-packet-path-nginx-to-keycloak"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-vm-network-mode-bridge-nat-or-routed.md",
|
|
"status": "초안",
|
|
"studioId": "38716d7f-1aa1-48d8-ab4c-3fc505332128",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "VM1 과 VM2 의 TAP/vnet interface 는 무엇이고 어디에 붙어 있는가",
|
|
"kind": "question",
|
|
"slug": "tap-interface-to-vm-mapping",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-2",
|
|
"final/document.md#99-tap의-역할",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-1",
|
|
"final/document.md#118-실제-linux에서-확인할-명령어"
|
|
],
|
|
"known": "§99 는 TAP 이 물리 장치가 아니라 Host Linux Kernel 이 제공하는 가상 Ethernet interface(tap0 · vnet0 같은 이름)이고 VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점이라고 적었다. 수신은 Linux Bridge → TAP → VM, 송신은 VM → TAP → Linux Bridge 다. 확인 명령으로 `ip link` · `ip tuntap show` · `bridge link` · `virsh domiflist <domain>` 을 들었고 §118 이 같은 명령을 계층별 목록으로 다시 적었다. §117.1 은 TAP/Bridge 연결 오류의 증상으로 VM 외부 통신 불가 · Host ↔ VM 통신 불가 · 특정 VM 만 통신 불가 셋을 들었다. 두 VM 의 interface 이름도 어느 bridge 에 붙어 있는지도 SSOT 에는 없다.",
|
|
"unknown": "VM1 과 VM2 의 Host 쪽 interface 이름이 각각 무엇인지, 각 interface 의 MAC 과 model 이 무엇인지, 그리고 그 둘이 같은 bridge 에 붙어 있는지 서로 다른 곳에 붙어 있는지.",
|
|
"next-verification": "`virsh domiflist vm1` 과 `virsh domiflist vm2` 로 각 VM 의 interface · type · source · model · MAC 을 적고, `ip link` 로 Host 에 실재하는 이름과 대조하고, `bridge link` 로 어느 bridge 의 port 인지를 적는다 (§122 OQ-2). 두 VM 의 결과를 한 표로 남긴다.",
|
|
"decision-criterion": "VM 마다 interface 이름 · MAC · 붙어 있는 bridge 를 한 표로 적으면 닫는다. 이 표는 reference:bisect-the-packet-path-with-capture-points 가 요구하는 capture 지점의 이름을 대는 것이라, 표가 없으면 question:actual-packet-path-nginx-to-keycloak 의 tcpdump 를 어느 interface 에 걸어야 하는지 정할 수 없다. 두 VM 이 서로 다른 bridge 에 붙어 있으면 §117.1 의 「특정 VM 만 통신 불가」를 진단할 때 그 사실을 먼저 본다고 적는다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:bisect-the-packet-path-with-capture-points",
|
|
"question:vm-network-mode-bridge-nat-or-routed",
|
|
"question:actual-packet-path-nginx-to-keycloak"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-tap-interface-to-vm-mapping.md",
|
|
"status": "초안",
|
|
"studioId": "397c4789-0272-449b-86d6-2c4a3a122401",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 호스트에서 vhost-net 이 실제로 packet datapath 를 맡고 있는가",
|
|
"kind": "question",
|
|
"slug": "is-vhost-net-actually-in-use",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-3",
|
|
"final/document.md#103-qemu-virtio-device-model의-역할",
|
|
"final/document.md#104-왜-tap-→-vhost-net-→-qemu-→-virtqueue-라고-일반화하면-안-되는가",
|
|
"final/document.md#106-qemu가-userspace인데-packet이-qemu를-안-거칠-수-있는-이유",
|
|
"final/document.md#107-vhost-net-최적화",
|
|
"final/document.md#108-vhost-net은-qemu를-제거하지-않는다",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-4"
|
|
],
|
|
"known": "§103 은 QEMU 의 virtio Device Model 이 Host Userspace 의 QEMU process 안에 있고, 장치 생성/설정/관리와 실제 packet datapath 처리라는 두 역할을 나눠 봐야 한다고 적었다. datapath 는 QEMU backend 를 직접 쓰면 TAP → QEMU virtio backend → virtqueue → Guest 이고, vhost-net 을 쓰면 TAP → vhost-net → virtqueue → Guest 다. §104 는 그래서 `TAP → vhost-net → QEMU → virtqueue` 를 일반적인 경로로 그리면 안 된다고 못박았고, §106 은 장치의 생성/관리 주체와 runtime datapath 처리 주체가 다르다는 것을 CPU 가상화(QEMU 가 vCPU 를 만들어도 Guest instruction 은 KVM/VMX 가 실행한다)에 빗대 설명했다. §108 은 vhost-net 을 써도 QEMU 가 lifecycle · device 생성 · feature negotiation · queue configuration · backend 연결 · device reset 을 계속 맡는다고 적었다. §117.4 는 높은 packet rate 에서 QEMU userspace 가 datapath 를 직접 처리하면 CPU overhead 가 커질 수 있다고 밝혔다. 이 Host 가 둘 중 어느 backend 를 쓰는지는 SSOT 에 없다.",
|
|
"unknown": "이 Host 에서 vhost 커널 모듈이 올라와 있는지, 두 VM 의 domain XML 과 QEMU arguments 가 vhost backend 를 쓰도록 되어 있는지, 그래서 지금 흐르는 packet 의 datapath 가 §103 이 그린 둘 가운데 어느 쪽인지.",
|
|
"next-verification": "`lsmod | grep vhost` 로 모듈 적재를 보고(§122 OQ-3 · §118), 그것만으로는 그 VM 이 쓴다는 뜻이 아니므로 `virsh dumpxml vm1` · `virsh dumpxml vm2` 의 interface 절에서 driver name 을 읽고 QEMU 실행 인자를 함께 확인한다. Host 에 vhost 커널 스레드가 떠 있는지도 process 목록에서 확인해 VM 별로 짝지어 적는다.",
|
|
"decision-criterion": "두 VM 각각에 대해 backend 가 vhost-net 인지 QEMU userspace 인지가 설정과 실행 상태로 확정되면 닫는다. vhost-net 이면 §125 의 「Data Path - vhost-net 사용」 그림이 이 Host 의 경로라고 적고, QEMU backend 면 「Data Path - QEMU backend 사용」 쪽이라고 적는다. 어느 쪽이든 그 결과가 question:qemu-backend-vs-vhost-net-on-this-host 의 비교 대상 하나를 고정하고, 후보 SSOT-116-test-environment-packet-path 의 NEEDS_EVIDENCE 를 푸는 세 확인 가운데 하나가 된다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"question:qemu-backend-vs-vhost-net-on-this-host",
|
|
"question:network-virtualization-cpu-cost-under-load",
|
|
"question:actual-packet-path-nginx-to-keycloak"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-is-vhost-net-actually-in-use.md",
|
|
"status": "초안",
|
|
"studioId": "484fd832-c7d3-413e-897a-97892e4e10ac",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "QEMU backend 와 vhost-net 의 차이가 이 호스트에서 실제로 보이는가",
|
|
"kind": "question",
|
|
"slug": "qemu-backend-vs-vhost-net-on-this-host",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-4",
|
|
"final/document.md#107-vhost-net-최적화",
|
|
"final/document.md#110-data-copy-최적화",
|
|
"final/document.md#111-interrupt-notification-최적화",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-4"
|
|
],
|
|
"known": "§107 은 QEMU userspace 가 packet 마다 I/O 를 처리하면 Host Kernel ↔ QEMU Userspace 전환이 쌓이고 packet rate 가 높아질수록 userspace/kernel transition · scheduling · copy · notification 비용이 커질 수 있다고 적었다. 최적화 방향은 packet 마다 QEMU userspace 가 개입하던 것을 kernel backend 로 옮겨 context switch 와 userspace overhead 를 줄이는 것이다. §110 은 그 구조가 buffer descriptor 로 불필요한 copy 를 줄이도록 설계되어 있지만 항상 zero-copy 라고 일반화하면 안 되고 실제 copy 여부가 kernel version · QEMU version · vhost configuration · offload · NIC capability · packet path · GSO/GRO/TSO 에 따라 달라질 수 있다고 밝혔다. §122 OQ-4 는 비교할 축으로 Latency · Throughput · QEMU CPU · Host CPU · Context Switch · Packet rate 여섯을 적었다. 이 Host 에서 두 backend 를 재 본 값은 없다.",
|
|
"unknown": "같은 workload 를 두 backend 로 돌렸을 때 여섯 축이 실제로 얼마나 달라지는지, 그리고 그 차이가 이 실험의 결과를 다르게 읽어야 할 만큼인지 아니면 측정 흔들림 안인지.",
|
|
"next-verification": "question:is-vhost-net-actually-in-use 로 현재 backend 를 먼저 확정한 뒤, 같은 VM 을 다른 backend 로 바꿔 구성하고 동일한 workload 를 양쪽에 건다. 두 구성 각각에서 §122 OQ-4 의 여섯 축을 같은 시각에 기록한다 — Latency 와 Throughput 과 packet rate 는 부하 도구가 재는 값을, QEMU CPU 와 Host CPU 와 context switch 는 Host 에서 process/스레드 단위로 잰다. 부하를 걸기 전 같은 여섯을 한 번 찍어 기준값으로 둔다.",
|
|
"decision-criterion": "두 구성의 여섯 축을 한 표로 나란히 적으면 닫는다. 차이가 기준값 흔들림 안이면 이 Host 의 packet rate 에서는 backend 선택이 결과를 바꾸지 않는다고 적고 닫는다. 차이가 나면 그 표가 Case 가 되고, 어느 backend 로 실험을 고정할지는 그 Case 뒤에 Decision 으로 넘긴다. 어느 쪽이든 §110 이 말한 조건들(kernel/QEMU version · offload · NIC capability)을 함께 적지 않으면 다른 환경에 재사용할 수 없다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"question:is-vhost-net-actually-in-use",
|
|
"question:network-virtualization-cpu-cost-under-load",
|
|
"reference:verify-the-network-path-before-blaming-the-application"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-qemu-backend-vs-vhost-net-on-this-host.md",
|
|
"status": "초안",
|
|
"studioId": "bded6560-dc8d-473d-966c-5b037bb84c4c",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 가상 머신들의 virtio-net 에 multi-queue 가 켜져 있는가",
|
|
"kind": "question",
|
|
"slug": "virtio-net-multi-queue-enabled",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-5",
|
|
"final/document.md#112-multi-queue-최적화",
|
|
"final/document.md#100-virtqueue의-역할",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-5"
|
|
],
|
|
"known": "§112 는 queue 하나만 쓰면 특정 vCPU 나 처리 경로에 부하가 몰릴 수 있고 virtio-net 은 multi-queue 를 쓸 수 있다고 적었다. RX Queue 0~3 을 vCPU 0~3 에 대응시킨 예를 들었고 목적을 packet processing 병렬화 · single queue bottleneck 완화 · multi-core 활용으로 놓았으며, 효과가 workload · CPU affinity · IRQ placement · queue configuration 에 따라 달라진다고 밝혔다. §100 은 virtqueue 가 Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 shared queue 이고 네트워크에서는 보통 TX/RX 를 쓴다고 적었다. §117.5 는 single queue bottleneck 의 확인 대상으로 virtio multi-queue · IRQ distribution · per-vCPU CPU usage · RSS/RPS/XPS 를 들었다. 이 VM 들의 queue 수는 SSOT 에 없다.",
|
|
"unknown": "두 VM 의 virtio-net 에 설정된 queue 수가 몇인지, Guest 가 실제로 몇 개를 쓰고 있는지, 그리고 그 queue 들의 IRQ 가 vCPU 에 흩어져 있는지 한 vCPU 에 몰려 있는지.",
|
|
"next-verification": "§122 OQ-5 가 적은 넷을 확인한다 — QEMU/libvirt 의 NIC configuration(`virsh dumpxml` 의 interface 절에 적힌 queue 수), Guest 에서 `ethtool` 로 본 channel 수, 실제 queue count, 그리고 Guest 의 IRQ 분포. 두 VM 을 같은 방식으로 적고 vCPU 수와 나란히 남긴다.",
|
|
"decision-criterion": "VM 마다 설정된 queue 수 · Guest 가 쓰는 queue 수 · IRQ 분포를 한 표로 적으면 닫는다. queue 가 하나로 나오면 §117.5 의 single queue bottleneck 이 이 환경에서 구조적으로 가능하다고 적고, 그것이 실제로 병목인지는 부하를 건 뒤 question:network-virtualization-cpu-cost-under-load 의 per-vCPU 사용량이 답한다. 여럿으로 나오고 IRQ 도 흩어져 있으면 이 축은 현재 실험에서 우선순위를 낮추고 닫는다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"question:network-virtualization-cpu-cost-under-load",
|
|
"question:is-vhost-net-actually-in-use"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-virtio-net-multi-queue-enabled.md",
|
|
"status": "초안",
|
|
"studioId": "1a996f8d-b04e-49d2-88ef-4877e21f7c0e",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Host Nginx 에서 Keycloak 까지 packet 은 실제로 어디를 지나는가",
|
|
"kind": "question",
|
|
"slug": "actual-packet-path-nginx-to-keycloak",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-6",
|
|
"final/document.md#116-현재-keycloak-k3s-테스트-환경과-연결",
|
|
"final/document.md#119-실제-packet-path-추적",
|
|
"final/document.md#94-전체-네트워크-계층",
|
|
"final/document.md#125-최종-기준-구조"
|
|
],
|
|
"known": "§116 은 이 테스트 환경의 경로를 Client → Host Physical NIC → Host Nginx → Host Network → VM1/VM2 → K3s → Keycloak 으로 놓고, VM network 까지 펼치면 Physical NIC → Host Network Stack/Bridge/Route/NAT → TAP(vm1)/TAP(vm2) → vhost-net → virtqueue → virtio-net → Guest Network Stack → K3s networking → Keycloak 이 된다고 적었다. §94 와 §125 가 같은 경로를 수신·송신 양방향으로 그렸다. §119 는 그 경로를 확인하는 방법으로 Host 에서 physical NIC · bridge · tap/vnet 에, Guest 에서 guest interface 에 각각 `tcpdump -ni` 를 걸고 어디까지 보이는지로 의심 구간을 좁히라고 적었다. §116 이 그린 펼친 경로는 이 Host 에서 확인된 것이 아니라 기준 구조를 이 환경에 얹은 그림이다.",
|
|
"unknown": "Host Nginx 를 지난 packet 이 실제로 어느 bridge 와 어느 TAP 을 거쳐 어느 VM 의 interface 로 들어가는지, 그리고 그 경로가 §116 이 그린 그림과 같은지 다른지. K3s 안에서 Keycloak Pod 까지 가는 구간은 §116 이 별도 계층으로 미뤄 둔 부분이라 이 물음이 닫는 범위 밖이다.",
|
|
"next-verification": "question:vm-network-mode-bridge-nat-or-routed 와 question:tap-interface-to-vm-mapping 으로 capture 지점의 이름을 먼저 확정한다. 그다음 Host 에서 `sudo tcpdump -ni <physical-nic>` · `sudo tcpdump -ni <bridge>` · `sudo tcpdump -ni <tap-or-vnet>` 을, Guest 에서 `sudo tcpdump -ni <guest-interface>` 를 동시에 걸고 Host Nginx 를 통해 Keycloak 요청을 한 번 보낸다 (§122 OQ-6 · §119). 네 지점의 O/X 를 그대로 적는다. offload 가 켜져 있으면 §113 대로 packet size 와 checksum 이 wire 와 다르게 보일 수 있으므로 그 상태를 함께 적는다.",
|
|
"decision-criterion": "네 지점의 capture 결과로 실제 경로를 한 줄로 적으면 닫는다. §116 이 그린 그림과 같으면 그 그림을 이 Host 에서 확인된 경로로 승격하고 후보 SSOT-116-test-environment-packet-path 를 다시 판정한다. 다르면 어느 hop 이 다른지를 적고 §119 의 표대로 그 구간을 의심 구간으로 넘긴다. 중간 지점에서 끊기면 그것은 이 물음의 답이 아니라 장애이므로 reference:bisect-the-packet-path-with-capture-points 로 넘긴다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:bisect-the-packet-path-with-capture-points",
|
|
"question:vm-network-mode-bridge-nat-or-routed",
|
|
"question:tap-interface-to-vm-mapping",
|
|
"reference:verify-the-network-path-before-blaming-the-application"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-actual-packet-path-nginx-to-keycloak.md",
|
|
"status": "초안",
|
|
"studioId": "600a2621-f6d8-42df-9629-7db65011545d",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "부하 중 network 가상화가 지연을 바꿀 만큼 호스트 CPU 를 쓰는가",
|
|
"kind": "question",
|
|
"slug": "network-virtualization-cpu-cost-under-load",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#122-open-question-oq-7",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-7",
|
|
"final/document.md#107-vhost-net-최적화",
|
|
"final/document.md#111-interrupt-notification-최적화",
|
|
"final/document.md#120-keycloak-refresh-token-실험과의-관계"
|
|
],
|
|
"known": "§117.7 은 vhost-net · QEMU thread · softirq 도 Host CPU 를 쓰므로 network 문제처럼 보여도 CPU scheduling 문제일 수 있다고 적었다. §107 은 packet rate 가 높아질수록 userspace/kernel transition · scheduling · copy · notification 비용이 커질 수 있다고, §111 은 packet 마다 과도한 interrupt/notification 이 나면 overhead 가 커져 batching 과 interrupt moderation 이 중요하다고 밝혔다. §120 은 Node1 요청만 지연 · VM2 packet loss · Host bridge misconfiguration · NAT/conntrack issue · Host CPU contention 으로 인한 vhost 처리 지연을 Refresh Token 경쟁이나 DB lock 으로 오해하지 않도록 network path 를 따로 검증하라고 적었다. §122 OQ-7 은 관찰 대상으로 QEMU CPU · vhost thread · softirq · Host CPU · Guest CPU · network latency 여섯을 적었다. 이 여섯 가운데 vhost thread 와 softirq 는 제1부·제2부 어디에도 나오지 않아 CPU 가상화 쪽 물음이 재는 지표와 겹치지 않는다.",
|
|
"unknown": "Keycloak load test 구간에서 vhost 커널 스레드와 softirq 가 Host CPU 를 얼마나 쓰는지, 그 사용량이 QEMU vCPU thread 사용량과 어떻게 나뉘는지, 그리고 그것이 network latency 와 같은 시간축에서 함께 움직이는지.",
|
|
"next-verification": "Keycloak load test 를 돌리면서 §122 OQ-7 의 여섯을 같은 시각에 기록한다 — Host 에서 QEMU process 와 vhost 커널 스레드의 CPU 사용량을 스레드 단위로, softirq 시간을, Host 전체 CPU 를 적고, 각 Guest 에서 Guest CPU 를, 부하 도구에서 network latency 를 적는다. 부하를 걸기 전 같은 여섯을 한 번 찍어 기준값으로 둔다. Guest 의 steal time 과 QEMU vCPU thread 쪽은 question:virtualization-layer-saturation-during-refresh 가 이미 재므로 같은 실험 구간에서 두 기록을 함께 남긴다.",
|
|
"decision-criterion": "부하 구간의 vhost thread 와 softirq 사용량이 기준값과 다르지 않고 network latency 도 움직이지 않으면, 이 부하 수준에서는 network 가상화가 Host CPU 를 지연에 영향을 줄 만큼 쓰지 않는다고 적고 닫는다. 셋 중 하나라도 움직이면 그 표가 Case 가 되고, vhost thread 를 어느 CPU 에 둘지나 multi-queue 를 켤지는 그 Case 뒤에 Decision 으로 넘긴다. 어느 쪽이든 이 결과가 없으면 §120 이 경고한 오귀속(network 지연을 Refresh Token 경쟁으로 읽는 것)을 배제했다고 말할 수 없다.",
|
|
"relations": [
|
|
"concept:guest-packet-path-to-physical-nic",
|
|
"reference:verify-the-network-path-before-blaming-the-application",
|
|
"question:qemu-backend-vs-vhost-net-on-this-host",
|
|
"question:virtio-net-multi-queue-enabled",
|
|
"question:virtualization-layer-saturation-during-refresh"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "network-virtualization/question/question-network-virtualization-cpu-cost-under-load.md",
|
|
"status": "초안",
|
|
"studioId": "79ac61d6-cbe6-483b-9961-02ca8c02b5c2",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"decision": []
|
|
}
|
|
},
|
|
"storage-virtualization": {
|
|
"topic": "storage-virtualization",
|
|
"title": "스토리지 가상화 — Guest 의 write() 와 fsync() 가 Host 물리 NVMe 까지 가는 길",
|
|
"readerQuestion": "Guest 애플리케이션의 write() 와 fsync() 는 어느 계층을 거쳐 Host 의 물리 NVMe 까지 가고, 느리거나 데이터가 남지 않았을 때 그것이 storage 가상화의 어느 자리 문제인지 무엇을 보고 가르는가?",
|
|
"kinds": {
|
|
"case": [],
|
|
"concept": [
|
|
{
|
|
"title": "Guest 의 write() 가 virtqueue 에 실리기까지 — VFS · Filesystem · Page Cache · Block Layer · virtio-blk",
|
|
"kind": "concept",
|
|
"slug": "guest-block-io-path-to-virtqueue",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#128-전체-구조",
|
|
"final/document.md#129-guest-application-read-write-에서-시작",
|
|
"final/document.md#130-vfs-공통-파일-인터페이스-계층",
|
|
"final/document.md#131-filesystem-ext4-xfs-파일-세계를-block-공간에-배치",
|
|
"final/document.md#132-inode",
|
|
"final/document.md#133-page-cache-write-가-바로-ssd-write는-아니다",
|
|
"final/document.md#134-guest-block-i-o-layer",
|
|
"final/document.md#135-dev-vda-guest가-보는-가상-block-device",
|
|
"final/document.md#136-dev-vda-와-filesystem-관계",
|
|
"final/document.md#137-virtio-blk-guest의-가상-block-device-driver",
|
|
"final/document.md#138-virtio-blk와-virtqueue",
|
|
"final/document.md#139-virtqueue의-실제-의미",
|
|
"final/document.md#166-storage-i-o-completion",
|
|
"final/document.md#127-문서-목적",
|
|
"final/document.md#172-storage-virtualization-canonical-flow",
|
|
"final/document.md#173-network-virtualization과-비교",
|
|
"final/document.md#177-최종-요약"
|
|
],
|
|
"basis-version": "QEMU/KVM 의 virtio-blk frontend + virtqueue 구성. Guest 는 ext4 나 XFS 를 쓰고 buffered I/O 로 `write()` 하는 경우를 기준으로 삼는다 — §130 이 ext4 와 XFS 를 같은 자리에 놓았고 §133 이 「일반적인 buffered I/O」를 전제로 Page Cache 를 설명했다. SSOT 가 커널·QEMU·libvirt 버전을 한 번도 적지 않아 특정 버전에 고정하지 않는다. 이 글이 멈추는 경계도 SSOT 가 그었다 — §127 이 qcow2 내부 L1/L2 table · blk-mq tag allocator · NVMe submission/completion queue 를 별도 문서로 미뤘고, §134 도 `bio` · request · queue · `blk-mq` 가 실제로 존재한다고만 적고 내부로 들어가지 않는다.",
|
|
"classification": "제4부에서 경로가 시작하는 구간이다. §129 부터 §139 까지가 한 줄기로 이어진다 — 애플리케이션은 `write(fd, buffer, size);` 를 부르고, VFS 가 그 fd 를 어느 filesystem 구현으로 보낼지 정하고, ext4/XFS 가 파일 세계를 block 공간에 배치하고, Page Cache 가 dirty page 로 받아 두었다가 writeback 하고, Block I/O Layer 가 그것을 READ/WRITE/FLUSH/DISCARD 요청으로 바꾸고, `/dev/vda` 를 통해 virtio-blk driver 가 Virtio block request 로 구성해 virtqueue 에 게시한다. 중간을 잘라 내면 인과가 끊긴다 — Page Cache 만 떼면 `write()` 성공이 왜 SSD 영속화가 아닌지 말할 수 없고, virtqueue 만 떼면 무엇과 무엇 사이의 queue 인지 말할 수 없다. §128 과 §172 와 §177 이 그린 canonical flow 의 Guest 절반이 이 글이고, 나머지 셋(backend 형태 · 완료의 뜻 · Host block stack)은 그 그림의 어느 구간을 맡는지로 갈린다. §166 이 completion 도 같은 virtqueue 로 돌아온다고 적어 이 글의 마지막 절이 된다.",
|
|
"missing-verification": "이 테스트 Host 에서 잰 값이 하나도 없다. §175 의 OQ-1 이 이 Host 의 `/dev/vda` 가 무엇에 붙어 있는지를 아직 확인하지 않았다고 적어 두었고, Guest 의 filesystem 이 ext4 인지 XFS 인지도 SSOT 어디에도 없다. 이 글은 「이 구조에서는 이렇게 동작한다」까지만 말하고 「이 서버가 그 구조다」라고는 말하지 않는다. 실제 요청 수나 latency 를 재려면 question:guest-fsync-latency-vs-host-storage-latency 가 먼저 돌아야 한다.",
|
|
"relations": [
|
|
"concept:qemu-block-backend-forms",
|
|
"concept:write-completion-is-not-durability",
|
|
"concept:host-block-stack-under-the-vm",
|
|
"reference:confirm-the-disk-backend-on-the-host",
|
|
"question:vm-disk-backend-mapping",
|
|
"question:guest-fsync-latency-vs-host-storage-latency",
|
|
"concept:guest-packet-path-to-physical-nic"
|
|
],
|
|
"ssot-assets": [
|
|
"guest-block-io-to-virtqueue"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/concept/concept-guest-block-io-path-to-virtqueue.md",
|
|
"status": "초안",
|
|
"studioId": "3b05c1f0-13e9-414a-97a6-2078fb4bab26",
|
|
"assets": [
|
|
"guest-block-io-to-virtqueue"
|
|
],
|
|
"assetFiles": [
|
|
"guest-block-io-to-virtqueue"
|
|
],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "/dev/vda 뒤에 있는 것 — qcow2 · RAW · Host block device",
|
|
"kind": "concept",
|
|
"slug": "qemu-block-backend-forms",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#140-vm-boundary를-넘으면-qemu가-등장",
|
|
"final/document.md#141-qemu가-물리-ssd를-직접-제어하는-것은-아니다",
|
|
"final/document.md#142-qcow2-host에서는-파일-guest에서는-디스크",
|
|
"final/document.md#143-qcow2-virtual-size와-실제-host-사용량",
|
|
"final/document.md#144-raw-image",
|
|
"final/document.md#145-host-block-device를-직접-backend로-사용-가능",
|
|
"final/document.md#146-실제-연결-확인",
|
|
"final/document.md#128-전체-구조",
|
|
"final/document.md#172-storage-virtualization-canonical-flow",
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"basis-version": "QEMU block backend 세 형태 — qcow2 파일 · RAW 파일 · Host block device — 를 libvirt 로 정의한 VM 기준. §142 는 `/var/lib/libvirt/images/keycloak-node1.qcow2` 를, §145 는 `/dev/nvme0n1p3` 를 예로 들었다. SSOT 가 QEMU·libvirt 버전을 적지 않아 특정 버전에 고정하지 않고, §127 이 qcow2 내부 L1/L2 table 을 범위 밖으로 두었으므로 이 글은 backend 형태의 구분과 그 구분이 무엇을 바꾸는지까지만 설명한다.",
|
|
"classification": "§128 이 핵심 문장으로 뽑은 것이 이 글의 물음이다 — Guest 는 `/dev/vda` 를 실제 block device 처럼 보지만 Host 에서는 그 disk 가 qcow2 파일일 수도, RAW 파일일 수도, 실제 block device 일 수도 있다. 세 갈래가 각각 무엇을 바꾸는지가 SSOT 에 따로 적혀 있다 — qcow2 는 Copy-on-Write · sparse allocation · snapshot 에 유리하지만 metadata/mapping 처리가 있고(§144), virtual size 와 Host 실제 할당량이 갈리며(§143), 파일 backend 이면 Guest filesystem 아래에 Host filesystem/storage stack 이 한 번 더 놓인다(§141). C1 과 갈라 두는 이유는 이 구간에서만 경로가 셋으로 분기하기 때문이다 — 경로를 그리는 글에 이 분기를 넣으면 세 갈래 각각의 결과가 한 글의 각주가 된다. §144 가 「RAW = 무조건 빠름 / qcow2 = 무조건 느림」으로 일반화하지 말라고 못박은 것이 이 글이 닫는 자리다.",
|
|
"missing-verification": "이 Host 의 backend 가 셋 중 무엇인지 SSOT 에 없다. §175 의 OQ-1 · OQ-2 · OQ-3 · OQ-5 넷이 그 확인을 아직 돌리지 않은 상태로 적혀 있고, §143 이 든 100 GB/3GB 나 1GB→10GB→40GB 는 예시 값이지 이 장비에서 잰 값이 아니다. 성능 비교도 이 저장소에 없다 — §144 가 cache mode · storage backend · workload pattern · queue depth · snapshot chain · underlying filesystem · physical device 에 따라 달라진다고만 적었다.",
|
|
"relations": [
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"concept:write-completion-is-not-durability",
|
|
"concept:host-block-stack-under-the-vm",
|
|
"reference:confirm-the-disk-backend-on-the-host",
|
|
"question:vm-disk-backend-mapping",
|
|
"question:disk-image-format-and-actual-host-usage",
|
|
"question:host-block-device-under-the-disk-image"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/concept/concept-qemu-block-backend-forms.md",
|
|
"status": "초안",
|
|
"studioId": "892b6087-8961-486c-b4d9-d3dd46bc2605",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "완료라는 말의 네 가지 뜻 — write · writeback · flush · 전원 장애 생존",
|
|
"kind": "concept",
|
|
"slug": "write-completion-is-not-durability",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#147-vm에서는-page-cache가-두-번-나타날-수-있다",
|
|
"final/document.md#148-write-완료와-영속화는-다르다",
|
|
"final/document.md#149-direct-i-o",
|
|
"final/document.md#150-fsync-가-필요한-이유",
|
|
"final/document.md#151-flush",
|
|
"final/document.md#152-가장-위험한-상황-거짓-완료",
|
|
"final/document.md#153-qemu-cache-mode",
|
|
"final/document.md#154-cache=none",
|
|
"final/document.md#155-cache=writeback",
|
|
"final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유",
|
|
"final/document.md#157-device-side-cache",
|
|
"final/document.md#170-postgresql-예시-wal과-durability",
|
|
"final/document.md#133-page-cache-write-가-바로-ssd-write는-아니다",
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"basis-version": "Linux `O_DIRECT` 와 QEMU/libvirt disk 의 `cache=none` · `cache=writeback` 두 설정 기준. §153 이 「대표적으로 볼 수 있는 설정」으로 이 둘만 들었으므로 다른 cache mode 값은 이 글의 범위가 아니고, SSOT 가 QEMU 버전을 적지 않아 버전별 차이도 다루지 않는다. §151 이 실제 ordering/durability semantics 는 더 복잡하다고 스스로 밝힌 만큼 이 글은 WRITE 와 FLUSH 의 구분까지만 말한다.",
|
|
"classification": "§148 이 네 단계를 한 줄로 세웠다 — `write()` 완료 ≠ writeback 완료 ≠ fsync/flush 완료 ≠ 전원 장애에도 안전한 durability. 그 네 자리마다 VM 에서만 생기는 사정이 붙는다. Page Cache 가 Guest 와 Host 양쪽에 두 번 나타날 수 있고(§147), Direct I/O 는 Page Cache 우회이지 자동 durability 보장이 아니며(§149), `cache=none` 은 이중 caching 을 줄이지만 즉시 durable media 반영을 뜻하지 않고(§154), `cache=writeback` 이 Guest 의 `fsync()`/FLUSH 를 무시한다는 뜻도 아니다(§155). Host Page Cache 를 우회해도 device 쪽 volatile write cache 가 남는다(§157). 이 글이 닫는 것은 §152 다 — Guest 에게 `FLUSH 완료` 라고 응답했는데 실제로는 Host RAM 에만 있는 상태는 성능 문제가 아니라 durability contract 가 깨지는 correctness 문제다. C1·C2·C4 가 경로를 말한다면 이 글은 그 경로 위에서 「완료」라는 응답이 무엇을 보장하는지를 말하므로 물음이 다르다. §170 의 PostgreSQL WAL 예시가 그 보장이 깨질 때 무엇이 어긋나는지를 보여 준다.",
|
|
"missing-verification": "이 Host 의 disk cache mode 가 무엇인지 SSOT 에 없다 — §175 OQ-4 가 그 확인을 적어 두었다. 거짓 완료(§152)가 이 환경에서 실제로 일어나는지도, device 가 power-loss protection 을 갖췄는지도 재지 않았다. §157 이 device flush/FUA semantics 와 power-loss protection 여부가 「중요할 수 있다」고만 적은 자리가 그대로 남아 있다. `fsync()` latency 값은 question:guest-fsync-latency-vs-host-storage-latency 가 잰 뒤에야 이 글에 들어온다.",
|
|
"relations": [
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"concept:qemu-block-backend-forms",
|
|
"concept:host-block-stack-under-the-vm",
|
|
"reference:a-speedup-that-removed-durability-is-not-an-optimization",
|
|
"question:qemu-disk-cache-mode",
|
|
"question:guest-fsync-latency-vs-host-storage-latency"
|
|
],
|
|
"ssot-assets": [
|
|
"write-completion-boundaries"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/concept/concept-write-completion-is-not-durability.md",
|
|
"status": "초안",
|
|
"studioId": "8fafaeea-8746-4537-87a4-679a3a91aa4c",
|
|
"assets": [
|
|
"write-completion-boundaries"
|
|
],
|
|
"assetFiles": [
|
|
"write-completion-boundaries"
|
|
],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "VM 아래에 한 번 더 있는 Host block stack — blk-mq · I/O Scheduler · NVMe",
|
|
"kind": "concept",
|
|
"slug": "host-block-stack-under-the-vm",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#158-host-block-layer",
|
|
"final/document.md#159-여러-vm이-하나의-nvme를-공유하면",
|
|
"final/document.md#160-blk-mq-multi-queue-block-layer",
|
|
"final/document.md#161-i-o-scheduler",
|
|
"final/document.md#162-none",
|
|
"final/document.md#163-실제-i-o-scheduler-확인",
|
|
"final/document.md#164-nvme-driver와-physical-device",
|
|
"final/document.md#165-nvme와-ssd-구분",
|
|
"final/document.md#167-storage-contention",
|
|
"final/document.md#141-qemu가-물리-ssd를-직접-제어하는-것은-아니다",
|
|
"final/document.md#172-storage-virtualization-canonical-flow"
|
|
],
|
|
"basis-version": "현대 Linux 의 `blk-mq` 기반 block layer 와 NVMe driver 기준. scheduler 는 §161 이 든 `none` · `mq-deadline` · `bfq` 셋이고 §163 의 확인 예시 출력은 `[none] mq-deadline` 이다. SSOT 가 커널 버전을 적지 않아 고정하지 않고, §127 이 blk-mq tag allocator 와 NVMe submission/completion queue 를 별도 문서로 미뤘으므로 이 글은 queue 가 여럿이라는 구조와 dispatch 정책이 있다는 데까지만 설명한다.",
|
|
"classification": "§158 의 한 문장이 이 글이 존재하는 이유다 — Host Block Layer 는 그 I/O 가 VM 안 PostgreSQL 에서 시작했는지 Host process 에서 시작했는지를 본질적으로 구분해서 처리하는 계층이 아니고, 모두 Host block request 다. 그래서 VM 두 대와 Nginx 와 Host 기타 프로세스의 요청이 한 queue 로 들어오고(§159), `blk-mq` 가 CPU 마다 queue 를 두어 병렬로 처리하고(§160), I/O Scheduler 가 들어온 순서 그대로 dispatch 하지 않을 수 있다(§161). 그 결과가 §167 의 Storage Contention 이고 SSOT 는 그것을 CPU Contention 과 다른 자원 경쟁으로 못박았다 — 하나는 Host logical CPU 실행 시간 경쟁이고 하나는 IOPS/bandwidth/queue/device 처리시간 경쟁이다. C2 가 backend 형태를 말한다면 이 글은 그 backend 아래에서 요청이 어떻게 줄을 서고 누구와 섞이는지를 말한다. §165 의 SSD 와 NVMe 구분(저장장치 종류 대 PCIe 기반 protocol/interface)이 이 계층의 이름을 정리한다.",
|
|
"missing-verification": "이 Host 의 I/O Scheduler 도, VM 들이 같은 물리 장치를 쓰는지도 SSOT 에 없다 — §175 의 OQ-5 · OQ-6 · OQ-7 이 그 확인을 적어 두었다. §159 가 그린 VM1·VM2·Nginx 동시 I/O 도 이 환경에서 실제로 겹치는지 재지 않았고, §167 의 「VM1 에서 대량 I/O 가 발생하면 VM2 의 storage latency 가 증가할 수 있다」는 구조적 가능성이지 관측이 아니다.",
|
|
"relations": [
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"concept:qemu-block-backend-forms",
|
|
"concept:write-completion-is-not-durability",
|
|
"reference:read-storage-before-blaming-cpu-for-latency",
|
|
"question:host-block-device-under-the-disk-image",
|
|
"question:host-io-scheduler",
|
|
"question:vm1-storage-load-vs-vm2-latency"
|
|
],
|
|
"ssot-assets": [
|
|
"vms-sharing-one-nvme"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/concept/concept-host-block-stack-under-the-vm.md",
|
|
"status": "초안",
|
|
"studioId": "ecaaa37d-7b33-4cbf-9bc5-4c6caad14ee5",
|
|
"assets": [
|
|
"vms-sharing-one-nvme"
|
|
],
|
|
"assetFiles": [
|
|
"vms-sharing-one-nvme"
|
|
],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"reference": [
|
|
{
|
|
"title": "지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다",
|
|
"kind": "reference",
|
|
"slug": "read-storage-before-blaming-cpu-for-latency",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#168-cpu가-정상이어도-storage-때문에-느릴-수-있다",
|
|
"final/document.md#167-storage-contention",
|
|
"final/document.md#169-storage-관측-명령어",
|
|
"final/document.md#174-핵심-claim",
|
|
"final/document.md#177-최종-요약"
|
|
],
|
|
"classification": "§168 이 규칙을 그대로 적었다 — PostgreSQL 이 storage completion 을 기다리고 있으면 CPU usage 가 높지 않을 수도 있어서 CPU 30% 인데 request latency 2초 가 가능하고, 따라서 CPU 지표만으로 latency 원인을 판단하면 안 된다. §167 이 그 앞에서 CPU Contention 과 Storage Contention 을 다른 자원 경쟁으로 갈라 두었고, §169 가 무엇을 볼지의 도구를 대고, §177 이 CPU usage 만 보지 말고 함께 볼 여덟 가지를 나열한다. §174 Claim 6 이 같은 것을 한 줄로 접었다 — Storage 성능은 Guest 내부만으로 결정되지 않는다. 원 프로젝트의 이름을 지워도 규칙이 남으므로 Case 요약이 아니고, 제2부의 reference:memory-symptom-needs-layer-separation 이 메모리 증상 안에서 다섯 갈래를 가른다면 이 규칙은 CPU 냐 storage 냐를 가르므로 답하는 물음이 다르다.",
|
|
"scope": "요청 latency 나 처리량 저하의 원인을 자원에 귀속하려는 모든 판독. 특히 CPU usage 가 낮은데 latency 가 큰 구간, DB 가 낀 경로, VM 여러 대가 한 물리 장치를 쓰는 환경에 적용한다. 같은 시간축에 남길 것은 §177 이 적은 여덟이다 — Guest I/O latency · Host I/O queue · Host storage latency · QEMU backend · cache mode · I/O Scheduler · NVMe · 다른 VM 의 Storage load. 도구는 §169 가 댄다 — Guest 에서 `lsblk` · `mount` · `df -h` · `cat /proc/mounts` · `iostat -xz 1`, Host 에서 `virsh domblklist <VM_NAME>` · `qemu-img info <disk-image>` · `lsblk` · `cat /sys/block/<device>/queue/scheduler` · `iostat -xz 1` · `iotop`.",
|
|
"exceptions": "이 규칙은 어느 자원인지를 좁힐 뿐 원인을 확정하지 않는다. storage 지표가 깨끗해도 CPU 쪽이 아니라는 뜻은 아니고, 제1부가 적은 vCPU contention 과 steal time 은 이 규칙 밖에서 따로 본다. `iostat -xz 1` 이 보여 주는 device utilization 성격의 지표는 NVMe 처럼 병렬성이 큰 장치에서 포화도로 그대로 읽히지 않는다 — §160 이 NVMe 가 높은 queue depth 와 병렬성을 지원한다고 적은 것이 그 이유다. Host 에서 잰 값은 어느 VM 의 I/O 인지 구분해 주지 않는다(§158) — VM 별로 가르려면 §169 의 `iotop` 이나 VM 쪽 관측을 같은 시각에 함께 찍어야 한다. 이 저장소에는 이 규칙으로 원인을 실제로 가른 측정이 아직 없다.",
|
|
"relations": [
|
|
"concept:host-block-stack-under-the-vm",
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"reference:confirm-the-disk-backend-on-the-host",
|
|
"question:vm1-storage-load-vs-vm2-latency",
|
|
"question:guest-fsync-latency-vs-host-storage-latency",
|
|
"reference:memory-symptom-needs-layer-separation"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/reference/reference-read-storage-before-blaming-cpu-for-latency.md",
|
|
"status": "초안",
|
|
"studioId": "b1cda8c4-d31d-4ae4-a4d9-4103a0ab3109",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "빨라진 구성이 durability contract 를 지운 것은 아닌지 먼저 가른다",
|
|
"kind": "reference",
|
|
"slug": "a-speedup-that-removed-durability-is-not-an-optimization",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#171-성능과-durability의-trade-off",
|
|
"final/document.md#152-가장-위험한-상황-거짓-완료",
|
|
"final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유",
|
|
"final/document.md#148-write-완료와-영속화는-다르다",
|
|
"final/document.md#157-device-side-cache",
|
|
"final/document.md#150-fsync-가-필요한-이유",
|
|
"final/document.md#170-postgresql-예시-wal과-durability",
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"classification": "§171 이 규칙 문장을 그대로 적었다 — `fsync()` 를 없애서 빨라졌다면 그것이 최적화가 아니라 durability contract 를 제거한 것일 수 있다. 그 판단이 왜 성능 문제가 아닌지는 §152 가 댄다. Guest 에게 `FLUSH 완료` 라고 응답했는데 실제로는 Host RAM 에만 있으면 PostgreSQL 은 durability 가 확보되었다고 판단하고, 직후 Host 전원이 나가면 RAM 의 data 가 사라진다 — 성능 문제가 아니라 correctness 문제다. §156 이 반대 방향의 오독까지 막는다. writeback 이라는 이름만 보고 위험하다고 단정하는 것이 아니라 Guest 의 flush/fsync semantics 가 전체 backend/storage stack 에서 올바르게 보존되는지를 보는 것이 정확한 표현이다. 규칙이 향하는 대상이 설정 선택과 성능 개선의 평가라 개념 본문의 각주로 두면 다음 프로젝트가 다시 찾지 못한다.",
|
|
"scope": "storage 관련 설정이나 코드를 바꿔 write/commit latency 가 개선됐을 때, 그리고 cache mode · Direct I/O · `fsync()` 호출 · filesystem mount option 을 고르기 전에 적용한다. 확인 순서는 무엇이 빨라졌는지가 아니라 어느 경계가 사라졌는지다 — §148 의 네 단계(`write()` 완료 · writeback 완료 · fsync/flush 완료 · 전원 장애에도 안전한 상태) 중 어디까지 보장되는지를 먼저 적고, §156 이 그린 chain(Guest 가 요구한 durability → Guest Filesystem → Guest Block Layer → virtio → QEMU/backend → Host Storage → Device)에서 그 의미가 끊기는 자리가 있는지를 본다. DB workload 에서는 §170 처럼 애플리케이션이 어떤 durability protocol 을 쓰는지도 함께 적는다.",
|
|
"exceptions": "durability 를 실제로 포기해도 되는 데이터가 있다 — 다시 만들 수 있는 캐시나 파생 파일이 그렇고, 그때는 빨라진 것이 정당한 선택이다. 이 규칙이 요구하는 것은 포기하지 말라는 것이 아니라 포기한 사실을 적으라는 것이다. 반대로 `cache=none` 이나 Direct I/O 를 골랐다는 사실만으로 durability 가 확보되지도 않는다 — Host Page Cache 우회는 즉시 durable media 반영이 아니고(§149 · §154), device 쪽 volatile write cache 가 그 뒤에 또 있다(§157). §151 이 실제 ordering/durability semantics 는 더 복잡하다고 밝혔으므로 이 규칙으로 특정 설정이 안전하다고 결론내지 않는다. 이 저장소에는 durability 를 실제로 재 본 실험이 없다 — 규칙은 SSOT 가 서술한 것이고 이 Host 에서 확인된 것이 아니다.",
|
|
"relations": [
|
|
"concept:write-completion-is-not-durability",
|
|
"concept:qemu-block-backend-forms",
|
|
"question:qemu-disk-cache-mode",
|
|
"question:guest-fsync-latency-vs-host-storage-latency",
|
|
"reference:read-storage-before-blaming-cpu-for-latency"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/reference/reference-a-speedup-that-removed-durability-is-not-an-optimization.md",
|
|
"status": "초안",
|
|
"studioId": "decbab8d-9c98-45c6-b5b8-e6162e407299",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Guest 안에서 본 disk 로 backend 를 단정하지 않는다",
|
|
"kind": "reference",
|
|
"slug": "confirm-the-disk-backend-on-the-host",
|
|
"readiness": "READY",
|
|
"source": [
|
|
"final/document.md#145-host-block-device를-직접-backend로-사용-가능",
|
|
"final/document.md#146-실제-연결-확인",
|
|
"final/document.md#143-qcow2-virtual-size와-실제-host-사용량",
|
|
"final/document.md#144-raw-image",
|
|
"final/document.md#135-dev-vda-guest가-보는-가상-block-device",
|
|
"final/document.md#142-qcow2-host에서는-파일-guest에서는-디스크",
|
|
"final/document.md#169-storage-관측-명령어"
|
|
],
|
|
"classification": "§145 가 규칙 문장을 그대로 적었다 — 「Guest 에 `/dev/vda` 가 있다」는 정보만으로 backend 구조를 알 수 없다. §135 도 Guest Linux 가 `/dev/vda` 를 하나의 block device 로 인식하지만 그것이 Host 의 실제 SSD 라는 뜻은 아니라고 적었고, §142 는 같은 대상을 Host 관점(파일 하나)과 Guest 관점(디스크)에서 보면 둘 다 맞다고 놓았다. §146 이 그 확정 절차를 댄다 — Guest 에서 `lsblk`, Host 에서 `virsh domblklist <VM_NAME>` 로 Target 과 Source 를 잇는다. 이 규칙이 없으면 §143 의 virtual size 와 §144 의 성능 일반화가 둘 다 잘못된 전제 위에서 읽힌다. 제3부의 reference:bisect-the-packet-path-with-capture-points 가 network 경로를 확정하는 자리에 있는 것과 같은 위치이고, OQ-1 · OQ-2 · OQ-3 · OQ-5 넷이 모두 이 규칙 위에서 돌아가므로 네 글에 되풀이하지 않고 한 편으로 두고 가리킨다.",
|
|
"scope": "VM 의 disk 성능·용량·durability 를 판단하기 전에, 그리고 Guest 안에서 잰 storage 수치를 해석하기 전에 적용한다. 확정할 것은 셋이다 — `/dev/vda` 가 붙은 Source 가 무엇인지(`virsh domblklist <VM_NAME>`), 그것이 qcow2 인지 RAW 인지 Host block device 인지(`qemu-img info <image>`), 그리고 파일이라면 어느 Host filesystem 과 어느 block device 위에 있는지(§169 의 `lsblk`). 용량을 볼 때는 `qemu-img info` 의 virtual size 와 실제 allocation 을 구분해서 본다(§143).",
|
|
"exceptions": "backend 가 Host block device 라면(§145) qcow2 쪽 확인 — virtual size 와 실제 할당량의 차이, mapping/metadata 처리 — 은 적용되지 않는다. 반대로 backend 를 확정했다고 성능이 예측되지도 않는다. §144 가 「RAW = 무조건 빠름 / qcow2 = 무조건 느림」으로 일반화하지 말라고 못박고 cache mode · storage backend · workload pattern · queue depth · snapshot chain · underlying filesystem · physical device 를 함께 들었으므로, 이 규칙은 무엇 위에서 재고 있는지를 확정할 뿐 결과를 대신 말하지 않는다. 이 저장소에는 아직 이 절차를 실제로 돌린 출력이 없다.",
|
|
"relations": [
|
|
"concept:qemu-block-backend-forms",
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"question:vm-disk-backend-mapping",
|
|
"question:disk-image-format-and-actual-host-usage",
|
|
"question:host-block-device-under-the-disk-image",
|
|
"reference:read-storage-before-blaming-cpu-for-latency"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/reference/reference-confirm-the-disk-backend-on-the-host.md",
|
|
"status": "초안",
|
|
"studioId": "274c5636-33f6-4c19-a54b-d2a96af31289",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"question": [
|
|
{
|
|
"title": "이 호스트의 /dev/vda 는 어떤 backend 에 붙어 있는가",
|
|
"kind": "question",
|
|
"slug": "vm-disk-backend-mapping",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-1",
|
|
"final/document.md#135-dev-vda-guest가-보는-가상-block-device",
|
|
"final/document.md#145-host-block-device를-직접-backend로-사용-가능",
|
|
"final/document.md#146-실제-연결-확인",
|
|
"final/document.md#140-vm-boundary를-넘으면-qemu가-등장"
|
|
],
|
|
"known": "§135 는 virtio-blk 를 쓰는 VM 에서 `/dev/vda` · `/dev/vdb` 같은 이름이 보이고 Guest Linux 가 그것을 하나의 block device 로 인식하지만 그것이 Host 의 실제 SSD 라는 뜻은 아니라고 적었다. §145 는 backend 가 반드시 파일일 필요도 없어서 `/dev/vda` 아래에 qcow2 file · RAW file · Host block device 셋이 올 수 있고, 그래서 「Guest 에 `/dev/vda` 가 있다」는 정보만으로 backend 구조를 알 수 없다고 못박았다. §140 은 VM 경계를 넘으면 QEMU 의 virtio-blk Device Model 과 Block Backend 가 그 연결을 맡는다고 적었고, §146 은 확인 방법으로 Guest 의 `lsblk` 와 Host 의 `virsh domblklist <VM_NAME>` 를 들고 Target/Source 표 예시(`vda` → `/var/lib/libvirt/images/vm1.qcow2`)를 보였다. 이 Host 의 VM 이 어떤 Source 에 붙어 있는지는 SSOT 어디에도 없다.",
|
|
"unknown": "이 Host 의 각 VM 에 어떤 disk 가 몇 개 붙어 있는지, 각 Target(`vda` 등)의 Source 가 무엇인지, 그리고 그 Source 가 파일인지 Host block device 인지.",
|
|
"next-verification": "§175 OQ-1 이 적은 둘을 그대로 돌린다 — 각 Guest 에서 `lsblk` 로 보이는 block device 와 partition 을 적고, Host 에서 `virsh domblklist <VM_NAME>` 로 Target 과 Source 를 적는다. VM 마다 한 행으로 남기고 출력은 그대로 증거로 둔다.",
|
|
"decision-criterion": "VM 마다 Target ↔ Source 대응이 출력으로 확정되면 닫는다. Source 가 파일이면 question:disk-image-format-and-actual-host-usage 와 question:host-block-device-under-the-disk-image 로 이어지고, Host block device 면 §145 의 갈래가 이 환경이라고 적고 qcow2 쪽 후속 물음 둘은 이 Host 에 적용되지 않는다고 적는다. 어느 쪽이든 그 결과가 reference:confirm-the-disk-backend-on-the-host 가 요구하는 첫 항목을 채운다.",
|
|
"relations": [
|
|
"concept:qemu-block-backend-forms",
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"reference:confirm-the-disk-backend-on-the-host",
|
|
"question:disk-image-format-and-actual-host-usage",
|
|
"question:host-block-device-under-the-disk-image"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-vm-disk-backend-mapping.md",
|
|
"status": "초안",
|
|
"studioId": "1f76d54b-bb17-4174-8128-0c2d71d4256f",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 disk image 는 qcow2 인가 RAW 인가, 그리고 Guest 가 보는 크기와 Host 가 실제로 쓰는 크기는 얼마나 다른가",
|
|
"kind": "question",
|
|
"slug": "disk-image-format-and-actual-host-usage",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-3",
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-2",
|
|
"final/document.md#143-qcow2-virtual-size와-실제-host-사용량",
|
|
"final/document.md#144-raw-image",
|
|
"final/document.md#142-qcow2-host에서는-파일-guest에서는-디스크"
|
|
],
|
|
"known": "§142 는 같은 대상이 Host 에서는 파일 하나이고 Guest 에서는 `/dev/vda` 라는 디스크이며 둘 다 맞다고 놓았다. §143 은 qcow2 가 가상 disk size 와 실제 Host 할당량이 다를 수 있다고 적고, Guest 가 보는 공간 100 GB 에 Host 실제 할당 3GB 인 그림과 Guest 가 데이터를 기록하면서 Actual 이 1GB → 10GB → 40GB 로 늘 수 있다는 예를 들었다. 확인 명령으로 `qemu-img info vm1.qcow2` 를 들고 `virtual size` 와 실제 allocation 을 구분해서 봐야 한다고 했다. §144 는 RAW 가 qcow2 보다 구조가 단순하고 qcow2 는 Copy-on-Write · sparse allocation · snapshot 등에 유리하지만 metadata/mapping 처리가 있다고 적으면서, 「RAW = 무조건 빠름 / qcow2 = 무조건 느림」으로 일반화하면 안 된다고 못박았다. §175 OQ-2 는 `qemu-img info /path/to/disk-image` 를, OQ-3 은 `qemu-img info <image>` · `du -h <image>` · `ls -lh <image>` 셋을 들고 세 명령이 보여주는 의미가 서로 다를 수 있으므로 비교하라고 했다. 이 Host 의 image 형식도 크기도 SSOT 에 없다.",
|
|
"unknown": "각 VM 의 disk image 가 qcow2 인지 RAW 인지, 그리고 `qemu-img info` 의 virtual size 와 `du -h` 가 보여주는 실제 점유량과 `ls -lh` 가 보여주는 파일 크기 셋이 이 Host 에서 얼마나 벌어져 있는지.",
|
|
"next-verification": "question:vm-disk-backend-mapping 이 확정한 Source 경로마다 `qemu-img info <image>` 로 file format 과 virtual size 와 disk size 를 적고, 같은 경로에 `du -h <image>` 와 `ls -lh <image>` 를 돌려 세 값을 한 행에 나란히 남긴다 (§175 OQ-2 · OQ-3). VM 이 여럿이면 한 표로 만든다.",
|
|
"decision-criterion": "image 마다 형식과 세 크기가 한 표로 적히면 닫는다. qcow2 이고 세 값이 벌어져 있으면 §143 이 말한 차이가 이 Host 에서 얼마인지를 확정한 것이고, 그 차이가 시간에 따라 어떻게 자라는지는 별도 측정으로 넘긴다. RAW 이면 §144 의 갈래가 이 환경이라고 적고 sparse 여부만 세 값의 차이로 판정한다. 어느 쪽이든 성능 결론은 여기서 내지 않는다 — §144 가 형식만으로 일반화하지 말라고 적었고, 성능은 question:vm1-storage-load-vs-vm2-latency 와 question:guest-fsync-latency-vs-host-storage-latency 가 잰다.",
|
|
"relations": [
|
|
"concept:qemu-block-backend-forms",
|
|
"reference:confirm-the-disk-backend-on-the-host",
|
|
"question:vm-disk-backend-mapping",
|
|
"question:host-block-device-under-the-disk-image"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-disk-image-format-and-actual-host-usage.md",
|
|
"status": "초안",
|
|
"studioId": "ae69e2e1-1a3b-4ae3-ae2a-572af07b95d7",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 VM 들의 QEMU disk cache mode 는 무엇인가",
|
|
"kind": "question",
|
|
"slug": "qemu-disk-cache-mode",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-4",
|
|
"final/document.md#153-qemu-cache-mode",
|
|
"final/document.md#154-cache=none",
|
|
"final/document.md#155-cache=writeback",
|
|
"final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유",
|
|
"final/document.md#147-vm에서는-page-cache가-두-번-나타날-수-있다"
|
|
],
|
|
"known": "§153 은 QEMU/libvirt disk 에서 대표적으로 볼 수 있는 설정으로 `cache=none` 과 `cache=writeback` 을 들고, 이름만 보고 「none = cache 자체가 없음 / writeback = 무조건 위험」으로 해석하면 부정확하며 핵심은 QEMU 가 Host Page Cache 와 write completion/flush semantics 를 어떤 방식으로 사용할 것인가라고 적었다. §154 는 `cache=none` 을 Host Page Cache 를 우회하는 방향의 I/O 구성으로 놓아 이중 caching 을 줄일 수 있지만 Host Page Cache 우회가 즉시 durable media 반영을 뜻하지는 않는다고 했다. §155 는 `cache=writeback` 이 Host Page Cache 를 사용할 수 있는 구성이고 일반 write 는 Host RAM 에서 빠르게 completion 될 수 있지만 그것이 Guest 의 `fsync()`/FLUSH 를 무시한다는 뜻은 아니라고 적었다. §147 은 Guest buffered I/O + Host file-backed disk + Host Page Cache 를 함께 쓰면 같은 데이터가 Guest RAM 과 Host RAM 양쪽에 cache 될 수 있다고 밝혔다. §175 OQ-4 는 `virsh dumpxml <VM_NAME>` 로 disk driver 설정의 cache 관련 값을 확인하라고 했다. 이 Host 의 설정 값은 SSOT 에 없다.",
|
|
"unknown": "각 VM 의 disk driver 에 cache 값이 명시되어 있는지, 명시되어 있다면 무엇인지, 명시가 없다면 그 자리에서 실제로 무엇이 적용되는지.",
|
|
"next-verification": "VM 마다 `virsh dumpxml <VM_NAME>` 을 돌려 disk 요소의 driver 설정을 그대로 적는다 (§175 OQ-4). 출력의 cache 관련 값과 함께 같은 disk 의 Source 와 형식(question:vm-disk-backend-mapping · question:disk-image-format-and-actual-host-usage 의 결과)을 한 행에 둔다.",
|
|
"decision-criterion": "VM 마다 cache 값이 출력으로 확정되면 닫는다. `cache=none` 이면 §154 의 서술이, `cache=writeback` 이면 §155 의 서술이 이 Host 에 적용된다고 적고, 어느 쪽이든 §156 이 요구한 것 — Guest 의 flush/fsync semantics 가 전체 chain 에서 보존되는가 — 은 이 값만으로 답하지 않는다고 함께 적는다. 값이 명시되어 있지 않으면 그 사실을 적고 실제 적용 값을 확인할 방법을 다음 검증으로 남긴다. 이 값을 어떻게 둘 것인지는 후보 대장의 SSOT-153-157-cache-mode-choice-not-made 가 NEEDS_DECISION 으로 들고 있다.",
|
|
"relations": [
|
|
"concept:write-completion-is-not-durability",
|
|
"reference:a-speedup-that-removed-durability-is-not-an-optimization",
|
|
"question:guest-fsync-latency-vs-host-storage-latency",
|
|
"question:vm-disk-backend-mapping"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-qemu-disk-cache-mode.md",
|
|
"status": "초안",
|
|
"studioId": "480f86ac-86fb-4290-9bf5-584763aa1363",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "disk image 는 최종적으로 어느 Host block device 위에 있는가",
|
|
"kind": "question",
|
|
"slug": "host-block-device-under-the-disk-image",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-5",
|
|
"final/document.md#158-host-block-layer",
|
|
"final/document.md#159-여러-vm이-하나의-nvme를-공유하면",
|
|
"final/document.md#141-qemu가-물리-ssd를-직접-제어하는-것은-아니다",
|
|
"final/document.md#163-실제-i-o-scheduler-확인"
|
|
],
|
|
"known": "§141 은 backend 가 qcow2 파일이면 QEMU 가 결국 Host Linux 에 파일 I/O 를 요청하고 그것이 Host Filesystem → Host Block Layer → NVMe Driver → Physical NVMe 로 내려가므로 Guest storage stack 아래에 Host storage stack 이 한 번 더 존재할 수 있다고 적었다. §158 은 그 경로를 QEMU → `vm1.qcow2` → Host ext4/XFS → Host Block Layer → `/dev/nvme0n1` 로 그리고, Host Block Layer 는 그 I/O 가 VM 에서 시작했는지 Host process 에서 시작했는지를 본질적으로 구분해서 처리하는 계층이 아니라고 밝혔다. §159 는 여러 VM 의 QEMU 와 Nginx 와 Host 기타 프로세스가 같은 Host Block Layer 를 지나 하나의 NVMe 로 간다고 그렸다. §175 OQ-5 는 `lsblk` 와 `findmnt` 로 확인하라고 했다. 이 Host 의 filesystem 배치도 물리 장치도 SSOT 에 없다.",
|
|
"unknown": "disk image 가 놓인 디렉터리가 어느 mount point 에 속하는지, 그 mount 가 어느 partition 과 어느 block device 위에 있는지, 그리고 VM 들의 image 가 같은 device 를 공유하는지 서로 다른 device 에 있는지.",
|
|
"next-verification": "question:vm-disk-backend-mapping 이 확정한 Source 경로마다 `findmnt` 로 그 경로가 속한 mount 와 source device 를 적고, `lsblk` 로 그 device 의 partition·상위 device 관계를 적는다 (§175 OQ-5). VM 이 여럿이면 image 경로 → mount → partition → device 한 행씩으로 남긴다.",
|
|
"decision-criterion": "image 마다 최종 block device 이름이 확정되면 닫는다. VM 들이 같은 device 를 공유하면 §159 가 그린 상황이 이 환경이라고 적고 question:vm1-storage-load-vs-vm2-latency 가 그것을 실제로 재는 물음이 된다. 서로 다른 device 면 그 사실을 적고 그 질문의 전제가 이 환경에 없다고 함께 적는다. 여기서 확정한 device 이름이 question:host-io-scheduler 의 `<device>` 자리를 채운다.",
|
|
"relations": [
|
|
"concept:host-block-stack-under-the-vm",
|
|
"concept:qemu-block-backend-forms",
|
|
"question:vm-disk-backend-mapping",
|
|
"question:host-io-scheduler",
|
|
"question:vm1-storage-load-vs-vm2-latency",
|
|
"reference:confirm-the-disk-backend-on-the-host"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-host-block-device-under-the-disk-image.md",
|
|
"status": "초안",
|
|
"studioId": "eead2379-94fe-463a-9e5e-06a01bf2105d",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "이 호스트의 I/O Scheduler 는 무엇인가",
|
|
"kind": "question",
|
|
"slug": "host-io-scheduler",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-6",
|
|
"final/document.md#161-i-o-scheduler",
|
|
"final/document.md#162-none",
|
|
"final/document.md#163-실제-i-o-scheduler-확인",
|
|
"final/document.md#160-blk-mq-multi-queue-block-layer"
|
|
],
|
|
"known": "§161 은 여러 I/O request 가 있다고 해서 항상 들어온 순서 그대로 device 에 전달되는 것은 아니고 I/O Scheduler 가 dispatch 정책을 갖는다고 적으며 대표적으로 볼 수 있는 것으로 `none` · `mq-deadline` · `bfq` 를 들었다. §162 는 `none` 이 복잡한 scheduling 정책을 최소화해 비교적 직접 device 쪽으로 dispatch 하는 방향이고 NVMe 처럼 device 자체가 강한 병렬성과 queueing 기능을 가진 경우 적합할 수 있지만, `none` 이 block layer 가 아무 일도 하지 않는다는 뜻은 아니라고 적었다. §160 은 `blk-mq` 가 CPU 마다 queue 를 두어 여러 CPU 가 병렬로 block I/O 를 처리하는 구조를 그렸다. §163 은 확인 명령으로 `cat /sys/block/nvme0n1/queue/scheduler` 를 들고 예시 출력 `[none] mq-deadline` 에서 대괄호 안이 현재 선택된 scheduler 라고 했으며, SATA/SCSI device 라면 `cat /sys/block/sda/queue/scheduler` 처럼 확인한다고 적었다. 이 Host 의 값은 SSOT 에 없다.",
|
|
"unknown": "이 Host 에서 VM disk image 를 담고 있는 block device 의 현재 scheduler 가 무엇이고 선택 가능한 목록이 무엇인지, 그리고 장치가 여럿이면 장치마다 값이 다른지.",
|
|
"next-verification": "question:host-block-device-under-the-disk-image 가 확정한 device 이름을 넣어 `cat /sys/block/<device>/queue/scheduler` 를 돌리고 출력을 그대로 적는다 (§175 OQ-6). 대괄호가 붙은 값이 현재 선택된 것이다. VM image 가 놓인 장치가 여럿이면 장치마다 적는다.",
|
|
"decision-criterion": "device 마다 현재 scheduler 와 선택지가 출력으로 적히면 닫는다. `none` 이면 §162 의 서술이 이 Host 에 적용된다고 적고, `mq-deadline` 이나 `bfq` 면 dispatch 정책이 개입한다는 사실을 question:vm1-storage-load-vs-vm2-latency 의 해석 조건으로 넘긴다. scheduler 를 바꿀지 말지는 이 질문이 정하지 않는다 — 바꾼 전후를 비교한 측정이 나온 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:host-block-stack-under-the-vm",
|
|
"question:host-block-device-under-the-disk-image",
|
|
"question:vm1-storage-load-vs-vm2-latency",
|
|
"reference:read-storage-before-blaming-cpu-for-latency"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-host-io-scheduler.md",
|
|
"status": "초안",
|
|
"studioId": "77aa0188-5c2b-4f47-bda7-7c66b084968d",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "VM1 의 storage 부하가 VM2 의 지연을 실제로 밀어 올리는가",
|
|
"kind": "question",
|
|
"slug": "vm1-storage-load-vs-vm2-latency",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-7",
|
|
"final/document.md#167-storage-contention",
|
|
"final/document.md#159-여러-vm이-하나의-nvme를-공유하면",
|
|
"final/document.md#168-cpu가-정상이어도-storage-때문에-느릴-수-있다"
|
|
],
|
|
"known": "§159 는 여러 VM 의 QEMU 와 Host 프로세스가 같은 Host Block Layer queue 로 들어와 device 로 dispatch 된다고 그렸다. §167 은 여러 VM 이 동일한 Physical NVMe 를 사용하면 storage resource 경쟁이 발생할 수 있고 VM1 에서 대량 I/O 가 발생하면 VM2 의 storage latency 가 증가할 수 있다고 적으면서, CPU Contention 이 Host logical CPU 실행 시간 경쟁이고 Storage Contention 은 IOPS/bandwidth/queue/device 처리시간 경쟁이라 둘은 다른 자원 경쟁이라고 못박았다. §168 은 storage completion 을 기다리는 동안 CPU usage 가 높지 않을 수 있어 CPU 30% 인데 request latency 2초 가 가능하다고 적었다. §175 OQ-7 은 VM1 에서 별도의 테스트 파일/디스크로 controlled I/O load 를 발생시키고 VM2 의 application latency 와 Host storage 지표를 동시에 보라고 했다. 이 Host 에서 그렇게 재 본 결과는 없다.",
|
|
"unknown": "VM1 에 controlled I/O load 를 걸었을 때 VM2 의 application latency 가 baseline 대비 실제로 달라지는지, 달라진다면 같은 구간의 Host storage 지표가 같은 방향으로 움직이는지, 그리고 그 변화가 CPU 쪽 지표와는 무관한지.",
|
|
"next-verification": "먼저 question:host-block-device-under-the-disk-image 로 두 VM 이 같은 device 를 쓰는지 확정한다. 그 다음 baseline 구간에서 VM2 의 application latency 와 Host `iostat -xz 1` 과 CPU 를 같은 시각에 기록하고, VM1 에서 별도의 테스트 파일/디스크로 controlled I/O load 를 발생시킨 뒤 같은 셋을 다시 기록하고, 부하를 걷은 회복 구간을 세 번째로 찍는다 (§175 OQ-7). 어느 VM 이 I/O 를 내는지는 §169 의 `iotop` 으로 함께 남긴다.",
|
|
"decision-criterion": "세 구간 표에서 부하 구간에만 VM2 latency 와 Host storage 지표가 함께 오르면 §167 이 그린 경쟁이 이 환경에서 이어진다는 것을 확인한 것이고 그 시계열이 Case 가 된다. VM1 부하 중에도 VM2 latency 가 baseline 과 다르지 않으면 이 구성과 이 부하 수준에서는 경쟁이 관찰되지 않는다고 적고 닫는다. 장치를 분리할지 · scheduler 를 바꿀지 · I/O 를 제한할지는 그 Case 가 나온 뒤 Decision 으로 넘긴다.",
|
|
"relations": [
|
|
"concept:host-block-stack-under-the-vm",
|
|
"reference:read-storage-before-blaming-cpu-for-latency",
|
|
"question:host-block-device-under-the-disk-image",
|
|
"question:host-io-scheduler",
|
|
"question:guest-fsync-latency-vs-host-storage-latency",
|
|
"question:vcpu-contention-under-two-vm-load"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-vm1-storage-load-vs-vm2-latency.md",
|
|
"status": "초안",
|
|
"studioId": "ed64d4ff-aa01-48cc-ae68-6a683b025cde",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
},
|
|
{
|
|
"title": "Guest 의 fsync() 지연과 Host storage 지연은 같이 오르는가",
|
|
"kind": "question",
|
|
"slug": "guest-fsync-latency-vs-host-storage-latency",
|
|
"readiness": "OPEN",
|
|
"source": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-8",
|
|
"final/document.md#150-fsync-가-필요한-이유",
|
|
"final/document.md#169-storage-관측-명령어",
|
|
"final/document.md#170-postgresql-예시-wal과-durability",
|
|
"final/document.md#171-성능과-durability의-trade-off",
|
|
"final/document.md#148-write-완료와-영속화는-다르다"
|
|
],
|
|
"known": "§150 은 `fsync(fd);` 가 변경 내용을 필요한 영속성 경계까지 반영하도록 요청하는 것이고 VM 에서는 그 의미가 Guest Filesystem → Guest Block Layer → virtio-blk → QEMU/Backend → Host Storage Stack → Physical Storage 전체 stack 으로 전달되어야 한다고 적었다. §148 은 `write()` 완료와 writeback 완료와 fsync/flush 완료와 전원 장애에도 안전한 durability 가 서로 다르다고 못박았다. §170 은 PostgreSQL 이 WAL 등의 durability protocol 을 쓰며 필요한 시점에 storage synchronization 을 수행하고, VM storage layer 가 flush/fsync semantics 를 제대로 보존하지 않으면 PostgreSQL 의 durability assumption 과 실제 storage behavior 가 어긋날 수 있다고 적었다. §171 은 특히 DB workload 에서 `fsync()` latency 가 transaction latency 와 연결될 수 있다고 했다. §169 는 Host 관측으로 `iostat -xz 1` 과 `iotop` 을 들었다. §175 OQ-8 은 Guest application/DB latency 와 Host `iostat` 를 시간축으로 함께 관찰하라고 했다. 이 Host 에서 잰 값은 없다.",
|
|
"unknown": "이 Host 에서 Guest 의 `fsync()` 나 DB transaction latency 가 커지는 구간과 Host 쪽 storage latency 가 커지는 구간이 시간축에서 겹치는지, 겹친다면 두 값이 같은 크기로 움직이는지 Guest 쪽이 더 크게 벌어지는지.",
|
|
"next-verification": "Guest 에서 application/DB latency 를 기록하면서 같은 시각에 Host 에서 `iostat -xz 1` 을 돌려 두 계열을 같은 타임스탬프로 남긴다 (§175 OQ-8). 부하가 없는 구간과 있는 구간을 모두 찍고, 어느 프로세스가 I/O 를 내는지는 §169 의 `iotop` 으로 함께 적는다. 이때의 cache mode 는 question:qemu-disk-cache-mode 의 결과를 조건으로 함께 기록한다.",
|
|
"decision-criterion": "두 계열이 같은 구간에서 함께 오르면 §150 이 말한 전달 경로가 이 환경에서 이어진다는 것을 확인한 것이고 그 시계열이 Case 가 된다. Guest `fsync()` latency 는 오르는데 Host storage latency 가 따라 오르지 않으면 그 차이가 어느 계층에서 생기는지 — Guest 쪽 대기인지 QEMU/backend 쪽인지 — 를 다음 물음으로 남기고 닫는다. 어느 쪽이든 성능을 위해 durability 를 줄이는 방향은 reference:a-speedup-that-removed-durability-is-not-an-optimization 을 지나야 한다.",
|
|
"relations": [
|
|
"concept:write-completion-is-not-durability",
|
|
"concept:guest-block-io-path-to-virtqueue",
|
|
"reference:a-speedup-that-removed-durability-is-not-an-optimization",
|
|
"reference:read-storage-before-blaming-cpu-for-latency",
|
|
"question:qemu-disk-cache-mode",
|
|
"question:vm1-storage-load-vs-vm2-latency",
|
|
"question:host-major-fault-vs-storage-latency"
|
|
],
|
|
"publication": "게시됨",
|
|
"file": "storage-virtualization/question/question-guest-fsync-latency-vs-host-storage-latency.md",
|
|
"status": "초안",
|
|
"studioId": "be3c2c58-1ed4-4eae-876a-3114faa61c94",
|
|
"assets": [],
|
|
"assetFiles": [],
|
|
"evidenceFiles": []
|
|
}
|
|
],
|
|
"decision": []
|
|
}
|
|
}
|
|
},
|
|
"candidates": [
|
|
{
|
|
"id": "SSOT-02-19-execution-path-as-one-concept",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#2-전체-구조",
|
|
"final/document.md#19-이-ssot에서-파생될-concept"
|
|
],
|
|
"summary": "virsh · libvirt · QEMU · /dev/kvm · KVM Core · kvm_intel · VMX 를 거쳐 물리 CPU 에 닿는 실행 경로가 한 줄기로 이어진다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§19 가 이 경로를 하나의 CONCEPT 로 관리하라고 적었고, 경로 중간을 잘라 내면 인과가 끊겨 독립성 검사를 통과한다. 이 프로젝트에서 유일하게 독립 기록이 되는 후보다"
|
|
},
|
|
{
|
|
"id": "SSOT-03-component-roles",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#3-각-구성요소의-역할"
|
|
],
|
|
"summary": "구성요소 일곱의 역할 — virsh 는 CLI 이고 VM 을 실행하는 것은 QEMU 프로세스다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "경로 위 정거장들의 설명이다. 따로 떼면 무엇으로 가는 길목인지 말할 수 없어 어느 것도 혼자 서지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-04-vcpu-thread-mapping",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#4-vcpu와-vcpu-thread"
|
|
],
|
|
"summary": "Guest 의 vCPU 하나에 Host 의 QEMU vCPU thread 하나가 대응한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "이 대응이 없으면 뒤의 스케줄링·contention·steal time 절이 무엇에 대한 이야기인지 성립하지 않는다. 개념의 한 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-05-host-scheduler-owns-vcpu-thread",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#5-host-linux-scheduler와-실제-cpu"
|
|
],
|
|
"summary": "vCPU thread 도 다른 Host thread 와 같이 Linux Scheduler 가 실행할 logical CPU 를 정한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "같은 경로의 다음 칸이다. 독립 기록으로 빼면 앞뒤 절을 다시 설명해야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-06-kvm-run-and-vm-entry",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#6-kvm_run과-guest-실행"
|
|
],
|
|
"summary": "vCPU thread 가 KVM_RUN 을 부르면 VM Entry 로 Guest 코드가 실제 CPU 에서 실행된다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "경로가 커널로 넘어가는 지점이다. VM Exit 절과 짝이라 떼면 왕복이 반쪽만 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-07-vm-exit-is-not-shutdown",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#7-vm-entry와-vm-exit"
|
|
],
|
|
"summary": "VM Exit 은 VM 종료가 아니라 Guest 실행에서 Hypervisor 로 제어권이 넘어가는 전환이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "오해를 바로잡는 정의 한 절이다. 정의 하나로 독립 기록을 만들면 §8·§9·§24.9 가 갈 곳을 잃는다"
|
|
},
|
|
{
|
|
"id": "SSOT-08-what-causes-vm-exit",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#8-무엇이-실제로-vm-exit을-발생시키는가"
|
|
],
|
|
"summary": "VM Exit 은 root 권한이 아니라 VMCS 의 VM-Execution Control 설정과 동작 종류가 정한다 — HLT · IN/OUT · CPUID · CR · MSR · Exception · External Interrupt",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "일곱 원인이 같은 질문에 같은 결론으로 답한다 — 무엇이 Exit 하는지는 VMX control 이 정한다. 개념 안의 표나 하위 절이지 일곱 편이 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-09-exit-handled-in-kvm-or-qemu",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#9-vm-exit-이후-처리"
|
|
],
|
|
"summary": "Exit Reason 에 따라 KVM 안에서 끝나기도 하고 KVM_RUN 이 반환되어 QEMU 까지 올라가기도 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§8 과 한 왕복을 이루는 절이다. §24.9 의 「Exit 처리 위치가 KVM 인지 QEMU 인지 본다」도 여기에 기댄다"
|
|
},
|
|
{
|
|
"id": "SSOT-10-idle-guest-releases-cpu",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#10-guest가-idle이면-물리-cpu는-어떻게-되는가"
|
|
],
|
|
"summary": "Guest 가 idle 이면 vCPU thread 가 block/sleep 되고 Host 는 그 CPU 시간을 다른 workload 에 쓴다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§8.1 의 HLT exiting 이 그대로 이어지는 결론이다. 원인 절과 결과 절을 다른 기록으로 나눌 이유가 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-11-four-vcpu-is-not-four-cpus",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#11-vm의-4-vcpu는-정확히-무엇을-의미하는가"
|
|
],
|
|
"summary": "4 vCPU 는 실행 컨텍스트 4개이지 물리 CPU 4개의 영구 예약이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§4·§5 에서 이미 나온 사실을 한 문장으로 못박은 자리다. 없애고 개념의 한 절로 넣어도 이해가 달라지지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-12-overcommit-and-contention",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#12-cpu-contention과-overcommit"
|
|
],
|
|
"summary": "vCPU 총합이 logical CPU 를 넘으면 vCPU thread 끼리 Host CPU 시간을 두고 경쟁한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§24.2·§24.3 이 같은 내용을 문제 목록 형태로 다시 적는다. 한 기록 안에서 한 번 설명하고 표로 잇는 편이 맞다"
|
|
},
|
|
{
|
|
"id": "SSOT-13-steal-time-is-a-clue",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#13-steal-time"
|
|
],
|
|
"summary": "steal time 은 Host contention·overcommit 을 의심할 단서이지 단독으로 원인을 확정하는 지표가 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "지표 하나의 읽는 법이다. §24.4 와 §25 의 표 행이 같은 것을 말하므로 개념 안에서 한 번 설명한다"
|
|
},
|
|
{
|
|
"id": "SSOT-14-observation-commands",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#14-실제-linux에서-확인할-수-있는-것"
|
|
],
|
|
"summary": "이 계층을 눈으로 확인하는 Linux 명령 아홉 — /proc/cpuinfo · lsmod · /dev/kvm · virsh list · ps -T · psr · steal time · perf kvm",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "Reference 가 되려면 적용 조건과 예외를 댈 수 있어야 하는데 이 저장소에는 이 명령들을 실제로 돌린 출력이 아직 없다. 지금은 개념의 「어디를 보면 이 경로가 보이는가」 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-15-layered-diagnosis-view",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#15-cpu-가상화-관점에서-장애를-보는-방법"
|
|
],
|
|
"summary": "VM 안이 느릴 때 Guest · Host/QEMU · KVM · Hardware 로 계층을 나눠 본다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "이 관점으로 원인을 실제로 가른 사건이 이 저장소에 아직 하나도 없다. 근거 Case 가 없는 규칙은 Case 결론을 선언문으로 바꾼 것도 못 되므로 개념의 한 절로 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-16-kvm-layer-under-the-keycloak-experiment",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#16-현재-keycloak-k3s-실험과의-관계"
|
|
],
|
|
"summary": "Keycloak 멀티 노드 실험 구조 아래에 KVM 계층이 하나 더 있고, 그래서 원인을 분리해야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§19 가 「Keycloak/K3s 실험 결과와 Host 자원 문제를 구분하는 기준」을 CONCEPT 범위에 넣었다. 이 개념이 왜 필요한지를 말하는 절이라 개념 안에 있어야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-18-bare-metal-vs-vm-cpu-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#18-bare-metal-k3s와-vm-기반-k3s의-차이"
|
|
],
|
|
"summary": "bare-metal K3s 는 Host scheduler 직행이고 VM 기반 K3s 는 vCPU · QEMU thread · KVM/VMX 계층이 더 붙는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "같은 경로를 계층 유무로 견준 것이다. 경로를 설명한 글 안에서만 대비가 성립한다"
|
|
},
|
|
{
|
|
"id": "SSOT-24-cpu-failure-modes",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제"
|
|
],
|
|
"summary": "Guest saturation · overcommit · contention · steal time · scheduling latency · vCPU 과다 할당 · 잘못된 pinning · 과도한 VM Exit · Host saturation — 구조적으로 가능한 문제와 각각의 확인 지표",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§28 이 CONCEPT 에서 확정할 범위를 「어떤 문제가 발생할 수 있는가 · 어떤 지표로 의심하나 · 어느 계층인가」로 그었고 이 절이 정확히 그것이다. 아홉 모드가 같은 물음에 같은 결론으로 답하므로 개념 안의 하위 절이지 아홉 편이 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-24-8-cgroup-throttling-boundary",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제"
|
|
],
|
|
"summary": "K3s cgroup CPU limit 으로 인한 throttling 은 KVM 문제가 아니지만 같은 application latency 로 보여 진단 경계에 포함한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "이 개념이 다루는 경계의 바깥을 짚는 절이라 개념이 스스로 안고 있어야 한다. 따로 빼면 「CPU 가상화 문제가 아닌 것」만 담은 기록이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-24-11-numa-locality",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제"
|
|
],
|
|
"summary": "NUMA node 사이의 remote memory access 가 성능에 영향을 줄 수 있다",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "문서가 스스로 「상세한 memory placement 와 NUMA tuning 은 메모리 가상화 CONCEPT 에서 다룬다」고 범위를 넘겼다. 이 프로젝트가 메모리 가상화를 담는 SSOT 를 가지면 그때 다시 판정한다. 지금 CPU 개념에 넣으면 그 글에서 이어 쓸 수 없는 문단이 하나 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-25-layer-diagnosis-table",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#25-cpu-문제를-계층별로-구분하는-진단표"
|
|
],
|
|
"summary": "문제 11개를 주된 계층 · 대표 현상 · 우선 확인할 것으로 늘어놓은 진단표",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "표 자체가 §24 를 한 화면으로 접은 것이다. 문서도 「원인을 확정하는 것이 아니라 조사 범위를 줄이는 것」이라고 적었다. 개념 본문의 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-26-layers-to-separate-when-reading-the-experiment",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#26-현재-keycloak-실험에서-cpu-문제를-오판하지-않기-위한-기준"
|
|
],
|
|
"summary": "Application/Auth · Storage · K3s · Guest · Virtualization · Host 여섯 경계를 분리해서 읽는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§15 의 계층 분리를 Keycloak 실험에 맞춰 다시 그린 것이다. 개념이 설명한 경로 위에 실험 요소를 얹은 그림이라 같은 글에 있어야 읽힌다"
|
|
},
|
|
{
|
|
"id": "SSOT-28-what-the-concept-confirms",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#28-concept-->-open-question-->-case-적용-기준"
|
|
],
|
|
"summary": "CONCEPT 은 구조적 가능성과 지표와 계층까지만 확정하고, 현재 서버에서 실제로 발생하는지는 확정하지 않는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "이 개념이 무엇을 사실로 말하고 무엇을 말하지 않는지의 경계다. 그 경계를 다른 기록에 두면 이 글을 읽는 사람이 어디까지 믿어야 하는지 모른다"
|
|
},
|
|
{
|
|
"id": "SSOT-17-26-22-separate-concurrency-and-load-tests",
|
|
"kindCandidate": "DECISION",
|
|
"sourceRefs": [
|
|
"final/document.md#17-동시성-테스트와-부하-테스트를-분리해야-한다",
|
|
"final/document.md#26-현재-keycloak-실험에서-cpu-문제를-오판하지-않기-위한-기준",
|
|
"final/document.md#22-현재-단계의-핵심-claim"
|
|
],
|
|
"summary": "refresh 경쟁은 CPU 여유 상태에서 concurrency 실험으로 먼저 보고, 자원 포화는 별도의 load/stress 실험으로 본다",
|
|
"disposition": "NEEDS_DECISION",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "문서는 「분리해서 수행하는 것이 원인 분석에 유리하다」까지다. 프로젝트가 실제로 그렇게 하기로 정한 기록도, 감수한 비용(실험이 두 벌이 되고 두 결과를 잇는 해석이 따로 필요하다)도 적혀 있지 않다. 권고를 Decision 으로 올리면 「기술이 존재한다」를 근거로 바꾸는 것과 같은 실수가 된다. 실험 계획이 정해지면 다시 판정한다"
|
|
},
|
|
{
|
|
"id": "SSOT-22-claims-1-11",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#22-현재-단계의-핵심-claim"
|
|
],
|
|
"summary": "Claim 1~11 — virsh 의 역할부터 idle vCPU 의 CPU 반환까지, 메커니즘 서술을 한 문장씩으로 줄인 것",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:kvm-vcpu-to-physical-cpu",
|
|
"reason": "§3~§11 의 서술을 선언문으로 바꾼 것이다. 선언문만 모은 기록은 근거를 가리키지 못한다. 개념 본문이 같은 것을 근거와 함께 이미 담는다"
|
|
},
|
|
{
|
|
"id": "SSOT-22-claims-12-13",
|
|
"kindCandidate": "CASE",
|
|
"sourceRefs": [
|
|
"final/document.md#22-현재-단계의-핵심-claim"
|
|
],
|
|
"summary": "Claim 12·13 — contention/overcommit 이 Guest 성능에 영향을 주며, VM 기반 실험 환경의 CPU contention 이 Keycloak 실험 결과를 왜곡할 수 있다",
|
|
"disposition": "NEEDS_EVIDENCE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "다른 Claim 과 달리 이 둘은 「이 환경에서 실제로 그러한가」를 말한다. 이 테스트 Host 에서 잰 값이 없어 개념 본문에서도 가능성으로만 쓰고, 측정하면 Case 후보로 다시 판정한다"
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-1-vcpu-contention-under-two-vm-load",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-1. 현재 테스트 Host 에서 VM 두 대에 부하를 주면 vCPU contention 이 실제로 발생하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vcpu-contention-under-two-vm-load",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 종료 기준이 없다던 앞의 판정은 §20 이 적은 확인 대상 다섯을 종료 기준으로 옮겨 적어 해소했다. OQ-7 과 한 글감으로 합칠지는 값을 잰 뒤에야 아는 것이라 지금은 각각 올리고 relations 로 잇는다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-2-virtualization-layer-saturation-during-refresh",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-2. Keycloak 동시 refresh 실험 중 CPU 가상화 계층이 결과에 영향을 줄 정도로 포화되는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:virtualization-layer-saturation-during-refresh",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 아는 것과 모르는 것은 실험 전에도 갈린다 — §16·§26 이 서술한 계층 구조와 §20 이 적은 관찰 대상 다섯이 known 이고, 이 Host 에서의 값이 unknown 이다. 종료 기준은 §20 이 스스로 밝힌 목적(refresh 경쟁과 Host resource contention 의 분리)에서 끌어 적었다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-3-idle-vcpu-thread-appearance",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-3. Guest 가 idle 일 때 vCPU thread 는 실제 테스트 환경에서 어떻게 보이는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:idle-vcpu-thread-appearance",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 결과가 §10 의 서술과 같으면 개념으로 흡수되고 다르면 Case 가 된다던 앞의 판정은 버리는 이유가 아니라 그대로 종료 기준이다 — decision-criterion 에 그 갈림을 적었다. 확인 명령도 §20 이 이미 두 줄로 적어 두었다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-4-vm-exit-distribution-by-workload",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-4. 실제 workload 에서 어떤 VM Exit 이 주로 발생하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm-exit-distribution-by-workload",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 도구가 이 환경에서 되는지부터 확인해야 한다는 앞의 판정은 버리는 이유가 아니라 next-verification 의 첫 단계다 — 안 되는 것으로 확인되는 것도 이 질문을 닫는 결과다. OQ-11 과는 종료 기준이 달라 합치지 않고 relations 로 잇는다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-5-vcpu-thread-migration-without-pinning",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-5. pinning 을 하지 않은 상태에서 vCPU thread 는 Host logical CPU 사이를 실제로 이동하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vcpu-thread-migration-without-pinning",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 관찰 하나짜리 물음이지만 답에 따라 OQ-10 의 pinning 실험을 할 이유가 있는지가 갈린다 — 설계가 답에 달려 있다는 조건을 만족한다. 독립 Question 으로 남을지 OQ-10 의 관측이 될지를 재 봐야 안다던 앞의 판정은 decision-criterion 에 그대로 옮겼다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-20-oq-6-is-production-on-a-hypervisor",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#20-이-concept에서-파생되는-open-question"
|
|
],
|
|
"summary": "OQ-6. 현재 운영 서버는 CPU 가상화 계층의 영향을 받는 구조인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:is-production-on-a-hypervisor",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 확인 전에는 아는 것과 모르는 것을 나눠 적을 수 없다던 앞의 판정을 뒤집었다 — §18 과 §20 이 그린 두 경로가 known 이고 운영 서버가 어느 쪽인지가 unknown 이다. 답에 따라 §25 의 어느 행을 운영 진단에 쓰는지가 갈리므로 설계가 답에 달린 Question 의 조건을 만족한다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-7-steal-time-increase-under-two-cpu-bound-vms",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-7. VM 두 대를 동시에 CPU-bound 로 만들면 Guest steal time 은 실제로 얼마나 증가하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:steal-time-increase-under-two-cpu-bound-vms",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. OQ-1 의 수치판이라 재고 나면 둘이 한 Question 인지 갈린다던 앞의 판정은 그대로다. 다만 그 판정은 값을 잰 뒤의 일이고, 지금 둘을 미리 한 글감으로 합치면 어느 쪽 종료 기준으로 닫혔는지가 남지 않는다. 각각 올리고 relations 로 잇는다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-8-throughput-vs-vcpu-count",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-8. vCPU 수를 늘릴수록 현재 테스트 Host 에서 Keycloak 처리량도 계속 증가하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:throughput-vs-vcpu-count",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 어디서 꺾이면 「과다 할당」으로 부를지 기준이 없다던 앞의 판정은 §24.6 에서 기준을 끌어 적어 해소했다 — 처리량이 더 오르지 않는 지점이 있으면 그것이 이 workload 의 상한이고, 세 구성이 같은 방향으로 오르면 상한에 닿지 않은 것이다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-9-throttling-vs-contention",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-9. K3s CPU limit 으로 생긴 throttling 과 Host vCPU contention 을 지표로 구분할 수 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:throttling-vs-contention",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 재현하기 전에는 구분이 되는지조차 모른다던 앞의 판정이 곧 이 종류의 전제다. Case 는 재현한 뒤에 쓰고, 그 전까지 무엇을 어떻게 재현해 무엇을 견줄지를 적어 두는 자리가 Question 이다. 견줄 지표는 §25 가 이미 두 행으로 갈라 적어 두었다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-10-pinning-before-and-after",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-10. CPU pinning 전후로 Keycloak latency 와 vCPU scheduling 변동이 달라지는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:pinning-before-and-after",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 측정 전에 Decision 으로 올리면 감수한 비용 없이 선택을 만들게 된다던 앞의 판정은 그대로 유효하다 — 그래서 Decision 이 아니라 Question 으로 올린다. 설계가 답에 달려 있고 다음 검증과 종료 기준이 있는 것이 이 종류의 조건이고 셋 다 갖췄다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-11-exit-distribution-for-keycloak-workload",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-11. Keycloak workload 의 VM Exit 분포는 idle · CPU-bound · I/O-bound 와 어떻게 다른가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:exit-distribution-for-keycloak-workload",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. OQ-4 와 같은 측정에 묶이는 것과 한 글감인 것은 다르다. OQ-4 는 workload 다섯의 분포를 견주는 물음이고 이것은 Keycloak 구간의 분포가 latency 와 같이 움직이는지를 묻는다 — 종료 기준이 달라 각각 올리고 relations 로 잇는다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-27-oq-12-host-numa-topology",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#27-문제-영역에서-파생되는-추가-open-question"
|
|
],
|
|
"summary": "OQ-12. 현재 Host 의 NUMA topology 가 VM 성능을 고려해야 할 정도의 구조인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-numa-topology",
|
|
"reason": "NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정했다. Question 은 답이 아직 없는 판단을 적는 종류라 이 Host 에서 잰 값이 하나도 없다는 것이 글감으로 올리지 못할 이유가 아니다 — 무엇을 알고 무엇을 모르는지, 무엇을 재면 닫히는지를 적어 두는 자리가 Question 이고, 값이 나오면 그때 Case 가 된다. 문서가 종료 기준을 스스로 적은 유일한 OQ 라 Question 으로 올리기에 조건이 가장 갖춰진 후보다. Host 를 확인하기 전에는 답이 없다는 것이 앞의 NEEDS_EVIDENCE 사유였는데, 답이 없는 상태를 그대로 적는 것이 Question 이다. 사용자가 §20·§27 의 OQ 열둘을 OQ 하나에 글감 하나로 올리기로 정했다."
|
|
},
|
|
{
|
|
"id": "SSOT-21-record-system-flow",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#21-open-question에서-case가-만들어지는-흐름"
|
|
],
|
|
"summary": "SSOT → CONCEPT → OPEN QUESTION → CASE 로 이어지고 CASE 에서 다시 OPEN QUESTION 이 나온다는 기록 체계",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "CPU 가상화가 아니라 이 저장소가 기록을 잇는 방식을 설명한 절이다. 분석에는 남아야 하고 공개 기록으로는 읽을 사람이 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-23-next-verification-plan",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#23-다음-단계"
|
|
],
|
|
"summary": "VMX 확인부터 VM Exit 관찰까지 테스트 Host 에서 돌릴 검증 순서와, 그 뒤 네트워크 가상화로 넘어간다는 계획",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "다음에 무엇을 잴지의 진행 계획이다. 계획은 실행되면 Case 가 되고 그 전까지는 분석에 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-29-gva-gpa-hpa-two-translations",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#29-이-문서에서-먼저-고정할-전체-구조",
|
|
"final/document.md#79-전체-memory-virtualization-실행-경로",
|
|
"final/document.md#87-최종-기준-그림"
|
|
],
|
|
"summary": "GVA → GPA → HPA. Guest 가 물리 주소라고 믿는 GPA 와 실제 Host RAM 의 HPA 사이에 변환이 한 번 더 있다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "§29 가 이 부에서 먼저 고정할 구조로 놓고 §87 이 같은 그림을 최종 기준으로 다시 그렸다. 이 부의 나머지 다섯 개념이 전부 이 경로 위의 자리라 이것을 빼면 어느 것도 혼자 서지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-30-32-virtual-memory-basics",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#30-일반-linux의-virtual-memory부터-시작한다",
|
|
"final/document.md#31-page와-physical-frame",
|
|
"final/document.md#32-virtual-address-=-page-+-offset"
|
|
],
|
|
"summary": "프로세스마다 독립된 virtual address space 가 있고, 매핑 단위는 4 KiB page 와 physical frame 이며, virtual address 는 page 와 offset 으로 갈린다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "KVM 고유 기능이 아니라 일반 Linux 의 주소 변환이다. 개념의 첫 절로 들어가면 되고 따로 읽을 이유가 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-33-guest-page-table",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#33-guest-page-table"
|
|
],
|
|
"summary": "Guest Kernel 이 프로세스마다 virtual page → guest physical frame 매핑을 관리하지만 매 접근마다 커널 코드가 table 을 뒤지는 것은 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "변환 경로의 한 단계다. 이 단계만 떼어 읽을 사람이 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-34-mmu-performs-the-translation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#34-mmu-실제-주소-변환을-수행하는-cpu-하드웨어"
|
|
],
|
|
"summary": "주소 변환을 실제로 수행하는 주체는 CPU 의 MMU 이고 Guest Kernel 은 table 을 구성·관리한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "「누가 만들고 누가 쓰는가」는 개념 본문의 한 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-35-tlb-caches-translations",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#35-tlb-주소-변환-결과의-cpu-cache"
|
|
],
|
|
"summary": "TLB 는 최근 translation 결과를 CPU 가 캐시해 둔 것이라 hit 이면 page-table walk 를 건너뛴다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "변환 경로의 성능 특성이다. §43 의 nested walk 비용과 §51 의 TLB coverage 가 이것을 전제한다"
|
|
},
|
|
{
|
|
"id": "SSOT-35-tlb-miss-is-not-page-fault",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#35-tlb-주소-변환-결과의-cpu-cache"
|
|
],
|
|
"summary": "TLB Miss 는 table 을 조회해 정상 매핑을 찾는 사건이고 Page Fault 는 현재 접근을 완료할 수 없는 사건이라 둘은 다르다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "「어느 계층의 사건인가」를 가르는 첫 구분이라 fault 계층 개념의 도입부에 들어간다. §82 의 CLAIM-MEM-07 이 같은 것을 한 문장으로 적었다"
|
|
},
|
|
{
|
|
"id": "SSOT-36-bare-metal-vs-vm-translation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#36-bare-metal과-vm의-차이"
|
|
],
|
|
"summary": "bare-metal 은 page table 한 번으로 끝나지만 VM 에서는 Guest 가 얻은 physical address 가 Host physical address 가 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "EPT 가 왜 필요한지를 세우는 대조다. 개념 안에서 EPT 절 바로 앞에 온다"
|
|
},
|
|
{
|
|
"id": "SSOT-37-ept-second-stage-translation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#37-ept-extended-page-tables"
|
|
],
|
|
"summary": "EPT 는 GPA → HPA 를 CPU 하드웨어가 수행하는 second-level address translation 이고 Guest Page Table 과 같은 table 이 아니다. AMD 에는 NPT 계열이 대응한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "주소 변환 경로의 두 번째 단계다. 이 개념의 핵심 절이지 독립 글이 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-38-ept-isolates-guest-physical-space",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#38-왜-ept가-필요한가"
|
|
],
|
|
"summary": "VM 둘이 같은 GPA 를 써도 EPT 가 서로 다른 HPA 로 연결해 Guest physical address space 를 격리한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "EPT 절의 근거 예시다. 표 한 줄이나 예 하나로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-39-shadow-page-table-vs-ept",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#39-shadow-page-table과-ept의-의미"
|
|
],
|
|
"summary": "하드웨어 second-level translation 이 없던 방식은 hypervisor 가 shadow mapping 을 유지해야 해 관리 비용이 컸고, EPT/NPT 는 그 두 단계를 하드웨어로 옮겼다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "EPT 가 무엇을 대신하는지를 설명하는 배경이다. 개념 안의 한 절이면 충분하다"
|
|
},
|
|
{
|
|
"id": "SSOT-40-qemu-backs-guest-ram-in-host-userspace",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#40-qemu는-guest-ram을-어떻게-준비하는가"
|
|
],
|
|
"summary": "QEMU 는 Host userspace process 라 Guest RAM 도 자신의 Host Virtual Address Space 에 마련하고, RAM 하드웨어를 직접 제어하는 것이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "관리 경로의 시작이다. OQ-3 이 재려는 QEMU RSS 가 무엇인지도 이 절이 정한다"
|
|
},
|
|
{
|
|
"id": "SSOT-41-kvm-set-user-memory-region",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#41-kvm_set_user_memory_region",
|
|
"final/document.md#80-전체-memory-virtualization-관리-경로"
|
|
],
|
|
"summary": "QEMU 가 마련한 HVA 범위와 Guest GPA 범위의 대응을 `KVM_SET_USER_MEMORY_REGION` 으로 KVM 에 등록하고, 런타임 변환은 CPU 가 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "관리 경로(§80)와 실행 경로(§79)를 가르는 자리다. 개념이 그 둘을 같이 그린다"
|
|
},
|
|
{
|
|
"id": "SSOT-42-configured-memory-is-not-resident-memory",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#42-configured-memory와-실제-physical-ram-사용량은-같지-않을-수-있다"
|
|
],
|
|
"summary": "configured memory · Guest 가 지금 쓰는 memory · Host 에서 지금 resident 한 physical memory 셋은 같지 않을 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "OQ-2 와 OQ-3 이 이 절을 재려고 만들어졌다. 개념이 셋의 구분을 세우고 두 Question 이 이 Host 의 값을 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-43-nested-page-table-walk-cost",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#43-guest-page-table-자체도-메모리에-있다"
|
|
],
|
|
"summary": "Guest Page Table 자체도 Guest physical memory 에 있는 자료구조라 entry 를 읽는 데도 EPT 변환이 필요하고, 그래서 nested walk 에는 비용이 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "왜 TLB 가 중요한지를 잇는 절이다. 개념 안에서 TLB 절과 붙어 있어야 읽힌다"
|
|
},
|
|
{
|
|
"id": "SSOT-44-normal-memory-access-does-not-vm-exit",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#44-정상-memory-access는-매번-vm-exit하지-않는다",
|
|
"final/document.md#79-전체-memory-virtualization-실행-경로"
|
|
],
|
|
"summary": "정상 매핑이 있으면 CPU MMU 가 직접 변환하므로 Guest RAM 접근마다 VM Exit 이나 QEMU userspace 왕복이 생기지 않는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "CPU 부에서 VM Exit 을 읽은 사람이 가장 쉽게 틀리는 자리라 §44 가 「잘못된 이해」를 먼저 그렸다. 개념의 결론 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-45-guest-page-fault",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#45-guest-page-fault",
|
|
"final/document.md#48-guest-page-fault와-ept-violation-비교",
|
|
"final/document.md#49-host-page-fault도-별도로-존재한다"
|
|
],
|
|
"summary": "Guest Page Fault 는 GVA → GPA 단계에서, EPT Violation 은 GPA → HPA 단계에서, Host Page Fault 는 QEMU backing 의 Host virtual memory 에서 각각 따로 일어난다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "§48 의 비교표와 §49 의 세 갈래는 이 부에서 가장 여러 번 다시 쓰이는 구분이다. §86 의 진단 분류가 그 위에 서 있고 OQ-13·OQ-14 가 각각 Guest 쪽과 Host 쪽을 재라고 말한다. 정상 경로를 그리는 글과 갈라 둔 이유는 물음이 다르기 때문이다 — 그쪽은 정상일 때 무엇이 일어나는가를, 이쪽은 완료되지 않을 때 어느 계층이 받는가를 말한다"
|
|
},
|
|
{
|
|
"id": "SSOT-46-page-fault-causes",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#46-page-fault의-대표적인-원인"
|
|
],
|
|
"summary": "demand paging · swap-in · permission fault · copy-on-write · invalid access 다섯이 Page Fault 의 대표 원인이고, Page Fault 는 Segmentation Fault 와 다르다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "Guest Page Fault 절 아래의 하위 절이다. 다섯을 각각 글로 만들면 표 한 줄이 될 것이 다섯 편이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-47-ept-violation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#47-ept-violation"
|
|
],
|
|
"summary": "Guest 쪽 변환은 성공했는데 그 GPA 의 second-stage 접근을 현재 EPT 조건으로 완료할 수 없으면 EPT Violation 이고 VM Exit 을 거쳐 KVM 이 받는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "같은 개념의 두 번째 계층이다. §48 의 비교표가 이 절과 §45 를 나란히 놓는다"
|
|
},
|
|
{
|
|
"id": "SSOT-48-guest-page-fault-vs-ept-violation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#48-guest-page-fault와-ept-violation-비교"
|
|
],
|
|
"summary": "문제 위치 · 관련 table · 기본 관점 · 주요 처리 계층 · 앱 오류 여부 다섯 항목으로 Guest Page Fault 와 EPT Violation 을 갈라 놓은 비교표",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "개념 본문의 표다. 표 하나를 기록 하나로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-49-host-page-fault",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#49-host-page-fault도-별도로-존재한다"
|
|
],
|
|
"summary": "QEMU 도 Host 의 일반 userspace process 라 demand allocation·reclaim·swap 때문에 Host 쪽에서도 page fault 가 난다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "세 계층 가운데 셋째다. OQ-14 가 이 계층의 major fault 를 재려고 만들어졌다"
|
|
},
|
|
{
|
|
"id": "SSOT-50-51-huge-page-and-tlb-coverage",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#50-huge-page가-필요한-이유",
|
|
"final/document.md#51-huge-page와-tlb-coverage",
|
|
"final/document.md#52-vm에서-huge-page를-볼-때-주의할-점"
|
|
],
|
|
"summary": "page 가 커지면 같은 범위를 더 적은 매핑으로 덮어 TLB pressure 와 page-table walk 부담이 줄 수 있고, VM 에서는 Guest 단계·Host backing·EPT 매핑 셋을 따로 봐야 한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "OQ-4 와 OQ-5 가 이 개념을 필요로 한다. THP 정책 하나를 읽어도 그것이 Guest 쪽인지 Host backing 쪽인지 모르면 값이 뜻을 갖지 않는다. §51 은 예시 숫자를 특정 CPU 의 실제 TLB 용량으로 읽지 말라는 단서까지 달았다"
|
|
},
|
|
{
|
|
"id": "SSOT-52-huge-page-has-two-stages-in-a-vm",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#52-vm에서-huge-page를-볼-때-주의할-점"
|
|
],
|
|
"summary": "VM 에는 변환 단계가 둘이라 「Huge Page 를 쓴다」는 말만으로는 Guest page table 쪽인지 Host backing 쪽인지 EPT 매핑 쪽인지 정해지지 않는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "개념의 핵심 절이다. OQ-5 가 이 구분을 그대로 확인 항목으로 쓴다"
|
|
},
|
|
{
|
|
"id": "SSOT-53-thp",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#53-thp-transparent-huge-pages"
|
|
],
|
|
"summary": "THP 는 조건이 맞는 영역에 Linux 가 Huge Page 를 투명하게 활용하려는 기능이고 정책은 `/sys/kernel/mm/transparent_hugepage/enabled` 에서 읽는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "개념 안의 한 절이다. 정책 값 자체는 OQ-4 가 이 Host 에서 읽는다"
|
|
},
|
|
{
|
|
"id": "SSOT-54-thp-tradeoff",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#54-thp의-trade-off"
|
|
],
|
|
"summary": "Huge Page 에는 큰 contiguous 영역이 필요해 fragmentation 이 심하면 compaction 이 끼어들 수 있고, 그래서 THP 가 항상 성능을 높인다고 단정할 수 없다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "THP 절의 뒷면이다. 이익만 적고 비용을 빼면 개념이 반쪽이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-55-hugetlb",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#55-hugetlb"
|
|
],
|
|
"summary": "HugeTLB 는 관리자가 미리 확보한 명시적 Huge Page pool 을 쓰는 방식이라 예측 가능성이 오르는 대신 일반 allocation 의 유연성이 준다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "THP 와 짝을 이루는 절이다. §56 의 비교표가 둘을 나란히 놓는다"
|
|
},
|
|
{
|
|
"id": "SSOT-56-thp-vs-hugetlb",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#56-thp와-hugetlb-비교"
|
|
],
|
|
"summary": "관리 주체 · 애플리케이션 개입 · 유연성 · 사전 예약 · compaction 영향 · VM RAM backing 여섯 항목의 THP↔HugeTLB 비교표와 `AnonHugePages` ≠ `HugePages_Total`",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "개념 본문의 표다. OQ-4 가 그 표의 항목을 이 Host 에서 읽는다"
|
|
},
|
|
{
|
|
"id": "SSOT-57-memory-overcommit",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#57-memory-overcommit",
|
|
"final/document.md#58-cpu-overcommit과-memory-overcommit의-차이",
|
|
"final/document.md#59-host-memory-pressure와-reclaim"
|
|
],
|
|
"summary": "configured 총량이 Host RAM 을 넘는 구성이 성립하는 이유는 configured capacity 와 현재 working set 이 같지 않기 때문이고, RAM 이 모자라면 CPU 처럼 시간을 나누는 것이 아니라 reclaim·swap·ballooning·OOM 이 개입한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "OQ-6·OQ-7·OQ-14 셋이 이 개념 위에서만 읽힌다. CPU overcommit 과 성격이 다르다는 §58 이 이 부 전체에서 가장 오해되기 쉬운 자리라 앞에서 한 번 세워야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-58-cpu-overcommit-vs-memory-overcommit",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#58-cpu-overcommit과-memory-overcommit의-차이"
|
|
],
|
|
"summary": "CPU 가 모자라면 scheduler 가 실행 시간을 나누지만 RAM 이 모자라면 「지금 존재해야 하는 page 를 어디에 둘 것인가」가 남는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "개념의 도입 대조다. 한 절이면 되고 독립 글로 읽을 것이 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-59-host-reclaim",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#59-host-memory-pressure와-reclaim"
|
|
],
|
|
"summary": "Host 수요가 available physical memory 에 가까워지면 reclaim 이 돌고, file-backed clean page 는 버렸다 다시 읽으면 되지만 anonymous page 는 swap 같은 backing 이 필요하다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "압박 경로의 첫 단계다. 개념 본문의 한 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-60-host-swap-turns-guest-ram-access-into-io",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#60-host-swap이-vm에-미치는-영향"
|
|
],
|
|
"summary": "Guest 는 RAM 에 접근했다고 생각하는데 Host backing page 가 swap-out 되어 있으면 그 접근이 Host page fault 와 swap-in I/O 대기로 바뀐다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "이 개념이 존재하는 이유가 되는 절이다. OQ-7 이 이것을 실험으로 확인한다"
|
|
},
|
|
{
|
|
"id": "SSOT-61-guest-swap-is-not-host-swap",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#61-guest-swap과-host-swap"
|
|
],
|
|
"summary": "Guest Swap 은 Guest kernel 이 `/dev/vda` 로 내려보내는 것이고 Host Swap 은 QEMU backing 이 Host kernel 에 눌리는 것이라 서로 다른 계층이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "계층 구분이라 개념 안에 있어야 한다. OQ-6 이 둘을 같은 시각에 재라고 요구하는 근거다"
|
|
},
|
|
{
|
|
"id": "SSOT-62-memory-pressure-reaches-storage",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#62-memory-pressure와-storage-contention의-연결",
|
|
"final/document.md#81-cpu-network-storage-memory-연결"
|
|
],
|
|
"summary": "Guest swap I/O · Host swap I/O · DB I/O · filesystem writeback 이 한 물리 장치로 몰릴 수 있어 memory pressure 가 storage contention 을 거쳐 application latency 까지 온다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "메모리를 CPU 사용률로 판단하지 않게 하는 절이다. OQ-14 가 이 연결을 같은 시간축에서 확인한다"
|
|
},
|
|
{
|
|
"id": "SSOT-63-swap-used-alone-is-not-a-verdict",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#63-swap-used만-보고-장애를-판단하면-안-된다"
|
|
],
|
|
"summary": "Swap Used 값 하나로 memory pressure 를 단정할 수 없고 swap-in/out 지속 여부 · reclaim pressure · major fault · storage latency 를 Guest 와 Host 에서 함께 봐야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:memory-symptom-needs-layer-separation",
|
|
"reason": "「지표 하나로 계층을 단정하지 않는다」는 규칙의 대표 사례라 그 Reference 의 한 행으로 들어간다. 규칙을 두 벌 쓰면 어느 쪽을 따르는지가 갈린다"
|
|
},
|
|
{
|
|
"id": "SSOT-71-oom-mechanism",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#71-oom"
|
|
],
|
|
"summary": "reclaim 으로도 필요한 memory 를 확보하지 못하면 OOM 이 되고 OOM Killer 가 프로세스를 골라 종료할 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "압박 경로의 마지막 단계다. 개념 안에서 §72 와 붙어 있어야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-72-guest-oom-vs-host-oom",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#72-guest-oom과-host-oom"
|
|
],
|
|
"summary": "Guest OOM 은 Guest 프로세스를 죽이지만 Host OOM 에서 QEMU 가 victim 이 되면 VM 전체가 멈추고, cgroup limit 이 있으면 Host RAM 이 남아도 그 경계에서 OOM 이 난다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "영향 범위가 다르다는 것이 이 개념의 결론이다. OOM 의 발생 계층을 확인하라는 §86 의 갈래도 여기서 나온다"
|
|
},
|
|
{
|
|
"id": "SSOT-64-65-virtio-balloon",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#64-ballooning이-필요한-이유",
|
|
"final/document.md#65-virtio-balloon-구조"
|
|
],
|
|
"summary": "Host 는 Guest 안에서 어느 memory 가 중요한지 모르므로 무작정 swap-out 하는 대신 Guest kernel 과 협력해 회수한다. virtio-balloon 은 그 협력용 가상 장치이고 RAM 자체를 제공하는 장치가 아니다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "OQ-8 과 OQ-9 가 이 개념을 필요로 한다. balloon 은 Guest 안의 driver 와 QEMU 쪽 device 가 virtqueue 로 맞물린 별도 메커니즘이라 압박 경로 안의 한 절로 넣으면 inflate/deflate 의 방향조차 설명할 자리가 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-66-balloon-inflate",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#66-balloon-inflate"
|
|
],
|
|
"summary": "Host 가 balloon 을 inflate 하면 Guest 안의 balloon 이 커져 Guest usable memory 가 줄고 Host 가 회수할 수 있는 backing 이 는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "개념의 핵심 동작이다. §68 의 deflate 와 한 절 안에서 방향이 갈린다"
|
|
},
|
|
{
|
|
"id": "SSOT-67-what-balloon-page-return-means",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#67-balloon-page-반환의-의미"
|
|
],
|
|
"summary": "balloon driver 는 Guest page 를 확보하고 그 사실을 Host 에 알리는 것이며, Host 쪽 실제 release 동작은 QEMU/KVM 버전과 backing 종류·설정에 따라 달라질 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "단정하지 않은 자리를 그대로 옮겨야 하는 절이라 개념 본문에 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-68-balloon-deflate",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#68-balloon-deflate"
|
|
],
|
|
"summary": "balloon target 을 줄이면 balloon page 가 반환되어 Guest usable memory 가 는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "inflate 와 짝인 한 문장이다. 따로 읽을 것이 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-69-over-inflation-pressures-the-guest",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#69-ballooning을-과도하게-하면-guest가-압박을-받는다"
|
|
],
|
|
"summary": "working set 이 큰데 과도하게 inflate 하면 Guest reclaim → page cache 회수 → Guest swap → 심하면 Guest OOM 으로 이어져, Host RAM 을 확보하려던 조치가 Guest latency 를 올릴 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "개념의 감수 비용 절이다. OQ-9 가 이 경로를 실험 대상으로 삼는다"
|
|
},
|
|
{
|
|
"id": "SSOT-70-ballooning-is-not-memory-hotplug",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#70-ballooning과-memory-hotplug"
|
|
],
|
|
"summary": "ballooning 은 기존 capacity 안에서 usable memory 를 회수·반환하는 것이고 hotplug 는 capacity 자체를 더하는 것이라 다르다. `virtio-mem` 같은 다른 방식도 있어 동적 memory 관리를 ballooning 하나로 일반화하면 안 된다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "개념의 경계 절이다. 잘못 뭉치는 것을 막는 문장이라 본문에 있어야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-73-74-numa-local-and-remote",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#73-numa",
|
|
"final/document.md#74-local-memory와-remote-memory",
|
|
"final/document.md#75-vcpu와-numa의-연결"
|
|
],
|
|
"summary": "NUMA 에서는 어느 CPU 가 어느 RAM 을 읽느냐로 비용이 갈리고, Guest vCPU 는 Host 의 QEMU vCPU thread 라 그 thread 가 도는 node 와 backing page 가 있는 node 가 어긋나면 remote access 가 된다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "OQ-11 과 OQ-12 가 이 개념 위에 선다. CPU 부의 question:host-numa-topology 가 「상세한 memory placement 와 NUMA tuning 은 메모리 가상화 CONCEPT 에서 다룬다」고 범위를 넘긴 자리가 여기다"
|
|
},
|
|
{
|
|
"id": "SSOT-75-vcpu-placement-decides-which-node-reads-ram",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#75-vcpu와-numa의-연결"
|
|
],
|
|
"summary": "Guest 안에서는 단순한 memory load 인데 실제 하드웨어에서는 vCPU thread 가 도는 node 에 따라 interconnect 를 건널 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "개념의 핵심 연결이다. CPU 부의 vCPU thread 서술과 메모리 배치가 여기서 만난다"
|
|
},
|
|
{
|
|
"id": "SSOT-76-pinning-alone-does-not-finish-numa",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#76-vcpu-pinning만으로는-numa-최적화가-끝나지-않는다"
|
|
],
|
|
"summary": "vCPU 를 Node 0 에 pinning 해도 backing page 가 Node 1 에 몰려 있으면 remote access 가 늘 수 있어 vCPU placement 와 memory placement 를 함께 봐야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "개념의 결론 절이다. OQ-11 이 이 어긋남을 이 Host 에서 확인한다"
|
|
},
|
|
{
|
|
"id": "SSOT-77-guest-numa",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#77-guest-numa"
|
|
],
|
|
"summary": "큰 VM 에서는 Guest 에게 NUMA topology 자체를 노출하고 Guest node 와 Host node 가 합리적으로 대응되도록 구성할 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "개념 안의 한 절이다. 이 프로젝트의 VM 이 그런 크기인지는 SSOT 에 적혀 있지 않다"
|
|
},
|
|
{
|
|
"id": "SSOT-78-numa-observation-commands",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#78-numa는-실제-장비-topology부터-확인한다"
|
|
],
|
|
"summary": "`lscpu` · `numactl --hardware` · `numastat -p <QEMU_PID>` · `virsh vcpupin` · `virsh vcpuinfo` — NUMA topology 와 배치를 읽는 명령",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "명령 목록만으로는 규칙이 되지 않는다. 개념 본문에서 무엇을 읽는 명령인지와 함께 놓아야 뜻이 있고, 실제 값은 OQ-11·OQ-12 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-78-measure-topology-before-optimizing",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#78-numa는-실제-장비-topology부터-확인한다"
|
|
],
|
|
"summary": "Host 가 단일 NUMA node 면 cross-node 문제가 주요 이슈가 아닐 수 있으므로 topology 를 먼저 재고 NUMA 최적화 필요성을 판단한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:memory-symptom-needs-layer-separation",
|
|
"reason": "「재기 전에 단정하지 않는다」는 같은 규칙의 NUMA 판이라 그 Reference 의 적용 범위 한 줄로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-79-memory-execution-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#79-전체-memory-virtualization-실행-경로"
|
|
],
|
|
"summary": "TLB → Guest Page Table(#PF 가능) → GPA → VM Boundary → EPT(Violation 가능) → HPA → NUMA node 로 이어지는 실행 경로 한 장",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "개념이 그리는 경로 그대로다. 그림 한 장을 기록 하나로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-80-memory-management-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#80-전체-memory-virtualization-관리-경로"
|
|
],
|
|
"summary": "virsh → libvirt → QEMU(backing · balloon device · ioctl) → KVM(memory slot · EPT 매핑) → CPU 로 이어지는 관리 경로",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "실행 경로와 짝이라 같은 개념 안에서 나란히 놓아야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-81-memory-pressure-to-application-latency",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#81-cpu-network-storage-memory-연결"
|
|
],
|
|
"summary": "memory pressure → reclaim/swap → storage I/O → contention → application latency 로 이어지는 사슬과, vCPU pinning + memory placement 가 함께 NUMA locality 를 정한다는 연결",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "압박 개념의 결론 사슬이다. §62 와 같은 것을 한 번 더 그린 자리라 그 개념 안에 함께 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-81-four-resource-map",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#81-cpu-network-storage-memory-연결"
|
|
],
|
|
"summary": "CPU · Network · Storage · Memory 넷을 한 그림에 놓고 memory 가 그 전부를 받친다고 적은 지도",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "이 문서 네 부 전체의 지도이지 메모리만의 개념이 아니다. 제3부(네트워크)와 제4부(스토리지)가 같은 그림을 쓰므로 SSOT 에 두고 각 개념이 필요할 때 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-87-final-reference-picture",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#87-최종-기준-그림"
|
|
],
|
|
"summary": "Guest Userspace → Guest Kernel(TLB · Page Table) → VM Boundary → KVM/CPU(EPT) → Host RAM(NUMA) 한 장과, 관리 경로와 자원 압박 경로를 따로 기억하라는 지시",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "§29 와 §79 가 그린 것을 최종 기준으로 다시 그린 것이다. 같은 경로를 세 번째 기록으로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-translation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-01~06 — 두 단계 변환 · Guest Page Table 의 관리 주체 · EPT 의 하드웨어 지원 · 정상 접근이 VM Exit 을 부르지 않는다는 것 · QEMU backing 과 region 등록 · configured ≠ resident",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "개념 본문이 이미 서술한 것을 한 문장씩으로 줄인 목록이다. 개념의 요약 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-fault-layers",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-07~09 — TLB Miss ≠ Page Fault · Guest Page Fault 와 EPT Violation 의 발생 단계가 다르다 · Page Fault 자체는 프로그램 오류가 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:page-fault-layers-in-a-vm",
|
|
"reason": "fault 계층 개념이 서술한 것의 요약이다. 그 글의 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-huge-page",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-10~11 — Huge Page 가 TLB/page-table 효율을 개선할 가능성 · THP 와 HugeTLB 는 같은 방식이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:huge-pages-in-a-vm",
|
|
"reason": "huge page 개념의 요약 두 줄이다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-pressure",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-12~14 와 17 — Memory Overcommit 의 성격 · Guest Swap 과 Host Swap 의 계층 · pressure 가 storage 와 latency 를 악화시킬 수 있다 · Guest OOM 과 Host OOM 의 영향 범위",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:memory-pressure-reclaim-swap-oom",
|
|
"reason": "압박 개념의 요약이다. 개념 안의 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-balloon",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-15~16 — virtio-balloon 은 협력용 장치이지 RAM 제공 장치가 아니다 · 과도한 inflate 는 Guest reclaim/swap/OOM 을 부를 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:virtio-balloon-memory-reclaim",
|
|
"reason": "balloon 개념의 요약 두 줄이다"
|
|
},
|
|
{
|
|
"id": "SSOT-82-claims-numa",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#82-핵심-claim-registry"
|
|
],
|
|
"summary": "CLAIM-MEM-18 — NUMA 시스템에서는 vCPU placement 와 memory placement 를 함께 봐야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:numa-locality-for-vcpu-and-memory",
|
|
"reason": "NUMA 개념의 결론을 한 문장으로 줄인 것이다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-1-host-numa-topology-overlap",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-1"
|
|
],
|
|
"summary": "OQ-1. Host 의 실제 NUMA topology 는 무엇인가 — node 수 · node 별 CPU · node 별 memory · node distance",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-numa-topology",
|
|
"reason": "CPU 부의 question:host-numa-topology 가 같은 것을 이미 묻고 있고 그 unknown 이 「단일인지 다중인지」를 그대로 담고 있다. 같은 한 번의 측정으로 닫히는 물음을 두 편으로 만들지 않는다. 그 질문이 「SSOT 는 이 확인에 쓸 명령을 적지 않았다」고 남긴 자리에 §83 OQ-1 의 `lscpu` · `numactl --hardware` 와 node 별 memory · node distance 를 확인 항목으로 더한다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-2-vm-configured-vs-current-memory",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-2"
|
|
],
|
|
"summary": "OQ-2. 각 VM 의 configured/current memory 는 얼마인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm-configured-vs-current-memory",
|
|
"reason": "§42 가 세운 세 값의 차이를 이 Host 에서 재는 물음이다. 답에 따라 overcommit 상태인지가 정해지고 그 뒤 실험 설계가 갈린다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-3-qemu-resident-memory-distribution",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-3"
|
|
],
|
|
"summary": "OQ-3. QEMU process 의 Host resident memory 는 어떻게 분포하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:qemu-resident-memory-distribution",
|
|
"reason": "configured 와 RSS 의 차이, 그리고 backing 이 anonymous 인지 huge page 인지를 재는 물음이다. §40·§41 이 서술한 backing 구조가 이 Host 에서 어떤 값인지가 답이다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-4-host-thp-policy",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-4"
|
|
],
|
|
"summary": "OQ-4. Host THP 정책은 무엇인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-thp-policy",
|
|
"reason": "§53 이 정책은 kernel/distribution/Host 설정에 따라 다르니 실제 시스템에서 확인하라고 적었다. 값을 읽어야 닫힌다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-5-vm-ram-backed-by-hugetlb",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-5"
|
|
],
|
|
"summary": "OQ-5. VM RAM 이 HugeTLB 로 명시적으로 backing 되어 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm-ram-backed-by-hugetlb",
|
|
"reason": "§52 가 가른 세 자리 가운데 Host backing 쪽을 이 Host 에서 확정하는 물음이다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-6-swap-activity-in-guest-and-host",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-6"
|
|
],
|
|
"summary": "OQ-6. Guest 와 Host 에서 현재 swap 이 발생하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:swap-activity-in-guest-and-host",
|
|
"reason": "§63 이 swap-used 값이 아니라 지금 오가는지를 보라고 적었다. Guest 와 Host 를 같은 시각에 재야 §61 의 계층 구분이 값으로 갈린다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-7-host-memory-pressure-vs-guest-latency",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-7"
|
|
],
|
|
"summary": "OQ-7. Host memory pressure 가 Guest latency 에 영향을 주는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-memory-pressure-vs-guest-latency",
|
|
"reason": "§60·§62 가 그린 경로가 이 Host 에서 실제로 이어지는지를 baseline → 압박 유도 → 재측정으로 확인하는 물음이다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-8-virtio-balloon-configured",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-8"
|
|
],
|
|
"summary": "OQ-8. virtio-balloon 이 VM 에 구성되어 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:virtio-balloon-configured",
|
|
"reason": "구성 여부가 정해지지 않으면 OQ-9 의 실험 자체가 성립하지 않는다. §83 이 driver 이름과 표시 방식이 환경마다 다를 수 있다는 단서를 달았다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-9-balloon-target-vs-guest-available-memory",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-9"
|
|
],
|
|
"summary": "OQ-9. Balloon target 변화가 Guest available memory 에 어떻게 반영되는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:balloon-target-vs-guest-available-memory",
|
|
"reason": "§66·§68 의 방향과 §69 의 과도 inflate 위험을 이 Host 에서 값으로 확인하는 물음이다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-10-host-numa-topology-overlap",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-10"
|
|
],
|
|
"summary": "OQ-10. VM vCPU 는 어느 Host CPU 에 배치되어 있는가",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-numa-topology",
|
|
"reason": "§83 OQ-10 이 스스로 「CPU 가상화 SSOT 의 pinning/overcommit 관측과 연결한다」고 적었고, CPU 부의 question:host-numa-topology 가 이미 두 VM 의 vCPU 배치를 unknown 에 담고 있다. 같은 `virsh vcpuinfo`/`vcpupin` 한 번으로 닫히는 것을 따로 세우지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-11-qemu-memory-numa-placement",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-11"
|
|
],
|
|
"summary": "OQ-11. QEMU memory 는 어느 NUMA node 에 배치되어 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:qemu-memory-numa-placement",
|
|
"reason": "CPU 부가 넘긴 자리다. vCPU 배치는 그쪽이 재고 memory 배치와 둘의 어긋남은 여기서 잰다 — `numastat -p <QEMU_PID>` 는 CPU 부 어디에도 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-12-numa-remote-access-vs-workload-latency",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-12"
|
|
],
|
|
"summary": "OQ-12. NUMA remote access 가 실제 workload latency 에 의미 있는 영향을 주는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:numa-remote-access-vs-workload-latency",
|
|
"reason": "topology 를 아는 것과 latency 가 달라지는 것은 다른 물음이다. §83 이 단순 topology 만 보고 성능 문제라고 단정하지 말라고 적었다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-13-guest-page-fault-vs-workload",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-13"
|
|
],
|
|
"summary": "OQ-13. Guest Page Fault 가 workload 변화와 함께 증가하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:guest-page-fault-vs-workload",
|
|
"reason": "§46 의 다섯 원인 가운데 무엇이 늘었는지를 갈라야 답이 된다. Page Fault 증가만으로 오류라고 판단하지 말라는 것이 §83 의 단서다"
|
|
},
|
|
{
|
|
"id": "SSOT-83-oq-14-host-major-fault-vs-storage-latency",
|
|
"kindCandidate": "QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#83-실제-환경에서-확인할-open-question-oq-14"
|
|
],
|
|
"summary": "OQ-14. Host Page Fault/major fault 와 storage latency 가 상관되는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-major-fault-vs-storage-latency",
|
|
"reason": "§49 의 Host 계층과 §62 의 storage 연결을 같은 시간축에서 확인하는 물음이다"
|
|
},
|
|
{
|
|
"id": "SSOT-84-recommended-experiment-order",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#84-권장-실험-순서"
|
|
],
|
|
"summary": "Host physical memory/NUMA 확인부터 NUMA locality 실험까지 열두 단계로 적은 권장 검증 순서",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "분석 진행 계획이다. 어느 Question 을 먼저 여느냐의 순서일 뿐 독립 기록으로 읽을 사람이 없다. CPU 부의 §23 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-85-conditions-to-record-with-every-experiment",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#85-실험-시-반드시-같이-기록할-것"
|
|
],
|
|
"summary": "Host(CPU model · core/thread · RAM · NUMA topology · swap 설정 · kernel version · THP policy · physical storage) · VM(vCPU · configured/current RAM · memory backing · balloon device · guest swap · guest kernel) · Workload(application · heap 설정 · request concurrency · DB workload · 측정 시간) 세 묶음을 실험마다 함께 남긴다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:record-the-conditions-with-every-memory-experiment",
|
|
"reason": "열두 Question 전부에 같이 걸리는 규칙이라 각 글에 되풀이할 것이 아니라 한 편으로 두고 가리킨다. 원 사건 이름을 지워도 규칙이 남는다 — 메모리 실험 결과를 다른 환경에 재사용하려면 어떤 조건을 같이 남겨야 하는가에 대한 답이다"
|
|
},
|
|
{
|
|
"id": "SSOT-86-classify-the-symptom-before-concluding",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#86-문제를-진단할-때의-분류"
|
|
],
|
|
"summary": "메모리 latency 나 OOM 을 보고 한 번에 「메모리 부족」이라고 결론내지 않고 Guest Virtual Memory · Virtualization Translation · Host Memory · Dynamic Memory · NUMA 다섯 갈래로 먼저 가른다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:memory-symptom-needs-layer-separation",
|
|
"reason": "다음 프로젝트에도 그대로 적용되는 판독 규칙이다. 다섯 갈래는 이 부의 여섯 개념을 가로지르는 라우팅이라 어느 개념 안에 넣어도 나머지 넷을 가리키지 못한다"
|
|
},
|
|
{
|
|
"id": "SSOT-88-do-not-judge-memory-from-one-guest-free",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#88-결론"
|
|
],
|
|
"summary": "Guest 하나의 `free -h` 만 보고 메모리 상태를 판단하지 않고 Guest → QEMU → Host → NUMA → Storage 영향을 같은 시간축에서 관측한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:memory-symptom-needs-layer-separation",
|
|
"reason": "§86 과 같은 규칙의 결론 문장이다. 그 Reference 의 적용 조건 한 줄로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-88-concept-is-fixed-oq-becomes-case",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#88-결론"
|
|
],
|
|
"summary": "이 문서의 개념 부분은 SSOT 로 고정하고 실제 서버에 종속되는 설정과 동작은 OQ-1~OQ-14 를 실험해 CASE 로 전환한다는 경계 선언",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-memory-address-translation",
|
|
"reason": "이 부가 무엇까지 확정하고 무엇을 확정하지 않는지를 그은 문장이라 개념의 missing-verification 이 그대로 받는다. CPU 부의 §28 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-89-part-scope-and-experiment-goals",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#89-문서-목적"
|
|
],
|
|
"summary": "제3부가 다루는 범위 — Guest 애플리케이션의 요청이 Guest Kernel · virtio-net · virtqueue · vhost-net · TAP · Bridge/Routing · Physical NIC 를 거쳐 나가고 돌아오는 구조 — 와 그 위에서 검증하려는 Keycloak 멀티 노드 · 동일 Refresh Token 동시 갱신 · 세션 상태 공유 · Host Nginx → VM → K3s → Keycloak 요청 경로 일곱 항목",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "이 부가 무엇을 다루고 무엇을 다루지 않는지의 선언이다. 따로 떼면 아무 것도 설명하지 않는 목차가 되고, 개념의 classification 과 missing-verification 이 그대로 받는다. CPU 부의 §28 과 메모리 부의 §88 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-90-virsh-libvirt-virtio-are-different-things",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#90-virsh-libvirt-virtio-구분"
|
|
],
|
|
"summary": "virsh 는 libvirt 에 관리 명령을 넣는 CLI 이고 packet datapath 에 직접 참여하지 않는다 · libvirt 는 VM lifecycle 과 NIC/network configuration 을 관리한다 · virtio 는 명령어도 단일 프로그램도 단일 커널 모듈도 아니라 Guest 와 Host/Hypervisor 사이의 표준 인터페이스다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§121 이 virsh · libvirt · virtio 셋을 CONCEPT 의 포함 범위 첫 줄에 넣었다. 셋의 구분은 경로의 어느 자리가 관리이고 어느 자리가 datapath 인지를 가르는 도입부라 개념 밖에 두면 §105 의 control/data path 절이 시작할 자리를 잃는다"
|
|
},
|
|
{
|
|
"id": "SSOT-91-virtio-net-is-split-across-guest-and-host",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#91-virtio-net은-정확히-어디에-있는가"
|
|
],
|
|
"summary": "virtio-net 은 한 자리에 있는 하나의 프로세스가 아니다. Guest 측에 TCP/IP Stack · virtio-net Frontend Driver · virtqueue 가 있고 Host 측에 QEMU virtio-net Device Model · vhost-net · TAP · Bridge/Routing/NAT · Physical NIC Driver 가 있다. virtio 는 특정 커널 계층이 아니라 frontend 와 backend 사이의 I/O 계약이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "개념이 서 있는 문장이다. 이 한 줄을 떼면 뒤의 §103~§109 가 「누가 무엇을 처리하는가」를 물을 수 없다. 독립 기록으로 만들면 경로의 정거장 배치도만 담은 글이 하나 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-92-frontend-and-backend",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#92-frontend와-backend"
|
|
],
|
|
"summary": "Frontend 는 Guest Kernel 의 virtio-net driver, Backend 는 Guest 가 넘긴 packet buffer 를 Host 쪽에서 처리하는 구현이고 backend 는 QEMU userspace 이거나 vhost-net kernel backend 다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§91 이 그은 분할에 이름을 붙인 절이다. 두 절을 떼어 두 기록으로 만들면 어느 쪽도 혼자 읽히지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-93-guest-sees-a-nic-not-qemu",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#93-guest-os는-왜-qemu가-아니라-virtio-net을-사용하는가"
|
|
],
|
|
"summary": "Guest 는 「QEMU 를 호출한다」가 아니라 「내 NIC 를 쓴다」로 동작한다. QEMU 가 Virtual PCI Bus 에 virtio NIC 를 노출하면 Guest Linux 가 virtio device 를 발견해 driver 를 bind 하고 ens3/eth0 형태의 interface 가 생긴다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "물리 서버의 경로와 VM 의 경로를 나란히 놓아 frontend 가 왜 Guest 안에 있어야 하는지를 보이는 절이다. 개념의 도입 절로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-94-121-125-packet-path-as-one-concept",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#94-전체-네트워크-계층",
|
|
"final/document.md#121-이-ssot에서-파생될-concept",
|
|
"final/document.md#125-최종-기준-구조"
|
|
],
|
|
"summary": "virtio-net + vhost-net + TAP + Linux Bridge 를 기준으로 한 수신·송신 양방향 전체 계층과, 그 요소들이 하나의 packet 실행 경로를 설명하므로 하나의 CONCEPT 로 관리한다는 §121 의 지시, 그리고 §125 가 다시 그린 Control/Setup 경로와 vhost-net·QEMU backend 두 Data Path",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§121 이 이 요소들을 하나의 CONCEPT 로 관리하라고 적었고 §125 가 같은 경로를 최종 기준 구조로 다시 그렸다. 경로 중간을 잘라 내면 packet 이 어디서 와서 어디로 가는지 말할 수 없어 독립성 검사를 통과한다. 제3부에서 유일하게 독립 개념이 되는 후보다"
|
|
},
|
|
{
|
|
"id": "SSOT-94-baseline-structure-is-one-of-many",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#94-전체-네트워크-계층"
|
|
],
|
|
"summary": "이 문서가 기준으로 삼은 것은 가장 기본적인 virtio-net + vhost-net + TAP + Linux Bridge 구조이고, 실제 환경은 Bridge · NAT · Routed Network · macvtap · SR-IOV · VFIO passthrough · Open vSwitch · Kubernetes CNI 에 따라 달라질 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "개념이 무엇을 기준으로 쓴 글인지를 밝히는 문장이라 basis-version 이 받는다. 따로 떼면 「이 문서가 안 다루는 구성 목록」만 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-95-physical-nic-hardware-is-not-the-interface-object",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#95-physical-nic의-역할"
|
|
],
|
|
"summary": "Physical NIC 는 링크와 서버를 잇는 하드웨어이고 Host Kernel 의 NIC driver 가 그것을 제어해 Linux 가 network interface 로 노출한다. Physical NIC hardware 와 Linux interface object 는 같지 않다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로의 마지막 정거장 설명이다. 하드웨어와 interface object 의 구분 한 줄만으로는 독립 기록이 되지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-96-linux-bridge-is-an-l2-software-switch",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#96-linux-bridge의-역할"
|
|
],
|
|
"summary": "Linux Bridge 는 Host Kernel 안의 L2 software switch 로 Ethernet frame 의 Destination MAC 을 보고 port 를 고른다. L2 forwarding · MAC learning · 여러 virtual/physical port 연결이 역할이고 `bridge link` · `bridge fdb show` · `ip link show type bridge` 로 본다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로 위 정거장 하나의 역할이다. §97·§98 과 나란히 놓여야 「이 셋 중 어느 구조인가」라는 물음이 성립하므로 셋을 흩으면 물음이 사라진다"
|
|
},
|
|
{
|
|
"id": "SSOT-97-routing-is-l3-not-l2",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#97-routing의-역할"
|
|
],
|
|
"summary": "Routing 은 Bridge 와 달리 L3 이고 IP 기반이며 서로 다른 IP network 를 잇는다. destination IP 를 보고 interface 나 next-hop 을 고르고 `ip route` 로 본다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§96 과 짝을 이루는 대비 절이다. 개념 본문의 표 한 행이 될 것을 기록으로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-98-tell-bridge-routing-and-nat-apart",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#98-nat의-역할"
|
|
],
|
|
"summary": "NAT 은 packet 의 IP/Port 를 바꾸고 VM 이 private subnet 을 쓰면 Host 가 NAT gateway 처럼 동작할 수 있다. 따라서 VM network 를 분석할 때 Bridge 기반인가 · Routing 기반인가 · NAT 기반인가를 먼저 구분해야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "구분해야 한다는 요구 자체는 개념이 안고, 이 Host 가 셋 중 어느 것인지는 §122 OQ-1 이 받아 question 글감이 되었다. 규칙과 그 규칙이 낳은 물음을 같은 자리에 두 번 적지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-99-tap-is-the-host-side-attach-point",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#99-tap의-역할"
|
|
],
|
|
"summary": "TAP 은 물리 장치가 아니라 Host Linux Kernel 이 제공하는 가상 Ethernet interface(tap0 · vnet0)이고 VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점이다. `ip link` · `ip tuntap show` · `bridge link` · `virsh domiflist <domain>` 로 본다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로가 Guest 를 떠나 Host 로 넘어오는 자리의 설명이다. 이 interface 가 이 Host 에서 무엇인지는 §122 OQ-2 가 따로 묻는다"
|
|
},
|
|
{
|
|
"id": "SSOT-100-virtqueue-is-a-descriptor-shared-queue",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#100-virtqueue의-역할"
|
|
],
|
|
"summary": "virtqueue 는 NIC 도 Linux network interface 도 아니고 Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 shared queue 다. 네트워크에서는 TX(Guest → Host)와 RX(Host → Guest)를 쓰고, packet payload 를 매번 userspace API 호출로 넘기는 대신 Guest memory buffer 와 descriptor 를 공유·참조하도록 설계되어 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로의 한 정거장이자 §110·§112 가 말하는 최적화가 걸리는 자리다. 떼어 내면 무엇과 무엇 사이의 queue 인지 말할 수 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-101-guest-tcp-ip-stack-is-real",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#101-guest-tcp-ip-stack의-역할"
|
|
],
|
|
"summary": "Guest TCP/IP Stack 은 Guest Linux Kernel 의 실제 network stack 이다. Socket · TCP · UDP · IP · Routing · Neighbor/ARP · Firewall · Network Driver 가 Guest 안에 그대로 있고 VM 이라고 stack 이 가짜인 것이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로의 Guest 쪽 절반이다. 하위 절 넷(Socket · TCP · IP · Ethernet)은 일반 Linux network stack 설명이라 이 개념 밖에서 독립 기록이 될 자리가 없다"
|
|
},
|
|
{
|
|
"id": "SSOT-102-keycloak-only-sees-a-socket",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#102-packet이-keycloak까지-올라오는-과정"
|
|
],
|
|
"summary": "Ethernet Frame → IP Packet → TCP Segment → Socket → HTTP → Keycloak 순으로 올라오고, Keycloak 은 virtqueue · vhost-net · TAP · Bridge · Physical NIC 를 직접 알 필요 없이 Guest Linux 가 준 TCP socket 위에서 HTTP 를 처리한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로의 끝이자 §120 이 「애플리케이션 증상과 network 계층을 갈라야 한다」고 말할 때 근거로 삼는 문장이다. 개념의 마지막 절로 들어가고 Reference 쪽에서는 source 로 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-103-qemu-device-model-has-two-roles",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#103-qemu-virtio-device-model의-역할"
|
|
],
|
|
"summary": "QEMU 의 virtio Device Model 은 Host Userspace 의 QEMU process 안에 있고 역할이 둘이다 — 장치 생성/설정/관리(device 노출 · feature negotiation · virtqueue 설정 · backend 연결)와 실제 packet datapath 처리. datapath 는 QEMU backend 를 직접 쓰는 경우와 vhost-net 을 쓰는 경우로 갈린다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§104·§106·§108 이 되풀이해 교정하는 오해의 근원이 이 두 역할을 하나로 본 것이다. 네 절이 같은 결론(관리 주체와 packet 처리 주체는 다르다)에 닿으므로 개념 안의 한 절이지 네 편이 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-104-do-not-generalize-tap-vhost-qemu-virtqueue",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#104-왜-tap-→-vhost-net-→-qemu-→-virtqueue-라고-일반화하면-안-되는가"
|
|
],
|
|
"summary": "`TAP → vhost-net → QEMU → virtqueue` 를 모든 환경의 일반적인 packet 경로로 그리면 안 된다. vhost-net 의 목적 하나가 datapath 에서 QEMU userspace 를 우회하는 것이라 fast path 는 `TAP → vhost-net → virtqueue → Guest` 로 이해한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§124 의 Claim 9 와 같은 문장이고 §103 이 나눈 두 역할의 따름정리다. 개념이 그리는 그림이 어떤 그림이 아닌지를 못박는 절이라 그 그림과 같은 글에 있어야 한다"
|
|
},
|
|
{
|
|
"id": "SSOT-105-control-path-vs-data-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#105-control-path와-data-path"
|
|
],
|
|
"summary": "Control/Setup Path 는 virsh → libvirt → QEMU → virtio-net Device Model 로 이어져 feature negotiation · virtqueue setup · vhost-net setup 을 하고, Data Path 는 packet 이 반복해 흐르는 경로다. 여기서 control 은 Kubernetes Control Plane 이 아니라 일반적인 설정/제어 경로를 뜻한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "경로를 둘로 가르는 축이다. 축을 떼면 §90 의 virsh/libvirt 와 §94 의 packet 계층이 한 그림에 놓일 이유가 없어진다"
|
|
},
|
|
{
|
|
"id": "SSOT-106-device-owner-is-not-the-per-packet-processor",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#106-qemu가-userspace인데-packet이-qemu를-안-거칠-수-있는-이유"
|
|
],
|
|
"summary": "장치의 생성/관리 주체라는 것과 모든 packet 의 runtime datapath 를 처리한다는 것은 다르다. QEMU 가 vCPU 를 만든다고 Guest 의 ADD·MOV·SUB 를 전부 QEMU 가 실행하지 않는 것처럼, QEMU 가 virtual NIC 를 만든다고 packet 을 하나씩 처리해야 하는 것은 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "CPU 가상화와의 비유로 §103 의 두 역할을 다시 설명한 절이다. 이 비유는 cpu-virtualization 의 개념을 relations 로 가리키는 다리가 되고, 따로 떼면 비유만 남는다"
|
|
},
|
|
{
|
|
"id": "SSOT-107-vhost-net-moves-the-hot-path-into-the-kernel",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#107-vhost-net-최적화"
|
|
],
|
|
"summary": "QEMU userspace 가 packet 마다 I/O 를 처리하면 kernel ↔ userspace 전환 비용이 쌓이고 packet rate 가 높아질수록 transition · scheduling · copy · notification 비용이 커질 수 있다. vhost-net 은 hot path 를 kernel backend 로 옮겨 그 비용을 줄인다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "개념이 설명하는 두 datapath 가운데 하나의 존재 이유다. 이 Host 에서 그 차이가 실제로 보이는지는 §122 OQ-4 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-108-vhost-net-does-not-remove-qemu",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#108-vhost-net은-qemu를-제거하지-않는다"
|
|
],
|
|
"summary": "vhost-net 을 써도 QEMU 는 VM lifecycle · virtual hardware model · virtio device 생성 · feature negotiation · queue configuration · backend 연결 · device reset · control/configuration 처리를 계속 맡는다. vhost-net 은 QEMU 제거가 아니라 반복적인 virtio packet datapath 의 상당 부분을 Host Kernel 로 offload 하는 것이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§124 의 Claim 16 과 같은 문장이고 §103 의 역할 A 가 남아 있음을 확인하는 절이다. §104 와 같은 오해를 반대편에서 막는 것이라 같은 글에 있어야 짝이 맞는다"
|
|
},
|
|
{
|
|
"id": "SSOT-109-fast-path-and-control-slow-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#109-fast-path와-slow-control-path"
|
|
],
|
|
"summary": "Fast Path 는 빈번히 반복되는 packet forwarding/data transfer 경로(TAP → vhost-net → virtqueue)이고 Control/Slow Path 는 device 초기화 · feature negotiation · queue setup · configuration change · device reset 처럼 빈도가 낮은 설정/예외 처리다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§105 의 축에 빈도라는 이름을 붙인 절이다. 두 절이 같은 결론에 닿으므로 개념 안의 한 절로 합친다"
|
|
},
|
|
{
|
|
"id": "SSOT-110-not-always-zero-copy",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#110-data-copy-최적화"
|
|
],
|
|
"summary": "virtio/virtqueue/vhost 구조는 buffer descriptor 로 불필요한 copy 와 context switch 를 줄이도록 설계되어 있지만 항상 zero-copy 라고 일반화하면 안 된다. 실제 copy 여부는 kernel version · QEMU version · vhost configuration · offload · NIC capability · packet path · GSO/GRO/TSO 에 따라 달라질 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§121 이 CONCEPT 포함 범위에 넣은 최적화 항목이고, 「항상 그렇다」로 굳히면 안 된다는 단서다. 단서 하나로는 독립 기록이 되지 않고 개념의 한 절로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-111-notification-batching-and-moderation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#111-interrupt-notification-최적화"
|
|
],
|
|
"summary": "Guest 와 Host 는 queue 에 새 packet/buffer 가 있음을 서로 알려야 하고, packet 마다 과도한 interrupt/notification 이 나면 overhead 가 커질 수 있어 batching · interrupt moderation · queueing 이 중요하다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "virtqueue 절의 이어지는 설명이다. §122 의 어떤 OQ 도 이것만 따로 재지 않으므로 개념 안에 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-112-multi-queue",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#112-multi-queue-최적화"
|
|
],
|
|
"summary": "queue 하나만 쓰면 특정 vCPU/처리 경로에 부하가 몰릴 수 있어 virtio-net 은 multi-queue 를 쓸 수 있다. RX Queue 를 vCPU 에 나눠 packet processing 을 병렬화하고 single queue bottleneck 을 줄이는데, 효과는 workload · CPU affinity · IRQ placement · queue configuration 에 따라 달라진다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "구조 설명은 개념이 안고, 이 Host 의 virtio-net 에 실제로 켜져 있는지는 §122 OQ-5 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-113-offload-optimizations",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#113-offload-최적화"
|
|
],
|
|
"summary": "TSO · GSO · GRO · Checksum Offload 는 작은 packet 을 하나씩 처리하는 CPU overhead 와 segmentation/aggregation 비용을 줄인다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§121 이 포함 범위에 넣은 최적화 항목이라 개념 본문의 목록으로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-113-117-6-offload-distorts-packet-capture",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#113-offload-최적화",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-6"
|
|
],
|
|
"summary": "offload 가 켜져 있으면 tcpdump 에서 보이는 packet size 나 checksum 이 실제 wire 에서 보이는 것과 다르게 보일 수 있다. §117.6 은 packet capture 가 예상과 다르게 보이는 원인 후보로 GSO · GRO · TSO · Checksum offload 를 든다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:bisect-the-packet-path-with-capture-points",
|
|
"reason": "계층마다 capture 해서 끊긴 자리를 가르는 규칙이 스스로 안고 있어야 하는 예외다. 이 단서 없이 capture 결과를 읽으면 정상 동작을 이상으로 읽는다"
|
|
},
|
|
{
|
|
"id": "SSOT-114-bridge-does-not-always-traverse-host-l3",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#114-linux-bridge가-항상-host-tcp-ip-stack을-거치는-것은-아니다"
|
|
],
|
|
"summary": "Bridge 가 단순 L2 forwarding 을 하는 경우 frame 이 반드시 Host 의 일반적인 L3 TCP/IP stack 을 거치는 것은 아니다(VM1 TAP → Bridge → VM2 TAP). Routing · NAT · Host-local termination · Firewall 이 걸리면 L3/Netfilter 경로가 개입하므로 `Physical NIC → Host TCP/IP Stack → Bridge` 를 고정된 packet path 로 보면 안 된다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§104 와 같은 종류의 교정이고 경로가 구성에 따라 달라진다는 개념의 결론이다. 동시에 capture 결과를 읽는 예외이기도 해서 Reference 쪽에서는 source 로 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-115-host-nic-does-not-go-through-virtio-again",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#115-host-physical-nic로-나갈-때-virtio를-다시-거치지-않는다"
|
|
],
|
|
"summary": "Host Physical NIC 로 나갈 때 virtio 를 다시 거치는 것이 아니라 Physical NIC 의 실제 driver 를 쓴다. virtio 는 Guest virtual I/O device 와 Host backend 사이의 인터페이스이지 Host 쪽에도 한 벌 더 있는 계층이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§124 의 Claim 13 과 같은 문장이고 §91 의 「virtio 는 I/O 계약이다」가 경로 끝에서 다시 확인되는 자리다. 개념의 마지막 교정 절로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-116-test-environment-packet-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#116-현재-keycloak-k3s-테스트-환경과-연결"
|
|
],
|
|
"summary": "이 테스트 환경의 경로를 Client → Host Physical NIC → Host Nginx → Host Network → VM1/VM2 → K3s → Keycloak 으로 놓고, VM network 까지 펼치면 Bridge/Route/NAT → TAP(vm1)/TAP(vm2) → vhost-net → virtqueue → virtio-net → Guest Network Stack → K3s networking → Keycloak 이 된다는 서술",
|
|
"disposition": "NEEDS_EVIDENCE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "이 그림의 앞부분(Host Nginx 아래 VM 두 대에 K3s/Keycloak)은 §89 가 밝힌 실험 구성이지만, 펼친 뒷부분은 이 Host 가 Bridge 인지 NAT 인지도(OQ-1) TAP 이 무엇인지도(OQ-2) vhost-net 을 쓰는지도(OQ-3) 확인하기 전의 가정이다. 「이 환경에서 실제로 그러하다」는 주장이라 재기 전에는 Case 도 Concept 도 아니다. OQ-1·2·3·6 이 답하면 다시 판정한다. CPU 부의 SSOT-22-claims-12-13 과 같은 처분이다"
|
|
},
|
|
{
|
|
"id": "SSOT-117-1-3-connectivity-failures",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-1",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-2",
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-3"
|
|
],
|
|
"summary": "TAP/Bridge 연결 오류(VM 외부 통신 불가 · Host ↔ VM 통신 불가 · 특정 VM 만 통신 불가) · Routing 오류(같은 subnet 은 되는데 다른 subnet 은 안 됨 · gateway 까지는 되고 외부는 실패) · NAT/Firewall 오류(VM → Internet 실패 · 외부 → VM 접근 실패 · 특정 port 만 실패)와 각각의 확인 명령",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:bisect-the-packet-path-with-capture-points",
|
|
"reason": "증상 셋 모두가 「어느 hop 에서 끊겼는가」로 환원되고 §119 의 계층별 capture 가 그것을 가른다. 셋을 따로 기록으로 만들면 같은 규칙의 부분 증상이 셋이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-117-4-vhost-net-unused-or-inefficient-datapath",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-4"
|
|
],
|
|
"summary": "높은 packet rate 에서 QEMU userspace 가 datapath 를 직접 처리하면 CPU overhead 가 커질 수 있고, 관찰 대상은 QEMU CPU usage · vhost thread · packet rate · latency · context switch 다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§107 이 말한 비용이 구조에서 어긋나는 자리로 다시 나온 것이다. 개념의 「이 구조에서 어긋날 수 있는 자리」 절로 들어가고, 이 Host 에서 실제로 그런지는 OQ-3·OQ-4·OQ-7 이 받는다. CPU 부의 §24 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-117-5-single-queue-bottleneck",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-5"
|
|
],
|
|
"summary": "queue/vCPU 하나에 packet processing 이 몰릴 수 있고 확인 대상은 virtio multi-queue · IRQ distribution · per-vCPU CPU usage · RSS/RPS/XPS 다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "§112 와 같은 결론에 닿는 절이라 개념 안에서 같은 자리에 놓인다. 이 Host 의 상태는 OQ-5 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-117-7-host-cpu-contention-looks-like-network-latency",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#117-이-구조에서-발생할-수-있는-문제-117-7"
|
|
],
|
|
"summary": "vhost-net · QEMU thread · softirq 도 Host CPU 를 쓰므로 network 문제처럼 보여도 CPU scheduling 문제일 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:verify-the-network-path-before-blaming-the-application",
|
|
"reason": "증상을 어느 계층에 귀속할지의 규칙이고 §120 과 방향만 반대다(하나는 애플리케이션 증상을 network 로, 하나는 network 증상을 CPU 로 되돌린다). 같은 Reference 의 적용 조건과 예외로 들어가고, 재는 것은 OQ-7 이 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-118-per-layer-observation-commands",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#118-실제-linux에서-확인할-명령어"
|
|
],
|
|
"summary": "Physical NIC · Linux Bridge · TAP/vnet · libvirt VM NIC · libvirt network · Routing · Guest NIC · virtio 장치 · vhost 아홉 자리를 보는 명령 목록 — `ip link` · `ethtool` · `bridge link` · `bridge fdb show` · `ip tuntap show` · `virsh domiflist` · `virsh net-list --all` · `virsh net-info` · `virsh net-dumpxml` · `ip route` · `ip rule` · `ip neigh` · `lspci` · `lsmod | grep virtio` · `lsmod | grep vhost`",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:bisect-the-packet-path-with-capture-points",
|
|
"reason": "명령 목록 자체는 규칙이 아니다. §119 의 규칙이 각 지점에서 무엇을 실행할지를 이 목록이 대므로 그 Reference 의 본문 표가 된다. CPU 부의 §14 는 붙일 Reference 가 없어 개념으로 갔지만 여기는 있다"
|
|
},
|
|
{
|
|
"id": "SSOT-119-bisect-the-path-with-tcpdump",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#119-실제-packet-path-추적"
|
|
],
|
|
"summary": "Host 의 physical NIC · bridge · tap/vnet 과 Guest 의 interface 에서 각각 `tcpdump -ni` 를 걸어 어디까지 보이는지로 의심 구간을 좁힌다 — Physical NIC O · Bridge O · TAP X 이면 Host Bridge/TAP mapping 을, TAP O · Guest NIC X 이면 virtio/vhost/Guest NIC 계층을, Guest NIC O · Socket X 이면 Guest routing/firewall/listen 상태를 의심한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:bisect-the-packet-path-with-capture-points",
|
|
"reason": "원 사건의 이름을 지워도 규칙이 남는다 — KVM/libvirt 환경이면 어디서든 같은 순서로 구간을 좁힌다. §117.1~.3 의 증상 셋과 §118 의 명령 목록이 이 규칙의 적용 대상과 도구이고, §113·§114 가 예외를 댄다. OQ-1 · OQ-2 · OQ-6 셋이 모두 이 규칙 위에서 돌아가므로 세 글에 되풀이하지 않고 한 편으로 두고 가리킨다. 메모리 부의 §85·§86 이 세운 기준을 따랐다"
|
|
},
|
|
{
|
|
"id": "SSOT-120-verify-the-network-path-separately",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#120-keycloak-refresh-token-실험과의-관계"
|
|
],
|
|
"summary": "Refresh Token 경쟁 자체는 virtio-net 문제가 아니지만 Client → Nginx → VM1/VM2 → K3s → Keycloak → PostgreSQL/Redis 경로를 공유하므로 network virtualization 문제가 실험 결과에 영향을 줄 수 있다. Node1 요청만 지연 · VM2 packet loss · Host bridge misconfiguration · NAT/conntrack issue · Host CPU contention 으로 인한 vhost 처리 지연을 Refresh Token 경쟁이나 DB lock 으로 오해하지 않도록 network path 를 별도로 검증한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:verify-the-network-path-before-blaming-the-application",
|
|
"reason": "이 부가 존재하는 이유(§89)와 결론(§124 Claim 17)을 잇는 규칙이고, 다음 프로젝트에도 그대로 적용된다 — 경로를 공유하는 실험에서 애플리케이션·저장소 원인으로 결론내기 전에 공유 계층을 따로 검증한다. §119 의 규칙은 network 안에서 어느 hop 인지를 가르고 이 규칙은 그것이 network 인지 아닌지를 가르므로 둘은 다른 물음에 답한다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-1-vm-network-mode-bridge-nat-or-routed",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-1"
|
|
],
|
|
"summary": "OQ-1. 현재 VM network 는 Bridge · NAT · Routing 중 어떤 구조인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm-network-mode-bridge-nat-or-routed",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-2-tap-interface-to-vm-mapping",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-2"
|
|
],
|
|
"summary": "OQ-2. VM1/VM2 의 TAP/vnet interface 는 무엇인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:tap-interface-to-vm-mapping",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-3-is-vhost-net-actually-in-use",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-3"
|
|
],
|
|
"summary": "OQ-3. 현재 환경에서 vhost-net 이 실제 사용되는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:is-vhost-net-actually-in-use",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-4-qemu-backend-vs-vhost-net-on-this-host",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-4"
|
|
],
|
|
"summary": "OQ-4. QEMU backend 와 vhost-net 의 성능 차이가 현재 Host 에서 관찰 가능한가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:qemu-backend-vs-vhost-net-on-this-host",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-5-virtio-net-multi-queue-enabled",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-5"
|
|
],
|
|
"summary": "OQ-5. Multi-queue 가 현재 virtio-net 에 활성화되어 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:virtio-net-multi-queue-enabled",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-6-actual-packet-path-nginx-to-keycloak",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-6"
|
|
],
|
|
"summary": "OQ-6. Host Nginx 에서 VM1/VM2 Keycloak 까지 실제 packet path 는 무엇인가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:actual-packet-path-nginx-to-keycloak",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-122-oq-7-network-virtualization-cpu-cost-under-load",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#122-open-question-oq-7"
|
|
],
|
|
"summary": "OQ-7. Keycloak load test 시 network virtualization 이 latency 에 영향을 줄 정도로 Host CPU 를 사용하는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:network-virtualization-cpu-cost-under-load",
|
|
"reason": "§122 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고 답에 따라 이 부의 서술이 이 Host 에 적용되는지가 갈리며 §122 가 확인 명령이나 관찰 대상을 함께 적어 다음 검증이 있다. 앞선 두 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-123-oq-to-case-flow",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#123-open-question-→-case"
|
|
],
|
|
"summary": "SSOT → CONCEPT → OPEN QUESTION → 실제 packet capture/configuration 확인/load test → CASE 로 이어지는 기록 흐름과 vhost-net 예시",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "네트워크 가상화가 아니라 이 저장소가 기록을 잇는 방식을 설명한 절이다. 분석에는 남아야 하고 공개 기록으로는 읽을 사람이 없다. CPU 부의 §21 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-124-claims-1-16",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#124-핵심-claim"
|
|
],
|
|
"summary": "Claim 1~16 — virsh 는 datapath 에 참여하지 않는다 · libvirt 는 lifecycle/config 를 관리한다 · virtio 는 단일 프로세스나 모듈이 아닌 표준이다 · frontend 는 Guest Kernel 에 있다 · QEMU Device Model 은 생성/negotiation/lifecycle 을 맡는다 · virtqueue 는 descriptor 기반 shared queue 다 · vhost-net 이 없으면 QEMU userspace 가 backend 다 · vhost-net 은 datapath 상당 부분을 Host Kernel 로 옮긴다 · 그러므로 TAP → vhost-net → QEMU → virtqueue 로 일반화하면 안 된다 · TAP 은 Host-side 접점이다 · Bridge 는 L2, Routing 은 L3 다 · Physical NIC 로 나갈 때 virtio 를 다시 거치지 않는다 · Guest TCP/IP Stack 은 실제 stack 이다 · Keycloak 은 socket 만 안다 · vhost-net 의 목적은 QEMU 제거가 아니라 offload 다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-packet-path-to-physical-nic",
|
|
"reason": "열여섯 전부가 메커니즘 서술이고 §90~§115 가 이미 본문으로 말한 것을 한 화면으로 접은 것이다. 「이 환경에서 실제로 그러하다」고 주장한 것이 없어 NEEDS_EVIDENCE 로 남길 것도 없다. 개념 본문의 요약 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-124-claim-17-network-and-token-race-look-alike",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#124-핵심-claim"
|
|
],
|
|
"summary": "Claim 17 — Network virtualization 문제와 Keycloak Refresh Token 경쟁 문제는 별개지만 같은 실험 환경에서 서로 비슷한 증상으로 보일 수 있으므로 계층별 관측이 필요하다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:verify-the-network-path-before-blaming-the-application",
|
|
"reason": "열일곱 중 유일하게 메커니즘이 아니라 판독 규칙이다. §120 이 본문으로 말한 것의 결론 문장이라 그 Reference 의 한 줄로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-126-next-practice-order",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#126-다음-실습-순서"
|
|
],
|
|
"summary": "Physical NIC 확인부터 multi-queue/offload 확인까지 열두 단계의 실습 순서와, 검증되지 않은 항목은 OPEN QUESTION 으로 남기고 결과가 나오면 CASE 로 전환한다는 원칙, 그 다음 K3s/CNI/Service/Pod network 계층을 잇는다는 계획",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "다음에 무엇을 어떤 순서로 잴지의 진행 계획이다. 계획은 실행되면 Case 가 되고 그 전까지는 분석에 남는다. CPU 부의 §23 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-128-139-guest-block-io-path",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#128-전체-구조",
|
|
"final/document.md#129-guest-application-read-write-에서-시작",
|
|
"final/document.md#134-guest-block-i-o-layer",
|
|
"final/document.md#137-virtio-blk-guest의-가상-block-device-driver",
|
|
"final/document.md#138-virtio-blk와-virtqueue"
|
|
],
|
|
"summary": "§128 이 그린 canonical flow 의 Guest 절반 — 애플리케이션의 `write()` 가 VFS · ext4/XFS · Guest Page Cache · Guest Block Layer · `/dev/vda` · virtio-blk Frontend 를 거쳐 virtqueue 에 실린다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로 중간을 잘라 내면 인과가 끊긴다 — Page Cache 만 떼면 `write()` 성공이 왜 SSD 영속화가 아닌지 말할 수 없고, virtqueue 만 떼면 무엇과 무엇 사이의 queue 인지 말할 수 없다. 독립성 검사를 통과하고, 제4부에서 경로가 시작하는 구간이라 나머지 셋(backend 형태 · 완료의 뜻 · Host block stack)이 이 글을 딛고 갈린다"
|
|
},
|
|
{
|
|
"id": "SSOT-140-142-what-is-behind-dev-vda",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#140-vm-boundary를-넘으면-qemu가-등장",
|
|
"final/document.md#141-qemu가-물리-ssd를-직접-제어하는-것은-아니다",
|
|
"final/document.md#142-qcow2-host에서는-파일-guest에서는-디스크"
|
|
],
|
|
"summary": "VM 경계를 넘으면 QEMU 의 virtio-blk Device Model 과 Block Backend 가 받고, backend 가 파일이면 QEMU 는 Host Linux 에 파일 I/O 를 요청하므로 Guest storage stack 아래에 Host storage stack 이 한 번 더 존재할 수 있다. 같은 대상이 Host 에서는 파일 하나이고 Guest 에서는 디스크다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:qemu-block-backend-forms",
|
|
"reason": "이 구간에서만 경로가 셋(qcow2 · RAW · Host block device)으로 분기하고, 갈래마다 결과가 다르다 — virtual size 와 실제 할당량의 차이 · mapping/metadata 처리 · Host filesystem 이 한 겹 더 있는지. 경로를 그리는 C1 에 넣으면 세 갈래의 결과가 한 글의 각주가 된다. §128 이 핵심 문장으로 뽑은 것이 이 분기다"
|
|
},
|
|
{
|
|
"id": "SSOT-147-157-completion-and-cache-boundaries",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#147-vm에서는-page-cache가-두-번-나타날-수-있다",
|
|
"final/document.md#148-write-완료와-영속화는-다르다",
|
|
"final/document.md#149-direct-i-o",
|
|
"final/document.md#150-fsync-가-필요한-이유",
|
|
"final/document.md#151-flush",
|
|
"final/document.md#152-가장-위험한-상황-거짓-완료"
|
|
],
|
|
"summary": "Page Cache 가 Guest 와 Host 양쪽에 두 번 나타날 수 있고, `write()` 완료 ≠ writeback 완료 ≠ fsync/flush 완료 ≠ 전원 장애에도 안전한 durability 이며, Guest 에게 거짓 완료를 응답하는 것은 성능 문제가 아니라 correctness 문제다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "C1·C2·C4 가 「데이터가 어디를 지나는가」를 말한다면 이 글은 「완료라는 응답이 무엇을 보장하는가」를 말하므로 물음이 다르다. 없애고 경로 글의 한 절로 넣으면 §148 의 네 경계와 §152 의 correctness 판정이 각주가 되고, cache mode 를 고르는 사람이 다시 찾지 못한다"
|
|
},
|
|
{
|
|
"id": "SSOT-158-167-host-block-stack",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#158-host-block-layer",
|
|
"final/document.md#159-여러-vm이-하나의-nvme를-공유하면",
|
|
"final/document.md#160-blk-mq-multi-queue-block-layer",
|
|
"final/document.md#161-i-o-scheduler",
|
|
"final/document.md#164-nvme-driver와-physical-device",
|
|
"final/document.md#167-storage-contention"
|
|
],
|
|
"summary": "Host Block Layer 는 그 I/O 가 VM 에서 왔는지 Host process 에서 왔는지 본질적으로 구분해 처리하는 계층이 아니라 모두 Host block request 이고, `blk-mq` 와 I/O Scheduler 와 NVMe Driver 를 지나며, 여러 VM 이 한 device 를 쓰면 Storage Contention 이 생긴다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "backend 형태를 말하는 C2 아래에서 요청이 어떻게 줄을 서고 누구와 섞이는지는 다른 물음이다. §158 의 「모두 Host block request 다」가 §167 의 경쟁을 낳고, 그 경쟁은 이 계층을 설명하지 않으면 읽히지 않는다. OQ-5 · OQ-6 · OQ-7 셋이 이 글 위에서 돌아간다"
|
|
},
|
|
{
|
|
"id": "SSOT-168-cpu-is-fine-but-storage-is-slow",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#168-cpu가-정상이어도-storage-때문에-느릴-수-있다"
|
|
],
|
|
"summary": "PostgreSQL 이 storage completion 을 기다리면 CPU usage 가 높지 않을 수 있어 CPU 30% 인데 request latency 2초 가 가능하므로 CPU 지표만으로 latency 원인을 판단하면 안 된다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:read-storage-before-blaming-cpu-for-latency",
|
|
"reason": "원 프로젝트의 이름을 지워도 규칙이 남는다 — DB 가 낀 경로면 어디서든 같은 순서로 자원을 가른다. §167 이 CPU Contention 과 Storage Contention 을 다른 자원 경쟁으로 갈라 적용 조건을 대고 §169 와 §177 이 무엇을 함께 볼지를 댄다. 제2부의 §85·§86 이 세운 기준을 따랐다"
|
|
},
|
|
{
|
|
"id": "SSOT-171-durability-vs-latency-tradeoff",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#171-성능과-durability의-trade-off"
|
|
],
|
|
"summary": "`fsync()` 를 없애서 빨라졌다면 그것이 최적화가 아니라 durability contract 를 제거한 것일 수 있다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:a-speedup-that-removed-durability-is-not-an-optimization",
|
|
"reason": "설정 선택과 성능 개선의 평가에 걸리는 규칙이라 개념 본문의 각주로 두면 다음에 같은 판단을 하는 사람이 찾지 못한다. §152 가 왜 성능 문제가 아닌지를, §156 이 반대 방향의 오독(writeback 이라는 이름만 보고 위험하다고 단정하는 것)을 막아 적용 조건과 예외가 둘 다 SSOT 안에 있다"
|
|
},
|
|
{
|
|
"id": "SSOT-145-backend-cannot-be-inferred-from-the-guest",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#145-host-block-device를-직접-backend로-사용-가능"
|
|
],
|
|
"summary": "「Guest 에 `/dev/vda` 가 있다」는 정보만으로 backend 구조를 알 수 없다 — 그 아래에 qcow2 file · RAW file · Host block device 셋이 올 수 있다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:confirm-the-disk-backend-on-the-host",
|
|
"reason": "OQ-1 · OQ-2 · OQ-3 · OQ-5 넷이 모두 이 규칙 위에서 돌아가므로 네 글에 되풀이하지 않고 한 편으로 두고 가리킨다. §146 이 확정 절차를, §143·§144 가 확정하지 않고 읽었을 때 무엇을 잘못 읽게 되는지를 댄다. 제3부의 reference:bisect-the-packet-path-with-capture-points 와 같은 위치다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-1-vm-disk-backend-mapping",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-1"
|
|
],
|
|
"summary": "OQ-1. VM 의 `/dev/vda` 는 어떤 Host backend 에 연결되어 있는가",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm-disk-backend-mapping",
|
|
"reason": "§175 가 아직 돌리지 않은 확인으로 적어 둔 물음이다. 답이 없고, 답에 따라 §142~§145 중 어느 갈래가 이 Host 에 적용되는지가 갈리며, `lsblk` 와 `virsh domblklist <VM_NAME>` 라는 다음 검증이 있다. 앞선 세 부가 OPEN QUESTION 을 그대로 question 글감으로 올린 것과 같은 기준이고, 다른 부의 question 이 같은 측정으로 닫는 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-2-disk-image-format",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-2"
|
|
],
|
|
"summary": "OQ-2. Backend 는 qcow2 인가 RAW 인가",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:disk-image-format-and-actual-host-usage",
|
|
"reason": "OQ-3 과 같은 한 번의 `qemu-img info` 출력으로 닫힌다 — 형식은 그 출력의 첫 줄이고 OQ-3 이 요구한 세 값 비교의 전제다. 같은 측정으로 닫히는 물음을 두 편으로 만들지 않는다. 제2부가 OQ-1 과 OQ-10 을 한 물음으로 합친 것과 같은 판단이다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-3-disk-image-format-and-actual-host-usage",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-3"
|
|
],
|
|
"summary": "OQ-3. qcow2 Virtual Size 와 실제 Host 사용량은 얼마나 다른가 — `qemu-img info` · `du -h` · `ls -lh` 세 명령이 보여주는 의미가 서로 다를 수 있으므로 비교한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:disk-image-format-and-actual-host-usage",
|
|
"reason": "§143 이 100 GB 대 3GB 라는 예시로만 말한 차이를 이 Host 에서 확정하는 물음이다. 답이 없고, 답에 따라 저장 공간 계획과 §144 의 성능 일반화 경계가 갈리며, 세 명령이라는 다음 검증이 있다. OQ-2 를 흡수해 한 편으로 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-4-qemu-disk-cache-mode",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-4"
|
|
],
|
|
"summary": "OQ-4. QEMU disk cache mode 는 무엇인가 — `virsh dumpxml <VM_NAME>` 의 disk driver 설정에서 cache 관련 값을 확인한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:qemu-disk-cache-mode",
|
|
"reason": "§153~§156 이 두 설정의 뜻을 갈라 놓았지만 이 Host 가 무엇을 쓰는지는 적혀 있지 않다. 답에 따라 §147 의 이중 caching 이 이 환경에 있는지가 갈리고 확인 명령이 있다. 값을 어떻게 둘 것인지는 별도로 NEEDS_DECISION 에 남겼다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-5-host-block-device-under-the-disk-image",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-5"
|
|
],
|
|
"summary": "OQ-5. qcow2 가 최종적으로 어느 Host block device 위에 있는가 — `lsblk` 와 `findmnt` 로 확인한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-block-device-under-the-disk-image",
|
|
"reason": "OQ-1 이 image 경로까지 확정한다면 이 물음은 그 경로가 놓인 물리 장치까지 내려간다. 닫는 명령도 결과가 여는 물음도 다르다 — 여기서 나온 device 이름이 OQ-6 의 `<device>` 자리를 채우고 OQ-7 의 전제(두 VM 이 같은 장치를 쓰는가)를 정한다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-6-host-io-scheduler",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-6"
|
|
],
|
|
"summary": "OQ-6. Host I/O Scheduler 는 무엇인가 — `cat /sys/block/<device>/queue/scheduler`",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:host-io-scheduler",
|
|
"reason": "§161·§162 가 정책의 존재와 `none` 의 뜻을 설명했지만 이 Host 의 값은 없다. 답에 따라 OQ-7 의 해석 조건이 달라지고 §163 이 확인 명령과 읽는 법(대괄호 안이 현재 선택된 것)을 함께 적어 다음 검증이 있다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-7-vm1-storage-load-vs-vm2-latency",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-7"
|
|
],
|
|
"summary": "OQ-7. VM1 Storage load 가 VM2 latency 에 영향을 주는가 — VM1 에서 별도의 테스트 파일/디스크로 controlled I/O load 를 발생시키고 VM2 의 application latency 와 Host storage 지표를 동시에 본다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:vm1-storage-load-vs-vm2-latency",
|
|
"reason": "§167 이 구조적 가능성으로만 적은 것을 이 Host 에서 재는 물음이다. 답에 따라 장치 분리나 I/O 제한이 필요한지가 갈리고 실험 설계가 §175 에 적혀 있다. 제1부의 question:vcpu-contention-under-two-vm-load 와 부하 형태가 같지만 재는 자원이 CPU 가 아니라 storage 라 같은 측정으로 닫히지 않는다 — relations 로만 이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-175-oq-8-guest-fsync-latency-vs-host-storage-latency",
|
|
"kindCandidate": "OPEN_QUESTION",
|
|
"sourceRefs": [
|
|
"final/document.md#175-실제-테스트-서버에서-확인할-open-questions-oq-8"
|
|
],
|
|
"summary": "OQ-8. Guest `fsync()` latency 와 Host storage latency 가 같이 증가하는가 — Guest application/DB latency 와 Host `iostat` 를 시간축으로 함께 관찰한다",
|
|
"disposition": "PROMOTE",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "question:guest-fsync-latency-vs-host-storage-latency",
|
|
"reason": "§150 이 말한 전달 경로가 이 환경에서 이어지는지를 재는 물음이다. 제2부의 question:host-major-fault-vs-storage-latency 와 가장 가깝지만 그쪽은 Host memory pressure 로 유도한 major fault 가 storage 를 미는지를 보고 이쪽은 애플리케이션의 `fsync()` 가 Host storage 까지 전달되는지를 본다 — 유도 방법도 계열도 달라 같은 실행으로 닫히지 않는다. relations 로만 이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-127-part-scope-and-deferred-internals",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#127-문서-목적"
|
|
],
|
|
"summary": "제4부가 다루는 범위 — Guest 의 `write()`/`fsync()` 가 Host 물리 SSD/NVMe 까지 내려가는 하나의 일관된 경로, 그리고 VFS 부터 Storage contention 까지 열넷 — 과, qcow2 내부 L1/L2 table · blk-mq tag allocator · NVMe submission/completion queue 를 별도 문서로 미룬다는 선언",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "이 부가 무엇을 다루고 무엇을 다루지 않는지의 선언이다. 따로 떼면 아무 것도 설명하지 않는 목차가 되고, 네 개념의 basis-version 과 missing-verification 이 그대로 받는다. 제3부의 §89 와 제2부의 §88 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-129-application-does-not-touch-the-device",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#129-guest-application-read-write-에서-시작"
|
|
],
|
|
"summary": "VM 안의 PostgreSQL 이나 Keycloak 은 SSD 나 virtio-blk 를 직접 다루지 않고 `write(fd, buffer, size);` 로 Guest Linux Kernel 에 파일 연산을 요청하며, 이 시점에는 아직 QEMU · qcow2 · Host NVMe 가 등장하지 않는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로의 첫 칸이다. 한 문장으로 개념 안에 설명되므로 독립 기록이 되지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-130-vfs-routes-to-the-filesystem",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#130-vfs-공통-파일-인터페이스-계층"
|
|
],
|
|
"summary": "VFS 는 여러 filesystem 을 동일한 API 로 쓰게 하는 공통 계층이고, 이 fd 가 어떤 파일인가 → 어떤 filesystem 에 속하는가 → 해당 구현으로 연산 전달 순으로 동작한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로의 두 번째 칸이고 ext4 든 XFS 든 같은 자리를 지난다는 것을 말한다. 개념 본문의 한 절이다"
|
|
},
|
|
{
|
|
"id": "SSOT-131-132-filesystem-and-inode-map-files-onto-blocks",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#131-filesystem-ext4-xfs-파일-세계를-block-공간에-배치",
|
|
"final/document.md#132-inode"
|
|
],
|
|
"summary": "ext4/XFS 가 파일·디렉터리라는 논리 구조를 block 공간에 배치하고, inode 가 파일 metadata 와 저장 위치를 관리하며 파일 이름 자체와 inode 는 같은 것이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "§132 스스로 「inode 내부 구현까지 파고들 필요는 없지만 filesystem 이 파일과 block 을 연결한다는 점은 알아야 한다」고 범위를 그었다. 그 한 문단이 개념 안에 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-133-write-lands-in-page-cache-first",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#133-page-cache-write-가-바로-ssd-write는-아니다"
|
|
],
|
|
"summary": "buffered I/O 에서 `write()` 는 Page Cache 에 먼저 닿아 dirty page 가 되고 나중에 writeback 되므로 `write()` 성공은 Physical SSD 영속화 완료가 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로 위의 한 칸이라 C1 에 들어간다. 이 절이 던진 「완료가 무슨 뜻인가」는 §148 이 받아 concept:write-completion-is-not-durability 로 이어지므로 그 글도 이 절을 source 로 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-134-block-layer-turns-file-offsets-into-device-requests",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#134-guest-block-i-o-layer"
|
|
],
|
|
"summary": "Block I/O Layer 가 filesystem 세계의 「offset 8192 에 4KB write」를 block device 세계의 READ/WRITE/FLUSH/DISCARD 요청으로 바꾸고, 내부에는 `bio` · request · queue · `blk-mq` 가 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "두 세계를 잇는 칸이다. 내부 자료구조는 §127 이 범위 밖으로 두었으므로 개념 본문에서도 이름까지만 적는다"
|
|
},
|
|
{
|
|
"id": "SSOT-135-dev-vda-is-not-the-host-ssd",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#135-dev-vda-guest가-보는-가상-block-device"
|
|
],
|
|
"summary": "virtio-blk 를 쓰는 VM 에서는 `/dev/vda` · `/dev/vdb` 처럼 보이고 Guest Linux 는 그것을 하나의 block device 로 인식하지만 그것이 Host 의 실제 SSD 라는 뜻은 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로의 칸이면서 reference:confirm-the-disk-backend-on-the-host 가 세우는 규칙의 근거다. 개념에 흡수하고 그 Reference 가 source 로 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-136-block-device-view-and-filesystem-view",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#136-dev-vda-와-filesystem-관계"
|
|
],
|
|
"summary": "`/dev/vda` → partition → filesystem → mount point 로 이어지는 관계이고, `cd /var/lib/postgresql` 은 filesystem 세계를 보는 것이며 `lsblk` 에서 `vda` 를 보는 것은 block device 세계를 보는 것이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "두 관점의 구분이라 개념 안의 그림 한 장으로 들어간다. 독립 기록으로 두면 문단 둘인 글이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-137-driver-and-device-node-are-different-things",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#137-virtio-blk-guest의-가상-block-device-driver"
|
|
],
|
|
"summary": "`/dev/vda` 는 Guest Linux 에 보이는 block device 이고 virtio-blk 는 그 virtual block device 를 제어하는 Guest Kernel driver 다 — Network 의 `ens3` 와 virtio-net 이 같은 관계다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "이름 둘을 가르는 절이다. 개념 본문의 한 절이고, Network 대응은 §173 의 표가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-138-139-virtqueue-is-descriptors-over-guest-ram",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#138-virtio-blk와-virtqueue",
|
|
"final/document.md#139-virtqueue의-실제-의미"
|
|
],
|
|
"summary": "virtio-blk driver 가 Guest Block Layer 의 요청을 Virtio block request 로 구성해 virtqueue 에 게시하고, virtqueue 는 단순한 데이터 파이프가 아니라 Guest RAM 의 I/O buffer 를 descriptor 가 가리키는 구조이며 처리가 끝나면 backend 가 completion 을 돌려준다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "경로의 마지막 칸이다. 제3부의 concept:guest-packet-path-to-physical-nic 이 같은 구조를 packet 쪽에서 설명하므로 여기서는 storage 요청의 모양만 적고 그 글을 relations 로 가리킨다"
|
|
},
|
|
{
|
|
"id": "SSOT-166-completion-travels-back-through-virtqueue",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#166-storage-i-o-completion"
|
|
],
|
|
"summary": "WRITE 요청은 아래로 내려가고 완료는 NVMe → NVMe Driver → Host Block Layer → QEMU/backend → virtqueue completion → virtio-blk → Guest Block Layer 로 올라오므로 virtqueue 는 request 뿐 아니라 completion 전달 구조까지 포함해 이해해야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "이 절의 결론 문장이 virtqueue 를 가리키므로 C1 의 마지막 절로 들어간다. 왕복 경로 한 장을 기록 하나로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-172-177-canonical-flow-and-summary",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#172-storage-virtualization-canonical-flow",
|
|
"final/document.md#177-최종-요약"
|
|
],
|
|
"summary": "Guest Userspace 부터 Non-volatile Media 까지의 canonical flow 와 그 역방향 completion, 그리고 write 완료 ≠ writeback 완료 ≠ flush 완료 ≠ 전원 장애에도 살아남는 durability 라는 요약과 CPU usage 만 보지 말고 함께 볼 여덟 가지",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "네 개념이 나눠 설명하는 경로를 한 장으로 그린 지도다. 경로가 시작하는 C1 이 그 그림을 열면서 싣고 나머지 셋은 자기가 그림의 어느 구간인지를 가리킨다. 제2부가 §79 와 §87 을 같은 이유로 첫 개념에 흡수했다"
|
|
},
|
|
{
|
|
"id": "SSOT-173-network-storage-correspondence",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#173-network-virtualization과-비교"
|
|
],
|
|
"summary": "virtio-net ↔ virtio-blk · packet ↔ block I/O request · TX/RX virtqueue ↔ I/O virtqueue · TAP/network backend ↔ QEMU block backend · Linux Bridge/Route ↔ Host filesystem/block stack · Physical NIC ↔ Physical SSD/NVMe · Guest TCP/IP Stack ↔ Guest VFS/Filesystem/Block Layer · send/recv ↔ read/write/fsync 대응표",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:guest-block-io-path-to-virtqueue",
|
|
"reason": "제3부를 읽은 독자를 이 부로 잇는 다리다. SSOT 가 스스로 붙인 단서(학습용 대응 관계이며 각 요소가 1:1 로 같은 종류라는 뜻은 아니다)까지 표와 함께 옮긴다. 표 하나를 독립 기록으로 두면 문단 셋인 글이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-143-virtual-size-is-not-host-allocation",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#143-qcow2-virtual-size와-실제-host-사용량"
|
|
],
|
|
"summary": "qcow2 는 가상 disk size 와 실제 Host 할당량이 다를 수 있고(Guest 가 보는 100 GB 에 Host 실제 3GB), Guest 가 기록하면서 Actual 이 1GB → 10GB → 40GB 로 늘 수 있으므로 `qemu-img info vm1.qcow2` 의 `virtual size` 와 실제 allocation 을 구분해서 봐야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:qemu-block-backend-forms",
|
|
"reason": "backend 가 qcow2 일 때만 생기는 성질이라 그 갈래를 설명하는 개념 안에 들어간다. 이 Host 의 값을 재는 것은 question:disk-image-format-and-actual-host-usage 가 따로 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-144-raw-is-not-automatically-faster",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#144-raw-image"
|
|
],
|
|
"summary": "RAW 는 qcow2 보다 구조가 단순하고 qcow2 는 Copy-on-Write · sparse allocation · snapshot 에 유리하지만 metadata/mapping 처리가 있으며, 「RAW = 무조건 빠름 / qcow2 = 무조건 느림」으로 일반화하면 안 된다 — 실제 성능은 cache mode · storage backend · workload pattern · queue depth · snapshot chain · underlying filesystem · physical device 에 영향을 받는다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:qemu-block-backend-forms",
|
|
"reason": "형식 둘을 가르면서 그 구분만으로 성능을 말하지 말라고 닫는 절이다. 개념이 분기를 설명하고 끝나는 자리가 여기라 개념 본문의 마지막 절이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-174-claims-1-3-virtual-disk-and-nested-stacks",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"summary": "Claim 1~3 — Guest 의 `/dev/vda` 는 virtual block device 이고 실제 Host backend 는 qcow2 · RAW · Host block device 등이 될 수 있다 · `virtio-blk + virtqueue` 가 Guest block I/O 를 Host backend 와 연결한다 · qcow2 가 Host filesystem 위의 파일이면 Guest filesystem 아래에 Host filesystem/storage stack 이 한 번 더 존재한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:qemu-block-backend-forms",
|
|
"reason": "셋 다 메커니즘 서술이고 §135·§138·§141·§142·§145 가 이미 본문으로 말한 것을 한 화면으로 접은 것이다. 「이 환경에서 실제로 그러하다」고 주장한 것이 없어 NEEDS_EVIDENCE 로 남길 것도 없다. 개념 본문의 요약 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-153-155-qemu-cache-mode",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#153-qemu-cache-mode",
|
|
"final/document.md#154-cache=none",
|
|
"final/document.md#155-cache=writeback"
|
|
],
|
|
"summary": "`cache=none` 과 `cache=writeback` 은 이름 그대로 읽으면 부정확하고 핵심은 QEMU 가 Host Page Cache 와 write completion/flush semantics 를 어떻게 쓰는가다 — `cache=none` 은 우회 방향이라 이중 caching 을 줄이지만 즉시 durable media 반영이 아니고, `cache=writeback` 은 Host Page Cache 를 쓰지만 Guest 의 `fsync()`/FLUSH 를 무시한다는 뜻이 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "완료의 뜻을 설명하는 개념 안에서 설정 둘이 그 뜻을 어떻게 바꾸는지의 절이 된다. 설정 이름 셋을 각각 기록으로 만들면 같은 물음에 답하는 글이 셋이 된다"
|
|
},
|
|
{
|
|
"id": "SSOT-156-writeback-is-not-automatically-unsafe",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유"
|
|
],
|
|
"summary": "정확한 표현은 「writeback caching 에서는 volatile cache 가 존재할 수 있으므로 Guest 의 flush/fsync semantics 가 전체 backend/storage stack 에서 올바르게 보존되는지가 중요하다」이며, Guest 가 요구한 durability 가 Guest Filesystem → Guest Block Layer → virtio → QEMU/backend → Host Storage → Device chain 에서 깨지지 않아야 한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "개념이 그리는 chain 그대로다. 이 절이 세운 판독 규칙은 reference:a-speedup-that-removed-durability-is-not-an-optimization 이 예외 항목으로 받아 두 곳에 같은 문장을 두지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-157-device-side-cache",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#157-device-side-cache"
|
|
],
|
|
"summary": "Host Page Cache 를 우회해도 Storage controller/device 가 volatile write cache 를 가질 수 있어 RAM 에서 나갔다 ≠ Device 에 command 가 전달됐다 ≠ 전원이 끊겨도 살아남는 상태가 됐다 이고, device flush/FUA semantics 와 power-loss protection 여부도 중요할 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "§148 의 네 경계 뒤에 하나가 더 있다는 절이라 같은 개념의 마지막 칸이다. 따로 떼면 앞의 세 경계를 다시 설명해야 읽힌다"
|
|
},
|
|
{
|
|
"id": "SSOT-170-postgresql-wal-durability",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#170-postgresql-예시-wal과-durability"
|
|
],
|
|
"summary": "PostgreSQL 은 WAL 등의 durability protocol 을 쓰며 필요한 시점에 storage synchronization 을 수행하고, VM storage layer 가 flush/fsync semantics 를 제대로 보존하지 않으면 PostgreSQL 의 durability assumption 과 실제 storage behavior 가 어긋날 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "개념이 말한 보장이 깨질 때 애플리케이션에서 무엇이 어긋나는지를 보이는 예시다. 예시 하나를 독립 기록으로 만들지 않고 개념 본문의 적용 절로 넣는다"
|
|
},
|
|
{
|
|
"id": "SSOT-174-claims-4-5-cache-and-durability",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"summary": "Claim 4~5 — Guest 와 Host 양쪽에 Page Cache 가 존재할 수 있고 Direct I/O 와 QEMU cache mode 는 Host Page Cache 사용 방식과 연결된다 · `write()` 완료와 durability 는 같은 의미가 아니다(write ≠ writeback ≠ fsync/flush 완료 ≠ 전원 장애에도 안전한 상태)",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:write-completion-is-not-durability",
|
|
"reason": "둘 다 메커니즘 서술이고 §147~§157 이 본문으로 말한 것을 접은 것이다. 개념 본문의 요약 표로 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-159-one-nvme-serves-many-sources",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#159-여러-vm이-하나의-nvme를-공유하면"
|
|
],
|
|
"summary": "VM1 QEMU · VM2 QEMU · Nginx · Host 기타 프로세스의 요청이 같은 Host Block Layer queue 에서 관리되어 NVMe 로 dispatch 된다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "§158 의 「모두 Host block request 다」가 그림으로 이어진 것이다. 개념 본문의 한 절이고, 이 Host 에서 실제로 겹치는지는 question:vm1-storage-load-vs-vm2-latency 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-160-blk-mq-parallel-queues",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#160-blk-mq-multi-queue-block-layer"
|
|
],
|
|
"summary": "`blk-mq` 는 CPU 마다 queue 를 두어 여러 CPU 가 병렬로 block I/O 를 처리하게 하며 NVMe 가 높은 병렬성과 queue depth 를 지원하기 때문에 중요하고, Storage 처리 역시 CPU scheduling 과 완전히 독립된 세계는 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "Host block stack 의 한 칸이다. 마지막 문장이 제1부의 CPU 개념과 이어지는 자리라 개념의 relations 로 잇고 본문은 여기 한 절로 둔다"
|
|
},
|
|
{
|
|
"id": "SSOT-161-io-scheduler-reorders-requests",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#161-i-o-scheduler"
|
|
],
|
|
"summary": "여러 I/O request 가 있다고 해서 항상 들어온 순서 그대로 device 에 전달되는 것은 아니고 I/O Scheduler 가 dispatch 정책을 가지며 대표적으로 `none` · `mq-deadline` · `bfq` 를 볼 수 있다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "Host block stack 의 한 칸이다. 이 Host 의 값은 question:host-io-scheduler 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-162-none-scheduler",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#162-none"
|
|
],
|
|
"summary": "`none` 은 복잡한 scheduling 정책을 최소화해 비교적 직접 device 쪽으로 dispatch 하는 방향이고 NVMe 처럼 device 자체가 강한 병렬성과 queueing 을 가지면 적합할 수 있지만, block layer 가 아무 일도 하지 않는다는 뜻은 아니다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "scheduler 값 하나의 뜻이다. 개념 본문에서 §161 의 목록에 붙는 한 문단이고 독립 기록이 될 분량도 물음도 아니다"
|
|
},
|
|
{
|
|
"id": "SSOT-163-read-the-active-io-scheduler",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#163-실제-i-o-scheduler-확인"
|
|
],
|
|
"summary": "`cat /sys/block/nvme0n1/queue/scheduler` 의 출력 `[none] mq-deadline` 에서 대괄호 안이 현재 선택된 scheduler 이고, SATA/SCSI device 라면 `cat /sys/block/sda/queue/scheduler` 처럼 확인한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "명령 하나와 출력 읽는 법이다. 개념 본문에 두고, 이 Host 에서 실제로 돌리는 것은 question:host-io-scheduler 가 next-verification 으로 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-164-nvme-driver-is-a-host-kernel-driver",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#164-nvme-driver와-physical-device"
|
|
],
|
|
"summary": "NVMe Driver 는 Host Linux Kernel 의 device driver 이고 Network 에서 physical NIC driver 가 하드웨어를 제어하는 것과 동일한 계층적 위치다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "Host block stack 의 마지막 칸이다. 한 문단으로 개념 안에 들어간다"
|
|
},
|
|
{
|
|
"id": "SSOT-165-nvme-is-a-protocol-ssd-is-a-device-class",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#165-nvme와-ssd-구분"
|
|
],
|
|
"summary": "SSD 는 저장장치의 넓은 종류이고 NVMe 는 PCIe 기반 non-volatile storage 를 위한 protocol/interface 이며, SSD 아래에 SATA SSD(SATA/AHCI)와 NVMe SSD(PCIe + NVMe)가 갈린다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "이 계층의 이름을 정리하는 절이다. 용어 구분 하나를 독립 기록으로 만들지 않는다"
|
|
},
|
|
{
|
|
"id": "SSOT-167-storage-contention-is-not-cpu-contention",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#167-storage-contention"
|
|
],
|
|
"summary": "여러 VM 이 동일한 Physical NVMe 를 쓰면 storage resource 경쟁이 생겨 VM1 의 대량 I/O 가 VM2 의 storage latency 를 올릴 수 있고, CPU Contention(Host logical CPU 실행 시간 경쟁)과 Storage Contention(IOPS/bandwidth/queue/device 처리시간 경쟁)은 다른 자원 경쟁이다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "concept:host-block-stack-under-the-vm",
|
|
"reason": "§158·§159 가 세운 구조의 결과라 같은 개념 안에서 닫힌다. 여기서 나온 판독 규칙은 reference:read-storage-before-blaming-cpu-for-latency 가 받고, 이 Host 에서 재는 것은 question:vm1-storage-load-vs-vm2-latency 가 받는다"
|
|
},
|
|
{
|
|
"id": "SSOT-146-verify-the-guest-to-host-disk-link",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#146-실제-연결-확인"
|
|
],
|
|
"summary": "Guest 의 `lsblk` 와 Host 의 `virsh domblklist <VM_NAME>` 로 Target 과 Source 를 이어 `/dev/vda` → virtio-blk → QEMU → `/var/lib/libvirt/images/vm1.qcow2` 관계를 확인한다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:confirm-the-disk-backend-on-the-host",
|
|
"reason": "명령 둘과 판독 절차 자체가 §145 규칙의 실행 방법이다. 그 Reference 의 scope 가 요구하는 첫 확인이라 본문 절로 들어간다. 제3부에서 §118 의 명령 목록을 §119 의 Reference 로 넣은 것과 같다"
|
|
},
|
|
{
|
|
"id": "SSOT-169-storage-observation-commands",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#169-storage-관측-명령어"
|
|
],
|
|
"summary": "device I/O 관측은 `iostat -xz 1` 로 read/write throughput · IOPS · request latency · queue 상태 · device utilization 성격의 지표를 보고, 어떤 process 가 I/O 를 내는지는 `iotop` 으로 본다. Guest 는 `lsblk` · `mount` · `df -h` · `cat /proc/mounts` · `iostat -xz 1`, Host 는 `virsh domblklist <VM_NAME>` · `qemu-img info <disk-image>` · `lsblk` · `cat /sys/block/<device>/queue/scheduler` · `iostat -xz 1` · `iotop`",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:read-storage-before-blaming-cpu-for-latency",
|
|
"reason": "명령 목록 자체는 규칙이 아니다. §168 의 규칙이 무엇을 함께 보라고 요구하고 이 목록이 그 도구를 대므로 그 Reference 의 본문 표가 된다. 제3부의 §118 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-174-claim-6-storage-perf-is-not-guest-only",
|
|
"kindCandidate": "REFERENCE",
|
|
"sourceRefs": [
|
|
"final/document.md#174-핵심-claim"
|
|
],
|
|
"summary": "Claim 6 — Storage 성능은 Guest 내부만으로 결정되지 않고 QEMU/backend · Host block queue · I/O scheduler · NVMe · cache · 다른 VM 의 storage load 가 함께 영향을 준다",
|
|
"disposition": "MERGE_INTO",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": "reference:read-storage-before-blaming-cpu-for-latency",
|
|
"reason": "여섯 Claim 중 유일하게 메커니즘이 아니라 판독 규칙이다. §168 이 본문으로 말한 것의 결론 문장이라 그 Reference 의 한 줄로 들어간다. 제3부의 Claim 17 과 같은 처분이다"
|
|
},
|
|
{
|
|
"id": "SSOT-176-recommended-practice-order",
|
|
"kindCandidate": "CONCEPT",
|
|
"sourceRefs": [
|
|
"final/document.md#176-권장-실습-흐름"
|
|
],
|
|
"summary": "Guest 에서 `/dev/vda` 확인부터 DB fsync latency 와 Host storage latency 상관관계 확인까지 여덟 단계의 권장 실습 흐름",
|
|
"disposition": "KEEP_IN_SSOT",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "다음에 무엇을 어떤 순서로 잴지의 진행 계획이다. 계획은 실행되면 Case 가 되고 그 전까지는 분석에 남는다. 제1부의 §23 · 제2부의 §84 · 제3부의 §126 도 같은 처분이었다"
|
|
},
|
|
{
|
|
"id": "SSOT-153-157-cache-mode-choice-not-made",
|
|
"kindCandidate": "DECISION",
|
|
"sourceRefs": [
|
|
"final/document.md#153-qemu-cache-mode",
|
|
"final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유"
|
|
],
|
|
"summary": "이 환경의 VM disk cache mode 를 `cache=none` 으로 둘 것인가 `cache=writeback` 으로 둘 것인가",
|
|
"disposition": "NEEDS_DECISION",
|
|
"dispositionReview": "CONFIRMED",
|
|
"target": null,
|
|
"reason": "SSOT 는 두 설정의 뜻과 각각의 오해를 갈라 놓기만 했고 어느 쪽을 쓰기로 정했다고 적지 않았다. §156 은 오히려 이름만 보고 단정하지 말라고 못박아 방향을 제시하지 않는다. 감수한 비용도 적혀 있지 않다. 게다가 현재 값이 무엇인지조차 확인되지 않았다 — question:qemu-disk-cache-mode 가 그것을 먼저 답해야 한다. 권고 없는 서술을 Decision 으로 올리면 「기술이 존재한다」를 근거로 바꾸는 실수가 된다"
|
|
}
|
|
],
|
|
"counts": {
|
|
"topics": 4,
|
|
"nodes": 57,
|
|
"written": 57,
|
|
"unwritten": 0,
|
|
"unlisted": 0,
|
|
"candidates": 213
|
|
},
|
|
"unlisted": [],
|
|
"history": {
|
|
"2026-09-08": "S2 — SSOT(절 28개)에서 후보 39건을 뽑아 처분을 적고 PROMOTE 하나만 글감으로 올렸다. 앵커 형식을 h2 절 제목 슬러그로 정하면서 final/document.md 의 frontmatter 를 떼고 heading 단계를 맞췄다(본문 문장은 그대로).",
|
|
"2026-09-08 · S2 재판정": "§20 의 OQ-1~6 과 §27 의 OQ-7~12 열둘을 NEEDS_EVIDENCE 에서 PROMOTE 로 다시 판정하고 cpu-virtualization 주제에 question 글감 열둘로 올렸다. readiness 는 전부 OPEN 이고 known 에는 SSOT 가 서술한 것만, unknown 에는 이 Host 에서 재야 아는 것만 적었다. 앵커는 h2 절 제목 슬러그에 OQ 번호를 구분자로 붙인 형식이다. 후보 27건과 concept 글감은 그대로 두었다.",
|
|
"2026-09-09 · S2-B 제3부": "SSOT 제3부(네트워크 가상화 §89~§126, 절 38개)에서 후보 48건을 뽑아 처분을 적고 PROMOTE 10건을 network-virtualization 주제의 글감으로 올렸다 — concept 하나 · reference 둘 · question 일곱. candidateScope.sections 에 제3부 절 제목 38개를 덧붙였다. 제1부·제2부의 주제 둘과 후보 116건은 그대로 두었다.",
|
|
"2026-09-09 · S2-C 제4부": "SSOT 제4부(스토리지 가상화 §127~§177, 절 51개)에서 후보 56건을 뽑아 처분을 적고 PROMOTE 14건을 storage-virtualization 주제의 글감으로 올렸다 — concept 넷 · reference 셋 · question 일곱. candidateScope.sections 에 제4부 절 제목 51개를 덧붙이고 최상단 note 의 「주제도 하나이고 글감도 concept 하나」를 지금 상태(주제 넷 · 글감 57)로 고쳤다. 제1~3부의 주제 셋과 후보 164건은 그대로 두었다."
|
|
}
|
|
}
|