๐Ÿง Linux

KSM (Kernel Samepage Merging)

๊ฐœ์š”

KSM(Kernel Samepage Merging)์€ Linux ์ปค๋„ 2.6.32๋ถ€ํ„ฐ ๋„์ž…๋œ ๋ฉ”๋ชจ๋ฆฌ ์ค‘๋ณต ์ œ๊ฑฐ(deduplication) ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. KVM ๊ฐ€์ƒํ™” ํ™˜๊ฒฝ์—์„œ ์œ ์‚ฌํ•œ ๊ฒŒ์ŠคํŠธ OS ์ด๋ฏธ์ง€ ๊ฐ„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต์œ ๋ฅผ ์œ„ํ•ด ๊ฐœ๋ฐœ๋˜์—ˆ์œผ๋‚˜, ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

KSM์€ ์ปค๋„ ์Šค๋ ˆ๋“œ์ธ ksmd๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์Šค์บ”ํ•˜์—ฌ ๋™์ผํ•œ ๋‚ด์šฉ์„ ๊ฐ€์ง„ ํŽ˜์ด์ง€๋ฅผ ์ฐพ์•„ ํ•˜๋‚˜์˜ ์“ฐ๊ธฐ ๋ณดํ˜ธ ํŽ˜์ด์ง€๋กœ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์ˆ˜์ •ํ•˜๋ ค ํ•˜๋ฉด ์ž๋™์œผ๋กœ Copy-on-Write(COW)๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋…๋ฆฝ์ ์ธ ๋ณต์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌผ๋ฆฌ์  RAM ์‚ฌ์šฉ๋Ÿ‰์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, KVM ํ™˜๊ฒฝ์—์„œ๋Š” ์ตœ๋Œ€ 300%์˜ ์˜ค๋ฒ„์ปค๋ฐ‹์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

KSM์€ madvise(MADV_MERGEABLE)๋กœ ๋“ฑ๋ก๋œ ์ต๋ช…(private anonymous) ํŽ˜์ด์ง€์—๋งŒ ๋™์ž‘ํ•˜๋ฉฐ, ํŒŒ์ผ ๊ธฐ๋ฐ˜ page cache๋Š” ๋ณ‘ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ‘ํ•ฉ๋œ ํŽ˜์ด์ง€๋„ ์Šค์™‘์•„์›ƒ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‹ค์‹œ ์Šค์™‘์ธ๋˜๋ฉด ๊ณต์œ  ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ksmd๊ฐ€ ๋™์ผ์„ฑ์„ ๋‹ค์‹œ ์ฐพ์•„ ์žฌ๋ณ‘ํ•ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

KSM ๊ฐœ์š”

๊ทธ๋ฆผ 1. KSM ๋™์ž‘ ๊ฐœ์š” ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๋ณ‘ํ•ฉ ๊ฐœ๋…

ํ•ต์‹ฌ ๊ฐœ๋…

ksmd ์ปค๋„ ์Šค๋ ˆ๋“œ

ksmd๋Š” KSM์˜ ํ•ต์‹ฌ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ปค๋„ ์Šค๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ง€์ •๋œ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์Šค์บ”ํ•˜๊ณ , ๋™์ผํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฐพ์•„ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

  • sleep_millisecs: ์Šค์บ” ๊ฐ„๊ฒฉ(๋ฐ€๋ฆฌ์ดˆ). ๊ธฐ๋ณธ๊ฐ’ 20ms
  • pages_to_scan: ํ•œ ๋ฒˆ์— ์Šค์บ”ํ•  ํŽ˜์ด์ง€ ์ˆ˜. ๊ธฐ๋ณธ๊ฐ’ 100
  • run: ksmd ์ œ์–ด (0: ์ค‘์ง€, 1: ์‹คํ–‰, 2: ์ค‘์ง€+๋ณ‘ํ•ฉ ํ•ด์ œ)
  • ์Šค์บ”์€ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•œ ๋น ๋ฅธ ๋น„๊ต ํ›„ memcmp()๋กœ ์ตœ์ข… ํ™•์ธ

madvise ์ธํ„ฐํŽ˜์ด์Šค

KSM์€ madvise(2) ์‹œ์Šคํ…œ ์ฝœ์„ ํ†ตํ•ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋ณ‘ํ•ฉ ๋Œ€์ƒ ์˜์—ญ์„ ์ง์ ‘ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • MADV_MERGEABLE: ์ง€์ •๋œ ์ฃผ์†Œ ๋ฒ”์œ„๋ฅผ KSM ๋ณ‘ํ•ฉ ๋Œ€์ƒ์œผ๋กœ ๋“ฑ๋ก
  • MADV_UNMERGEABLE: ์ด์ „์— ๋“ฑ๋ก๋œ ๋ณ‘ํ•ฉ ๋Œ€์ƒ์„ ์ทจ์†Œํ•˜๊ณ  ์ด๋ฏธ ๋ณ‘ํ•ฉ๋œ ํŽ˜์ด์ง€๋ฅผ ํ•ด์ œ
  • CONFIG_KSM์ด ๋น„ํ™œ์„ฑํ™”๋œ ์ปค๋„์—์„œ๋Š” MADV_MERGEABLE์ด EINVAL๋กœ ์‹คํŒจ
  • ๋ณ‘ํ•ฉ ํ•ด์ œ ์‹œ ๊ฐ‘์ž๊ธฐ ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์–ด OOM ํ‚ฌ๋Ÿฌ๊ฐ€ ๋ฐœ๋™๋  ์ˆ˜ ์žˆ์Œ

stable tree / unstable tree

KSM์€ ๋ชจ๋“  ํ›„๋ณด ํŽ˜์ด์ง€๋ฅผ ๋งค๋ฒˆ ์™„์ „ ๋น„๊ตํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ stable tree์™€ unstable tree๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • stable tree: ์ด๋ฏธ ๋ณ‘ํ•ฉ๋œ KSM ํŽ˜์ด์ง€๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ตฌ์กฐ๋กœ, ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ณต์œ  ํŽ˜์ด์ง€๋ฅผ ๊ด€๋ฆฌ
  • unstable tree: ์ด๋ฒˆ ์Šค์บ” ์ฃผ๊ธฐ์—์„œ ๋ณ‘ํ•ฉ ํ›„๋ณด๋กœ ๋ฐœ๊ฒฌ๋œ ์ต๋ช… ํŽ˜์ด์ง€๋ฅผ ์ž„์‹œ๋กœ ๋ณด๊ด€ํ•˜๋Š” ๊ตฌ์กฐ
  • ํ•ด์‹œ ๋น„๊ต์™€ tree ํƒ์ƒ‰์œผ๋กœ ํ›„๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ขํžŒ ๋’ค ์ตœ์ข…์ ์œผ๋กœ memcmp()๋กœ ๋™์ผ์„ฑ์„ ํ™•์ธ
  • max_page_sharing ํ•œ๋„์— ๋„๋‹ฌํ•œ ํŽ˜์ด์ง€๋Š” ๋ณ„๋„ ์ฒด์ธ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ์ด ๋น„์šฉ์ด ์ปค์ง€๋ฉด VM ์—ฐ์‚ฐ ์ง€์—ฐ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ

sysfs ์ธํ„ฐํŽ˜์ด์Šค

KSM์€ /sys/kernel/mm/ksm/ ๋””๋ ‰ํ† ๋ฆฌ์˜ sysfs ํŒŒ์ผ์„ ํ†ตํ•ด ์ œ์–ด๋ฉ๋‹ˆ๋‹ค.

ํŒŒ๋ผ๋ฏธํ„ฐ ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
pages_to_scan 100 ํ•œ ๋ฒˆ์— ์Šค์บ”ํ•  ํŽ˜์ด์ง€ ์ˆ˜
sleep_millisecs 20 ์Šค์บ” ๊ฐ„๊ฒฉ (ms)
run 0 ksmd ์ œ์–ด (0:์ค‘์ง€, 1:์‹คํ–‰, 2:๋ณ‘ํ•ฉํ•ด์ œ)
merge_across_nodes 1 NUMA ๋…ธ๋“œ ๊ฐ„ ๋ณ‘ํ•ฉ ํ—ˆ์šฉ
use_zero_pages 0 ์ œ๋กœ ํŽ˜์ด์ง€ ํŠน๋ณ„ ์ฒ˜๋ฆฌ
max_page_sharing 8192 KSM ํŽ˜์ด์ง€๋‹น ์ตœ๋Œ€ ๊ณต์œ  ์ˆ˜
stable_node_chains_prune_millisecs ์ปค๋„ ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ ๊ณต์œ  ํ•œ๋„ ๋„๋‹ฌ ํŽ˜์ด์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ •๋ฆฌ ์ฃผ๊ธฐ
smart_scan 1 ์Šค๋งˆํŠธ ์Šค์บ” (์ด์ „ ์‹คํŒจ ํŽ˜์ด์ง€ ์Šคํ‚ต)

KSM ์–ด๋“œ๋ฐ”์ด์ €

KSM ์–ด๋“œ๋ฐ”์ด์ €๋Š” ํ›„๋ณด ํŽ˜์ด์ง€ ์ˆ˜์˜ ๋™์ ์ธ ๋ณ€ํ™”์— ์ ์‘ํ•˜์—ฌ pages_to_scan ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.

  • advisor_mode=scan-time: ์Šค์บ” ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์–ด๋“œ๋ฐ”์ด์ € ํ™œ์„ฑํ™”
  • advisor_target_scan_time: ์ „์ฒด ํ›„๋ณด ํŽ˜์ด์ง€ ์Šค์บ” ๋ชฉํ‘œ ์‹œ๊ฐ„(์ดˆ). ๊ธฐ๋ณธ๊ฐ’ 200์ดˆ
  • advisor_max_cpu: ksmd ์Šค๋ ˆ๋“œ์˜ ์ตœ๋Œ€ CPU ์‚ฌ์šฉ๋ฅ  ์ƒํ•œ. ๊ธฐ๋ณธ๊ฐ’ 70%
  • advisor_min_pages_to_scan/advisor_max_pages_to_scan: pages_to_scan ๋ฒ”์œ„ ์ œํ•œ

์ œ๋กœ ํŽ˜์ด์ง€ ์ตœ์ ํ™”

use_zero_pages ์˜ต์…˜์€ ๋นˆ ํŽ˜์ด์ง€(zero page)๋ฅผ ํŠน๋ณ„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ปค๋„ ์ œ๋กœ ํŽ˜์ด์ง€์™€ ๋ณ‘ํ•ฉํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  • use_zero_pages=1๋กœ ์„ค์ •ํ•˜๋ฉด ๋นˆ ํŽ˜์ด์ง€๋“ค์ด ๊ฐ๊ฐ ์ œ๋กœ ํŽ˜์ด์ง€์™€ ๋ณ‘ํ•ฉ
  • ์ƒ‰์ƒ ์ œ๋กœ ํŽ˜์ด์ง€(coloured zero page)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜์—์„œ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  • ํŠน์ • ์›Œํฌ๋กœ๋“œ์—์„œ๋Š” ์ฒดํฌ์„ฌ์ด ์ผ์น˜ํ•˜๋Š” ๋นˆ ํŽ˜์ด์ง€๋ฅผ ๊ณผ๋„ํ•˜๊ฒŒ ์Šค์บ”ํ•  ์ˆ˜ ์žˆ์–ด ์ฃผ์˜ ํ•„์š”

NUMA ์ธ์‹ ๋ณ‘ํ•ฉ

merge_across_nodes ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ NUMA ๋…ธ๋“œ์˜ ํŽ˜์ด์ง€ ๋ณ‘ํ•ฉ์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

  • merge_across_nodes=1 (๊ธฐ๋ณธ๊ฐ’): ๋ชจ๋“  ๋…ธ๋“œ์˜ ํŽ˜์ด์ง€๋ฅผ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ตœ๋Œ€ํ•œ ๋งŽ์€ ๊ณต์œ  ๋‹ฌ์„ฑ
  • merge_across_nodes=0: ๋™์ผํ•œ NUMA ๋…ธ๋“œ ๋‚ด ํŽ˜์ด์ง€๋งŒ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ ‘๊ทผ ์ง€์—ฐ์‹œ๊ฐ„ ์ตœ์†Œํ™”
  • NUMA ๊ฑฐ๋ฆฌ๊ฐ€ ํฐ ๋ฉ€ํ‹ฐ๋…ธ๋“œ ์‹œ์Šคํ…œ์—์„œ๋Š” 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์ง€์—ฐ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ 
  • ์„ค์ • ๋ณ€๊ฒฝ ์‹œ ๋จผ์ € run=2๋กœ ๋ชจ๋“  ๊ณต์œ ๋ฅผ ํ•ด์ œํ•œ ํ›„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

๋น„๊ต/๋ถ„์„

๊ธฐ๋ฒ• ์›๋ฆฌ ์ ํ•ฉํ•œ ๋Œ€์ƒ CPU ๋น„์šฉ ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ ํšจ๊ณผ ๋ณด์•ˆ ๊ณ ๋ ค
KSM (madvise) ์ฃผ๊ธฐ์  ์Šค์บ”์œผ๋กœ ๋™์ผ ํŽ˜์ด์ง€ ๋ณ‘ํ•ฉ KVM, ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ์ค‘๊ฐ„~๋†’์Œ ๋†’์Œ (์ตœ๋Œ€ 300% ์˜ค๋ฒ„์ปค๋ฐ‹) Side-channel ์œ„ํ—˜
KSM (global) ์ „์ฒด ์ต๋ช… ํŽ˜์ด์ง€ ์Šค์บ” ๋ฒ”์šฉ ๋†’์Œ ์ค‘๊ฐ„ ๋†’์€ ์Šค์บ” ๋น„์šฉ
COW (fork) fork ์‹œ ํŽ˜์ด์ง€ ๊ณต์œ , ์“ฐ๊ธฐ ์‹œ ๋ณต์ œ ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ ๋‚ฎ์Œ ์ค‘๊ฐ„ ์•ˆ์ „
ํˆฌ๋ช… ๊ฑฐ๋Œ€ ํŽ˜์ด์ง€ 4KBโ†’2MB ํŽ˜์ด์ง€ ๋ณ‘ํ•ฉ ๋Œ€์šฉ๋Ÿ‰ ์›Œํฌ๋กœ๋“œ ๋‚ฎ์Œ ์บ์‹œ ํšจ์œจ ํ–ฅ์ƒ ์•ˆ์ „
ํŽ˜์ด์ง€ ๊ณต์œ  (Uffd) userfaultfd๋ฅผ ํ†ตํ•œ ๊ณต์œ  VM ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ค‘๊ฐ„ ๋†’์Œ VM ์˜์กด

๋™์ž‘ ์›๋ฆฌ

KSM ์Šค์บ” ๋ฐ ๋ณ‘ํ•ฉ ํ๋ฆ„

  1. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด madvise(MADV_MERGEABLE)๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ KSM์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  2. ksmd ์Šค๋ ˆ๋“œ๊ฐ€ ์„ค์ •๋œ ๊ฐ„๊ฒฉ(sleep_millisecs)๋งˆ๋‹ค ํ›„๋ณด ์˜์—ญ์„ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ฐ ํŽ˜์ด์ง€์— ๋Œ€ํ•ด ํ•ด์‹œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ , ๋™์ผํ•œ ํ•ด์‹œ๋ฅผ ๊ฐ€์ง„ ๊ธฐ์กด ํŽ˜์ด์ง€์™€ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
  4. memcmp()๋กœ ํŽ˜์ด์ง€ ๋‚ด์šฉ์ด ์™„์ „ํžˆ ์ผ์น˜ํ•˜๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€๋“ค์„ ํ•˜๋‚˜์˜ ์“ฐ๊ธฐ ๋ณดํ˜ธ ํŽ˜์ด์ง€๋กœ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ณ‘ํ•ฉ๋œ ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค์˜ ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ์—”ํŠธ๋ฆฌ๊ฐ€ ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.
  6. ๋‚˜์ค‘์— ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€์— ์“ฐ๊ธฐ๋ฅผ ์‹œ๋„ํ•˜๋ฉด COW๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋ณต์ œ๋ฉ๋‹ˆ๋‹ค.
๋ณ‘ํ•ฉ ๊ฒฝ๋กœ:
  App Memory โ†’ madvise(MERGEABLE) โ†’ ksmd Scan โ†’ Hash Compare โ†’ memcmp โ†’ Merge (COW)

์“ฐ๊ธฐ ๊ฒฝ๋กœ:
  Process Write โ†’ COW Fault โ†’ Page Copy โ†’ Unmerge
KSM ๋ณ‘ํ•ฉ ํ๋ฆ„

๊ทธ๋ฆผ 2. KSM ํŽ˜์ด์ง€ ์Šค์บ”, ๋ณ‘ํ•ฉ, COW ํ๋ฆ„

KSM ์ˆ˜์ต์„ฑ ๊ณ„์‚ฐ

KSM์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ˆ์•ฝํ•˜์ง€๋งŒ rmap_item ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ์ „์ฒด ์ˆ˜์ต์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค:

general_profit โ‰ˆ ksm_saved_pages * sizeof(page) - (all_rmap_items) * sizeof(rmap_item)
  • ksm_saved_pages: pages_sharing + ksm_zero_pages์˜ ํ•ฉ
  • all_rmap_items: pages_sharing + pages_shared + pages_unshared + pages_volatile์˜ ํ•ฉ

ํ”„๋กœ์„ธ์Šค๋ณ„ ์ˆ˜์ต์„ฑ์€ /proc/<pid>/ksm_stat์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

process_profit โ‰ˆ ksm_saved_pages * sizeof(page) - ksm_rmap_items * sizeof(rmap_item)
  • ksm_rmap_items/ksm_merging_pages ๋น„์œจ์ด 64๋น„ํŠธ CPU์—์„œ 64๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์ˆ˜์ต์ด ๊ฑฐ์˜ ์—†๊ฑฐ๋‚˜ ์Œ์ˆ˜

๋ชจ๋‹ˆํ„ฐ๋ง ์ง€ํ‘œ

/sys/kernel/mm/ksm/ ๋ฐ /proc/vmstat์—์„œ KSM ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์ง€ํ‘œ ์„ค๋ช…
pages_shared ๊ณต์œ ๋œ ๊ณ ์œ  ํŽ˜์ด์ง€ ์ˆ˜
pages_sharing ๊ณต์œ ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ถ”๊ฐ€ ์‚ฌ์ดํŠธ ์ˆ˜ (์ ˆ์•ฝ๋œ ๋ฉ”๋ชจ๋ฆฌ)
pages_unshared ๊ณ ์œ ํ•˜์ง€๋งŒ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ™•์ธ๋˜๋Š” ํŽ˜์ด์ง€ ์ˆ˜
pages_volatile ๋„ˆ๋ฌด ๋น ๋ฅด๊ฒŒ ๋ณ€๊ฒฝ๋˜์–ด ํŠธ๋ฆฌ์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์—†๋Š” ํŽ˜์ด์ง€ ์ˆ˜
pages_skipped ์Šค๋งˆํŠธ ์Šค์บ” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๊ฑด๋„ˆ๋›ด ํŽ˜์ด์ง€ ์ˆ˜
full_scans ๋ชจ๋“  ๋ณ‘ํ•ฉ ๊ฐ€๋Šฅ ์˜์—ญ์ด ์Šค์บ”๋œ ํšŸ์ˆ˜
stable_node_chains max_page_sharing ํ•œ๋„์— ๋‹ฟ์€ KSM ํŽ˜์ด์ง€ ์ˆ˜
stable_node_dups dedup ํ•œ๋„ ๋•Œ๋ฌธ์— ๋ณต์ œ๋œ stable node ์ˆ˜
ksm_zero_pages ์ œ๋กœ ํŽ˜์ด์ง€ ์ตœ์ ํ™”๋กœ ์ ˆ์•ฝ๋œ ํŽ˜์ด์ง€ ์ˆ˜
cow_ksm KSM ํŽ˜์ด์ง€์— ์“ฐ๊ธฐ ์‹œ COW ๋ฐœ์ƒ ํšŸ์ˆ˜
ksm_swpin_copy ์Šค์™‘์ธ ์‹œ KSM ํŽ˜์ด์ง€ ๋ณต์ œ ํšŸ์ˆ˜

์Šค๋งˆํŠธ ์Šค์บ”

smart_scan=1 (๊ธฐ๋ณธ๊ฐ’)๋กœ ์„ค์ •ํ•˜๋ฉด ์ด์ „์— ๋ณ‘ํ•ฉ๋˜์ง€ ์•Š์€ ํŽ˜์ด์ง€๋ฅผ ๊ฑด๋„ˆ๋›ฐ์–ด ์Šค์บ” ํšจ์œจ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  • ์ด์ „ ์Šค์บ”์—์„œ ๋ณ‘ํ•ฉ์— ์‹คํŒจํ•œ ํŽ˜์ด์ง€๋Š” ๊ฑด๋„ˆ๋œ€
  • pages_skipped ์ง€ํ‘œ๋กœ ํšจ๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง ๊ฐ€๋Šฅ
  • ์Šค์บ” ๋น„์šฉ์„ ์ค„์ด๋ฉด์„œ๋„ ๋ณ‘ํ•ฉ ๊ฐ€๋Šฅ์„ฑ์„ ์œ ์ง€

์žฅ๋‹จ์ 

์žฅ์ 

  • ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ: ๋™์ผํ•œ ํŽ˜์ด์ง€๋ฅผ ๊ณต์œ ํ•˜์—ฌ ๋ฌผ๋ฆฌ์  RAM ์‚ฌ์šฉ๋Ÿ‰ ๋Œ€ํญ ๊ฐ์†Œ
  • KVM ์ตœ์ ํ™”: ๊ฐ€์ƒํ™” ํ™˜๊ฒฝ์—์„œ ๋‹ค์ˆ˜์˜ VM์„ ๋” ์ ์€ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์šด์˜ ๊ฐ€๋Šฅ
  • ์œ ์—ฐํ•œ ์ œ์–ด: madvise๋กœ ๋ณ‘ํ•ฉ ๋Œ€์ƒ์„ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ง์ ‘ ์ง€์ •
  • ์ž๋™ ์ตœ์ ํ™”: ์–ด๋“œ๋ฐ”์ด์ €๊ฐ€ ์›Œํฌ๋กœ๋“œ์— ๋”ฐ๋ผ ์Šค์บ” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž๋™ ์กฐ์ ˆ
  • NUMA ์ธ์‹: NUMA ๋…ธ๋“œ ๊ฐ„ ๋ณ‘ํ•ฉ์„ ์ œ์–ดํ•˜์—ฌ ์ ‘๊ทผ ์ง€์—ฐ์‹œ๊ฐ„ ์ตœ์†Œํ™” ๊ฐ€๋Šฅ

๋‹จ์ 

  • CPU ์˜ค๋ฒ„ํ—ค๋“œ: ksmd ์Šค๋ ˆ๋“œ๊ฐ€ ์ง€์†์ ์œผ๋กœ CPU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์บ” ์ˆ˜ํ–‰
  • ๋ณด์•ˆ ์œ„ํ—˜: ๋ฉ”๋ชจ๋ฆฌ ๊ณต์œ ๋กœ ์ธํ•œ Side-channel ๊ณต๊ฒฉ ๊ฐ€๋Šฅ์„ฑ
  • ์ง€์—ฐ์‹œ๊ฐ„ ์ฆ๊ฐ€: COW ๋ฐœ์ƒ ์‹œ ์ถ”๊ฐ€ ์ง€์—ฐ์‹œ๊ฐ„ ๋ฐœ์ƒ
  • ์Šค์™‘ ์‹œ ๊ณต์œ  ํ•ด์ œ: ์Šค์™‘์•„์›ƒ ํ›„ ์Šค์™‘์ธ ์‹œ ๊ณต์œ ๊ฐ€ ํ•ด์ œ๋˜์–ด ์žฌ๋ณ‘ํ•ฉ ํ•„์š”
  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์˜ค๋ฒ„ํ—ค๋“œ: rmap_item ์ €์žฅ์„ ์œ„ํ•œ ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„

๊ด€๋ จ ๊ธฐ์ˆ 

  • KVM (Kernel-based Virtual Machine): KSM์ด ์ตœ์ดˆ๋กœ ๊ฐœ๋ฐœ๋œ ๊ฐ€์ƒํ™” ํ”Œ๋žซํผ
  • COW (Copy-on-Write): KSM์˜ ๊ธฐ๋ฐ˜ ๊ธฐ์ˆ ๋กœ ์“ฐ๊ธฐ ๋ฐœ์ƒ ์‹œ ํŽ˜์ด์ง€ ๋ณต์ œ
  • madvise: ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ํŒจํ„ด์„ ์ปค๋„์— ์ „๋‹ฌํ•˜๋Š” ์‹œ์Šคํ…œ ์ฝœ
  • NUMA (Non-Uniform Memory Access): ๋ฉ€ํ‹ฐ์†Œ์ผ“ ์‹œ์Šคํ…œ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ์ตœ์ ํ™”
  • ํˆฌ๋ช… ๊ฑฐ๋Œ€ ํŽ˜์ด์ง€ (THP): 4KB ํŽ˜์ด์ง€๋ฅผ 2MB๋กœ ๋ณ‘ํ•ฉํ•˜์—ฌ ์บ์‹œ ํšจ์œจ ํ–ฅ์ƒ
  • zRAM: ๋ฉ”๋ชจ๋ฆฌ ์••์ถ•์„ ํ†ตํ•œ ๊ฐ€์ƒ ์Šค์™‘ ๊ตฌํ˜„
  • ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” (rmap): KSM์ด ์‚ฌ์šฉํ•˜๋Š” ์—ญ๋ฐฉํ–ฅ ๋งคํ•‘ ๊ตฌ์กฐ
  • Linux Kernel ๋ฌธ์„œ: /sys/kernel/mm/ksm/ ํŠœ๋„ˆ๋ธ”, ์ด๋ฒคํŠธ ์นด์šดํ„ฐ, ์ˆ˜์ต์„ฑ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€ ๋ฌธ์„œ
  • madvise(2) ๋งค๋‰ด์–ผ: MADV_MERGEABLE, MADV_UNMERGEABLE ์ ์šฉ ๋Œ€์ƒ๊ณผ ์‹คํŒจ ์กฐ๊ฑด ์„ค๋ช…

ํ•ต์‹ฌ ์ •๋ฆฌ

KSM์€ Linux ์ปค๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ์ค‘๋ณต ์ œ๊ฑฐ ๊ธฐ์ˆ ๋กœ, ksmd ์ปค๋„ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ๋™์ผํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฐพ์•„ ์“ฐ๊ธฐ ๋ณดํ˜ธ๋œ ํ•˜๋‚˜์˜ ๊ณต์œ  ํŽ˜์ด์ง€๋กœ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. KVM ๊ฐ€์ƒํ™” ํ™˜๊ฒฝ์—์„œ ์œ ์šฉํ•˜๋ฉฐ, madvise ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋ณ‘ํ•ฉ ๋Œ€์ƒ์„ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. sysfs๋ฅผ ํ†ตํ•œ ์„ธ๋ฐ€ํ•œ ์ œ์–ด์™€ ์–ด๋“œ๋ฐ”์ด์ €๋ฅผ ํ†ตํ•œ ์ž๋™ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, CPU ์˜ค๋ฒ„ํ—ค๋“œ์™€ ๋ณด์•ˆ ์œ„ํ—˜๊ณผ ๊ฐ™์€ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ์„ค์ •๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ ํšจ๊ณผ๋ฅผ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.