Verifying concurrent software using movers in CSPEC Tej Chajed , - - PowerPoint PPT Presentation

verifying concurrent software using movers in cspec
SMART_READER_LITE
LIVE PREVIEW

Verifying concurrent software using movers in CSPEC Tej Chajed , - - PowerPoint PPT Presentation

Verifying concurrent software using movers in CSPEC Tej Chajed , Frans Kaashoek, Butler Lampson*, Nickolai Zeldovich MIT CSAIL and *Microsoft Concurrent software is difficult to get right Programmer cannot reason about code in sequence 2


slide-1
SLIDE 1

Verifying concurrent software using movers in CSPEC

Tej Chajed, Frans Kaashoek, Butler Lampson*, Nickolai Zeldovich MIT CSAIL and *Microsoft

slide-2
SLIDE 2

Concurrent software is difficult to get right

2

Programmer cannot reason about code in sequence…

slide-3
SLIDE 3

Concurrent software is difficult to get right

3

instead, must consider many executions: Programmer cannot reason about code in sequence…

slide-4
SLIDE 4

Concurrent software is difficult to get right

3

instead, must consider many executions: … Programmer cannot reason about code in sequence…

slide-5
SLIDE 5

Goal: verify concurrent software

4

slide-6
SLIDE 6

Challenge for formal verification

  • Proofs must also cover every execution
  • Many approaches to managing this complexity
  • movers [Lipton, 1975]
  • rely-guarantee [1983]
  • RGSep [CONCUR 2007]
  • FCSL [PLDI 2015]
  • Iris [POPL 2017, LICS 2018, others]
  • many others

5

slide-7
SLIDE 7

Challenge for formal verification

  • Proofs must also cover every execution
  • Many approaches to managing this complexity
  • movers [Lipton, 1975]
  • rely-guarantee [1983]
  • RGSep [CONCUR 2007]
  • FCSL [PLDI 2015]
  • Iris [POPL 2017, LICS 2018, others]
  • many others
  • This work: our experience using movers

5

slide-8
SLIDE 8

Movers: reduce concurrent executions to sequential ones

6

time B 3 2 A 1

blue thread green thread

1 2 3 A B

slide-9
SLIDE 9

Movers: reduce concurrent executions to sequential ones

6

has the same effect as movers B 3 2 A 1

blue thread green thread

1 2 3 A B

B 3 2 A 1

slide-10
SLIDE 10

Movers: reduce concurrent executions to sequential ones

6

has the same effect as movers sequential reasoning B 3 2 A 1

blue thread green thread

1 2 3 A B

B 3 2 A 1 B 3 2 A 1

slide-11
SLIDE 11

Prior systems with mover reasoning

7

CIVL [CAV ’15, CAV ’18] framework relies pen & paper proofs IronFleet [SOSP ’15]

  • nly move network send/receive
slide-12
SLIDE 12

Contribution: CSPEC

  • Framework for verifying concurrency in systems software
  • general-purpose movers
  • patterns to support mover reasoning
  • machine checked in Coq to support extensibility

8

slide-13
SLIDE 13

Contribution: CSPEC

  • Framework for verifying concurrency in systems software
  • general-purpose movers
  • patterns to support mover reasoning
  • machine checked in Coq to support extensibility
  • Case studies using CSPEC
  • Lock-free file-system concurrency
  • Spinlock on top of x86-TSO (see paper)

8

slide-14
SLIDE 14

Case study: mail server using file-system concurrency

9

spool file system mbox

slide-15
SLIDE 15

Mail servers exploit file-system concurrency

10

spool file system # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”) mbox

1 2 3

slide-16
SLIDE 16

Mail servers exploit file-system concurrency

11

spool file system msg mbox

1 2 3

# accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-17
SLIDE 17

Spooling avoids reading partially-written messages

12

spool file system mbox

1 2 3

$TID =10 # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-18
SLIDE 18

Spooling avoids reading partially-written messages

12

spool file system

10

mbox

1 2 3

$TID =10 # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

10

slide-19
SLIDE 19

Threads use unique IDs to avoid conflicts

13

spool file system

10

msg mbox

1 2 3

$TID =10 $TID =11 # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-20
SLIDE 20

Threads use unique IDs to avoid conflicts

14

spool file system

10

mbox

1 2 3

$TID =10 $TID =11 # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-21
SLIDE 21

Threads use unique IDs to avoid conflicts

14

spool file system

10 11

mbox

1 2 3

$TID =10 $TID =11 # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-22
SLIDE 22

Timestamps help generate unique message names

15

spool file system mbox

1 2 3 4 10 11

link(/spool/11, /mbox/4) # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-23
SLIDE 23

Timestamps help generate unique message names

16

spool mbox

1 2 3

file system

4 10 11

link(/spool/10, /mbox/4)

EEXISTS ✗

# accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-24
SLIDE 24

Timestamps help generate unique message names

17

spool file system mbox

1 2 3 4 5 10 11

link(/spool/10, /mbox/5) # accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-25
SLIDE 25

Delivery concurrency does not use locks

18

spool file system mbox

1 2 3 5 4 10

# accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-26
SLIDE 26

Delivery concurrency does not use locks

19

spool file system mbox

1 2 3 4 5

# accept def deliver(msg): # spool create(“/spool/$TID”) write(“/spool/$TID”, msg) # store while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break # cleanup unlink(“/spool/$TID”)

slide-27
SLIDE 27

Proving delivery correct in CSPEC

20

file-system spec delivery specification

implementation and proof

CSPEC CSPEC provides supporting definitions and theorems

slide-28
SLIDE 28

Proof engineer reasons about file-system

  • perations

21

def deliver(msg): create(“/spool/$TID”, msg) while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break unlink(“/spool/$TID”) create( /sp/$TID, msg) ✓ link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t) ✓ unlink( /sp/$TID) ✓

slide-29
SLIDE 29

Proof engineer reasons about file-system

  • perations

21

def deliver(msg): create(“/spool/$TID”, msg) while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break unlink(“/spool/$TID”) create( /sp/$TID, msg) ✓ link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t) ✓ unlink( /sp/$TID) ✓ create(“/spool/$TID”) write(“/spool/$TID”, msg)

collapsed to

  • ne operation
slide-30
SLIDE 30

Proof engineer reasons about interleaving of file- system operations

22

def deliver(msg): create(“/spool/$TID”, msg) while True: t = time.time() if link(“/spool/$TID”, “/mbox/$t”): break unlink(“/spool/$TID”)

We assume file-system operations are atomic

create( /sp/$TID, msg) ✓ link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t) ✓ unlink( /sp/$TID) ✓

create

link unlink

slide-31
SLIDE 31

Proving atomicity of delivery

23

atomicity: concurrent deliveries appear to execute all at once (in some order)

create

link

link unlink create

link unlink create

link unlink

deliver

create

link

link unlink

deliver

slide-32
SLIDE 32

Proving atomicity of delivery

23

atomicity: concurrent deliveries appear to execute all at once (in some order)

create

link

link unlink create

link unlink create

link unlink

deliver

create

link

link unlink

deliver

Step 1: developer identifies commit point

slide-33
SLIDE 33

Proving atomicity of delivery

23

atomicity: concurrent deliveries appear to execute all at once (in some order)

create

link

link unlink create

link unlink create

link unlink

deliver

create

link

link unlink

deliver

Step 1: developer identifies commit point Step 2: prove operation occurs logically at commit point

slide-34
SLIDE 34

Example of movers for this execution

24

create

link

link unlink create

link unlink

slide-35
SLIDE 35

Example of movers for this execution

24

create

link

link unlink create

link unlink create

link

link unlink create

link unlink

slide-36
SLIDE 36

Example of movers for this execution

24

create

link

link unlink create

link unlink create

link

link unlink create

link unlink create

link

link unlink create

link unlink

slide-37
SLIDE 37

Right mover can be reordered after any green thread operation

25

A r A r

slide-38
SLIDE 38

Right mover can be reordered after any green thread operation

25

A r A r

left movers are the converse

slide-39
SLIDE 39

Movers need to consider only possible operations from other threads

26

create( /sp/$TID, msg) link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t) unlink( /sp/$TID) is one of

A r A r

for all green operations , is a right mover if A left movers are the converse

slide-40
SLIDE 40

Example mover proof: failing link is a right mover

27

Proof sketch (only case):

link

link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

slide-41
SLIDE 41

Example mover proof: failing link is a right mover

27

Proof sketch (only case):

link

link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t) ✓

$t $t ≠

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link

link

(otherwise then is impossible)

slide-42
SLIDE 42

Example mover proof: failing link is a right mover

27

Proof sketch (only case):

link

link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t) ✓

$t $t ≠

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link

link

(otherwise then is impossible) link operations are independent

slide-43
SLIDE 43

Failing link does not move left

28

slide-44
SLIDE 44

Failing link does not move left

28

link( /sp/$TID, /mbox/$t)

EEXISTS ✗

link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t) ✓ link( /sp/$TID, /mbox/$t)

EEXISTS ✗

if =

$t $t

slide-45
SLIDE 45

Challenge: how to limit what other operations to consider in mover proofs?

29

Delivery File system

  • deliver
  • create(f, d)
  • link(f1, f2)
  • unlink(f)
  • rename(f1, f2)

mover proof?

slide-46
SLIDE 46

Challenge: how to limit what other operations to consider in mover proofs?

29

Delivery File system

  • deliver
  • create(f, d)
  • link(f1, f2)
  • unlink(f)
  • rename(f1, f2)

mover proof?

create( f1, d) create( f2, d) create( f1, d) create( f2, d)

if filenames are identical

slide-47
SLIDE 47

Layers enable mover reasoning

30

Delivery File system

  • deliver
  • create(f, d)
  • link(f1, f2)
  • unlink(f)
  • rename(f1, f2)

Layers limit what operations are available use multiple layers to make operations movers

slide-48
SLIDE 48

Layers enable mover reasoning

31

Delivery File system Restricted file system restrict arguments to include $TID

  • create(/spool/$TID, d)
  • link(/spool/$TID, /mbox/$t)
  • unlink(/spool/$TID)

mover proof ✓

Layers limit what operations are available use multiple layers to make operations movers

slide-49
SLIDE 49

Layers enable mover reasoning

31

Delivery File system Restricted file system upper layers can only use restricted operations

  • create(/spool/$TID, d)
  • link(/spool/$TID, /mbox/$t)
  • unlink(/spool/$TID)

mover proof ✓

Layers limit what operations are available use multiple layers to make operations movers

slide-50
SLIDE 50

Movers are a layer proof pattern

32

mover pattern Obligation for developer: movers for each implementation

layer 1 layer 2

A B C D

foo bar

slide-51
SLIDE 51

Movers are a layer proof pattern

32

mover pattern

A B D C B A C

def foo: def bar: Obligation for developer: movers for each implementation

layer 1 layer 2

A B C D

foo bar

slide-52
SLIDE 52

Movers are a layer proof pattern

32

mover pattern

A B D C B A C

def foo: def bar: Obligation for developer: movers for each implementation CSPEC theorem: entire layer implementation is atomic

layer 1 layer 2

A B C D

foo bar

slide-53
SLIDE 53

CSPEC provides other patterns to support mover reasoning

  • Abstraction / forward simulation
  • Invariants
  • Error state
  • Protocols
  • Retry loops
  • Partitioning

33

(see paper for details)

pattern

  • bligations

proof connecting layers

slide-54
SLIDE 54

Using CSPEC to verify CMAIL

34

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

CSPEC

auto generated framework

slide-55
SLIDE 55

Using CSPEC to verify CMAIL

34

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)


 Coq extraction CSPEC

auto generated framework

slide-56
SLIDE 56

Using CSPEC to verify CMAIL

34

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)


 Coq extraction

GHC

CSPEC executable

auto generated framework

Linux

slide-57
SLIDE 57

What is proven vs. assumed correct?

35

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)

Coq extraction GHC CSPEC executable

  • k

Coq proof checker Linux proven

auto generated

assumed correct

slide-58
SLIDE 58

Concurrency inside CMAIL is proven

36

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)

Coq extraction GHC CSPEC executable

  • k

Coq proof checker Linux proven

auto generated

assumed correct

slide-59
SLIDE 59

Trust that the tools and OS are correct

37

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)

Coq extraction GHC CSPEC executable

  • k

Coq proof checker Linux proven

auto generated

assumed correct

slide-60
SLIDE 60

Mail server-specific assumptions

38

file-system spec mail library spec implementation layers patterns

CMAIL (Coq) Coq

calls to file-system SMTP + POP3 extracted implementation

CMAIL (Haskell)

Coq extraction GHC CSPEC executable

  • k

Coq proof checker Linux proven

auto generated

assumed correct

slide-61
SLIDE 61

Evaluation

  • Can CMAIL exploit file-system concurrency for speedup?
  • How much effort was verifying CMAIL?
  • What is the benefit of CSPEC’s machine-checked proofs?

39

slide-62
SLIDE 62

CMAIL achieves speedup with multiple cores

40

kreq/s 35 70 105 140 # cores 1 2 3 4 5 6 7 8 9 10 11 12

CMAIL GoMail

slide-63
SLIDE 63

CMAIL was work but doable

41

proof:code ratio CMAIL 11.5x CertiKOS 13.8x IronFleet 7.7x IronClad 4.8x CompCert 4.6x

Took two authors 6 months

{

concurrent

{

sequential

slide-64
SLIDE 64

Machine-checked proofs give confidence in framework changes

42

Three anecdotes of changes to CSPEC: Machine-checked proofs ensure soundness of entire system

slide-65
SLIDE 65

Machine-checked proofs give confidence in framework changes

42

  • Implemented partitioning pattern to support multiple users

Three anecdotes of changes to CSPEC: Machine-checked proofs ensure soundness of entire system

slide-66
SLIDE 66

Machine-checked proofs give confidence in framework changes

42

  • Implemented partitioning pattern to support multiple users
  • Improved mover pattern for a CMAIL left mover proof

Three anecdotes of changes to CSPEC: Machine-checked proofs ensure soundness of entire system

slide-67
SLIDE 67

Machine-checked proofs give confidence in framework changes

42

  • Implemented partitioning pattern to support multiple users
  • Improved mover pattern for a CMAIL left mover proof
  • Implemented error-state pattern for the x86-TSO lock proof

Three anecdotes of changes to CSPEC: Machine-checked proofs ensure soundness of entire system

slide-68
SLIDE 68

CSPEC is a framework for verifying concurrency in systems software

  • Layers and patterns (esp. movers) make proofs manageable
  • Machine-checked framework supports adding new patterns
  • Evaluated by verifying mail server and x86-TSO lock

github.com/mit-pdos/cspec

43

slide-69
SLIDE 69

CSPEC is a framework for verifying concurrency in systems software

  • Layers and patterns (esp. movers) make proofs manageable
  • Machine-checked framework supports adding new patterns
  • Evaluated by verifying mail server and x86-TSO lock

github.com/mit-pdos/cspec

43

poster #1

slide-70
SLIDE 70

44

Backup slides

CMAIL perf experimental setup

slide-71
SLIDE 71

Performance experiment setup for CMAIL

45

in-memory file system

process

client

deliver + pickup

CMAIL

core 1

slide-72
SLIDE 72

Performance experiment setup for CMAIL

45

in-memory file system

process

client

deliver + pickup

CMAIL

core 1

process

client

deliver + pickup

CMAIL

core 2

process

client

deliver + pickup

CMAIL

core 12