feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
@@ -0,0 +1,33 @@
# balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다
## Alternative text
virtio-balloon Driver, virtqueue, QEMU virtio-balloon Device, Host Memory Management 네 참여자 사이의 순서도. 앞 세 메시지는 오른쪽에서 왼쪽으로 Guest 안으로 들어가고 뒤 세 메시지는 왼쪽에서 오른쪽으로 Host 로 돌아온다.
## Long description
참여자는 왼쪽부터 Guest kernel 의 virtio-balloon Driver, virtqueue, QEMU virtio-balloon Device, Host Memory Management 네 개다. 메시지는 위에서 아래로 읽는다. 1번은 Host Memory Management 가 QEMU 쪽 device 에 balloon target 조정을 보내는 것이고, 2번에서 그 요청이 virtqueue 로 내려가면서 VM Boundary 를 넘고, 3번에서 Guest kernel 의 driver 에 balloon target 이 닿는다. 여기서 방향이 바뀐다. 4번에서 driver 가 확보한 Guest page 를 virtqueue 에 올리고, 5번에서 그것이 다시 VM Boundary 를 넘어 QEMU 쪽 device 로 가고, 6번에서 device 가 Host Memory Management 에 회수 가능 backing 으로 넘긴다. target 을 올릴 때와 내릴 때 Guest 가 쓸 수 있는 memory 가 어느 쪽으로 움직이는지는 본문의 표가 맡는다.
## Elements and evidence
- **virtio-balloon Driver** (driver): Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. Evidence: L3013L3015, L3046L3046.
- **virtqueue** (queue): Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. Evidence: L3017L3017.
- **QEMU virtio-balloon
Device** (service): Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. Evidence: L3022L3022, L3037L3041.
- **Host Memory
Management** (service): balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. Evidence: L3025L3025, L3034L3037.
## Relationships
- **Host Memory
Management → QEMU virtio-balloon
Device:** Balloon target 조정. Evidence: L3034L3041.
- **QEMU virtio-balloon
Device → virtqueue:** VM Boundary. Evidence: L3017L3022, L3041L3046.
- **virtqueue → virtio-balloon Driver:** Balloon target. Evidence: L3013L3017, L3043L3046.
- **virtio-balloon Driver → virtqueue:** Guest pages 확보. Evidence: L3046L3050.
- **virtqueue → QEMU virtio-balloon
Device:** VM Boundary. Evidence: L3017L3025.
- **QEMU virtio-balloon
Device → Host Memory
Management:** 회수 가능 backing. Evidence: L3022L3028, L3077L3079.
@@ -0,0 +1,21 @@
# balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다
# Question: Host 가 balloon target 을 바꾸면 그 요청은 어떤 순서로 어느 경계를 건너 Guest 안의 driver 까지 가고, 확보된 page 는 어떻게 Host 로 돌아오는가
direction: right
n0: "virtio-balloon Driver" {
shape: rectangle
}
n1: "virtqueue" {
shape: queue
}
n2: "QEMU virtio-balloon\nDevice" {
shape: rectangle
}
n3: "Host Memory\nManagement" {
shape: rectangle
}
n3 -> n2: "Balloon target 조정"
n2 -> n1: "VM Boundary"
n1 -> n0: "Balloon target"
n0 -> n1: "Guest pages 확보"
n1 -> n2: "VM Boundary"
n2 -> n3: "회수 가능 backing"
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
<diagram id="virtio-balloon-inflate-deflate" name="balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다">
<mxGraphModel dx="870" dy="542" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="870" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n_balloon-driver" value="virtio-balloon Driver&lt;br/&gt;Guest Kernel" tooltip="Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다. | Evidence: L3013-L3015, L3046-L3046" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="45.0" y="35.0" width="181.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_virtqueue" value="virtqueue" tooltip="Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다. | Evidence: L3017-L3017" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="255.0" y="35.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_qemu-balloon-device" value="QEMU virtio-balloon
Device" tooltip="Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다. | Evidence: L3022-L3022, L3037-L3041" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="465.0" y="35.0" width="167.0" height="74.0" as="geometry"/>
</mxCell>
<mxCell id="n_host-memory-management" value="Host Memory
Management" tooltip="balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리. | Evidence: L3025-L3025, L3034-L3037" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="675.0" y="35.0" width="150.0" height="74.0" as="geometry"/>
</mxCell>
<mxCell id="e_target-adjust" value="Balloon target 조정" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-memory-management" target="n_qemu-balloon-device">
<mxGeometry relative="1" as="geometry">
<mxPoint x="649.2" y="128.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_target-crosses-in" value="VM Boundary" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-balloon-device" target="n_virtqueue">
<mxGeometry relative="1" as="geometry">
<mxPoint x="439.2" y="190.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_target-to-driver" value="Balloon target" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtqueue" target="n_balloon-driver">
<mxGeometry relative="1" as="geometry">
<mxPoint x="232.8" y="252.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_pages-secured" value="Guest pages 확보" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_balloon-driver" target="n_virtqueue">
<mxGeometry relative="1" as="geometry">
<mxPoint x="232.8" y="314.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_pages-cross-out" value="VM Boundary" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtqueue" target="n_qemu-balloon-device">
<mxGeometry relative="1" as="geometry">
<mxPoint x="439.2" y="376.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_reclaimable-backing" value="회수 가능 backing" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-balloon-device" target="n_host-memory-management">
<mxGeometry relative="1" as="geometry">
<mxPoint x="649.2" y="438.0" as="offset"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,835 @@
{
"type": "excalidraw",
"version": 2,
"source": "techviz-harness",
"elements": [
{
"id": "edge-target-adjust",
"type": "arrow",
"x": 548.5,
"y": 140.0,
"width": 201.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 737020640,
"version": 1,
"versionNonce": 1525160168,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
201.5,
0.0
],
[
0.0,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-host-memory-management",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-qemu-balloon-device",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-target-adjust",
"type": "text",
"x": 581.25,
"y": 116.0,
"width": 136,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 453083568,
"version": 1,
"versionNonce": 1469276324,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "Balloon target 조정",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "Balloon target 조정",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-target-crosses-in",
"type": "arrow",
"x": 330.0,
"y": 202.0,
"width": 218.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 1982038005,
"version": 1,
"versionNonce": 61702621,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
218.5,
0.0
],
[
0.0,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-qemu-balloon-device",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-virtqueue",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-target-crosses-in",
"type": "text",
"x": 394.25,
"y": 178.0,
"width": 90,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 777212613,
"version": 1,
"versionNonce": 349365301,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "VM Boundary",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "VM Boundary",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-target-to-driver",
"type": "arrow",
"x": 135.5,
"y": 264.0,
"width": 194.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 135515254,
"version": 1,
"versionNonce": 613652303,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
194.5,
0.0
],
[
0.0,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-virtqueue",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-balloon-driver",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-target-to-driver",
"type": "text",
"x": 176.75,
"y": 240.0,
"width": 112,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 1817118777,
"version": 1,
"versionNonce": 19943219,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "Balloon target",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "Balloon target",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-pages-secured",
"type": "arrow",
"x": 135.5,
"y": 326.0,
"width": 194.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 107373777,
"version": 1,
"versionNonce": 1878244752,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
0.0,
0.0
],
[
194.5,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-balloon-driver",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-virtqueue",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-pages-secured",
"type": "text",
"x": 176.75,
"y": 302.0,
"width": 112,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 695343754,
"version": 1,
"versionNonce": 1171214433,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "Guest pages 확보",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "Guest pages 확보",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-pages-cross-out",
"type": "arrow",
"x": 330.0,
"y": 388.0,
"width": 218.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 1480907426,
"version": 1,
"versionNonce": 1830405205,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
0.0,
0.0
],
[
218.5,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-virtqueue",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-qemu-balloon-device",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-pages-cross-out",
"type": "text",
"x": 394.25,
"y": 364.0,
"width": 90,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 19536809,
"version": 1,
"versionNonce": 1120594763,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "VM Boundary",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "VM Boundary",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-reclaimable-backing",
"type": "arrow",
"x": 548.5,
"y": 450.0,
"width": 201.5,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": null,
"seed": 289901807,
"version": 1,
"versionNonce": 383977982,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"points": [
[
0.0,
0.0
],
[
201.5,
0.0
]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "node-qemu-balloon-device",
"focus": 0,
"gap": 4
},
"endBinding": {
"elementId": "node-host-memory-management",
"focus": 0,
"gap": 4
},
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": true
},
{
"id": "edge-label-reclaimable-backing",
"type": "text",
"x": 597.25,
"y": 426.0,
"width": 104,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 617340894,
"version": 1,
"versionNonce": 525555255,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "회수 가능 backing",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "회수 가능 backing",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "node-balloon-driver",
"type": "rectangle",
"x": 45.0,
"y": 35.0,
"width": 181.0,
"height": 71.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#ffffff",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 1402975843,
"version": 1,
"versionNonce": 162304747,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false
},
{
"id": "node-label-balloon-driver",
"type": "text",
"x": 55.0,
"y": 45.0,
"width": 161.0,
"height": 51.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 218037921,
"version": 1,
"versionNonce": 1781698181,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "virtio-balloon Driver\nGuest Kernel",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "virtio-balloon Driver\nGuest Kernel",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "node-virtqueue",
"type": "rectangle",
"x": 255.0,
"y": 35.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f3f0ff",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 1427608734,
"version": 1,
"versionNonce": 104915312,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false
},
{
"id": "node-label-virtqueue",
"type": "text",
"x": 265.0,
"y": 45.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 1863917934,
"version": 1,
"versionNonce": 579283696,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "virtqueue",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "virtqueue",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "node-qemu-balloon-device",
"type": "rectangle",
"x": 465.0,
"y": 35.0,
"width": 167.0,
"height": 74.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#ffffff",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 823854416,
"version": 1,
"versionNonce": 1128635888,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false
},
{
"id": "node-label-qemu-balloon-device",
"type": "text",
"x": 475.0,
"y": 45.0,
"width": 147.0,
"height": 54.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 560943017,
"version": 1,
"versionNonce": 818393145,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "QEMU virtio-balloon\nDevice",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "QEMU virtio-balloon\nDevice",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "node-host-memory-management",
"type": "rectangle",
"x": 675.0,
"y": 35.0,
"width": 150.0,
"height": 74.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#ffffff",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 765979520,
"version": 1,
"versionNonce": 934288555,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false
},
{
"id": "node-label-host-memory-management",
"type": "text",
"x": 685.0,
"y": 45.0,
"width": 130.0,
"height": 54.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 0,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": null,
"roundness": {
"type": 3
},
"seed": 1363069112,
"version": 1,
"versionNonce": 234953733,
"isDeleted": false,
"boundElements": [],
"updated": 0,
"link": null,
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "Host Memory\nManagement",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "Host Memory\nManagement",
"autoResize": true,
"lineHeight": 1.25
}
],
"appState": {
"gridSize": 10,
"viewBackgroundColor": "#ffffff",
"currentItemFontFamily": 5
},
"files": {}
}
@@ -0,0 +1,31 @@
{
"harness_version": "0.2.0",
"spec_id": "virtio-balloon-inflate-deflate",
"spec_version": "1.1",
"spec_sha256": "1a53fd7e3e5cf5b553be00d6c12f47f8493d302f9a79f660d29e1d85490e61de",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"anchor": {
"kind": "heading",
"value": "65. virtio-balloon 구조",
"line": 3008
}
},
"outputs": [
"virtio-balloon-inflate-deflate.svg",
"virtio-balloon-inflate-deflate.drawio",
"virtio-balloon-inflate-deflate.mmd",
"virtio-balloon-inflate-deflate.d2",
"virtio-balloon-inflate-deflate.excalidraw",
"virtio-balloon-inflate-deflate.alt.md"
],
"lint_issue_count": 0,
"assumption_count": 0,
"assumptions_allowed": false,
"composition_profile": "sequence",
"reference_ids": [
"payment-approval-sequence"
],
"diagram_only": true
}
@@ -0,0 +1,13 @@
%% balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다
%% question: Host 가 balloon target 을 바꾸면 그 요청은 어떤 순서로 어느 경계를 건너 Guest 안의 driver 까지 가고, 확보된 page 는 어떻게 Host 로 돌아오는가
sequenceDiagram
participant n0 as virtio-balloon Driver
participant n1 as virtqueue
participant n2 as QEMU virtio-balloon<br/>Device
participant n3 as Host Memory<br/>Management
n3->>n2: Balloon target 조정
n2->>n1: VM Boundary
n1->>n0: Balloon target
n0->>n1: Guest pages 확보
n1->>n2: VM Boundary
n2->>n3: 회수 가능 backing
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="870" height="542" viewBox="0 0 870 542" role="img" aria-labelledby="diagram-title diagram-description">
<title id="diagram-title">balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다</title>
<desc id="diagram-description">참여자는 왼쪽부터 Guest kernel 의 virtio-balloon Driver, virtqueue, QEMU virtio-balloon Device, Host Memory Management 네 개다. 메시지는 위에서 아래로 읽는다. 1번은 Host Memory Management 가 QEMU 쪽 device 에 balloon target 조정을 보내는 것이고, 2번에서 그 요청이 virtqueue 로 내려가면서 VM Boundary 를 넘고, 3번에서 Guest kernel 의 driver 에 balloon target 이 닿는다. 여기서 방향이 바뀐다. 4번에서 driver 가 확보한 Guest page 를 virtqueue 에 올리고, 5번에서 그것이 다시 VM Boundary 를 넘어 QEMU 쪽 device 로 가고, 6번에서 device 가 Host Memory Management 에 회수 가능 backing 으로 넘긴다. target 을 올릴 때와 내릴 때 Guest 가 쓸 수 있는 memory 가 어느 쪽으로 움직이는지는 본문의 표가 맡는다.</desc>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;virtio-balloon-inflate-deflate&quot;,&quot;profile&quot;:&quot;sequence&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;65. virtio-balloon 구조&quot;,&quot;line&quot;:3008}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
<style>
:root { color-scheme: light; }
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
.canvas { fill: #ffffff; }
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
.group-label-bg { fill: #ffffff; }
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
.edge.style-dotted { stroke-dasharray: 2 5; }
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.edge.emphasis-muted { stroke: #9ca3af; }
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
.edge-label-bg { fill: #ffffff; }
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
.node-shape.assumption { stroke-dasharray: 4 4; }
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
.controller-led { fill: #4b5563; }
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
.node-detail { font-size: 11px; fill: #374151; }
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
</style>
</defs>
<rect class="canvas" width="870" height="542" />
<rect class="node-shape kind-driver emphasis-primary role-participant" data-evidence="3013-3015,3046-3046" x="45.0" y="35.0" width="181.0" height="71.0" rx="7" />
<text class="node-label" x="135.5" y="62.0">virtio-balloon Driver</text>
<line class="node-detail-divider" x1="59.0" y1="83.0" x2="212.0" y2="83.0" />
<text class="node-detail" x="61.0" y="100.0">Guest Kernel</text>
<line class="lifeline" x1="135.5" y1="106.0" x2="135.5" y2="512.0" />
<rect class="node-shape kind-queue emphasis-normal role-participant" data-evidence="3017-3017" x="255.0" y="35.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="330.0" y="65.0">virtqueue</text>
<line class="lifeline" x1="330.0" y1="99.0" x2="330.0" y2="512.0" />
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3022-3022,3037-3041" x="465.0" y="35.0" width="167.0" height="74.0" rx="7" />
<text class="node-label" x="548.5" y="62.0">QEMU virtio-balloon</text>
<text class="node-label" x="548.5" y="80.0">Device</text>
<line class="lifeline" x1="548.5" y1="109.0" x2="548.5" y2="512.0" />
<rect class="node-shape kind-service emphasis-normal role-participant" data-evidence="3025-3025,3034-3037" x="675.0" y="35.0" width="150.0" height="74.0" rx="7" />
<text class="node-label" x="750.0" y="62.0">Host Memory</text>
<text class="node-label" x="750.0" y="80.0">Management</text>
<line class="lifeline" x1="750.0" y1="109.0" x2="750.0" y2="512.0" />
<polyline class="edge kind-control style-solid emphasis-normal" points="750.0,140.0 548.5,140.0" data-evidence="3034-3041" />
<rect class="edge-label-bg" x="573.2" y="114.0" width="152.0" height="22" rx="3" />
<text class="edge-label" x="649.2" y="129.0">1. Balloon target 조정</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="548.5,202.0 330.0,202.0" data-evidence="3017-3022,3041-3046" />
<rect class="edge-label-bg" x="383.4" y="176.0" width="111.8" height="22" rx="3" />
<text class="edge-label" x="439.2" y="191.0">2. VM Boundary</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="330.0,264.0 135.5,264.0" data-evidence="3013-3017,3043-3046" />
<rect class="edge-label-bg" x="166.8" y="238.0" width="131.9" height="22" rx="3" />
<text class="edge-label" x="232.8" y="253.0">3. Balloon target</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="135.5,326.0 330.0,326.0" data-evidence="3046-3050" />
<rect class="edge-label-bg" x="166.8" y="300.0" width="131.9" height="22" rx="3" />
<text class="edge-label" x="232.8" y="315.0">4. Guest pages 확보</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="330.0,388.0 548.5,388.0" data-evidence="3017-3025" />
<rect class="edge-label-bg" x="383.4" y="362.0" width="111.8" height="22" rx="3" />
<text class="edge-label" x="439.2" y="377.0">5. VM Boundary</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="548.5,450.0 750.0,450.0" data-evidence="3022-3028,3077-3079" />
<rect class="edge-label-bg" x="586.6" y="424.0" width="125.2" height="22" rx="3" />
<text class="edge-label" x="649.2" y="439.0">6. 회수 가능 backing</text>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB