From patchwork Tue Oct 4 11:30:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 678034 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3spGwS0QWnz9s5w for ; Tue, 4 Oct 2016 22:32:08 +1100 (AEDT) Received: from localhost ([::1]:41606 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brNx6-0000sn-Cu for incoming@patchwork.ozlabs.org; Tue, 04 Oct 2016 07:32:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43139) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brNw3-0008Vs-RH for qemu-devel@nongnu.org; Tue, 04 Oct 2016 07:31:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brNw0-0007qJ-Fj for qemu-devel@nongnu.org; Tue, 04 Oct 2016 07:30:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48150) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brNw0-0007po-4T for qemu-devel@nongnu.org; Tue, 04 Oct 2016 07:30:56 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8F6BC50F57; Tue, 4 Oct 2016 11:30:55 +0000 (UTC) Received: from thinkpad.redhat.com (ovpn-112-35.ams2.redhat.com [10.36.112.35]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u94BUnZv015059; Tue, 4 Oct 2016 07:30:52 -0400 From: Laurent Vivier To: Paolo Bonzini Date: Tue, 4 Oct 2016 13:30:47 +0200 Message-Id: <1475580648-6470-2-git-send-email-lvivier@redhat.com> In-Reply-To: <1475580648-6470-1-git-send-email-lvivier@redhat.com> References: <1475580648-6470-1-git-send-email-lvivier@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 04 Oct 2016 11:30:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/2] accel: allows to select the "best" accelerator X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Peter Maydell , Thomas Huth , Stefano Stabellini , "Michael S . Tsirkin" , qemu-devel@nongnu.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" By default, QEMU uses 'tcg' or the one provided with the "accel" property. But sometime, user wants to use a real accelerator without knowing if he really can, with, for instance accel=kvm:tcg. In this case, and if the accelerator is not available we have a noisy "XXX accelerator not found". By allowing the user to ask the "best" accelerator for the given target, we can avoid this problem. This patch introduces a new parameter for the "accel" property, the "best" keyword. You can ask to use the best accelerator with "-M accel=best", or if you want to use your favorite accelerator and if it is not available, the best one, you can use, for instance "-M accel=kvm:best". Signed-off-by: Laurent Vivier --- accel.c | 58 ++++++++++++++++++++++++++++++++++++++++++-------- include/sysemu/accel.h | 1 + kvm-all.c | 1 + qemu-options.hx | 4 +++- qtest.c | 1 + xen-common.c | 1 + 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/accel.c b/accel.c index 403eb5e..07a738d 100644 --- a/accel.c +++ b/accel.c @@ -60,6 +60,38 @@ static AccelClass *accel_find(const char *opt_name) return ac; } +static void accel_filter_best(ObjectClass *klass, void *opaque) +{ + AccelClass **best = opaque; + AccelClass *ac = ACCEL_CLASS(klass); + + if (ac->available && !ac->available()) { + return; + } + + if (ac->priority < 0) { + return; + } + + if (*best == NULL) { + *best = ac; + return; + } + + if (ac->priority > (*best)->priority) { + *best = ac; + } +} + +static AccelClass *accel_find_best(void) +{ + AccelClass *best = NULL; + + object_class_foreach(accel_filter_best, TYPE_ACCEL, false, &best); + + return ACCEL_CLASS(best); +} + static int accel_init_machine(AccelClass *acc, MachineState *ms) { ObjectClass *oc = OBJECT_CLASS(acc); @@ -97,15 +129,22 @@ void configure_accelerator(MachineState *ms) p++; } p = get_opt_name(buf, sizeof(buf), p, ':'); - acc = accel_find(buf); - if (!acc) { - fprintf(stderr, "\"%s\" accelerator not found.\n", buf); - continue; - } - if (acc->available && !acc->available()) { - printf("%s not supported for this target\n", - acc->name); - continue; + if (strcmp(buf, "best") == 0) { + acc = accel_find_best(); + if (acc == NULL) { + break; + } + } else { + acc = accel_find(buf); + if (!acc) { + fprintf(stderr, "\"%s\" accelerator not found.\n", buf); + continue; + } + if (acc->available && !acc->available()) { + printf("%s not supported for this target\n", + acc->name); + continue; + } } ret = accel_init_machine(acc, ms); if (ret < 0) { @@ -137,6 +176,7 @@ static void tcg_accel_class_init(ObjectClass *oc, void *data) ac->name = "tcg"; ac->init_machine = tcg_init; ac->allowed = &tcg_allowed; + ac->priority = 10; } #define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg") diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h index 15944c1..5f2d7c9 100644 --- a/include/sysemu/accel.h +++ b/include/sysemu/accel.h @@ -40,6 +40,7 @@ typedef struct AccelClass { int (*available)(void); int (*init_machine)(MachineState *ms); bool *allowed; + int priority; } AccelClass; #define TYPE_ACCEL "accel" diff --git a/kvm-all.c b/kvm-all.c index fc2898a..1b7d82a 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -2460,6 +2460,7 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data) ac->name = "KVM"; ac->init_machine = kvm_init; ac->allowed = &kvm_allowed; + ac->priority = 100; } static const TypeInfo kvm_accel_type = { diff --git a/qemu-options.hx b/qemu-options.hx index 01f01df..8ed7454 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -55,7 +55,9 @@ available machines. Supported machine properties are: This is used to enable an accelerator. Depending on the target architecture, kvm, xen, or tcg can be available. By default, tcg is used. If there is more than one accelerator specified, the next one is used if the previous one fails -to initialize. +to initialize. You can ask to use the best accelerator with "accel=best". If +you want to use one accelerator and if it is not available, the best one, you +can use, for instance, "accel=kvm:best". @item kernel_irqchip=on|off Controls in-kernel irqchip support for the chosen accelerator when available. @item gfx_passthru=on|off diff --git a/qtest.c b/qtest.c index 22482cc..4915f51 100644 --- a/qtest.c +++ b/qtest.c @@ -698,6 +698,7 @@ static void qtest_accel_class_init(ObjectClass *oc, void *data) ac->available = qtest_available; ac->init_machine = qtest_init_accel; ac->allowed = &qtest_allowed; + ac->priority = -1; } #define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest") diff --git a/xen-common.c b/xen-common.c index e641ad1..19848be 100644 --- a/xen-common.c +++ b/xen-common.c @@ -140,6 +140,7 @@ static void xen_accel_class_init(ObjectClass *oc, void *data) ac->name = "Xen"; ac->init_machine = xen_init; ac->allowed = &xen_allowed; + ac->priority = 100; } #define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")