All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] migration: fix ram decompression race deadlock
@ 2016-05-12 18:42 Maxim Nestratov
  0 siblings, 0 replies; only message in thread
From: Maxim Nestratov @ 2016-05-12 18:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: den, Maxim Nestratov

The way how decompress_data_with_multi_threads communicates with
do_data_decompress is incorrect. Imagine the following scenario.
The function do_data_decompress just finished decompression and
released param->mutex and got preempted. In parallel, the function
decompress_data_with_multi_threads called start_decompression and
then it starts to loop infinitely waiting for decompression to
complete, which will never happend because decomp_param[idx].start
is true and do_data_decompress will never enter while loop again.
The patch fixes this problem by correcting while loop where we
wait for condition only and other actions are moved out of it.

Signed-off-by: Maxim Nestratov <mnestratov@virtuozzo.com>
---
 migration/ram.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 3f05738..579bfc0 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2193,18 +2193,18 @@ static void *do_data_decompress(void *opaque)
         qemu_mutex_lock(&param->mutex);
         while (!param->start && !quit_decomp_thread) {
             qemu_cond_wait(&param->cond, &param->mutex);
-            pagesize = TARGET_PAGE_SIZE;
-            if (!quit_decomp_thread) {
-                /* uncompress() will return failed in some case, especially
-                 * when the page is dirted when doing the compression, it's
-                 * not a problem because the dirty page will be retransferred
-                 * and uncompress() won't break the data in other pages.
-                 */
-                uncompress((Bytef *)param->des, &pagesize,
-                           (const Bytef *)param->compbuf, param->len);
-            }
-            param->start = false;
         }
+        pagesize = TARGET_PAGE_SIZE;
+        if (!quit_decomp_thread) {
+           /* uncompress() will return failed in some case, especially
+            * when the page is dirted when doing the compression, it's
+            * not a problem because the dirty page will be retransferred
+            * and uncompress() won't break the data in other pages.
+            */
+            uncompress((Bytef *)param->des, &pagesize,
+                       (const Bytef *)param->compbuf, param->len);
+        }
+        param->start = false;
         qemu_mutex_unlock(&param->mutex);
     }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-05-12 18:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-12 18:42 [Qemu-devel] [PATCH] migration: fix ram decompression race deadlock Maxim Nestratov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.