From patchwork Fri May 13 07:27:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 9088511 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BEE15BF29F for ; Fri, 13 May 2016 07:28:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 292DF201FE for ; Fri, 13 May 2016 07:28:07 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3F2D5201F5 for ; Fri, 13 May 2016 07:28:06 +0000 (UTC) Received: from localhost ([::1]:33116 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b17W1-00087g-FV for patchwork-qemu-devel@patchwork.kernel.org; Fri, 13 May 2016 03:28:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b17Vu-00085m-9X for qemu-devel@nongnu.org; Fri, 13 May 2016 03:27:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b17Vp-0008Qw-4w for qemu-devel@nongnu.org; Fri, 13 May 2016 03:27:57 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:27022 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b17Vo-0008KV-MS for qemu-devel@nongnu.org; Fri, 13 May 2016 03:27:53 -0400 Received: from irbis.sw.ru ([10.30.2.139]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id u4D7R1f9011586; Fri, 13 May 2016 10:27:02 +0300 (MSK) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Date: Fri, 13 May 2016 10:27:01 +0300 Message-Id: <1463124421-16587-1-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.1.4 X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH 1/1] migration: fix ram decompression race deadlock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Amit Shah , den@openvz.org, Maxim Nestratov , Juan Quintela Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Maxim Nestratov There is a race in between do_data_decompress and start_decompression. do_data_decompress() while (!quit_decomp_thread) { qemu_mutex_lock(¶m->mutex); while (!param->start && !quit_decomp_thread) { qemu_cond_wait(¶m->cond, ¶m->mutex); ... param->start = false; } qemu_mutex_unlock(¶m->mutex); [ preempted here, start_decompression() is executed ] } start_decompression() { qemu_mutex_lock(¶m->mutex); param->start = true; qemu_cond_signal(¶m->cond); qemu_mutex_unlock(¶m->mutex); } In this case do_data_decompress will never enter inner loop again and will eat 100% CPU. 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 Signed-off-by: Denis V. Lunev CC: Juan Quintela CC: Amit Shah --- 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(¶m->mutex); while (!param->start && !quit_decomp_thread) { qemu_cond_wait(¶m->cond, ¶m->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(¶m->mutex); }