{ "version": "1.1", "id": "virtio-balloon-inflate-deflate", "title": "balloon target 은 VM Boundary 를 건너 driver 에 닿고 확보한 page 는 같은 경계를 되건너 온다", "question": "Host 가 balloon target 을 바꾸면 그 요청은 어떤 순서로 어느 경계를 건너 Guest 안의 driver 까지 가고, 확보된 page 는 어떻게 Host 로 돌아오는가", "type": "sequence", "direction": "LR", "audience": [ "Host RAM 압박에 ballooning 을 쓸지 판단하려는 사람", "Guest 안의 메모리 압박을 Host 조치와 이어 보려는 사람" ], "summary": "balloon target 조정은 Host Memory Management 에서 QEMU 쪽 device 와 virtqueue 를 지나 VM Boundary 를 넘어 Guest kernel 의 driver 까지 가고, driver 가 확보한 Guest page 는 같은 경계를 반대 방향으로 되건너 Host 의 회수 가능 backing 이 된다.", "alt": "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 가 어느 쪽으로 움직이는지는 본문의 표가 맡는다.", "source_context": { "document": "docs/virtualization/final/document.md", "document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd", "anchor": { "kind": "heading", "value": "65. virtio-balloon 구조", "line": 3008 } }, "composition": { "profile": "sequence", "diagram_only": true, "reference_ids": [ "payment-approval-sequence" ], "rationale": "이 절과 다음 절이 세운 것은 조각들의 나열이 아니라 balloon 요청이 지나는 차례와 그 차례가 VM Boundary 를 두 번 건넌다는 사실이다. two-zone-pipeline 으로 구역 둘을 그려 보니 같은 구역 안의 이음이 캔버스 맨 위로 튀어 올라가고 경계 라벨이 건너편 상자에 먹혔다. orchestrator-workers 는 QEMU 아래에 교체 가능한 워커들을 두는 그림이라 driver 가 Guest 안에 있다는 사실이 지워진다. sequence 는 참여자를 한 줄로 세우고 메시지에 번호를 붙이므로 경계를 두 번 건너는 왕복이 그대로 드러난다.", "focus_node": "balloon-driver" }, "groups": [], "nodes": [ { "id": "balloon-driver", "label": "virtio-balloon Driver", "kind": "driver", "role": "participant", "shape": "box", "emphasis": "primary", "details": [ "Guest Kernel" ], "description": "Guest kernel 쪽 balloon driver. target 을 받아 Guest page 를 확보한다.", "evidence": [ { "start_line": 3013, "end_line": 3015 }, { "start_line": 3046, "end_line": 3046 } ], "assumption": false }, { "id": "virtqueue", "label": "virtqueue", "kind": "queue", "role": "participant", "shape": "box", "description": "Guest 와 QEMU 가 balloon 요청을 주고받는 공유 큐. VM Boundary 바로 안쪽이다.", "evidence": [ { "start_line": 3017, "end_line": 3017 } ], "assumption": false }, { "id": "qemu-balloon-device", "label": "QEMU virtio-balloon\nDevice", "kind": "service", "role": "participant", "shape": "box", "description": "Host 쪽 balloon device. 경계를 넘어온 내용을 Host memory management 로 넘긴다.", "evidence": [ { "start_line": 3022, "end_line": 3022 }, { "start_line": 3037, "end_line": 3041 } ], "assumption": false }, { "id": "host-memory-management", "label": "Host Memory\nManagement", "kind": "service", "role": "participant", "shape": "box", "description": "balloon target 을 정하는 쪽이자 회수 기회가 생기는 자리.", "evidence": [ { "start_line": 3025, "end_line": 3025 }, { "start_line": 3034, "end_line": 3037 } ], "assumption": false } ], "edges": [ { "id": "target-adjust", "from": "host-memory-management", "to": "qemu-balloon-device", "label": "Balloon target 조정", "kind": "control", "order": 1, "style": "solid", "evidence": [ { "start_line": 3034, "end_line": 3041 } ], "assumption": false }, { "id": "target-crosses-in", "from": "qemu-balloon-device", "to": "virtqueue", "label": "VM Boundary", "kind": "control", "order": 2, "style": "solid", "evidence": [ { "start_line": 3017, "end_line": 3022 }, { "start_line": 3041, "end_line": 3046 } ], "assumption": false }, { "id": "target-to-driver", "from": "virtqueue", "to": "balloon-driver", "label": "Balloon target", "kind": "control", "order": 3, "style": "solid", "evidence": [ { "start_line": 3013, "end_line": 3017 }, { "start_line": 3043, "end_line": 3046 } ], "assumption": false }, { "id": "pages-secured", "from": "balloon-driver", "to": "virtqueue", "label": "Guest pages 확보", "kind": "data", "order": 4, "style": "solid", "evidence": [ { "start_line": 3046, "end_line": 3050 } ], "assumption": false }, { "id": "pages-cross-out", "from": "virtqueue", "to": "qemu-balloon-device", "label": "VM Boundary", "kind": "data", "order": 5, "style": "solid", "evidence": [ { "start_line": 3017, "end_line": 3025 } ], "assumption": false }, { "id": "reclaimable-backing", "from": "qemu-balloon-device", "to": "host-memory-management", "label": "회수 가능 backing", "kind": "data", "order": 6, "style": "solid", "evidence": [ { "start_line": 3022, "end_line": 3028 }, { "start_line": 3077, "end_line": 3079 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "sequence 로 고른 이유는 §65 의 구조가 §66 의 차례와 붙어야 뜻이 나기 때문이다. 구조만 그리면 화살표가 한 방향뿐이고, 차례만 적으면 경계가 어디인지 안 보인다. deflate 쪽 절(§68)은 prepare 가 잡아 온 문맥(L2986-L3083) 밖이라 그 방향은 그리지 않았고, target 을 올릴 때와 내릴 때 Guest usable memory 가 어느 쪽으로 가는지는 기록 본문의 표가 이미 맡고 있어 그림에 넣지 않았다. 노드 라벨의 줄바꿈은 렌더러가 22자까지만 접기 때문에 넣었다 — 접지 않으면 글자가 상자 밖으로 나간다." } }