The benefits and costs of writing a POSIX kernel in a high-level - - PowerPoint PPT Presentation

the benefits and costs of writing a posix kernel in a
SMART_READER_LITE
LIVE PREVIEW

The benefits and costs of writing a POSIX kernel in a high-level - - PowerPoint PPT Presentation

The benefits and costs of writing a POSIX kernel in a high-level language Cody Cutler, M. Frans Kaashoek, Robert T. Morris MIT CSAIL 1 / 38 Should we use high-level languages to build OS kernels? 2 / 38 HLL Benefits Easier to program


slide-1
SLIDE 1

The benefits and costs of writing a POSIX kernel in a high-level language

Cody Cutler, M. Frans Kaashoek, Robert T. Morris

MIT CSAIL

1 / 38

slide-2
SLIDE 2

Should we use high-level languages to build OS kernels?

2 / 38

slide-3
SLIDE 3

HLL Benefits

Easier to program Simpler concurrency with GC Prevents classes of kernel bugs

3 / 38

slide-4
SLIDE 4

Kernel memory safety matters

Inspected Linux kernel execute code CVEs for 2017 40 CVEs due to just memory-safety bugs

4 / 38

slide-5
SLIDE 5

Kernel memory safety matters

Inspected Linux kernel execute code CVEs for 2017 40 CVEs due to just memory-safety bugs HLL would have prevented code execution

4 / 38

slide-6
SLIDE 6

HLL downside: safety costs performance

Bounds, cast, nil-pointer checks Reflection Garbage collection

5 / 38

slide-7
SLIDE 7

Goal: measure HLL impact

Pros: Reduction of bugs Simpler code Cons: HLL safety tax GC CPU and memory overhead GC pause times

6 / 38

slide-8
SLIDE 8

Methodology

Build new HLL kernel, compare with Linux Isolate HLL impact: Same apps, POSIX interface, and monolithic organization

7 / 38

slide-9
SLIDE 9

Previous work

Taos(ASPLOS’87), Spin(SOSP’95), Singularity(SOSP’07), Tock(SOSP’17), J-kernel(ATC’98), KaffeOS(ATC’00), House(ICFP’05),... Explore new ideas Different architectures Several studies of HLL versus C for user programs Kernels different from user programs

8 / 38

slide-10
SLIDE 10

Previous work

Taos(ASPLOS’87), Spin(SOSP’95), Singularity(SOSP’07), Tock(SOSP’17), J-kernel(ATC’98), KaffeOS(ATC’00), House(ICFP’05),... Explore new ideas Different architectures Several studies of HLL versus C for user programs Kernels different from user programs None measure HLL impact in a monolithic POSIX kernel

8 / 38

slide-11
SLIDE 11

Contributions

BISCUIT, new x86-64 Go kernel Runs unmodified Linux applications with good performance Measurements of HLL costs for NGINX, Redis, and CMailbench Description of qualitative ways HLL helped New scheme to deal with heap exhaustion

9 / 38

slide-12
SLIDE 12

Which HLL?

Go is a good choice: Easy to call asm Compiled to machine code w/good compiler Easy concurrency Easy static analysis GC

10 / 38

slide-13
SLIDE 13

Go’s GC

Concurrent mark and sweep Stop-the-world pauses of 10s of µs

11 / 38

slide-14
SLIDE 14

BISCUIT overview

58 syscalls, LOC: 28k Go, 1.5k assembly (boot, entry/exit)

12 / 38

slide-15
SLIDE 15

Features

Multicore Threads Journaled FS (7k LOC) Virtual memory (2k LOC) TCP/IP stack (5k LOC) Drivers: AHCI and Intel 10G NIC (3k LOC)

13 / 38

slide-16
SLIDE 16

No fundamental challenges due to HLL But many implementation puzzles Interrupts Kernel threads are lightweight Runtime on bare-metal ...

14 / 38

slide-17
SLIDE 17

No fundamental challenges due to HLL But many implementation puzzles Interrupts Kernel threads are lightweight Runtime on bare-metal ... Surprising puzzle: heap exhaustion

14 / 38

slide-18
SLIDE 18

Puzzle: Heap exhaustion

15 / 38

slide-19
SLIDE 19

Puzzle: Heap exhaustion

15 / 38

slide-20
SLIDE 20

Puzzle: Heap exhaustion

15 / 38

slide-21
SLIDE 21

Puzzle: Heap exhaustion

15 / 38

slide-22
SLIDE 22

Puzzle: Heap exhaustion

Can’t allocate heap memory = ⇒ nothing works All kernels face this problem

15 / 38

slide-23
SLIDE 23

How to recover?

Strawman 1: Wait for memory in allocator?

16 / 38

slide-24
SLIDE 24

How to recover?

Strawman 1: Wait for memory in allocator? May deadlock!

16 / 38

slide-25
SLIDE 25

How to recover?

Strawman 1: Wait for memory in allocator? May deadlock! Strawman 2: Check/handle allocation failure, like C kernels?

16 / 38

slide-26
SLIDE 26

How to recover?

Strawman 1: Wait for memory in allocator? May deadlock! Strawman 2: Check/handle allocation failure, like C kernels? Difficult to get right

16 / 38

slide-27
SLIDE 27

How to recover?

Strawman 1: Wait for memory in allocator? May deadlock! Strawman 2: Check/handle allocation failure, like C kernels? Difficult to get right Can’t! Go doesn’t expose failed allocations and implicitly allocates Both cause problems for Linux; see “too small to fail” rule

16 / 38

slide-28
SLIDE 28

BISCUIT solution: reserve memory

To execute syscall...

17 / 38

slide-29
SLIDE 29

BISCUIT solution: reserve memory

To execute syscall...

17 / 38

slide-30
SLIDE 30

BISCUIT solution: reserve memory

To execute syscall...

17 / 38

slide-31
SLIDE 31

BISCUIT solution: reserve memory

To execute syscall...

17 / 38

slide-32
SLIDE 32

BISCUIT solution: reserve memory

To execute syscall...

17 / 38

slide-33
SLIDE 33

BISCUIT solution: reserve memory

To execute syscall... No checks, no error handling code, no deadlock

17 / 38

slide-34
SLIDE 34

Reservations

HLL easy to analyze Tool computes reservation via escape analysis Using Go’s static analysis packages ≈ three days of expert effort to apply tool

18 / 38

slide-35
SLIDE 35

Building BISCUIT was similar to other kernels

19 / 38

slide-36
SLIDE 36

Building BISCUIT was similar to other kernels BISCUIT adopted many Linux optimizations: large pages for kernel text per-CPU NIC transmit queues RCU-like directory cache concurrent FS transactions pad structs to remove false sharing Good OS performance more about optimizations, less about HLL

19 / 38

slide-37
SLIDE 37

Eval questions

Should we use high-level languages to build OS kernels? 1 Did BISCUIT benefit from HLL features? 2 Is BISCUIT performance in the same league as Linux? 3 What is the breakdown of HLL tax? 4 What is the performance cost of Go compared to C? More experiments in paper

20 / 38

slide-38
SLIDE 38

1: Qualitative benefits of HLL features

Simpler code with: GC’ed allocation defer multi-valued return closures maps

21 / 38

slide-39
SLIDE 39

HLL example benefits

Example 1: Memory safety Example 2: Simpler concurrency

22 / 38

slide-40
SLIDE 40

1: BISCUIT benefits from memory safety

Inspected fixes for all publicly-available execute code CVEs in Linux kernel for 2017 Category # Outcome in Go — 11 unknown logic 14 same use-after-free/double-free 8 disappear due to GC

  • ut-of-bounds

32 panic or disappear due to GC panic likely better than malicious code execution

23 / 38

slide-41
SLIDE 41

1: BISCUIT benefits from simpler concurrency

Generally, concurrency with GC simpler Particularly, GC greatly simplifies read-lock-free data structures Challenge: In C, how to determine when last reader is done? Main purpose of read-copy update (RCU) (PDCS’98) Linux uses RCU, but it’s not easy Code to start and end RCU sections No sleeping/scheduling in RCU sections ... In Go, no extra code — GC takes care of it

24 / 38

slide-42
SLIDE 42

Experimental setup

Hardware: 4 core 2.8Ghz Xeon-X3460 16 GB RAM Hyperthreads disabled Eval application: NGINX (1.11.5) – webserver Redis (3.0.5) – key/value store CMailbench – mail-server benchmark

25 / 38

slide-43
SLIDE 43

Applications are kernel intensive

No idle time 79%-92% kernel time In-memory FS Run for a minute 512MB heap RAM for BISCUIT

26 / 38

slide-44
SLIDE 44

2: Is BISCUIT perf in the same league as Linux?

Debian 9.4, Linux 4.9.82 Disabled expensive features: page-table isolation retpoline kernel address space layout randomization transparent huge-pages ...

27 / 38

slide-45
SLIDE 45

2: Biscuit is in the same league

BISCUIT ops/s Linux ops/s Ratio CMailbench (mem) 15,862 17,034 1.07 NGINX 88,592 94,492 1.07 Redis 711,792 775,317 1.09

28 / 38

slide-46
SLIDE 46

2: Biscuit is in the same league

BISCUIT ops/s Linux ops/s Ratio CMailbench (mem) 15,862 17,034 1.07 NGINX 88,592 94,492 1.07 Redis 711,792 775,317 1.09

28 / 38

slide-47
SLIDE 47

HLL cost unclear from comparison

May understate Linux performance due to features: NUMA awareness Optimizations for large number of cores (>4) ... Focus on HLL costs: Measure CPU cycles BISCUIT pays for HLL tax Compare code paths that differ only by language

29 / 38

slide-48
SLIDE 48

3: What is the breakdown of HLL tax?

Measure HLL tax: GC cycles Prologue cycles Write barrier cycles Safety cycles

30 / 38

slide-49
SLIDE 49

3: Prologue cycles are most expensive

GC GCs Prologue Write barrier Safety cycles cycles cycles cycles CMailbench 3% 42 6% < 1% 3% NGINX 2% 32 6% < 1% 2% Redis 1% 30 4% < 1% 2%

31 / 38

slide-50
SLIDE 50

3: Prologue cycles are most expensive

GC GCs Prologue Write barrier Safety cycles cycles cycles cycles CMailbench 3% 42 6% < 1% 3% NGINX 2% 32 6% < 1% 2% Redis 1% 30 4% < 1% 2%

31 / 38

slide-51
SLIDE 51

3: Prologue cycles are most expensive

GC GCs Prologue Write barrier Safety cycles cycles cycles cycles CMailbench 3% 42 6% < 1% 3% NGINX 2% 32 6% < 1% 2% Redis 1% 30 4% < 1% 2%

31 / 38

slide-52
SLIDE 52

3: Prologue cycles are most expensive

GC GCs Prologue Write barrier Safety cycles cycles cycles cycles CMailbench 3% 42 6% < 1% 3% NGINX 2% 32 6% < 1% 2% Redis 1% 30 4% < 1% 2%

31 / 38

slide-53
SLIDE 53

3: Prologue cycles are most expensive

GC GCs Prologue Write barrier Safety cycles cycles cycles cycles CMailbench 3% 42 6% < 1% 3% NGINX 2% 32 6% < 1% 2% Redis 1% 30 4% < 1% 2% Benchmarks allocate kernel heap rapidly but have little persistent kernel heap data Cycles used by GC increase with size of live kernel heap Dedicate 2 or 3× memory ⇒ low GC cycles

31 / 38

slide-54
SLIDE 54

4: What is the cost of Go compared to C?

Make code paths same in BISCUIT and Linux Two code paths in paper pipe ping-pong (systems calls, context switching) page-fault handler (exceptions, VM) Focus on pipe ping-pong: LOC: 1.2k Go, 1.8k C No allocation; no GC Top-10 most expensive instructions match

32 / 38

slide-55
SLIDE 55

4: C is 15% faster

C Go (ops/s) (ops/s) Ratio 536,193 465,811 1.15 Prologue/safety-checks ⇒ 16% more instructions

33 / 38

slide-56
SLIDE 56

Should one use HLL for a new kernel?

The HLL worked well for kernel development Performance is paramount ⇒ use C (up to 15%) Minimize memory use ⇒ use C (↓ mem. budget, ↑ GC cost) Safety is paramount ⇒ use HLL (40 CVEs stopped) Performance merely important ⇒ use HLL (pay 15%, memory)

34 / 38

slide-57
SLIDE 57

Questions?

The HLL worked well for kernel development Performance is paramount ⇒ use C (up to 15%) Minimize memory use ⇒ use C (↓ mem. budget, ↑ GC cost) Safety is paramount ⇒ use HLL (40 CVEs stopped) Performance merely important ⇒ use HLL (pay 15%, memory) git clone https://github.com/mit-pdos/biscuit.git

35 / 38

slide-58
SLIDE 58

36 / 38