]>
Commit | Line | Data |
---|---|---|
8632395d SP |
1 | From 4535f739edfdea392e381811963823bf05649e42 Mon Sep 17 00:00:00 2001 |
2 | From: Stefan Hajnoczi <stefanha@redhat.com> | |
3 | Date: Tue, 3 Jun 2014 11:21:01 +0200 | |
4 | Subject: [PATCH] aio: fix qemu_bh_schedule() bh->ctx race condition | |
5 | ||
6 | qemu_bh_schedule() is supposed to be thread-safe at least the first time | |
7 | it is called. Unfortunately this is not quite true: | |
8 | ||
9 | bh->scheduled = 1; | |
10 | aio_notify(bh->ctx); | |
11 | ||
12 | Since another thread may run the BH callback once it has been scheduled, | |
13 | there is a race condition if the callback frees the BH before | |
14 | aio_notify(bh->ctx) has a chance to run. | |
15 | ||
16 | Reported-by: Stefan Priebe <s.priebe@profihost.ag> | |
17 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | |
18 | Signed-off-by: Stefan Priebe <s.priebe@profihost.ag> | |
19 | --- | |
20 | async.c | 14 ++++++++++---- | |
21 | 1 file changed, 10 insertions(+), 4 deletions(-) | |
22 | ||
23 | diff --git a/async.c b/async.c | |
24 | index 6930185..5b6fe6b 100644 | |
25 | --- a/async.c | |
26 | +++ b/async.c | |
27 | @@ -117,15 +117,21 @@ void qemu_bh_schedule_idle(QEMUBH *bh) | |
28 | ||
29 | void qemu_bh_schedule(QEMUBH *bh) | |
30 | { | |
31 | + AioContext *ctx; | |
32 | + | |
33 | if (bh->scheduled) | |
34 | return; | |
35 | + ctx = bh->ctx; | |
36 | bh->idle = 0; | |
37 | - /* Make sure that idle & any writes needed by the callback are done | |
38 | - * before the locations are read in the aio_bh_poll. | |
39 | + /* Make sure that: | |
40 | + * 1. idle & any writes needed by the callback are done before the | |
41 | + * locations are read in the aio_bh_poll. | |
42 | + * 2. ctx is loaded before scheduled is set and the callback has a chance | |
43 | + * to execute. | |
44 | */ | |
45 | - smp_wmb(); | |
46 | + smp_mb(); | |
47 | bh->scheduled = 1; | |
48 | - aio_notify(bh->ctx); | |
49 | + aio_notify(ctx); | |
50 | } | |
51 | ||
52 | ||
53 | -- | |
54 | 1.7.10.4 | |
55 |