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

Verifying Concurrent Programs with Relaxed Conflict Detection

  • Upload
    early

  • View
    64

  • Download
    0

Embed Size (px)

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

Citation preview

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