qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/2] accel: allows to select the "best" accelerator


From: Laurent Vivier
Subject: [Qemu-devel] [PATCH 1/2] accel: allows to select the "best" accelerator
Date: Tue, 4 Oct 2016 13:30:47 +0200

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 <address@hidden>
---
 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")
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]