Verifying Concurrent Programs with Relaxed Conflict Detection

59
Verifying Concurrent Programs with Relaxed Conflict Detection Tayfun Elmas, Ismail Kuru, Serdar Taşıran, Omer Subasi Koç University Istanbul, Turkey

description

Verifying Concurrent Programs with Relaxed Conflict Detection. Tayfun Elmas , Ismail Kuru , Serdar Taşıran , Omer Subasi Koç University Istanbul, Turkey. Relaxed Conflict Detection. Pattern Traverse/Take snapshot of (large portion of) global state Do l ocal computation - PowerPoint PPT Presentation

Transcript of Verifying Concurrent Programs with Relaxed Conflict Detection

Page 1: Verifying Concurrent Programs  with Relaxed Conflict Detection

Verifying Concurrent Programs with Relaxed Conflict Detection

Tayfun Elmas, Ismail Kuru, Serdar Taşıran, Omer SubasiKoç University Istanbul, Turkey

Page 2: Verifying Concurrent Programs  with Relaxed Conflict Detection

2

Relaxed Conflict Detection• Pattern

– Traverse/Take snapshot of (large portion of) global state– Do local computation– Update small portion of global state

• Very common– Concurrent data structures– Parallelized optimization algorithms– Cloud computing– Performance optimizations for transactional memory

• Ignore WAR conflicts (Titos et al., HiPEAC ‘12)• Early release/early discard (e.g., Kozyrakis et al., WTW ‘06)

• Performance problem: Most operations conflict• Solution: Program so that some conflicts can be ignored• Verification problem: How do you reason about correctness?

Page 3: Verifying Concurrent Programs  with Relaxed Conflict Detection

Motivating Example: Sorted Linked List

1 3 6 9 12 15 17Head

5

16

Insert 5

Insert 16

Page 4: Verifying Concurrent Programs  with Relaxed Conflict Detection

Motivating Example: Sorted Linked List

1 3 6 9 12 15 17Head

5

16

Insert 5

Insert 16

Page 5: Verifying Concurrent Programs  with Relaxed Conflict Detection

1 3 6 9 12 15 17HeadREAD

Page 6: Verifying Concurrent Programs  with Relaxed Conflict Detection

1 3 6 9 12 15 17Head

5

WRITE

READ

Page 7: Verifying Concurrent Programs  with Relaxed Conflict Detection

Write-After-Read

conflict

1 3 6 9 12 15 17Head

16

WRITEREAD

5

WRITE

Page 8: Verifying Concurrent Programs  with Relaxed Conflict Detection

Write-After-Read

conflict

1 3 6 9 12 15 17Head

16

WRITEREAD

• Conventional TM conflict detection enforces conflict serializability– Does WriteSet(Tx1) intersect (ReadSet(Tx1) + WriteSet(Tx2)) ?– Any two concurrent insertions conflict!

5

WRITE

Page 9: Verifying Concurrent Programs  with Relaxed Conflict Detection

Linked List: Insertlist_insert(list_t *listPtr, node_t *node) {

atomic {

*curr = listPtr->head; do {

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

}}

9

Transactional memory:• Optimistic concurrency• Track read and write accesses a

transaction performs– ReadSet(Tx1)– WriteSet(Tx1)

• Enforce conflict serializability

• At commit time for Tx1for all concurrent transactions Tx2, check

WriteSet(Tx2) (ReadSet(Tx1) WriteSet(Tx1)) =

– Abort and retry Tx1 otherwise

Page 10: Verifying Concurrent Programs  with Relaxed Conflict Detection

1 3 6 9 12 15 17Head

5

16• But, allowing both insertions OK even if we ignore WAR conflict• Conflict serializability too strict• Options:

– Fine-grain, hand-crafted concurrency– Transactional memory + relaxed conflict detection

Page 11: Verifying Concurrent Programs  with Relaxed Conflict Detection

• Relaxed conflict detection• Programmer tells TM to ignore this kind of conflict• Need to reason that this still results in a correct program

Write-After-Read

conflict

1 3 6 9 12 15 17Head

16

WRITEREAD

5

WRITE

Page 12: Verifying Concurrent Programs  with Relaxed Conflict Detection

Linked List: Insertlist_insert(list_t *listPtr, node_t *node) {

atomic {

*curr = listPtr->head; Readdo { phase

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; Writeprev->next = node; phase

}}

12

Page 13: Verifying Concurrent Programs  with Relaxed Conflict Detection

13

Linked List: Insertlist_insert(list_t *listPtr, node_t *node) {

atomic {

*curr = listPtr->head; do {

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Strict conflict detection:

Can reason about transaction code sequentially.

Page 14: Verifying Concurrent Programs  with Relaxed Conflict Detection

14

Linked List: Insertlist_insert(list_t *listPtr, node_t *node) {

atomic [!WAR]{

*curr = listPtr->head; do {

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Ignore Write-After-Readconflicts:

• Writes by others interfere with transaction

• Cannot reasonsequentially

1 3 6

5READ 6; WRITE 5

Page 15: Verifying Concurrent Programs  with Relaxed Conflict Detection

15

Arguing that the !WAR block is atomiclist_insert(list_t *listPtr, node_t *node) {

atomic [!WAR]{

*curr = listPtr->head; do {

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Would like these actions to be “right movers”

• Can commute to the right of any actionby another thread

Atomicity of this block guaranteed by TM

• Write-write conflictsnot ignored

Page 16: Verifying Concurrent Programs  with Relaxed Conflict Detection

16

Making !WAR block atomiclist_insert(list_t *listPtr, node_t *node) {

atomic [!WAR]{

*curr = listPtr->head; do {

prev = curr; currT1 = currT1->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

nodeT2->next = currT2;

1 3 6

5READ 6; WRITE 5

Page 17: Verifying Concurrent Programs  with Relaxed Conflict Detection

17

Making !WAR block atomiclist_insert(list_t *listPtr, node_t *node) {

atomic [!WAR]{

*curr = listPtr->head; do {

prev = curr; currT1 = currT1->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

nodeT2->next = currT2;

Ignored WAR conflict:

currT1 = currT1->next;

does not move to the right of

nodeT2->next = currT2;

Page 18: Verifying Concurrent Programs  with Relaxed Conflict Detection

18

Abstractionlist_insert(list_t *listPtr, node_t *node) {

atomic [!WAR]{

*curr = listPtr->head; do {

(currT1 = currT1->next)+; havoc prev;

assume prev->next = curr; assume prev->key < node->key;

} while (curr != NULL && curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

• Abstract action right mover• Now block is atomic.• Sequential verification

1 3 6

5WRITE 5; READ 5, 6;

Page 19: Verifying Concurrent Programs  with Relaxed Conflict Detection

19

1. Sequentially verify the original code

list_insert(list_t *listPtr, node_t *node) {

*curr = listPtr->head; do {

prev = curr; curr = curr->next; } while (curr != NULL &&

curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Page 20: Verifying Concurrent Programs  with Relaxed Conflict Detection

20

2. Apply program transformation

list_insert(list_t *listPtr, node_t *node) {

*curr = listPtr->head; do {

(currT1 = currT1->next)+; havoc prev;

assume prev->next = curr; assume prev->key < node->key;

} while (curr != NULL && curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Do global read abstractions Abstract transaction becomes

atomic.

Page 21: Verifying Concurrent Programs  with Relaxed Conflict Detection

21

3. Prove abstract code sequentially

list_insert(list_t *listPtr, node_t *node) {

*curr = listPtr->head; do {

(currT1 = currT1->next)+; havoc prev;

assume prev->next = curr; assume prev->key < node->key;

} while (curr != NULL && curr->key < node->key);

node->next = curr; prev->next = node;

assert(node is in the list && list is sorted); }

}

Page 22: Verifying Concurrent Programs  with Relaxed Conflict Detection

22

Relaxed Conflict Detection• Pattern

– Traverse/Take snapshot of (large portion of) global state– Do local computation– Update small portion of global state

• Concurrent data structures, optimization algorithms, cloud computing• Performance optimizations for transactional memory

– Ignore WAR conflicts (Titos et al., HiPEAC ‘12)– Early release/early discard (e.g., Kozyrakis et al., WTW ‘06)

• Issue: Snapshot may be stale– But programmer thinks this is OK (as long as there is no write-write conflict with another operation)

• Problem:– How to verify properties of code running under a

relaxed consistency model

Page 23: Verifying Concurrent Programs  with Relaxed Conflict Detection

23

WAR Conflict Pattern

read xread y

read x write xwrite y

Page 24: Verifying Concurrent Programs  with Relaxed Conflict Detection

24

WAR Conflict Pattern

read xread y

read x write xwrite y

WAR conflict OK

Page 25: Verifying Concurrent Programs  with Relaxed Conflict Detection

25

WAR Conflict Pattern

read xread y

read x write xwrite y

WAR conflict OK

as long as no

WAW conflict

Page 26: Verifying Concurrent Programs  with Relaxed Conflict Detection

26

WAR Conflict Pattern

read x read y

read x write xwrite y

WAR conflict OK

as long as no

WAW conflict

read x read y

read x write xwrite x

WAR conflict

WAW conflict

Page 27: Verifying Concurrent Programs  with Relaxed Conflict Detection

27

WAR Conflict Pattern

read x read y

read x write xwrite y

WAR conflict OK

as long as no

WAW conflict

read x read y

read x write xwrite x

WAR conflict

WAW conflict

A B O R T

Page 28: Verifying Concurrent Programs  with Relaxed Conflict Detection

28

Labyrinth: Grid Routing• FindRoute(p1,p2)

– Route a wire on the gridconnecting points p1 and p2

– Wires must not touch

• FindRoute operation– Take snapshot of grid– Find shortest path from p1 to p2– Write path to shared memory

if path does not overlap others• Overlap = write-write conflict

• Stale snapshot OK as long as computed path does not overlap others– Same path could have been computed

even with up-to-date snapshot

Page 29: Verifying Concurrent Programs  with Relaxed Conflict Detection

Write-After-Read

conflict

1 3 6 9 12 15 17Head

16

WRITEREAD

5

WRITE

Page 30: Verifying Concurrent Programs  with Relaxed Conflict Detection

snapshotGS := GlobStn;

(x, xVal) := localComp(snapshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; } 30

Non-problematic Interleaving

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn := GlobStn-1[w->wVal];

Page 31: Verifying Concurrent Programs  with Relaxed Conflict Detection

31

Actual Interleaving

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn := GlobStn-1[w->wVal];

snapshotGS := GlobSt0;

snapshotGS := GlobStn;

(x, xVal) := localComp(snapshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; }

This is OK because

localComp(GlobStn, args) andlocalComp(GlobSt0,args)

would/might have produced same result.

Page 32: Verifying Concurrent Programs  with Relaxed Conflict Detection

32

Correctness Argument

• Blue transaction’s snapshot is stale

• Blue and green accesses conflict• But, end state consistent with

– green executed serially, then– blue executed serially

1 3 6 9 12 15 17Head

16

WRITEREAD

5

WRITE

Page 33: Verifying Concurrent Programs  with Relaxed Conflict Detection

QED: A Proof System for Concurrent Programs

Shaz QadeerMicrosoft Research

Redmond, WA

Serdar Taşıran, Tayfun Elmas, Ali SezginKoç University Istanbul, Turkey

http://qed.codeplex.com[POPL ’09, TACAS ‘10, PADTAD ‘10, VSTTE ‘10]

Page 34: Verifying Concurrent Programs  with Relaxed Conflict Detection

Intuition for proof steps

• Abstract some actions• Prove non-interference• Commute• Prove larger blocks atomic

• Abstract some actions• Prove non-interference• Commute• Prove larger blocks atomic

Page 35: Verifying Concurrent Programs  with Relaxed Conflict Detection

Coarser Atomic Actions

35

. . .

check

P1 PnP2

Correct

Difficult to prove• Fine-grain concurrency• Annotations at every interleaving point

Easy to prove• Larger atomic blocks• Local, sequential analysis within atomic blocks

Page 36: Verifying Concurrent Programs  with Relaxed Conflict Detection

36

QED’s Idea of Abstraction

If for all :

errors1 errors11. If then

s12. Else, if thens2 s1 s2

or errors1

s1

abstracted by

36

Page 37: Verifying Concurrent Programs  with Relaxed Conflict Detection

37

Flavors of Abstraction

if (x == 1) y := y + 1;

if (*) y := y + 1;

Adding non-determinism

Adding assertions (more behaviors that might go wrong)

t := x; havoc t;

assume x != t; skip;

assert (lock_owner == tid);x := t + 1;x := t + 1;

37

“Read abstraction”

Page 38: Verifying Concurrent Programs  with Relaxed Conflict Detection

QED Transformations: Reduction

[ S1; S2][ S1 ] ; [ S2 ]

I,P I,P’

38

If [S1] is a right mover or [S2] is a left mover

P P’

Page 39: Verifying Concurrent Programs  with Relaxed Conflict Detection

39

Reduction

;

... 1 2 ... n ; ...

right-mover:

For each execution:

Exist equivalent executions:

... 1 2 ... n ...

... 1 2 ... n ... ...........

... 1 2 ... n ...

;

39

Page 40: Verifying Concurrent Programs  with Relaxed Conflict Detection

Mover check in QED: Static, local, semantic

40

...

...

First-order verification condition

For each

;

...

Right-mover ?A

A B ;B A

B :

S1 S2 S3

S1 T2 S3

A B

B A

All actions in programrun by different thread

Page 41: Verifying Concurrent Programs  with Relaxed Conflict Detection

41

Atomicity Proof Idea

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn := GlobStn-1[w->wVal];

sshotGS := GlobSt0;

(x, xVal) := localComp(sshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; }

• Need this to be a “Right mover”• Must commute to the right of all other concurrent actions

Atomicity ensured bystrict conflict detection

Page 42: Verifying Concurrent Programs  with Relaxed Conflict Detection

42

Atomicity Proof Idea

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn := GlobStn-1[w->wVal];

sshotGS := GlobSt0;

(x, xVal) := localComp(sshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; }

• Need this to be a “Right mover”• Must commute to the right of all other concurrent actions

Atomicity ensured bystrict conflict detection

• Reasoning using Lipton’s reduction and abstraction• QED-like proof (“A Calculus of Atomic Actions”, POPL ’09)• Costly pairwise mover checks avoided

Page 43: Verifying Concurrent Programs  with Relaxed Conflict Detection

Atomicity Proof Idea

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn := GlobStn-1[w->wVal];

sshotGS := GlobSt0;

(x, xVal) := localComp(sshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; }

• Not a “Right mover”• Does not commute

to the right of global state updates

Page 44: Verifying Concurrent Programs  with Relaxed Conflict Detection

Reads and Updates do not Commute

1 3 6

5READ 6; WRITE 5

1 3 6

5WRITE 5; READ 5

Want to read 6 again!

Page 45: Verifying Concurrent Programs  with Relaxed Conflict Detection

Atomicity Proof Idea

GlobSt1 := GlobSt0[y->yVal];…GlobSt2 := GlobSt1[z->zVal];…GlobStn:= GlobStn-1[w->wVal];

sshotGS := GlobSt0;

(x, xVal) := localComp(sshotGS, args);

atomic { GlobSt := GlobSt [x->xVal]; }

• Not a “Right mover”• Does not commute

to the right of global state updates

• Idea: Abstract this read

• Add non-determinismso it can read GlobSt1, GlobSt2, …, GlobStn

Page 46: Verifying Concurrent Programs  with Relaxed Conflict Detection

Abstraction intuition

46

1 3 6

5ABSTRACT READ 6; WRITE 5

1 3 6

5WRITE 5; ABSTRACT READ 6

Need to jump over

5.

1 3 6

5READ 6; WRITE 5

1 3 6

5WRITE 5; READ 5

Want to read 6 again!

Page 47: Verifying Concurrent Programs  with Relaxed Conflict Detection

Abstraction intuition

47

1 3 6

5ABSTRACT READ 6; WRITE 5

1 3 6

5WRITE 5; ABSTRACT READ 6

Need to jump over

5.

1 3 6

5READ 6; WRITE 5

1 3 6

5WRITE 5; READ 5

Want to read 6 again!

curr = curr->next; abstracted bycurr = curr->next*; but don’t go past key.

Page 48: Verifying Concurrent Programs  with Relaxed Conflict Detection

48

Abstracting Read Accesses• Abstraction invariant AbsT,x:

A transition invariant for variable of type T at address x

• l := x.f becomes <obj = copy(x); havoc l; assume AbsT,x(state, state[obj.f l]) >

• “Read returns a non-deterministic value satisfying abstraction invariant”

• For the linked list insertion example

Absnode,x(old_st, new_st) = Reachold_st(list->head, x) ==>

Reachnew_st(list->head, x) ∧Reachnew_st (x, old(x->next))

∧Sortedold_st(list) ∧Sortednew_st(list)

Page 49: Verifying Concurrent Programs  with Relaxed Conflict Detection

Abstracting Accesses• Annotate write accesses:

– x.f := m becomes <assert AbsT,x(st, st[x.f m]); x := m >– Assertion: Proof obligation, ensures the abstraction invariant

• By construction, abstract reads commute to the right of annotated writes

• Assertions become proof obligations– Discharged using sequential reasoning– Abstraction invariant verified when operations are atomic

• Soundness guaranteed by theorem– Special case of QED soundness theorem– No pairwise mover check needed!

49

Page 50: Verifying Concurrent Programs  with Relaxed Conflict Detection

50

Ongoing Work: Obtaining the (Sequential) Specification

• When interpreted sequentially, the program may already have a specification– Spec already existed for Labyrinth and Genome

• Specifications (invariants) may be inferred mechanically• Done for the Genome benchmark using the Celia tool

– Invariant Synthesis for Programs Manipulating Lists with Unbounded Data A. Bouajjani, C. Dragoi, C. Enea, A. Rezine, and M. Sighireanu

CAV'10.

– On Inter-Procedural Analysis of Programs with Lists and Data A. Bouajjani, C. Dragoi, C. Enea, and M. Sighireanu PLDI'11.

Page 51: Verifying Concurrent Programs  with Relaxed Conflict Detection

51

Future Work: Obtaining the Abstraction Invariant

• Sometimes “true” is sufficient• Sometimes easy: Full cells never become empty (Labyrinth)

• Otherwise, need an over-approximation for

conflicting_updates* o read_access

• Can use annotation inference tool on the sequential code for

while (*) conflicting_updates; read_access;

Page 52: Verifying Concurrent Programs  with Relaxed Conflict Detection

52

Summary• Common pattern

– Traverse/Take snapshot of (large portion of) global state– Do local computation– Update small portion of global state

• Conflict serializability too costly– Fine-grain locking– Relaxed conflict detection

• Static proof approach for such programs– Read abstraction to capture effects of conflicting writes– Enables sequential proof on abstract program

• Ongoing work: Automation for inferring spec, abstraction invariant

Page 53: Verifying Concurrent Programs  with Relaxed Conflict Detection

53

Ongoing Work: Port Entire Proof Argument to VCC

• VCC: Verification tool for concurrent C programs (MS Aachen)– Used to verify Microsoft Hyper-V hypervisor– Uses Boogie, Z3

• Why VCC?– Can handle entire C– Larger agenda: Model and verify programs using novel concurrent

programming constructs• Programs with TM: race-freedom, static separation, assertions• Programs with relaxed consistency models, e.g. snapshot isolation

• Key ideas in VCC– Ownership, permissions expressed using ghost variables

• All annotations expressed using program logic– Objects have two-state invariants

• VCC checks that all actions preserve two-state invariants of all objects• Modular checks, converted to first-order logic queries for Z3.

Page 54: Verifying Concurrent Programs  with Relaxed Conflict Detection

54

Modeling Relaxed Conflict Detection in VCC

• Current proof argument– For each type, write an abstraction invariant– Relax read accesses using abstraction invariant

• Read accesses become right movers by construction– Relaxed code is atomic

• Discharge assertions used to justify right moverness– Verify desired properties on non-deterministic but sequential code

• Proof argument in VCC– Model TM and relaxed conflict detection using ownership, approval– Write two-state invariant about values returned by reads– Write two-state invariants about program objects– Verify that two-state invariants are admissible, preserved– Verify same specification as sequential version,

• Only rely on two-state invariant and atomicity within write block

Page 55: Verifying Concurrent Programs  with Relaxed Conflict Detection

Serdar Taşıran

Page 56: Verifying Concurrent Programs  with Relaxed Conflict Detection
Page 57: Verifying Concurrent Programs  with Relaxed Conflict Detection

Invited Speakers

Jim Larus Microsoft Research

Martin Rinard MIT

Giovanni Vigna UC Santa Barbara

Page 58: Verifying Concurrent Programs  with Relaxed Conflict Detection

Earlier Microsoft-Koç University Collaboration• Goldilocks: A Race Detection Tool

– Patented– Included in US and European

university curricula– Published in CACM Research

Highlights• One of 24 articles selected in

2010

• QED: A Verification Tool for Concurrent Programs– Winner: ACM Student Research

Competition– Best tool built using Microsoft

technology– Publicly available

reduceabstract

.....reducecheck

Correct

..

.

P1

Pn

P2

P1

Pn

Proof scriptBoogie 2, Z3

QEDPLprogram

Page 59: Verifying Concurrent Programs  with Relaxed Conflict Detection

Ongoing Research

• Tool support for new programming paradigms:– DesCloud: Cloud simulation on a desktop.– VCC verifier, relaxed conflict detection, relaxed consistency models

• Program Proof Tools– Handling relaxed hardware memory models in QED– Verifying TM implementations with QED

• Dynamic (Runtime) verification tools – Parallelizing race detection– Using TM to prevent and recover from races – Races in programs that use TM