From patchwork Wed Sep 9 15:11:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305795 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CF3CC43461 for ; Wed, 9 Sep 2020 15:14:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 11B5721919 for ; Wed, 9 Sep 2020 15:14:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="c4FFtqht" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 11B5721919 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57920 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1nY-00050X-2q for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:14:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36388) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lX-0000u3-9Y for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32553) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lU-0003kW-00 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IIDc3ykYJbs2CF6012HrA58e9+NyCuGJq9BhqyU/RYc=; b=c4FFtqhtoN3wIxm3E6DGl/1j4Zj/M/GIFxj2zLwIQ/ZJFta8xijy4vMt4iBN4WhhzdGjeC 3JFD3KN9bPZQ9MAll28L7ywEGk363pQ1g8LjJ7de2rb383Xld4tztEIkiwdrg6oQI73Mne GydI+TjdtZrB+NTvdG2e3V7fUwmPWr4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-573-jCe5qny3NTi47aucPKLMGQ-1; Wed, 09 Sep 2020 11:12:01 -0400 X-MC-Unique: jCe5qny3NTi47aucPKLMGQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3380B10059A7; Wed, 9 Sep 2020 15:12:00 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id B28F660BEC; Wed, 9 Sep 2020 15:11:58 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 01/13] monitor: Add Monitor parameter to monitor_set_cpu() Date: Wed, 9 Sep 2020 17:11:37 +0200 Message-Id: <20200909151149.490589-2-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 07:20:24 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Most callers actually don't have to rely on cur_mon, but already know for which monitor they call monitor_set_cpu(). Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/monitor/monitor.h | 2 +- monitor/hmp-cmds.c | 2 +- monitor/misc.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 1018d754a6..0dcaefd4f9 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -33,7 +33,7 @@ int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); int monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_flush(Monitor *mon); -int monitor_set_cpu(int cpu_index); +int monitor_set_cpu(Monitor *mon, int cpu_index); int monitor_get_cpu_index(void); void monitor_read_command(MonitorHMP *mon, int show_prompt); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 7711726fd2..f608b5b27b 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -996,7 +996,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict) /* XXX: drop the monitor_set_cpu() usage when all HMP commands that use it are converted to the QAPI */ cpu_index = qdict_get_int(qdict, "index"); - if (monitor_set_cpu(cpu_index) < 0) { + if (monitor_set_cpu(mon, cpu_index) < 0) { monitor_printf(mon, "invalid CPU index\n"); } } diff --git a/monitor/misc.c b/monitor/misc.c index e847b58a8c..b4f779b8d3 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -129,7 +129,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, cur_mon = &hmp.common; if (has_cpu_index) { - int ret = monitor_set_cpu(cpu_index); + int ret = monitor_set_cpu(&hmp.common, cpu_index); if (ret < 0) { cur_mon = old_mon; error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", @@ -255,7 +255,7 @@ static void monitor_init_qmp_commands(void) } /* Set the current CPU defined by the user. Callers must hold BQL. */ -int monitor_set_cpu(int cpu_index) +int monitor_set_cpu(Monitor *mon, int cpu_index) { CPUState *cpu; @@ -263,8 +263,8 @@ int monitor_set_cpu(int cpu_index) if (cpu == NULL) { return -1; } - g_free(cur_mon->mon_cpu_path); - cur_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu)); + g_free(mon->mon_cpu_path); + mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu)); return 0; } @@ -285,7 +285,7 @@ static CPUState *mon_get_cpu_sync(bool synchronize) if (!first_cpu) { return NULL; } - monitor_set_cpu(first_cpu->cpu_index); + monitor_set_cpu(cur_mon, first_cpu->cpu_index); cpu = first_cpu; } assert(cpu != NULL); From patchwork Wed Sep 9 15:11:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305792 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06F69C433E2 for ; Wed, 9 Sep 2020 15:18:53 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 69A5222284 for ; Wed, 9 Sep 2020 15:18:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PsA4wsf+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 69A5222284 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45102 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1s3-00036M-EB for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:18:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36416) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1la-0000xX-16 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:10 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:51705 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lY-0003lI-E8 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664327; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4YY/hDRmj2Wi2iM+XoQYflo+4uFEGUMSQ1k4k6cc6qo=; b=PsA4wsf+8uzxYWhQzrHYxBbl4nt988M0Oyxomdi0XH9cNNlxfjXawaEQJPsYgR/+GAAQ5U Jr2mziEedrJIbUeQ9lp4s7f84/lQ2LV6LF2SdDnXAnbI3g5PnCtDTuh2xqSa9q1LH72EX6 BB2xTKUqqTfYdHly5t9mwfgQN9XBMPM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-163-8AkW2gnTM0CaTJdMbhTtxw-1; Wed, 09 Sep 2020 11:12:03 -0400 X-MC-Unique: 8AkW2gnTM0CaTJdMbhTtxw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F0270801AE5; Wed, 9 Sep 2020 15:12:01 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E13260BEC; Wed, 9 Sep 2020 15:12:00 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 02/13] monitor: Add Monitor parameter to monitor_get_cpu_index() Date: Wed, 9 Sep 2020 17:11:38 +0200 Message-Id: <20200909151149.490589-3-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 02:43:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Most callers actually don't have to rely on cur_mon, but already know for which monitor they call monitor_get_cpu_index(). Signed-off-by: Kevin Wolf --- include/monitor/monitor.h | 2 +- hw/core/machine-hmp-cmds.c | 2 +- monitor/hmp-cmds.c | 2 +- monitor/misc.c | 20 ++++++++++---------- softmmu/cpus.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 0dcaefd4f9..a64502fbb2 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -34,7 +34,7 @@ int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) int monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_flush(Monitor *mon); int monitor_set_cpu(Monitor *mon, int cpu_index); -int monitor_get_cpu_index(void); +int monitor_get_cpu_index(Monitor *mon); void monitor_read_command(MonitorHMP *mon, int show_prompt); int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func, diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index 39999c47c5..da7d2e27b6 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -34,7 +34,7 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict) for (cpu = cpu_list; cpu; cpu = cpu->next) { int active = ' '; - if (cpu->value->cpu_index == monitor_get_cpu_index()) { + if (cpu->value->cpu_index == monitor_get_cpu_index(mon)) { active = '*'; } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index f608b5b27b..1e5e611ed9 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1007,7 +1007,7 @@ void hmp_memsave(Monitor *mon, const QDict *qdict) const char *filename = qdict_get_str(qdict, "filename"); uint64_t addr = qdict_get_int(qdict, "val"); Error *err = NULL; - int cpu_index = monitor_get_cpu_index(); + int cpu_index = monitor_get_cpu_index(mon); if (cpu_index < 0) { monitor_printf(mon, "No CPU available\n"); diff --git a/monitor/misc.c b/monitor/misc.c index b4f779b8d3..972726061c 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -269,23 +269,23 @@ int monitor_set_cpu(Monitor *mon, int cpu_index) } /* Callers must hold BQL. */ -static CPUState *mon_get_cpu_sync(bool synchronize) +static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize) { CPUState *cpu = NULL; - if (cur_mon->mon_cpu_path) { - cpu = (CPUState *) object_resolve_path_type(cur_mon->mon_cpu_path, + if (mon->mon_cpu_path) { + cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path, TYPE_CPU, NULL); if (!cpu) { - g_free(cur_mon->mon_cpu_path); - cur_mon->mon_cpu_path = NULL; + g_free(mon->mon_cpu_path); + mon->mon_cpu_path = NULL; } } - if (!cur_mon->mon_cpu_path) { + if (!mon->mon_cpu_path) { if (!first_cpu) { return NULL; } - monitor_set_cpu(cur_mon, first_cpu->cpu_index); + monitor_set_cpu(mon, first_cpu->cpu_index); cpu = first_cpu; } assert(cpu != NULL); @@ -297,7 +297,7 @@ static CPUState *mon_get_cpu_sync(bool synchronize) CPUState *mon_get_cpu(void) { - return mon_get_cpu_sync(true); + return mon_get_cpu_sync(cur_mon, true); } CPUArchState *mon_get_cpu_env(void) @@ -307,9 +307,9 @@ CPUArchState *mon_get_cpu_env(void) return cs ? cs->env_ptr : NULL; } -int monitor_get_cpu_index(void) +int monitor_get_cpu_index(Monitor *mon) { - CPUState *cs = mon_get_cpu_sync(false); + CPUState *cs = mon_get_cpu_sync(mon, false); return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX; } diff --git a/softmmu/cpus.c b/softmmu/cpus.c index e3b98065c9..ae643447e9 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -2224,7 +2224,7 @@ exit: void qmp_inject_nmi(Error **errp) { - nmi_monitor_handle(monitor_get_cpu_index(), errp); + nmi_monitor_handle(monitor_get_cpu_index(cur_mon), errp); } void dump_drift_info(void) From patchwork Wed Sep 9 15:11:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305796 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA9F0C43461 for ; Wed, 9 Sep 2020 15:13:33 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1827B21919 for ; Wed, 9 Sep 2020 15:13:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hw9DFpXk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1827B21919 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:53260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1mu-0003BK-1X for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:13:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36482) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lc-00014v-EG for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:12 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:52729 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lZ-0003lQ-DN for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664328; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NykECn6ZwbHknIaPpPllK8Iye8SiTIUrKm8fPlhjJEM=; b=hw9DFpXksTIuAR+poMeMAel9sF5VjoPB9vadvxIA1AiEjThFV5WPAmZjxRtJhotXN42al8 CkwwDuLMD4E1d3l1zBvmAMegUAwz9lJ/oGh75kJnVQZO7clKHaPhW47tX5WCmece9FJbO8 Z6SS55MsAjaEWP3yrJ6qdTadgOCP2zI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-395-kL15rK7jNK-qUAZhSd13NQ-1; Wed, 09 Sep 2020 11:12:04 -0400 X-MC-Unique: kL15rK7jNK-qUAZhSd13NQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DACA610059A7; Wed, 9 Sep 2020 15:12:03 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 44F5A60C15; Wed, 9 Sep 2020 15:12:02 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 03/13] monitor: Use getter/setter functions for cur_mon Date: Wed, 9 Sep 2020 17:11:39 +0200 Message-Id: <20200909151149.490589-4-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:05:47 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" cur_mon really needs to be coroutine-local as soon as we move monitor command handlers to coroutines and let them yield. As a first step, just remove all direct accesses to cur_mon so that we can implement this in the getter function later. Signed-off-by: Kevin Wolf --- include/monitor/monitor.h | 3 ++- audio/wavcapture.c | 8 ++++---- dump/dump.c | 2 +- hw/scsi/vhost-scsi.c | 2 +- hw/virtio/vhost-vsock.c | 2 +- migration/fd.c | 4 ++-- monitor/hmp.c | 11 +++++------ monitor/misc.c | 13 +++++++------ monitor/monitor.c | 24 +++++++++++++++++++++++- monitor/qmp-cmds-control.c | 2 ++ monitor/qmp-cmds.c | 2 +- monitor/qmp.c | 7 ++----- net/socket.c | 2 +- net/tap.c | 6 +++--- softmmu/cpus.c | 2 +- stubs/monitor-core.c | 5 ++++- tests/test-util-sockets.c | 12 +++++------- trace/control.c | 2 +- util/qemu-error.c | 6 +++--- util/qemu-print.c | 3 ++- util/qemu-sockets.c | 1 + 21 files changed, 72 insertions(+), 47 deletions(-) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index a64502fbb2..7b0ad1de12 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -5,7 +5,6 @@ #include "qapi/qapi-types-misc.h" #include "qemu/readline.h" -extern __thread Monitor *cur_mon; typedef struct MonitorHMP MonitorHMP; typedef struct MonitorOptions MonitorOptions; @@ -13,6 +12,8 @@ typedef struct MonitorOptions MonitorOptions; extern QemuOptsList qemu_mon_opts; +Monitor *monitor_cur(void); +Monitor *monitor_set_cur(Monitor *mon); bool monitor_cur_is_qmp(void); void monitor_init_globals(void); diff --git a/audio/wavcapture.c b/audio/wavcapture.c index 17e87ed6f4..c60286e162 100644 --- a/audio/wavcapture.c +++ b/audio/wavcapture.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "monitor/monitor.h" +#include "qemu/qemu-print.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "audio.h" @@ -94,9 +94,9 @@ static void wav_capture_info (void *opaque) WAVState *wav = opaque; char *path = wav->path; - monitor_printf (cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n", - wav->freq, wav->bits, wav->nchannels, - path ? path : "", wav->bytes); + qemu_printf("Capturing audio(%d,%d,%d) to %s: %d bytes\n", + wav->freq, wav->bits, wav->nchannels, + path ? path : "", wav->bytes); } static struct capture_ops wav_capture_ops = { diff --git a/dump/dump.c b/dump/dump.c index 383bc7876b..232027e92c 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -1986,7 +1986,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, #if !defined(WIN32) if (strstart(file, "fd:", &p)) { - fd = monitor_get_fd(cur_mon, p, errp); + fd = monitor_get_fd(monitor_cur(), p, errp); if (fd == -1) { return; } diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index a83ffeefc8..4d70fa036b 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -177,7 +177,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) } if (vs->conf.vhostfd) { - vhostfd = monitor_fd_param(cur_mon, vs->conf.vhostfd, errp); + vhostfd = monitor_fd_param(monitor_cur(), vs->conf.vhostfd, errp); if (vhostfd == -1) { error_prepend(errp, "vhost-scsi: unable to parse vhostfd: "); return; diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index c8f0699b4f..f9db4beb47 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -143,7 +143,7 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) } if (vsock->conf.vhostfd) { - vhostfd = monitor_fd_param(cur_mon, vsock->conf.vhostfd, errp); + vhostfd = monitor_fd_param(monitor_cur(), vsock->conf.vhostfd, errp); if (vhostfd == -1) { error_prepend(errp, "vhost-vsock: unable to parse vhostfd: "); return; diff --git a/migration/fd.c b/migration/fd.c index 0a29ecdebf..6f2f50475f 100644 --- a/migration/fd.c +++ b/migration/fd.c @@ -26,7 +26,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) { QIOChannel *ioc; - int fd = monitor_get_fd(cur_mon, fdname, errp); + int fd = monitor_get_fd(monitor_cur(), fdname, errp); if (fd == -1) { return; } @@ -55,7 +55,7 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc, void fd_start_incoming_migration(const char *fdname, Error **errp) { QIOChannel *ioc; - int fd = monitor_fd_param(cur_mon, fdname, errp); + int fd = monitor_fd_param(monitor_cur(), fdname, errp); if (fd == -1) { return; } diff --git a/monitor/hmp.c b/monitor/hmp.c index d598dd02bb..561e32d02f 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -1300,12 +1300,11 @@ cleanup: static void monitor_read(void *opaque, const uint8_t *buf, int size) { - MonitorHMP *mon; - Monitor *old_mon = cur_mon; + MonitorHMP *mon = container_of(opaque, MonitorHMP, common); + Monitor *old_mon; int i; - cur_mon = opaque; - mon = container_of(cur_mon, MonitorHMP, common); + old_mon = monitor_set_cur(&mon->common); if (mon->rs) { for (i = 0; i < size; i++) { @@ -1313,13 +1312,13 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size) } } else { if (size == 0 || buf[size - 1] != 0) { - monitor_printf(cur_mon, "corrupted command\n"); + monitor_printf(&mon->common, "corrupted command\n"); } else { handle_hmp_command(mon, (char *)buf); } } - cur_mon = old_mon; + monitor_set_cur(old_mon); } static void monitor_event(void *opaque, QEMUChrEvent event) diff --git a/monitor/misc.c b/monitor/misc.c index 972726061c..a5eb3025f8 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -125,13 +125,12 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, monitor_data_init(&hmp.common, false, true, false); - old_mon = cur_mon; - cur_mon = &hmp.common; + old_mon = monitor_set_cur(&hmp.common); if (has_cpu_index) { int ret = monitor_set_cpu(&hmp.common, cpu_index); if (ret < 0) { - cur_mon = old_mon; + monitor_set_cur(old_mon); error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number"); goto out; @@ -139,7 +138,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, } handle_hmp_command(&hmp, command_line); - cur_mon = old_mon; + monitor_set_cur(old_mon); qemu_mutex_lock(&hmp.common.mon_lock); if (qstring_get_length(hmp.common.outbuf) > 0) { @@ -297,7 +296,7 @@ static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize) CPUState *mon_get_cpu(void) { - return mon_get_cpu_sync(cur_mon, true); + return mon_get_cpu_sync(monitor_cur(), true); } CPUArchState *mon_get_cpu_env(void) @@ -1232,6 +1231,7 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict) void qmp_getfd(const char *fdname, Error **errp) { + Monitor *cur_mon = monitor_cur(); mon_fd_t *monfd; int fd, tmp_fd; @@ -1272,6 +1272,7 @@ void qmp_getfd(const char *fdname, Error **errp) void qmp_closefd(const char *fdname, Error **errp) { + Monitor *cur_mon = monitor_cur(); mon_fd_t *monfd; int tmp_fd; @@ -1361,7 +1362,7 @@ AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, const char *opaque, Error **errp) { int fd; - Monitor *mon = cur_mon; + Monitor *mon = monitor_cur(); AddfdInfo *fdinfo; fd = qemu_chr_fe_get_msgfd(&mon->chr); diff --git a/monitor/monitor.c b/monitor/monitor.c index b385a3d569..be3839a7aa 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -66,13 +66,31 @@ MonitorList mon_list; int mon_refcount; static bool monitor_destroyed; -__thread Monitor *cur_mon; +static __thread Monitor *cur_monitor; + +Monitor *monitor_cur(void) +{ + return cur_monitor; +} + +/** + * Sets a new current monitor and returns the old one. + */ +Monitor *monitor_set_cur(Monitor *mon) +{ + Monitor *old_monitor = cur_monitor; + + cur_monitor = mon; + return old_monitor; +} /** * Is the current monitor, if any, a QMP monitor? */ bool monitor_cur_is_qmp(void) { + Monitor *cur_mon = monitor_cur(); + return cur_mon && monitor_is_qmp(cur_mon); } @@ -209,6 +227,8 @@ int monitor_printf(Monitor *mon, const char *fmt, ...) */ int error_vprintf(const char *fmt, va_list ap) { + Monitor *cur_mon = monitor_cur(); + if (cur_mon && !monitor_cur_is_qmp()) { return monitor_vprintf(cur_mon, fmt, ap); } @@ -217,6 +237,8 @@ int error_vprintf(const char *fmt, va_list ap) int error_vprintf_unless_qmp(const char *fmt, va_list ap) { + Monitor *cur_mon = monitor_cur(); + if (!cur_mon) { return vfprintf(stderr, fmt, ap); } diff --git a/monitor/qmp-cmds-control.c b/monitor/qmp-cmds-control.c index 8f04cfa6e6..a456762f6a 100644 --- a/monitor/qmp-cmds-control.c +++ b/monitor/qmp-cmds-control.c @@ -69,6 +69,7 @@ static bool qmp_caps_accept(MonitorQMP *mon, QMPCapabilityList *list, void qmp_qmp_capabilities(bool has_enable, QMPCapabilityList *enable, Error **errp) { + Monitor *cur_mon = monitor_cur(); MonitorQMP *mon; assert(monitor_is_qmp(cur_mon)); @@ -119,6 +120,7 @@ static void query_commands_cb(const QmpCommand *cmd, void *opaque) CommandInfoList *qmp_query_commands(Error **errp) { CommandInfoList *list = NULL; + Monitor *cur_mon = monitor_cur(); MonitorQMP *mon; assert(monitor_is_qmp(cur_mon)); diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 864cbfa32e..c7bf6bb4dc 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -327,7 +327,7 @@ void qmp_add_client(const char *protocol, const char *fdname, Chardev *s; int fd; - fd = monitor_get_fd(cur_mon, fdname, errp); + fd = monitor_get_fd(monitor_cur(), fdname, errp); if (fd < 0) { return; } diff --git a/monitor/qmp.c b/monitor/qmp.c index d433ceae5b..bb2d9d0cc7 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -139,12 +139,9 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) QDict *rsp; QDict *error; - old_mon = cur_mon; - cur_mon = &mon->common; - + old_mon = monitor_set_cur(&mon->common); rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon)); - - cur_mon = old_mon; + monitor_set_cur(old_mon); if (mon->commands == &qmp_cap_negotiation_commands) { error = qdict_get_qdict(rsp, "error"); diff --git a/net/socket.c b/net/socket.c index 2d21fddd9c..15b410e8d8 100644 --- a/net/socket.c +++ b/net/socket.c @@ -727,7 +727,7 @@ int net_init_socket(const Netdev *netdev, const char *name, if (sock->has_fd) { int fd, ret; - fd = monitor_fd_param(cur_mon, sock->fd, errp); + fd = monitor_fd_param(monitor_cur(), sock->fd, errp); if (fd == -1) { return -1; } diff --git a/net/tap.c b/net/tap.c index 14dc904fca..688dcfafdf 100644 --- a/net/tap.c +++ b/net/tap.c @@ -696,7 +696,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, if (vhostfdname) { int ret; - vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err); + vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, &err); if (vhostfd == -1) { if (tap->has_vhostforce && tap->vhostforce) { error_propagate(errp, err); @@ -802,7 +802,7 @@ int net_init_tap(const Netdev *netdev, const char *name, return -1; } - fd = monitor_fd_param(cur_mon, tap->fd, errp); + fd = monitor_fd_param(monitor_cur(), tap->fd, errp); if (fd == -1) { return -1; } @@ -856,7 +856,7 @@ int net_init_tap(const Netdev *netdev, const char *name, } for (i = 0; i < nfds; i++) { - fd = monitor_fd_param(cur_mon, fds[i], errp); + fd = monitor_fd_param(monitor_cur(), fds[i], errp); if (fd == -1) { ret = -1; goto free_fail; diff --git a/softmmu/cpus.c b/softmmu/cpus.c index ae643447e9..aa1b6956f3 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -2224,7 +2224,7 @@ exit: void qmp_inject_nmi(Error **errp) { - nmi_monitor_handle(monitor_get_cpu_index(cur_mon), errp); + nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp); } void dump_drift_info(void) diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c index 6cff1c4e1d..0cd2d864b2 100644 --- a/stubs/monitor-core.c +++ b/stubs/monitor-core.c @@ -3,7 +3,10 @@ #include "qemu-common.h" #include "qapi/qapi-emit-events.h" -__thread Monitor *cur_mon; +Monitor *monitor_cur(void) +{ + return NULL; +} void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) { diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c index af9f5c0c70..6c50dbf051 100644 --- a/tests/test-util-sockets.c +++ b/tests/test-util-sockets.c @@ -52,6 +52,7 @@ static void test_fd_is_socket_good(void) static int mon_fd = -1; static const char *mon_fdname; +__thread Monitor *cur_mon; int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) { @@ -66,15 +67,12 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) /* * Syms of stubs in libqemuutil.a are discarded at .o file granularity. - * To replace monitor_get_fd() we must ensure everything in - * stubs/monitor.c is defined, to make sure monitor.o is discarded - * otherwise we get duplicate syms at link time. + * To replace monitor_get_fd() and monitor_cur(), we must ensure that we also + * replace any other symbol that is used in the binary and would be taken from + * the same stub object file, otherwise we get duplicate syms at link time. */ -__thread Monitor *cur_mon; +Monitor *monitor_cur(void) { return cur_mon; } int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); } -void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {} -void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {} - static void test_socket_fd_pass_name_good(void) { diff --git a/trace/control.c b/trace/control.c index c63a4de732..b35e512dce 100644 --- a/trace/control.c +++ b/trace/control.c @@ -176,7 +176,7 @@ void trace_enable_events(const char *line_buf) { if (is_help_option(line_buf)) { trace_list_events(); - if (cur_mon == NULL) { + if (monitor_cur() == NULL) { exit(0); } } else { diff --git a/util/qemu-error.c b/util/qemu-error.c index 3ee41438e9..aa30f03564 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -171,7 +171,7 @@ static void print_loc(void) int i; const char *const *argp; - if (!cur_mon && progname) { + if (!monitor_cur() && progname) { fprintf(stderr, "%s:", progname); sep = " "; } @@ -208,7 +208,7 @@ static void vreport(report_type type, const char *fmt, va_list ap) GTimeVal tv; gchar *timestr; - if (error_with_timestamp && !cur_mon) { + if (error_with_timestamp && !monitor_cur()) { g_get_current_time(&tv); timestr = g_time_val_to_iso8601(&tv); error_printf("%s ", timestr); @@ -216,7 +216,7 @@ static void vreport(report_type type, const char *fmt, va_list ap) } /* Only prepend guest name if -msg guest-name and -name guest=... are set */ - if (error_with_guestname && error_guest_name && !cur_mon) { + if (error_with_guestname && error_guest_name && !monitor_cur()) { error_printf("%s ", error_guest_name); } diff --git a/util/qemu-print.c b/util/qemu-print.c index e79d6b8396..69ba612f56 100644 --- a/util/qemu-print.c +++ b/util/qemu-print.c @@ -20,6 +20,7 @@ */ int qemu_vprintf(const char *fmt, va_list ap) { + Monitor *cur_mon = monitor_cur(); if (cur_mon) { return monitor_vprintf(cur_mon, fmt, ap); } @@ -48,7 +49,7 @@ int qemu_printf(const char *fmt, ...) int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap) { if (!stream) { - return monitor_vprintf(cur_mon, fmt, ap); + return monitor_vprintf(monitor_cur(), fmt, ap); } return vfprintf(stream, fmt, ap); } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index b37d288866..40c18ba142 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1092,6 +1092,7 @@ fail: static int socket_get_fd(const char *fdstr, int num, Error **errp) { + Monitor *cur_mon = monitor_cur(); int fd; if (num != 1) { error_setg_errno(errp, EINVAL, "socket_get_fd: too many connections"); From patchwork Wed Sep 9 15:11:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274122 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 358B9C43461 for ; Wed, 9 Sep 2020 15:20:28 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A310422286 for ; Wed, 9 Sep 2020 15:20:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ir+7FuWx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A310422286 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:51432 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1ta-0005cD-Mh for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:20:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36462) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lb-00013B-TQ for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:22012) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lZ-0003lP-Sc for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664328; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8EXGXnlOMCYuzVZ0885U5nv9lmo4TUQHX2VTkm7nf10=; b=Ir+7FuWxcP4ksnTiHDuB7qt0yiURJes4Rc143bFkZGppylvkKtQrIvLbnyeLT+LcJK8ACh tK8NzfZLbQ4QVhGbuEE+KYNeTf+gEtMl15u3P/Fe4z4reFvr+hS5IfI4zbp19g8+zlsTh4 TaVhKTi/DnCKiOdbJM0tOGIkDTqIbZ8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-410-XtGRFi6oO16zoCwmHnyfrQ-1; Wed, 09 Sep 2020 11:12:06 -0400 X-MC-Unique: XtGRFi6oO16zoCwmHnyfrQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A2B0C8015A4; Wed, 9 Sep 2020 15:12:05 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F15C60C07; Wed, 9 Sep 2020 15:12:04 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 04/13] hmp: Update current monitor only in handle_hmp_command() Date: Wed, 9 Sep 2020 17:11:40 +0200 Message-Id: <20200909151149.490589-5-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:25:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The current monitor is updated relatively early in the command handling code even though only the command handler actually needs it. The current monitor will become coroutine-local later, so we can only update it when we know in which coroutine the command will be exectued. Move it to handle_hmp_command() where this information will be available. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- monitor/hmp.c | 10 +++++----- monitor/misc.c | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/monitor/hmp.c b/monitor/hmp.c index 561e32d02f..896c670183 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -1061,6 +1061,7 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) QDict *qdict; const HMPCommand *cmd; const char *cmd_start = cmdline; + Monitor *old_mon; trace_handle_hmp_command(mon, cmdline); @@ -1079,7 +1080,11 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) return; } + /* old_mon is non-NULL when called from qmp_human_monitor_command() */ + old_mon = monitor_set_cur(&mon->common); cmd->cmd(&mon->common, qdict); + monitor_set_cur(old_mon); + qobject_unref(qdict); } @@ -1301,11 +1306,8 @@ cleanup: static void monitor_read(void *opaque, const uint8_t *buf, int size) { MonitorHMP *mon = container_of(opaque, MonitorHMP, common); - Monitor *old_mon; int i; - old_mon = monitor_set_cur(&mon->common); - if (mon->rs) { for (i = 0; i < size; i++) { readline_handle_byte(mon->rs, buf[i]); @@ -1317,8 +1319,6 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size) handle_hmp_command(mon, (char *)buf); } } - - monitor_set_cur(old_mon); } static void monitor_event(void *opaque, QEMUChrEvent event) diff --git a/monitor/misc.c b/monitor/misc.c index a5eb3025f8..ba1063024c 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -120,17 +120,13 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, int64_t cpu_index, Error **errp) { char *output = NULL; - Monitor *old_mon; MonitorHMP hmp = {}; monitor_data_init(&hmp.common, false, true, false); - old_mon = monitor_set_cur(&hmp.common); - if (has_cpu_index) { int ret = monitor_set_cpu(&hmp.common, cpu_index); if (ret < 0) { - monitor_set_cur(old_mon); error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number"); goto out; @@ -138,7 +134,6 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, } handle_hmp_command(&hmp, command_line); - monitor_set_cur(old_mon); qemu_mutex_lock(&hmp.common.mon_lock); if (qstring_get_length(hmp.common.outbuf) > 0) { From patchwork Wed Sep 9 15:11:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274127 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17A4DC433E2 for ; Wed, 9 Sep 2020 15:14:07 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7C0CF21919 for ; Wed, 9 Sep 2020 15:14:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="f5sHTGnh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7C0CF21919 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57158 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1nR-0004iB-E9 for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:14:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36504) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1ld-000178-B0 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:13 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:24115 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lb-0003m2-J0 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664330; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lMQlAf73YBYMHwrfbPfHm01yXpYu/jGVGq8w5VKBK4I=; b=f5sHTGnh8uAipsDM97I0bkyJXuhFBa3W6+on9ISEum8rVieztOO/hoSUhnuDuJzXCAptXi N22SAvt6WyYMrlZ0VLSQq8iSKlfBjUPj9WOJDp7gLiXZnsJr5l/k229SIdVz2+fFn2QrUD qewD0Cubp0F3NBPQKyaM95wQ5V+u/lw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-273-TRcUdzysNOenqlt_o2q-Kw-1; Wed, 09 Sep 2020 11:12:08 -0400 X-MC-Unique: TRcUdzysNOenqlt_o2q-Kw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 868BD1DDFD; Wed, 9 Sep 2020 15:12:07 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00C8A60C07; Wed, 9 Sep 2020 15:12:05 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 05/13] qmp: Assert that no other monitor is active Date: Wed, 9 Sep 2020 17:11:41 +0200 Message-Id: <20200909151149.490589-6-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:05:47 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" monitor_qmp_dispatch() is never supposed to be called in the context of another monitor, so assert that monitor_cur() is NULL instead of saving and restoring it. Signed-off-by: Kevin Wolf --- monitor/qmp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/monitor/qmp.c b/monitor/qmp.c index bb2d9d0cc7..8469970c69 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -140,8 +140,11 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) QDict *error; old_mon = monitor_set_cur(&mon->common); + assert(old_mon == NULL); + rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon)); - monitor_set_cur(old_mon); + + monitor_set_cur(NULL); if (mon->commands == &qmp_cap_negotiation_commands) { error = qdict_get_qdict(rsp, "error"); From patchwork Wed Sep 9 15:11:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274126 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6737FC43461 for ; Wed, 9 Sep 2020 15:14:54 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6F86821919 for ; Wed, 9 Sep 2020 15:14:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="JXndqzR1" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6F86821919 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:33138 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1oC-0006Sg-Ci for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:14:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36600) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1li-0001Lm-G4 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:18 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:55311) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lf-0003nq-RB for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664335; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R+GxBZ05I55j0DxODUUI8P5IDmobelPnlqIg9oLpL6k=; b=JXndqzR1JMGlSqve+QztuyKISp0sZUkgI7yPg5WQ7vR/S9hjaAtg5PjDJ+NdtaTajo8ggs xcaTJkpv8viz83u9fGWPwLBw5J+8c+Qysx8PNPxJW8dKR/oUJjd+FBuv0OtYkqQMTCdulF xrNxOAjycfd9HXaMIPhQSV2NsobPOIs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-82-x_wEyWlmNGisnF3QmgrPMA-1; Wed, 09 Sep 2020 11:12:10 -0400 X-MC-Unique: x_wEyWlmNGisnF3QmgrPMA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 666891084D79; Wed, 9 Sep 2020 15:12:09 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id D4FCF60C07; Wed, 9 Sep 2020 15:12:07 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 06/13] qmp: Call monitor_set_cur() only in qmp_dispatch() Date: Wed, 9 Sep 2020 17:11:42 +0200 Message-Id: <20200909151149.490589-7-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:25:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The correct way to set the current monitor for a coroutine handler will be different than for a blocking handler, so monitor_set_cur() needs to be called in qmp_dispatch(). Signed-off-by: Kevin Wolf --- include/qapi/qmp/dispatch.h | 3 ++- monitor/qmp.c | 8 +------- qapi/qmp-dispatch.c | 8 +++++++- qga/main.c | 2 +- stubs/monitor-core.c | 5 +++++ tests/test-qmp-cmds.c | 6 +++--- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 5a9cf82472..0c2f467028 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -14,6 +14,7 @@ #ifndef QAPI_QMP_DISPATCH_H #define QAPI_QMP_DISPATCH_H +#include "monitor/monitor.h" #include "qemu/queue.h" typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); @@ -49,7 +50,7 @@ const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - bool allow_oob); + bool allow_oob, Monitor *cur_mon); bool qmp_is_oob(const QDict *dict); typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque); diff --git a/monitor/qmp.c b/monitor/qmp.c index 8469970c69..922fdb5541 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -135,16 +135,10 @@ static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) { - Monitor *old_mon; QDict *rsp; QDict *error; - old_mon = monitor_set_cur(&mon->common); - assert(old_mon == NULL); - - rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon)); - - monitor_set_cur(NULL); + rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon), &mon->common); if (mon->commands == &qmp_cap_negotiation_commands) { error = qdict_get_qdict(rsp, "error"); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 79347e0864..2fdbc0fba4 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -89,7 +89,7 @@ bool qmp_is_oob(const QDict *dict) } QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - bool allow_oob) + bool allow_oob, Monitor *cur_mon) { Error *err = NULL; bool oob; @@ -152,7 +152,13 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, args = qdict_get_qdict(dict, "arguments"); qobject_ref(args); } + + assert(monitor_cur() == NULL); + monitor_set_cur(cur_mon); + cmd->fn(args, &ret, &err); + + monitor_set_cur(NULL); qobject_unref(args); if (err) { /* or assert(!ret) after reviewing all handlers: */ diff --git a/qga/main.c b/qga/main.c index 3febf3b0fd..241779a1d6 100644 --- a/qga/main.c +++ b/qga/main.c @@ -578,7 +578,7 @@ static void process_event(void *opaque, QObject *obj, Error *err) } g_debug("processing command"); - rsp = qmp_dispatch(&ga_commands, obj, false); + rsp = qmp_dispatch(&ga_commands, obj, false, NULL); end: ret = send_response(s, rsp); diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c index 0cd2d864b2..dc1748bf13 100644 --- a/stubs/monitor-core.c +++ b/stubs/monitor-core.c @@ -8,6 +8,11 @@ Monitor *monitor_cur(void) return NULL; } +Monitor *monitor_set_cur(Monitor *mon) +{ + return NULL; +} + void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) { } diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index d12ff47e26..5f1b245e19 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -152,7 +152,7 @@ static QObject *do_qmp_dispatch(bool allow_oob, const char *template, ...) req = qdict_from_vjsonf_nofail(template, ap); va_end(ap); - resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob, NULL); g_assert(resp); ret = qdict_get(resp, "return"); g_assert(ret); @@ -175,7 +175,7 @@ static void do_qmp_dispatch_error(bool allow_oob, ErrorClass cls, req = qdict_from_vjsonf_nofail(template, ap); va_end(ap); - resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob, NULL); g_assert(resp); error = qdict_get_qdict(resp, "error"); g_assert(error); @@ -231,7 +231,7 @@ static void test_dispatch_cmd_success_response(void) QDict *resp; qdict_put_str(req, "execute", "cmd-success-response"); - resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false, NULL); g_assert_null(resp); qobject_unref(req); } From patchwork Wed Sep 9 15:11:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274128 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A3FFC43461 for ; Wed, 9 Sep 2020 15:13:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 76FA621919 for ; Wed, 9 Sep 2020 15:13:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="dsT8l6J/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 76FA621919 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1mq-00032B-EB for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:13:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lg-0001HZ-Pu for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:16 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:39417 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1le-0003nQ-QK for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664334; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lvNq4ChIS1hKiFxa2oNR6I6FJv6jjeb4gi2yCNJNvk4=; b=dsT8l6J/6y66y5vo4Sgz0CDadALhs6haU+6UNpCFsFuJhqcLGvynRKcYKLkJVYoj6eGNhR FIM+Ho8V7jnRKHTO1gOQkAzzkePVW6AVhLxjyPGVKrIS82MJ+Kbv7I/R4ndDjzbSoufaGw 88nLxEvDJOqjcd1/7AHGNitLHmvGW/s= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-473-kf_N7Q71OR-dKXpgUWFEQA-1; Wed, 09 Sep 2020 11:12:12 -0400 X-MC-Unique: kf_N7Q71OR-dKXpgUWFEQA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3FF941882FA6; Wed, 9 Sep 2020 15:12:11 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id B81E060C07; Wed, 9 Sep 2020 15:12:09 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 07/13] monitor: Make current monitor a per-coroutine property Date: Wed, 9 Sep 2020 17:11:43 +0200 Message-Id: <20200909151149.490589-8-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:05:47 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This way, a monitor command handler will still be able to access the current monitor, but when it yields, all other code code will correctly get NULL from monitor_cur(). This uses a hash table to map the coroutine pointer to the current monitor of that coroutine. Outside of coroutine context, we associate the current monitor with the leader coroutine of the current thread. Approaches to implement some form of coroutine local storage directly in the coroutine core code have been considered and discarded because they didn't end up being much more generic than the hash table and their performance impact on coroutines not using coroutine local storage was unclear. As the block layer uses a coroutine per I/O request, this is a fast path and we have to be careful. It's safest to just stay out of this path with code only used by the monitor. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/monitor/monitor.h | 2 +- monitor/hmp.c | 4 ++-- monitor/monitor.c | 34 +++++++++++++++++++++++++++------- qapi/qmp-dispatch.c | 4 ++-- stubs/monitor-core.c | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 7b0ad1de12..026f8a31b2 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -13,7 +13,7 @@ typedef struct MonitorOptions MonitorOptions; extern QemuOptsList qemu_mon_opts; Monitor *monitor_cur(void); -Monitor *monitor_set_cur(Monitor *mon); +Monitor *monitor_set_cur(Coroutine *co, Monitor *mon); bool monitor_cur_is_qmp(void); void monitor_init_globals(void); diff --git a/monitor/hmp.c b/monitor/hmp.c index 896c670183..4b66ca1cd6 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -1081,9 +1081,9 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) } /* old_mon is non-NULL when called from qmp_human_monitor_command() */ - old_mon = monitor_set_cur(&mon->common); + old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common); cmd->cmd(&mon->common, qdict); - monitor_set_cur(old_mon); + monitor_set_cur(qemu_coroutine_self(), old_mon); qobject_unref(qdict); } diff --git a/monitor/monitor.c b/monitor/monitor.c index be3839a7aa..629aa073ee 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -58,29 +58,48 @@ IOThread *mon_iothread; /* Bottom half to dispatch the requests received from I/O thread */ QEMUBH *qmp_dispatcher_bh; -/* Protects mon_list, monitor_qapi_event_state, monitor_destroyed. */ +/* + * Protects mon_list, monitor_qapi_event_state, coroutine_mon, + * monitor_destroyed. + */ QemuMutex monitor_lock; static GHashTable *monitor_qapi_event_state; +static GHashTable *coroutine_mon; /* Maps Coroutine* to Monitor* */ MonitorList mon_list; int mon_refcount; static bool monitor_destroyed; -static __thread Monitor *cur_monitor; - Monitor *monitor_cur(void) { - return cur_monitor; + Monitor *mon; + + qemu_mutex_lock(&monitor_lock); + mon = g_hash_table_lookup(coroutine_mon, qemu_coroutine_self()); + qemu_mutex_unlock(&monitor_lock); + + return mon; } /** * Sets a new current monitor and returns the old one. + * + * If a non-NULL monitor is set for a coroutine, another call resetting it to + * NULL is required before the coroutine terminates, otherwise a stale entry + * would remain in the hash table. */ -Monitor *monitor_set_cur(Monitor *mon) +Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { - Monitor *old_monitor = cur_monitor; + Monitor *old_monitor = monitor_cur(); + + qemu_mutex_lock(&monitor_lock); + if (mon) { + g_hash_table_replace(coroutine_mon, co, mon); + } else { + g_hash_table_remove(coroutine_mon, co); + } + qemu_mutex_unlock(&monitor_lock); - cur_monitor = mon; return old_monitor; } @@ -623,6 +642,7 @@ void monitor_init_globals_core(void) { monitor_qapi_event_init(); qemu_mutex_init(&monitor_lock); + coroutine_mon = g_hash_table_new(NULL, NULL); /* * The dispatcher BH must run in the main loop thread, since we diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 2fdbc0fba4..5677ba92ca 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -154,11 +154,11 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, } assert(monitor_cur() == NULL); - monitor_set_cur(cur_mon); + monitor_set_cur(qemu_coroutine_self(), cur_mon); cmd->fn(args, &ret, &err); - monitor_set_cur(NULL); + monitor_set_cur(qemu_coroutine_self(), NULL); qobject_unref(args); if (err) { /* or assert(!ret) after reviewing all handlers: */ diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c index dc1748bf13..d058a2a00d 100644 --- a/stubs/monitor-core.c +++ b/stubs/monitor-core.c @@ -8,7 +8,7 @@ Monitor *monitor_cur(void) return NULL; } -Monitor *monitor_set_cur(Monitor *mon) +Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { return NULL; } From patchwork Wed Sep 9 15:11:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274124 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70936C43461 for ; Wed, 9 Sep 2020 15:18:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9BC7A22287 for ; Wed, 9 Sep 2020 15:18:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="bOpMYPPN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9BC7A22287 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1rO-0001en-Ki for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:18:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lo-0001bK-Fm for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:24 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:51473 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lk-0003oe-5o for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664339; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gFenBXJ1v77VH8XCWE3Si4bytw0yMjDNbw7/YxWLhds=; b=bOpMYPPNvkb+y9dY7Ml+9KYf92538jbtT7rM6NmVr1tg8tO2BDtcG96yF2b5yPVvj1URdg +eU68c5kPzGi8xnx3lRseeyhTYS+A4X6VcURKP9wGr8yEJWnOaEMN44JaPsKcuQB/Ykmfw smrc3gYelDQhbDuCNtzmaJoD9SlDv6k= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-424-v4ZdedgFPeqHC0yIi2nn7g-1; Wed, 09 Sep 2020 11:12:14 -0400 X-MC-Unique: v4ZdedgFPeqHC0yIi2nn7g-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3EBB8801AE5; Wed, 9 Sep 2020 15:12:13 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 95AEF60C87; Wed, 9 Sep 2020 15:12:11 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 08/13] qapi: Add a 'coroutine' flag for commands Date: Wed, 9 Sep 2020 17:11:44 +0200 Message-Id: <20200909151149.490589-9-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.003 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:13:17 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds a new 'coroutine' flag to QMP command definitions that tells the QMP dispatcher that the command handler is safe to be run in a coroutine. The documentation of the new flag pretends that this flag is already used as intended, which it isn't yet after this patch. We'll implement this in another patch in this series. Signed-off-by: Kevin Wolf Reviewed-by: Marc-André Lureau Reviewed-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 12 ++++++++++++ include/qapi/qmp/dispatch.h | 1 + tests/test-qmp-cmds.c | 4 ++++ scripts/qapi/commands.py | 10 +++++++--- scripts/qapi/doc.py | 2 +- scripts/qapi/expr.py | 10 ++++++++-- scripts/qapi/introspect.py | 2 +- scripts/qapi/schema.py | 12 ++++++++---- tests/qapi-schema/test-qapi.py | 7 ++++--- tests/qapi-schema/meson.build | 1 + tests/qapi-schema/oob-coroutine.err | 2 ++ tests/qapi-schema/oob-coroutine.json | 2 ++ tests/qapi-schema/oob-coroutine.out | 0 tests/qapi-schema/qapi-schema-test.json | 1 + tests/qapi-schema/qapi-schema-test.out | 2 ++ 15 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 tests/qapi-schema/oob-coroutine.err create mode 100644 tests/qapi-schema/oob-coroutine.json create mode 100644 tests/qapi-schema/oob-coroutine.out diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index f3e7ced212..36daa9b5f8 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -472,6 +472,7 @@ Syntax: '*gen': false, '*allow-oob': true, '*allow-preconfig': true, + '*coroutine': true, '*if': COND, '*features': FEATURES } @@ -596,6 +597,17 @@ before the machine is built. It defaults to false. For example: QMP is available before the machine is built only when QEMU was started with --preconfig. +Member 'coroutine' tells the QMP dispatcher whether the command handler +is safe to be run in a coroutine. It defaults to false. If it is true, +the command handler is called from coroutine context and may yield while +waiting for an external event (such as I/O completion) in order to avoid +blocking the guest and other background operations. + +It is an error to specify both 'coroutine': true and 'allow-oob': true +for a command. We don't currently have a use case for both together and +without a use case, it's not entirely clear what the semantics should +be. + The optional 'if' member specifies a conditional. See "Configuring the schema" below for more on this. diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 0c2f467028..9fd2b720a7 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -25,6 +25,7 @@ typedef enum QmpCommandOptions QCO_NO_SUCCESS_RESP = (1U << 0), QCO_ALLOW_OOB = (1U << 1), QCO_ALLOW_PRECONFIG = (1U << 2), + QCO_COROUTINE = (1U << 3), } QmpCommandOptions; typedef struct QmpCommand diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 5f1b245e19..d3413bfef0 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -36,6 +36,10 @@ void qmp_cmd_success_response(Error **errp) { } +void qmp_coroutine_cmd(Error **errp) +{ +} + Empty2 *qmp_user_def_cmd0(Error **errp) { return g_new0(Empty2, 1); diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index 3cf9e1110b..6e6fc94a14 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -176,7 +176,8 @@ out: return ret -def gen_register_command(name, success_response, allow_oob, allow_preconfig): +def gen_register_command(name, success_response, allow_oob, allow_preconfig, + coroutine): options = [] if not success_response: @@ -185,6 +186,8 @@ def gen_register_command(name, success_response, allow_oob, allow_preconfig): options += ['QCO_ALLOW_OOB'] if allow_preconfig: options += ['QCO_ALLOW_PRECONFIG'] + if coroutine: + options += ['QCO_COROUTINE'] if not options: options = ['QCO_NO_OPTIONS'] @@ -267,7 +270,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); def visit_command(self, name, info, ifcond, features, arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig): + allow_oob, allow_preconfig, coroutine): if not gen: return # FIXME: If T is a user-defined type, the user is responsible @@ -285,7 +288,8 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); self._genh.add(gen_marshal_decl(name)) self._genc.add(gen_marshal(name, arg_type, boxed, ret_type)) self._regy.add(gen_register_command(name, success_response, - allow_oob, allow_preconfig)) + allow_oob, allow_preconfig, + coroutine)) def gen_commands(schema, output_dir, prefix): diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 92f584edcf..11771de923 100644 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -264,7 +264,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor): def visit_command(self, name, info, ifcond, features, arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig): + allow_oob, allow_preconfig, coroutine): doc = self.cur_doc self._gen.add(texi_msg('Command', doc, ifcond, texi_arguments(doc, diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 2942520399..928cd1eb5c 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -88,10 +88,16 @@ def check_flags(expr, info): if key in expr and expr[key] is not False: raise QAPISemError( info, "flag '%s' may only use false value" % key) - for key in ['boxed', 'allow-oob', 'allow-preconfig']: + for key in ['boxed', 'allow-oob', 'allow-preconfig', 'coroutine']: if key in expr and expr[key] is not True: raise QAPISemError( info, "flag '%s' may only use true value" % key) + if 'allow-oob' in expr and 'coroutine' in expr: + # This is not necessarily a fundamental incompatibility, but we don't + # have a use case and the desired semantics isn't obvious. The simplest + # solution is to forbid it until we get a use case for it. + raise QAPISemError(info, "flags 'allow-oob' and 'coroutine' " + "are incompatible") def check_if(expr, info, source): @@ -342,7 +348,7 @@ def check_exprs(exprs): ['command'], ['data', 'returns', 'boxed', 'if', 'features', 'gen', 'success-response', 'allow-oob', - 'allow-preconfig']) + 'allow-preconfig', 'coroutine']) normalize_members(expr.get('data')) check_command(expr, info) elif meta == 'event': diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 23652be810..5907b09cd5 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -216,7 +216,7 @@ const QLitObject %(c_name)s = %(c_string)s; def visit_command(self, name, info, ifcond, features, arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig): + allow_oob, allow_preconfig, coroutine): arg_type = arg_type or self._schema.the_empty_object_type ret_type = ret_type or self._schema.the_empty_object_type obj = {'arg-type': self._use_type(arg_type), diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 78309a00f0..c44d391c3f 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -128,7 +128,7 @@ class QAPISchemaVisitor: def visit_command(self, name, info, ifcond, features, arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig): + allow_oob, allow_preconfig, coroutine): pass def visit_event(self, name, info, ifcond, features, arg_type, boxed): @@ -713,7 +713,8 @@ class QAPISchemaCommand(QAPISchemaEntity): def __init__(self, name, info, doc, ifcond, features, arg_type, ret_type, - gen, success_response, boxed, allow_oob, allow_preconfig): + gen, success_response, boxed, allow_oob, allow_preconfig, + coroutine): super().__init__(name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) assert not ret_type or isinstance(ret_type, str) @@ -726,6 +727,7 @@ class QAPISchemaCommand(QAPISchemaEntity): self.boxed = boxed self.allow_oob = allow_oob self.allow_preconfig = allow_preconfig + self.coroutine = coroutine def check(self, schema): super().check(schema) @@ -768,7 +770,7 @@ class QAPISchemaCommand(QAPISchemaEntity): visitor.visit_command( self.name, self.info, self.ifcond, self.features, self.arg_type, self.ret_type, self.gen, self.success_response, - self.boxed, self.allow_oob, self.allow_preconfig) + self.boxed, self.allow_oob, self.allow_preconfig, self.coroutine) class QAPISchemaEvent(QAPISchemaEntity): @@ -1074,6 +1076,7 @@ class QAPISchema: boxed = expr.get('boxed', False) allow_oob = expr.get('allow-oob', False) allow_preconfig = expr.get('allow-preconfig', False) + coroutine = expr.get('coroutine', False) ifcond = expr.get('if') features = self._make_features(expr.get('features'), info) if isinstance(data, OrderedDict): @@ -1086,7 +1089,8 @@ class QAPISchema: self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, features, data, rets, gen, success_response, - boxed, allow_oob, allow_preconfig)) + boxed, allow_oob, allow_preconfig, + coroutine)) def _def_event(self, expr, info, doc): name = expr['event'] diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index f396b471eb..e8db9d09d9 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -68,12 +68,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): def visit_command(self, name, info, ifcond, features, arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig): + allow_oob, allow_preconfig, coroutine): print('command %s %s -> %s' % (name, arg_type and arg_type.name, ret_type and ret_type.name)) - print(' gen=%s success_response=%s boxed=%s oob=%s preconfig=%s' - % (gen, success_response, boxed, allow_oob, allow_preconfig)) + print(' gen=%s success_response=%s boxed=%s oob=%s preconfig=%s%s' + % (gen, success_response, boxed, allow_oob, allow_preconfig, + " coroutine=True" if coroutine else "")) self._print_if(ifcond) self._print_features(features) diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build index c87d141417..7a9bc69cc0 100644 --- a/tests/qapi-schema/meson.build +++ b/tests/qapi-schema/meson.build @@ -141,6 +141,7 @@ schemas = [ 'nested-struct-data.json', 'nested-struct-data-invalid-dict.json', 'non-objects.json', + 'oob-coroutine.json', 'oob-test.json', 'allow-preconfig-test.json', 'pragma-doc-required-crap.json', diff --git a/tests/qapi-schema/oob-coroutine.err b/tests/qapi-schema/oob-coroutine.err new file mode 100644 index 0000000000..c01a4992bd --- /dev/null +++ b/tests/qapi-schema/oob-coroutine.err @@ -0,0 +1,2 @@ +oob-coroutine.json: In command 'oob-command-1': +oob-coroutine.json:2: flags 'allow-oob' and 'coroutine' are incompatible diff --git a/tests/qapi-schema/oob-coroutine.json b/tests/qapi-schema/oob-coroutine.json new file mode 100644 index 0000000000..0f67663bcd --- /dev/null +++ b/tests/qapi-schema/oob-coroutine.json @@ -0,0 +1,2 @@ +# Check that incompatible flags allow-oob and coroutine are rejected +{ 'command': 'oob-command-1', 'allow-oob': true, 'coroutine': true } diff --git a/tests/qapi-schema/oob-coroutine.out b/tests/qapi-schema/oob-coroutine.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 3a9f2cbb33..63f92adf68 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -148,6 +148,7 @@ 'returns': 'UserDefTwo' } { 'command': 'cmd-success-response', 'data': {}, 'success-response': false } +{ 'command': 'coroutine-cmd', 'data': {}, 'coroutine': true } # Returning a non-dictionary requires a name from the whitelist { 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' }, diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 891b4101e0..8868ca0dca 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -203,6 +203,8 @@ command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo gen=True success_response=True boxed=False oob=False preconfig=False command cmd-success-response None -> None gen=True success_response=False boxed=False oob=False preconfig=False +command coroutine-cmd None -> None + gen=True success_response=True boxed=False oob=False preconfig=False coroutine=True object q_obj_guest-get-time-arg member a: int optional=False member b: int optional=True From patchwork Wed Sep 9 15:11:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305794 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B870CC433E2 for ; Wed, 9 Sep 2020 15:15:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 261ED20757 for ; Wed, 9 Sep 2020 15:15:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Mi50zUKD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 261ED20757 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1p9-0007Dx-4V for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:15:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36748) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1ls-0001lf-I0 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:28 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:48927 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1ll-0003p8-PV for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664341; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q1vpMQqLgqTZe8O+N86RN1Ridb8ccaWzg8zgL9u8DKk=; b=Mi50zUKDCm/wkKonVl6Geuwo3jNSlzoRVJBl2mK0HfqnZLePOb8Z2GTvq11ZM765FaP6LU UPbg2eDLET8uCuoCWV27wSoJeSPR7ybl0LqlQjOEzPe5KGhlNWzukJcaTHdghtwsEPrbJ9 7TIbjzKeirFnXIR59Hk8YfeP0lCoogc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-129-Qb2S7zMUO8ONgeMfKD2zvQ-1; Wed, 09 Sep 2020 11:12:19 -0400 X-MC-Unique: Qb2S7zMUO8ONgeMfKD2zvQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C7C2E1005E5C; Wed, 9 Sep 2020 15:12:17 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8C3FF60C07; Wed, 9 Sep 2020 15:12:13 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 09/13] qmp: Move dispatcher to a coroutine Date: Wed, 9 Sep 2020 17:11:45 +0200 Message-Id: <20200909151149.490589-10-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:05:47 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This moves the QMP dispatcher to a coroutine and runs all QMP command handlers that declare 'coroutine': true in coroutine context so they can avoid blocking the main loop while doing I/O or waiting for other events. For commands that are not declared safe to run in a coroutine, the dispatcher drops out of coroutine context by calling the QMP command handler from a bottom half. Signed-off-by: Kevin Wolf Reviewed-by: Markus Armbruster --- include/qapi/qmp/dispatch.h | 1 + monitor/monitor-internal.h | 6 +- monitor/monitor.c | 55 +++++++++++++--- monitor/qmp.c | 122 +++++++++++++++++++++++++++--------- qapi/qmp-dispatch.c | 61 ++++++++++++++++-- qapi/qmp-registry.c | 3 + util/aio-posix.c | 8 ++- 7 files changed, 210 insertions(+), 46 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 9fd2b720a7..af8d96c570 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -31,6 +31,7 @@ typedef enum QmpCommandOptions typedef struct QmpCommand { const char *name; + /* Runs in coroutine context if QCO_COROUTINE is set */ QmpCommandFunc *fn; QmpCommandOptions options; QTAILQ_ENTRY(QmpCommand) node; diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index b39e03b744..b55d6df07f 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -155,7 +155,9 @@ static inline bool monitor_is_qmp(const Monitor *mon) typedef QTAILQ_HEAD(MonitorList, Monitor) MonitorList; extern IOThread *mon_iothread; -extern QEMUBH *qmp_dispatcher_bh; +extern Coroutine *qmp_dispatcher_co; +extern bool qmp_dispatcher_co_shutdown; +extern bool qmp_dispatcher_co_busy; extern QmpCommandList qmp_commands, qmp_cap_negotiation_commands; extern QemuMutex monitor_lock; extern MonitorList mon_list; @@ -173,7 +175,7 @@ void monitor_fdsets_cleanup(void); void qmp_send_response(MonitorQMP *mon, const QDict *rsp); void monitor_data_destroy_qmp(MonitorQMP *mon); -void monitor_qmp_bh_dispatcher(void *data); +void coroutine_fn monitor_qmp_dispatcher_co(void *data); int get_monitor_def(int64_t *pval, const char *name); void help_cmd(Monitor *mon, const char *name); diff --git a/monitor/monitor.c b/monitor/monitor.c index 629aa073ee..ac2722bf91 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -55,8 +55,32 @@ typedef struct { /* Shared monitor I/O thread */ IOThread *mon_iothread; -/* Bottom half to dispatch the requests received from I/O thread */ -QEMUBH *qmp_dispatcher_bh; +/* Coroutine to dispatch the requests received from I/O thread */ +Coroutine *qmp_dispatcher_co; + +/* Set to true when the dispatcher coroutine should terminate */ +bool qmp_dispatcher_co_shutdown; + +/* + * qmp_dispatcher_co_busy is used for synchronisation between the + * monitor thread and the main thread to ensure that the dispatcher + * coroutine never gets scheduled a second time when it's already + * scheduled (scheduling the same coroutine twice is forbidden). + * + * It is true if the coroutine is active and processing requests. + * Additional requests may then be pushed onto mon->qmp_requests, + * and @qmp_dispatcher_co_shutdown may be set without further ado. + * @qmp_dispatcher_co_busy must not be woken up in this case. + * + * If false, you also have to set @qmp_dispatcher_co_busy to true and + * wake up @qmp_dispatcher_co after pushing the new requests. + * + * The coroutine will automatically change this variable back to false + * before it yields. Nobody else may set the variable to false. + * + * Access must be atomic for thread safety. + */ +bool qmp_dispatcher_co_busy; /* * Protects mon_list, monitor_qapi_event_state, coroutine_mon, @@ -623,9 +647,24 @@ void monitor_cleanup(void) } qemu_mutex_unlock(&monitor_lock); - /* QEMUBHs needs to be deleted before destroying the I/O thread */ - qemu_bh_delete(qmp_dispatcher_bh); - qmp_dispatcher_bh = NULL; + /* + * The dispatcher needs to stop before destroying the I/O thread. + * + * We need to poll both qemu_aio_context and iohandler_ctx to make + * sure that the dispatcher coroutine keeps making progress and + * eventually terminates. qemu_aio_context is automatically + * polled by calling AIO_WAIT_WHILE on it, but we must poll + * iohandler_ctx manually. + */ + qmp_dispatcher_co_shutdown = true; + if (!atomic_xchg(&qmp_dispatcher_co_busy, true)) { + aio_co_wake(qmp_dispatcher_co); + } + + AIO_WAIT_WHILE(qemu_get_aio_context(), + (aio_poll(iohandler_get_aio_context(), false), + atomic_mb_read(&qmp_dispatcher_co_busy))); + if (mon_iothread) { iothread_destroy(mon_iothread); mon_iothread = NULL; @@ -649,9 +688,9 @@ void monitor_init_globals_core(void) * have commands assuming that context. It would be nice to get * rid of those assumptions. */ - qmp_dispatcher_bh = aio_bh_new(iohandler_get_aio_context(), - monitor_qmp_bh_dispatcher, - NULL); + qmp_dispatcher_co = qemu_coroutine_create(monitor_qmp_dispatcher_co, NULL); + atomic_mb_set(&qmp_dispatcher_co_busy, true); + aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co); } int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp) diff --git a/monitor/qmp.c b/monitor/qmp.c index 922fdb5541..69f6e93f38 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -133,6 +133,10 @@ static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) } } +/* + * Runs outside of coroutine context for OOB commands, but in + * coroutine context for everything else. + */ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) { QDict *rsp; @@ -205,43 +209,99 @@ static QMPRequest *monitor_qmp_requests_pop_any_with_lock(void) return req_obj; } -void monitor_qmp_bh_dispatcher(void *data) +void coroutine_fn monitor_qmp_dispatcher_co(void *data) { - QMPRequest *req_obj = monitor_qmp_requests_pop_any_with_lock(); + QMPRequest *req_obj = NULL; QDict *rsp; bool need_resume; MonitorQMP *mon; - if (!req_obj) { - return; - } + while (true) { + assert(atomic_mb_read(&qmp_dispatcher_co_busy) == true); - mon = req_obj->mon; - /* qmp_oob_enabled() might change after "qmp_capabilities" */ - need_resume = !qmp_oob_enabled(mon) || - mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1; - qemu_mutex_unlock(&mon->qmp_queue_lock); - if (req_obj->req) { - QDict *qdict = qobject_to(QDict, req_obj->req); - QObject *id = qdict ? qdict_get(qdict, "id") : NULL; - trace_monitor_qmp_cmd_in_band(qobject_get_try_str(id) ?: ""); - monitor_qmp_dispatch(mon, req_obj->req); - } else { - assert(req_obj->err); - rsp = qmp_error_response(req_obj->err); - req_obj->err = NULL; - monitor_qmp_respond(mon, rsp); - qobject_unref(rsp); - } + /* + * Mark the dispatcher as not busy already here so that we + * don't miss any new requests coming in the middle of our + * processing. + */ + atomic_mb_set(&qmp_dispatcher_co_busy, false); + + while (!(req_obj = monitor_qmp_requests_pop_any_with_lock())) { + /* + * No more requests to process. Wait to be reentered from + * handle_qmp_command() when it pushes more requests, or + * from monitor_cleanup() when it requests shutdown. + */ + if (!qmp_dispatcher_co_shutdown) { + qemu_coroutine_yield(); + + /* + * busy must be set to true again by whoever + * rescheduled us to avoid double scheduling + */ + assert(atomic_xchg(&qmp_dispatcher_co_busy, false) == true); + } + + /* + * qmp_dispatcher_co_shutdown may have changed if we + * yielded and were reentered from monitor_cleanup() + */ + if (qmp_dispatcher_co_shutdown) { + return; + } + } - if (need_resume) { - /* Pairs with the monitor_suspend() in handle_qmp_command() */ - monitor_resume(&mon->common); - } - qmp_request_free(req_obj); + if (atomic_xchg(&qmp_dispatcher_co_busy, true) == true) { + /* + * Someone rescheduled us (probably because a new requests + * came in), but we didn't actually yield. Do that now, + * only to be immediately reentered and removed from the + * list of scheduled coroutines. + */ + qemu_coroutine_yield(); + } - /* Reschedule instead of looping so the main loop stays responsive */ - qemu_bh_schedule(qmp_dispatcher_bh); + /* + * Move the coroutine from iohandler_ctx to qemu_aio_context for + * executing the command handler so that it can make progress if it + * involves an AIO_WAIT_WHILE(). + */ + aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co); + qemu_coroutine_yield(); + + mon = req_obj->mon; + /* qmp_oob_enabled() might change after "qmp_capabilities" */ + need_resume = !qmp_oob_enabled(mon) || + mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1; + qemu_mutex_unlock(&mon->qmp_queue_lock); + if (req_obj->req) { + QDict *qdict = qobject_to(QDict, req_obj->req); + QObject *id = qdict ? qdict_get(qdict, "id") : NULL; + trace_monitor_qmp_cmd_in_band(qobject_get_try_str(id) ?: ""); + monitor_qmp_dispatch(mon, req_obj->req); + } else { + assert(req_obj->err); + rsp = qmp_error_response(req_obj->err); + req_obj->err = NULL; + monitor_qmp_respond(mon, rsp); + qobject_unref(rsp); + } + + if (need_resume) { + /* Pairs with the monitor_suspend() in handle_qmp_command() */ + monitor_resume(&mon->common); + } + qmp_request_free(req_obj); + + /* + * Yield and reschedule so the main loop stays responsive. + * + * Move back to iohandler_ctx so that nested event loops for + * qemu_aio_context don't start new monitor commands. + */ + aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co); + qemu_coroutine_yield(); + } } static void handle_qmp_command(void *opaque, QObject *req, Error *err) @@ -302,7 +362,9 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) qemu_mutex_unlock(&mon->qmp_queue_lock); /* Kick the dispatcher routine */ - qemu_bh_schedule(qmp_dispatcher_bh); + if (!atomic_xchg(&qmp_dispatcher_co_busy, true)) { + aio_co_wake(qmp_dispatcher_co); + } } static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size) diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 5677ba92ca..754f7b854c 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -12,12 +12,16 @@ */ #include "qemu/osdep.h" + +#include "block/aio.h" #include "qapi/error.h" #include "qapi/qmp/dispatch.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" #include "sysemu/runstate.h" #include "qapi/qmp/qbool.h" +#include "qemu/coroutine.h" +#include "qemu/main-loop.h" static QDict *qmp_dispatch_check_obj(QDict *dict, bool allow_oob, Error **errp) @@ -88,6 +92,30 @@ bool qmp_is_oob(const QDict *dict) && !qdict_haskey(dict, "execute"); } +typedef struct QmpDispatchBH { + const QmpCommand *cmd; + Monitor *cur_mon; + QDict *args; + QObject **ret; + Error **errp; + Coroutine *co; +} QmpDispatchBH; + +static void do_qmp_dispatch_bh(void *opaque) +{ + QmpDispatchBH *data = opaque; + + assert(monitor_cur() == NULL); + monitor_set_cur(qemu_coroutine_self(), data->cur_mon); + data->cmd->fn(data->args, data->ret, data->errp); + monitor_set_cur(qemu_coroutine_self(), NULL); + aio_co_wake(data->co); +} + +/* + * Runs outside of coroutine context for OOB commands, but in coroutine + * context for everything else. + */ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, bool allow_oob, Monitor *cur_mon) { @@ -153,12 +181,35 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, qobject_ref(args); } + assert(!(oob && qemu_in_coroutine())); assert(monitor_cur() == NULL); - monitor_set_cur(qemu_coroutine_self(), cur_mon); - - cmd->fn(args, &ret, &err); - - monitor_set_cur(qemu_coroutine_self(), NULL); + if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { + monitor_set_cur(qemu_coroutine_self(), cur_mon); + cmd->fn(args, &ret, &err); + monitor_set_cur(qemu_coroutine_self(), NULL); + } else { + /* + * Not being in coroutine context implies that we're handling + * an OOB command, which must not have QCO_COROUTINE. + * + * This implies that we are in coroutine context, but the + * command doesn't have QCO_COROUTINE. We must drop out of + * coroutine context for this one. + */ + assert(!oob && qemu_in_coroutine() && !(cmd->options & QCO_COROUTINE)); + + QmpDispatchBH data = { + .cur_mon = cur_mon, + .cmd = cmd, + .args = args, + .ret = &ret, + .errp = &err, + .co = qemu_coroutine_self(), + }; + aio_bh_schedule_oneshot(qemu_get_aio_context(), do_qmp_dispatch_bh, + &data); + qemu_coroutine_yield(); + } qobject_unref(args); if (err) { /* or assert(!ret) after reviewing all handlers: */ diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index d0f9a1d3e3..58c65b5052 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -20,6 +20,9 @@ void qmp_register_command(QmpCommandList *cmds, const char *name, { QmpCommand *cmd = g_malloc0(sizeof(*cmd)); + /* QCO_COROUTINE and QCO_ALLOW_OOB are incompatible for now */ + assert(!((options & QCO_COROUTINE) && (options & QCO_ALLOW_OOB))); + cmd->name = name; cmd->fn = fn; cmd->enabled = true; diff --git a/util/aio-posix.c b/util/aio-posix.c index f7f13ebfc2..30bb21d699 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -15,6 +15,7 @@ #include "qemu/osdep.h" #include "block/block.h" +#include "qemu/main-loop.h" #include "qemu/rcu.h" #include "qemu/rcu_queue.h" #include "qemu/sockets.h" @@ -558,8 +559,13 @@ bool aio_poll(AioContext *ctx, bool blocking) * There cannot be two concurrent aio_poll calls for the same AioContext (or * an aio_poll concurrent with a GSource prepare/check/dispatch callback). * We rely on this below to avoid slow locked accesses to ctx->notify_me. + * + * aio_poll() may only be called in the AioContext's thread. iohandler_ctx + * is special in that it runs in the main thread, but that thread's context + * is qemu_aio_context. */ - assert(in_aio_context_home_thread(ctx)); + assert(in_aio_context_home_thread(ctx == iohandler_get_aio_context() ? + qemu_get_aio_context() : ctx)); qemu_lockcnt_inc(&ctx->list_lock); From patchwork Wed Sep 9 15:11:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 274123 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 878D9C43461 for ; Wed, 9 Sep 2020 15:19:26 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 08BBB22286 for ; Wed, 9 Sep 2020 15:19:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="I/uV9zU0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08BBB22286 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:47822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1sb-0004Ck-6T for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:19:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36866) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1ly-00022C-RR for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:34 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:37311 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1ln-0003pt-RU for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664342; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yPq3rM6ZMMv/7dmGNLv5CWGXMaj6732/fHE7gjjW2hs=; b=I/uV9zU0oahQMbrt2VfgxIv9IRAuctDaVJGfdJwPVDrT9kPq6NrI/eD1rDCHm9JM3RghXX XtVxwJkgqAeAS7Q6hGJWbqvtmbYfymxhJeWJ3CcOzWZnsss6XKdGJ/Mza6/r13EVKviO+5 fY3dbLC8IAoYHi43dYIcYayBcNfKqz4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-278-X6_P_yfsN6-Iy1RiJ1uocQ-1; Wed, 09 Sep 2020 11:12:20 -0400 X-MC-Unique: X6_P_yfsN6-Iy1RiJ1uocQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9307B1005E6A; Wed, 9 Sep 2020 15:12:19 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1D51A60C07; Wed, 9 Sep 2020 15:12:17 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 10/13] hmp: Add support for coroutine command handlers Date: Wed, 9 Sep 2020 17:11:46 +0200 Message-Id: <20200909151149.490589-11-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:20:45 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Often, QMP command handlers are not only called to handle QMP commands, but also from a corresponding HMP command handler. In order to give them a consistent environment, optionally run HMP command handlers in a coroutine, too. The implementation is a lot simpler than in QMP because for HMP, we still block the VM while the coroutine is running. Signed-off-by: Kevin Wolf Reviewed-by: Dr. David Alan Gilbert --- monitor/monitor-internal.h | 1 + monitor/hmp.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index b55d6df07f..ad2e64be13 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -74,6 +74,7 @@ typedef struct HMPCommand { const char *help; const char *flags; /* p=preconfig */ void (*cmd)(Monitor *mon, const QDict *qdict); + bool coroutine; /* * @sub_table is a list of 2nd level of commands. If it does not exist, * cmd should be used. If it exists, sub_table[?].cmd should be diff --git a/monitor/hmp.c b/monitor/hmp.c index 4b66ca1cd6..b858b0dbde 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -1056,12 +1056,26 @@ fail: return NULL; } +typedef struct HandleHmpCommandCo { + Monitor *mon; + const HMPCommand *cmd; + QDict *qdict; + bool done; +} HandleHmpCommandCo; + +static void handle_hmp_command_co(void *opaque) +{ + HandleHmpCommandCo *data = opaque; + data->cmd->cmd(data->mon, data->qdict); + monitor_set_cur(qemu_coroutine_self(), NULL); + data->done = true; +} + void handle_hmp_command(MonitorHMP *mon, const char *cmdline) { QDict *qdict; const HMPCommand *cmd; const char *cmd_start = cmdline; - Monitor *old_mon; trace_handle_hmp_command(mon, cmdline); @@ -1080,10 +1094,23 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) return; } - /* old_mon is non-NULL when called from qmp_human_monitor_command() */ - old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common); - cmd->cmd(&mon->common, qdict); - monitor_set_cur(qemu_coroutine_self(), old_mon); + if (!cmd->coroutine) { + /* old_mon is non-NULL when called from qmp_human_monitor_command() */ + Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common); + cmd->cmd(&mon->common, qdict); + monitor_set_cur(qemu_coroutine_self(), old_mon); + } else { + HandleHmpCommandCo data = { + .mon = &mon->common, + .cmd = cmd, + .qdict = qdict, + .done = false, + }; + Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data); + monitor_set_cur(co, &mon->common); + aio_co_enter(qemu_get_aio_context(), co); + AIO_WAIT_WHILE(qemu_get_aio_context(), !data.done); + } qobject_unref(qdict); } From patchwork Wed Sep 9 15:11:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305793 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DB8FC433E2 for ; Wed, 9 Sep 2020 15:17:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2F94B22272 for ; Wed, 9 Sep 2020 15:17:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BXiRFAnq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2F94B22272 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1qg-0000od-9G for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:17:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36834) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1lx-0001yi-FN for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:33 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:28898 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lp-0003qL-5c for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664344; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EhlBYBZa5MKP/ypPYxGQfG8Jorm1ey51c6s1ocNbuCA=; b=BXiRFAnqa2bwGVdXYk18ec/sHsCFuZ2ztK4SwirQVFUQ9Tf2nvf8lmli0+Xsp/5ccYvFWT MPqAUFG9kzsDm8HckbMb0URSbePRKJpWGTHY4dWgEpQhWp0h8ed4+xTOsVQGcUGkK04TVl ksCTp3vP2x02iKs65gao5g8NWRhvn7M= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-501-UinDH_6UOP6ZzJ8TU9TcxQ-1; Wed, 09 Sep 2020 11:12:22 -0400 X-MC-Unique: UinDH_6UOP6ZzJ8TU9TcxQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AF0041084D72; Wed, 9 Sep 2020 15:12:21 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id DBF9860C87; Wed, 9 Sep 2020 15:12:19 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 11/13] util/async: Add aio_co_reschedule_self() Date: Wed, 9 Sep 2020 17:11:47 +0200 Message-Id: <20200909151149.490589-12-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=kwolf@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:05:47 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add a function that can be used to move the currently running coroutine to a different AioContext (and therefore potentially a different thread). Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi --- include/block/aio.h | 10 ++++++++++ util/async.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/block/aio.h b/include/block/aio.h index b2f703fa3f..c37617b404 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -17,6 +17,7 @@ #ifdef CONFIG_LINUX_IO_URING #include #endif +#include "qemu/coroutine.h" #include "qemu/queue.h" #include "qemu/event_notifier.h" #include "qemu/thread.h" @@ -654,6 +655,15 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external) */ void aio_co_schedule(AioContext *ctx, struct Coroutine *co); +/** + * aio_co_reschedule_self: + * @new_ctx: the new context + * + * Move the currently running coroutine to new_ctx. If the coroutine is already + * running in new_ctx, do nothing. + */ +void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx); + /** * aio_co_wake: * @co: the coroutine diff --git a/util/async.c b/util/async.c index 4266745dee..a609e18693 100644 --- a/util/async.c +++ b/util/async.c @@ -569,6 +569,36 @@ void aio_co_schedule(AioContext *ctx, Coroutine *co) aio_context_unref(ctx); } +typedef struct AioCoRescheduleSelf { + Coroutine *co; + AioContext *new_ctx; +} AioCoRescheduleSelf; + +static void aio_co_reschedule_self_bh(void *opaque) +{ + AioCoRescheduleSelf *data = opaque; + aio_co_schedule(data->new_ctx, data->co); +} + +void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx) +{ + AioContext *old_ctx = qemu_get_current_aio_context(); + + if (old_ctx != new_ctx) { + AioCoRescheduleSelf data = { + .co = qemu_coroutine_self(), + .new_ctx = new_ctx, + }; + /* + * We can't directly schedule the coroutine in the target context + * because this would be racy: The other thread could try to enter the + * coroutine before it has yielded in this one. + */ + aio_bh_schedule_oneshot(old_ctx, aio_co_reschedule_self_bh, &data); + qemu_coroutine_yield(); + } +} + void aio_co_wake(struct Coroutine *co) { AioContext *ctx; From patchwork Wed Sep 9 15:11:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305790 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01C2AC43461 for ; Wed, 9 Sep 2020 15:21:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 816CA21941 for ; Wed, 9 Sep 2020 15:21:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Pzbe1oIa" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 816CA21941 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54222 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1uQ-0006qE-HY for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:21:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36904) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1m0-00027D-La for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:36 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:53155 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lr-0003rI-Of for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T1f93CLeI7XbsWc1n6jkN80r4+iwDZXWFjXEDaFuglk=; b=Pzbe1oIas7QIElI6ySLLyHiIleo65J0JGsvsfmlwCkk21Hi1BRNY4dxBSzqSgqpBLuDAY6 42y9TGfEHadFM7hmpOwbKGWGeHEJ0S/0nKVvF7TU7GFcsawc/LzPoqIF3JfC+aabbDdCzf 9Au04FPgHskyXJhlvz17ddIHwC7qWEE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-558-VOJ9l9jDNtyZtNsmsRzp4A-1; Wed, 09 Sep 2020 11:12:24 -0400 X-MC-Unique: VOJ9l9jDNtyZtNsmsRzp4A-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7F8651882FA0; Wed, 9 Sep 2020 15:12:23 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0749660C87; Wed, 9 Sep 2020 15:12:21 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 12/13] block: Add bdrv_co_move_to_aio_context() Date: Wed, 9 Sep 2020 17:11:48 +0200 Message-Id: <20200909151149.490589-13-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:20:45 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add a function to move the current coroutine to the AioContext of a given BlockDriverState. Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi --- include/block/block.h | 6 ++++++ block.c | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/block/block.h b/include/block/block.h index 981ab5b314..80ab322f11 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -626,6 +626,12 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); */ AioContext *bdrv_get_aio_context(BlockDriverState *bs); +/** + * Move the current coroutine to the AioContext of @bs and return the old + * AioContext of the coroutine. + */ +AioContext *coroutine_fn bdrv_co_move_to_aio_context(BlockDriverState *bs); + /** * Transfer control to @co in the aio context of @bs */ diff --git a/block.c b/block.c index 9538af4884..81403e00d1 100644 --- a/block.c +++ b/block.c @@ -6372,6 +6372,16 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs) return bs ? bs->aio_context : qemu_get_aio_context(); } +AioContext *coroutine_fn bdrv_co_move_to_aio_context(BlockDriverState *bs) +{ + Coroutine *self = qemu_coroutine_self(); + AioContext *old_ctx = qemu_coroutine_get_aio_context(self); + AioContext *new_ctx = bdrv_get_aio_context(bs); + + aio_co_reschedule_self(new_ctx); + return old_ctx; +} + void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co) { aio_co_enter(bdrv_get_aio_context(bs), co); From patchwork Wed Sep 9 15:11:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 305791 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14889C43461 for ; Wed, 9 Sep 2020 15:19:33 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8349622287 for ; Wed, 9 Sep 2020 15:19:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="i8dxZYIz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8349622287 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48436 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG1sh-0004RT-Fi for qemu-devel@archiver.kernel.org; Wed, 09 Sep 2020 11:19:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36948) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG1m2-0002B0-2w for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:34127) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG1lt-0003rh-3E for qemu-devel@nongnu.org; Wed, 09 Sep 2020 11:12:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599664348; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0GRAoEW8XedzP7Dl0ySriHPHHDVP8R9/ZqTh7Mo04Y8=; b=i8dxZYIzY2m/WiJ4W1rWuxQ3A0fl9/HokUrIVblwHcq3TIL7Yx5ybmYwPFj0hvzIVxSC3i u7NV/2mOuq/QAo2HHGqA23A9w+hMEuuyyDG2bkkkdzFY1MZuB5TuLZvlGcPY4rIVXboQUG +fGvEg6xIeHeCmKU2KZO8W0fl/Hjrnk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-90-QlCEJULlMNSCEx58UpeIWw-1; Wed, 09 Sep 2020 11:12:26 -0400 X-MC-Unique: QlCEJULlMNSCEx58UpeIWw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 49B8D1005E73; Wed, 9 Sep 2020 15:12:25 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-113-221.ams2.redhat.com [10.36.113.221]) by smtp.corp.redhat.com (Postfix) with ESMTP id CEC1660C07; Wed, 9 Sep 2020 15:12:23 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH v7 13/13] block: Convert 'block_resize' to coroutine Date: Wed, 9 Sep 2020 17:11:49 +0200 Message-Id: <20200909151149.490589-14-kwolf@redhat.com> In-Reply-To: <20200909151149.490589-1-kwolf@redhat.com> References: <20200909151149.490589-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:25:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, marcandre.lureau@gmail.com, stefanha@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" block_resize performs some I/O that could potentially take quite some time, so use it as an example for the new 'coroutine': true annotation in the QAPI schema. bdrv_truncate() requires that we're already in the right AioContext for the BlockDriverState if called in coroutine context. So instead of just taking the AioContext lock, move the QMP handler coroutine to the context. Call blk_unref() only after switching back because blk_unref() may only be called in the main thread. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 3 ++- blockdev.c | 13 ++++++------- hmp-commands.hx | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 0345f6f2d2..d3e49c9419 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1302,7 +1302,8 @@ { 'command': 'block_resize', 'data': { '*device': 'str', '*node-name': 'str', - 'size': 'int' } } + 'size': 'int' }, + 'coroutine': true } ## # @NewImageMode: diff --git a/blockdev.c b/blockdev.c index 7f2561081e..064989fc2d 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2439,14 +2439,14 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node, return ret; } -void qmp_block_resize(bool has_device, const char *device, - bool has_node_name, const char *node_name, - int64_t size, Error **errp) +void coroutine_fn qmp_block_resize(bool has_device, const char *device, + bool has_node_name, const char *node_name, + int64_t size, Error **errp) { Error *local_err = NULL; BlockBackend *blk = NULL; BlockDriverState *bs; - AioContext *aio_context; + AioContext *old_ctx; bs = bdrv_lookup_bs(has_device ? device : NULL, has_node_name ? node_name : NULL, @@ -2456,8 +2456,7 @@ void qmp_block_resize(bool has_device, const char *device, return; } - aio_context = bdrv_get_aio_context(bs); - aio_context_acquire(aio_context); + old_ctx = bdrv_co_move_to_aio_context(bs); if (size < 0) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size"); @@ -2479,8 +2478,8 @@ void qmp_block_resize(bool has_device, const char *device, bdrv_drained_end(bs); out: + aio_co_reschedule_self(old_ctx); blk_unref(blk); - aio_context_release(aio_context); } void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, diff --git a/hmp-commands.hx b/hmp-commands.hx index 60f395c276..ac360b73f6 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -76,6 +76,7 @@ ERST .params = "device size", .help = "resize a block image", .cmd = hmp_block_resize, + .coroutine = true, }, SRST