diff mbox series

[RFC,V1,04/14] accel: set accelerator and machine props earlier

Message ID 1729178055-207271-5-git-send-email-steven.sistare@oracle.com (mailing list archive)
State New
Headers show
Series precreate phase | expand

Commit Message

Steven Sistare Oct. 17, 2024, 3:14 p.m. UTC
Make all global and compat properties available before the first objects
are created.  Set accelerator compatibility properties in
configure_accelerators, when the accelerator is chosen, and call
configure_accelerators earlier.  Set machine options earlier.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 accel/accel-system.c |  2 --
 system/vl.c          | 34 ++++++++++++++++++----------------
 2 files changed, 18 insertions(+), 18 deletions(-)

Comments

Fabiano Rosas Oct. 18, 2024, 3:08 p.m. UTC | #1
Steve Sistare <steven.sistare@oracle.com> writes:

> Make all global and compat properties available before the first objects
> are created.  Set accelerator compatibility properties in
> configure_accelerators, when the accelerator is chosen, and call
> configure_accelerators earlier.  Set machine options earlier.
>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
>  accel/accel-system.c |  2 --
>  system/vl.c          | 34 ++++++++++++++++++----------------
>  2 files changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/accel/accel-system.c b/accel/accel-system.c
> index f6c947d..c8aeae4 100644
> --- a/accel/accel-system.c
> +++ b/accel/accel-system.c
> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>          ms->accelerator = NULL;
>          *(acc->allowed) = false;
>          object_unref(OBJECT(accel));
> -    } else {
> -        object_set_accelerator_compat_props(acc->compat_props);
>      }
>      return ret;
>  }
> diff --git a/system/vl.c b/system/vl.c
> index b94a6b9..bca2292 100644
> --- a/system/vl.c
> +++ b/system/vl.c
> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>          goto bad;
>      }
>  
> +    object_set_accelerator_compat_props(ac->compat_props);
>      acs->accel = accel;
>      return 1;
>  
> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>      parse_memory_options();
>  
>      qemu_create_machine(machine_opts_dict);
> -
> -    suspend_mux_open();
> -
> -    qemu_disable_default_devices();
> -    qemu_setup_display();
> -    qemu_create_default_devices();
> -    qemu_create_early_backends();
> -
>      qemu_apply_legacy_machine_options(machine_opts_dict);
>      qemu_apply_machine_options(machine_opts_dict);
>      qobject_unref(machine_opts_dict);
> -    phase_advance(PHASE_MACHINE_CREATED);
>  
> -    /*
> -     * Note: uses machine properties such as kernel-irqchip, must run
> -     * after qemu_apply_machine_options.
> -     */
>      accel = configure_accelerators(argv[0]);
> -    create_accelerator(accel);
> -    phase_advance(PHASE_ACCEL_CREATED);
>  
>      /*
> -     * Beware, QOM objects created before this point miss global and
> +     * QOM objects created after this point see all global and
>       * compat properties.
>       *
>       * Global properties get set up by qdev_prop_register_global(),
> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>       * called from do_configure_accelerator().
>       */
>  
> +    suspend_mux_open();
> +
> +    qemu_disable_default_devices();
> +    qemu_setup_display();
> +    qemu_create_default_devices();
> +    qemu_create_early_backends();
> +
> +    phase_advance(PHASE_MACHINE_CREATED);
> +
> +    /*
> +     * Note: uses machine properties such as kernel-irqchip, must run
> +     * after qemu_apply_machine_options.
> +     */
> +    create_accelerator(accel);
> +    phase_advance(PHASE_ACCEL_CREATED);
> +
>      machine_class = MACHINE_GET_CLASS(current_machine);
>      if (!qtest_enabled() && machine_class->deprecation_reason) {
>          warn_report("Machine type '%s' is deprecated: %s",

Hi Steve,

after this commit:

$ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
# random seed: R02Saf9b44f2d88dd417052905692ee79981
1..5
# Start of aarch64 tests
# Start of net tests
# Start of can tests
# starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
qemu-system-aarch64: Device 'canbus' not found

I tried briefly to figure out what the issue is, but I don't really
understand the dependencies involved. Hope you can tell us.
Steven Sistare Oct. 18, 2024, 3:32 p.m. UTC | #2
On 10/18/2024 11:08 AM, Fabiano Rosas wrote:
> Steve Sistare <steven.sistare@oracle.com> writes:
> 
>> Make all global and compat properties available before the first objects
>> are created.  Set accelerator compatibility properties in
>> configure_accelerators, when the accelerator is chosen, and call
>> configure_accelerators earlier.  Set machine options earlier.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> ---
>>   accel/accel-system.c |  2 --
>>   system/vl.c          | 34 ++++++++++++++++++----------------
>>   2 files changed, 18 insertions(+), 18 deletions(-)
>>
>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>> index f6c947d..c8aeae4 100644
>> --- a/accel/accel-system.c
>> +++ b/accel/accel-system.c
>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>           ms->accelerator = NULL;
>>           *(acc->allowed) = false;
>>           object_unref(OBJECT(accel));
>> -    } else {
>> -        object_set_accelerator_compat_props(acc->compat_props);
>>       }
>>       return ret;
>>   }
>> diff --git a/system/vl.c b/system/vl.c
>> index b94a6b9..bca2292 100644
>> --- a/system/vl.c
>> +++ b/system/vl.c
>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>           goto bad;
>>       }
>>   
>> +    object_set_accelerator_compat_props(ac->compat_props);
>>       acs->accel = accel;
>>       return 1;
>>   
>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>       parse_memory_options();
>>   
>>       qemu_create_machine(machine_opts_dict);
>> -
>> -    suspend_mux_open();
>> -
>> -    qemu_disable_default_devices();
>> -    qemu_setup_display();
>> -    qemu_create_default_devices();
>> -    qemu_create_early_backends();
>> -
>>       qemu_apply_legacy_machine_options(machine_opts_dict);
>>       qemu_apply_machine_options(machine_opts_dict);
>>       qobject_unref(machine_opts_dict);
>> -    phase_advance(PHASE_MACHINE_CREATED);
>>   
>> -    /*
>> -     * Note: uses machine properties such as kernel-irqchip, must run
>> -     * after qemu_apply_machine_options.
>> -     */
>>       accel = configure_accelerators(argv[0]);
>> -    create_accelerator(accel);
>> -    phase_advance(PHASE_ACCEL_CREATED);
>>   
>>       /*
>> -     * Beware, QOM objects created before this point miss global and
>> +     * QOM objects created after this point see all global and
>>        * compat properties.
>>        *
>>        * Global properties get set up by qdev_prop_register_global(),
>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>        * called from do_configure_accelerator().
>>        */
>>   
>> +    suspend_mux_open();
>> +
>> +    qemu_disable_default_devices();
>> +    qemu_setup_display();
>> +    qemu_create_default_devices();
>> +    qemu_create_early_backends();
>> +
>> +    phase_advance(PHASE_MACHINE_CREATED);
>> +
>> +    /*
>> +     * Note: uses machine properties such as kernel-irqchip, must run
>> +     * after qemu_apply_machine_options.
>> +     */
>> +    create_accelerator(accel);
>> +    phase_advance(PHASE_ACCEL_CREATED);
>> +
>>       machine_class = MACHINE_GET_CLASS(current_machine);
>>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>>           warn_report("Machine type '%s' is deprecated: %s",
> 
> Hi Steve,
> 
> after this commit:
> 
> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
> # random seed: R02Saf9b44f2d88dd417052905692ee79981
> 1..5
> # Start of aarch64 tests
> # Start of net tests
> # Start of can tests
> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
> qemu-system-aarch64: Device 'canbus' not found
> 
> I tried briefly to figure out what the issue is, but I don't really
> understand the dependencies involved. Hope you can tell us.

Thanks! I forgot to define the preinit method for the qtest accelerator in patch 1.
I'll verify that fixes the problem and send you a one-off patch if you want to continue
testing.

- Steve
Steven Sistare Oct. 18, 2024, 3:40 p.m. UTC | #3
On 10/18/2024 11:32 AM, Steven Sistare wrote:
> On 10/18/2024 11:08 AM, Fabiano Rosas wrote:
>> Steve Sistare <steven.sistare@oracle.com> writes:
>>
>>> Make all global and compat properties available before the first objects
>>> are created.  Set accelerator compatibility properties in
>>> configure_accelerators, when the accelerator is chosen, and call
>>> configure_accelerators earlier.  Set machine options earlier.
>>>
>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>> ---
>>>   accel/accel-system.c |  2 --
>>>   system/vl.c          | 34 ++++++++++++++++++----------------
>>>   2 files changed, 18 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>>> index f6c947d..c8aeae4 100644
>>> --- a/accel/accel-system.c
>>> +++ b/accel/accel-system.c
>>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>>           ms->accelerator = NULL;
>>>           *(acc->allowed) = false;
>>>           object_unref(OBJECT(accel));
>>> -    } else {
>>> -        object_set_accelerator_compat_props(acc->compat_props);
>>>       }
>>>       return ret;
>>>   }
>>> diff --git a/system/vl.c b/system/vl.c
>>> index b94a6b9..bca2292 100644
>>> --- a/system/vl.c
>>> +++ b/system/vl.c
>>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>>           goto bad;
>>>       }
>>> +    object_set_accelerator_compat_props(ac->compat_props);
>>>       acs->accel = accel;
>>>       return 1;
>>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>>       parse_memory_options();
>>>       qemu_create_machine(machine_opts_dict);
>>> -
>>> -    suspend_mux_open();
>>> -
>>> -    qemu_disable_default_devices();
>>> -    qemu_setup_display();
>>> -    qemu_create_default_devices();
>>> -    qemu_create_early_backends();
>>> -
>>>       qemu_apply_legacy_machine_options(machine_opts_dict);
>>>       qemu_apply_machine_options(machine_opts_dict);
>>>       qobject_unref(machine_opts_dict);
>>> -    phase_advance(PHASE_MACHINE_CREATED);
>>> -    /*
>>> -     * Note: uses machine properties such as kernel-irqchip, must run
>>> -     * after qemu_apply_machine_options.
>>> -     */
>>>       accel = configure_accelerators(argv[0]);
>>> -    create_accelerator(accel);
>>> -    phase_advance(PHASE_ACCEL_CREATED);
>>>       /*
>>> -     * Beware, QOM objects created before this point miss global and
>>> +     * QOM objects created after this point see all global and
>>>        * compat properties.
>>>        *
>>>        * Global properties get set up by qdev_prop_register_global(),
>>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>>        * called from do_configure_accelerator().
>>>        */
>>> +    suspend_mux_open();
>>> +
>>> +    qemu_disable_default_devices();
>>> +    qemu_setup_display();
>>> +    qemu_create_default_devices();
>>> +    qemu_create_early_backends();
>>> +
>>> +    phase_advance(PHASE_MACHINE_CREATED);
>>> +
>>> +    /*
>>> +     * Note: uses machine properties such as kernel-irqchip, must run
>>> +     * after qemu_apply_machine_options.
>>> +     */
>>> +    create_accelerator(accel);
>>> +    phase_advance(PHASE_ACCEL_CREATED);
>>> +
>>>       machine_class = MACHINE_GET_CLASS(current_machine);
>>>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>>>           warn_report("Machine type '%s' is deprecated: %s",
>>
>> Hi Steve,
>>
>> after this commit:
>>
>> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
>> # random seed: R02Saf9b44f2d88dd417052905692ee79981
>> 1..5
>> # Start of aarch64 tests
>> # Start of net tests
>> # Start of can tests
>> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
>> qemu-system-aarch64: Device 'canbus' not found
>>
>> I tried briefly to figure out what the issue is, but I don't really
>> understand the dependencies involved. Hope you can tell us.
> 
> Thanks! I forgot to define the preinit method for the qtest accelerator in patch 1.
> I'll verify that fixes the problem and send you a one-off patch if you want to continue
> testing.

Actually that is not a problem.  qtest qtest_init_accel does nothing, so preinit will do
nothing, so it is OK to not define preinit.

Still looking.

- Steve
Steven Sistare Oct. 18, 2024, 7:15 p.m. UTC | #4
On 10/18/2024 11:40 AM, Steven Sistare wrote:
> On 10/18/2024 11:32 AM, Steven Sistare wrote:
>> On 10/18/2024 11:08 AM, Fabiano Rosas wrote:
>>> Steve Sistare <steven.sistare@oracle.com> writes:
>>>
>>>> Make all global and compat properties available before the first objects
>>>> are created.  Set accelerator compatibility properties in
>>>> configure_accelerators, when the accelerator is chosen, and call
>>>> configure_accelerators earlier.  Set machine options earlier.
>>>>
>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>> ---
>>>>   accel/accel-system.c |  2 --
>>>>   system/vl.c          | 34 ++++++++++++++++++----------------
>>>>   2 files changed, 18 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>>>> index f6c947d..c8aeae4 100644
>>>> --- a/accel/accel-system.c
>>>> +++ b/accel/accel-system.c
>>>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>>>           ms->accelerator = NULL;
>>>>           *(acc->allowed) = false;
>>>>           object_unref(OBJECT(accel));
>>>> -    } else {
>>>> -        object_set_accelerator_compat_props(acc->compat_props);
>>>>       }
>>>>       return ret;
>>>>   }
>>>> diff --git a/system/vl.c b/system/vl.c
>>>> index b94a6b9..bca2292 100644
>>>> --- a/system/vl.c
>>>> +++ b/system/vl.c
>>>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>>>           goto bad;
>>>>       }
>>>> +    object_set_accelerator_compat_props(ac->compat_props);
>>>>       acs->accel = accel;
>>>>       return 1;
>>>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>>>       parse_memory_options();
>>>>       qemu_create_machine(machine_opts_dict);
>>>> -
>>>> -    suspend_mux_open();
>>>> -
>>>> -    qemu_disable_default_devices();
>>>> -    qemu_setup_display();
>>>> -    qemu_create_default_devices();
>>>> -    qemu_create_early_backends();
>>>> -
>>>>       qemu_apply_legacy_machine_options(machine_opts_dict);
>>>>       qemu_apply_machine_options(machine_opts_dict);
>>>>       qobject_unref(machine_opts_dict);
>>>> -    phase_advance(PHASE_MACHINE_CREATED);
>>>> -    /*
>>>> -     * Note: uses machine properties such as kernel-irqchip, must run
>>>> -     * after qemu_apply_machine_options.
>>>> -     */
>>>>       accel = configure_accelerators(argv[0]);
>>>> -    create_accelerator(accel);
>>>> -    phase_advance(PHASE_ACCEL_CREATED);
>>>>       /*
>>>> -     * Beware, QOM objects created before this point miss global and
>>>> +     * QOM objects created after this point see all global and
>>>>        * compat properties.
>>>>        *
>>>>        * Global properties get set up by qdev_prop_register_global(),
>>>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>>>        * called from do_configure_accelerator().
>>>>        */
>>>> +    suspend_mux_open();
>>>> +
>>>> +    qemu_disable_default_devices();
>>>> +    qemu_setup_display();
>>>> +    qemu_create_default_devices();
>>>> +    qemu_create_early_backends();
>>>> +
>>>> +    phase_advance(PHASE_MACHINE_CREATED);
>>>> +
>>>> +    /*
>>>> +     * Note: uses machine properties such as kernel-irqchip, must run
>>>> +     * after qemu_apply_machine_options.
>>>> +     */
>>>> +    create_accelerator(accel);
>>>> +    phase_advance(PHASE_ACCEL_CREATED);
>>>> +
>>>>       machine_class = MACHINE_GET_CLASS(current_machine);
>>>>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>>>>           warn_report("Machine type '%s' is deprecated: %s",
>>>
>>> Hi Steve,
>>>
>>> after this commit:
>>>
>>> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
>>> # random seed: R02Saf9b44f2d88dd417052905692ee79981
>>> 1..5
>>> # Start of aarch64 tests
>>> # Start of net tests
>>> # Start of can tests
>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
>>> qemu-system-aarch64: Device 'canbus' not found
>>>
>>> I tried briefly to figure out what the issue is, but I don't really
>>> understand the dependencies involved. Hope you can tell us.
>>
>> Thanks! I forgot to define the preinit method for the qtest accelerator in patch 1.
>> I'll verify that fixes the problem and send you a one-off patch if you want to continue
>> testing.
> 
> Actually that is not a problem.  qtest qtest_init_accel does nothing, so preinit will do
> nothing, so it is OK to not define preinit.
> 
> Still looking.

I understand this now.  The old code worked in this order:

   qemu_create_early_backends()
     ... creates "-object can-bus,id=canbus"
   qemu_create_machine()
   qemu_apply_machine_options()
     applies link property "canbus0" with value canbus, finds canbus object

The new code fails:

   qemu_create_machine()
   qemu_apply_machine_options()
     applies link property "canbus0" with value canbus,
     error because fails to find canbus object
   ...
   qemu_exit_precreate()
     qemu_create_early_backends()
       ... creates "-object can-bus,id=canbus"

The fix is to provide a new function, called before qemu_create_machine,
which creates only the backends that are needed to create the machine.
AFAIK can-bus is the only one, because the xlnx-zcu102 machine has
link properties.

- Steve
Peter Xu Oct. 21, 2024, 3:19 p.m. UTC | #5
On Thu, Oct 17, 2024 at 08:14:05AM -0700, Steve Sistare wrote:
> Make all global and compat properties available before the first objects
> are created.  Set accelerator compatibility properties in
> configure_accelerators, when the accelerator is chosen, and call
> configure_accelerators earlier.  Set machine options earlier.
> 
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
>  accel/accel-system.c |  2 --
>  system/vl.c          | 34 ++++++++++++++++++----------------
>  2 files changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/accel/accel-system.c b/accel/accel-system.c
> index f6c947d..c8aeae4 100644
> --- a/accel/accel-system.c
> +++ b/accel/accel-system.c
> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>          ms->accelerator = NULL;
>          *(acc->allowed) = false;
>          object_unref(OBJECT(accel));
> -    } else {
> -        object_set_accelerator_compat_props(acc->compat_props);
>      }
>      return ret;
>  }
> diff --git a/system/vl.c b/system/vl.c
> index b94a6b9..bca2292 100644
> --- a/system/vl.c
> +++ b/system/vl.c
> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>          goto bad;
>      }
>  
> +    object_set_accelerator_compat_props(ac->compat_props);

This is the probe/preinit iterator, might be good to keep it simple to only
make the decision of choosing one accel, then move this line over to
configure_accelerators() at the end.

>      acs->accel = accel;
>      return 1;
>  
> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>      parse_memory_options();
>  
>      qemu_create_machine(machine_opts_dict);
> -
> -    suspend_mux_open();
> -
> -    qemu_disable_default_devices();
> -    qemu_setup_display();
> -    qemu_create_default_devices();
> -    qemu_create_early_backends();
> -
>      qemu_apply_legacy_machine_options(machine_opts_dict);
>      qemu_apply_machine_options(machine_opts_dict);
>      qobject_unref(machine_opts_dict);
> -    phase_advance(PHASE_MACHINE_CREATED);
>  
> -    /*
> -     * Note: uses machine properties such as kernel-irqchip, must run
> -     * after qemu_apply_machine_options.
> -     */
>      accel = configure_accelerators(argv[0]);
> -    create_accelerator(accel);
> -    phase_advance(PHASE_ACCEL_CREATED);
>  
>      /*
> -     * Beware, QOM objects created before this point miss global and
> +     * QOM objects created after this point see all global and
>       * compat properties.
>       *
>       * Global properties get set up by qdev_prop_register_global(),
> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>       * called from do_configure_accelerator().
>       */
>  
> +    suspend_mux_open();
> +
> +    qemu_disable_default_devices();
> +    qemu_setup_display();
> +    qemu_create_default_devices();
> +    qemu_create_early_backends();
> +
> +    phase_advance(PHASE_MACHINE_CREATED);
> +
> +    /*
> +     * Note: uses machine properties such as kernel-irqchip, must run
> +     * after qemu_apply_machine_options.
> +     */
> +    create_accelerator(accel);
> +    phase_advance(PHASE_ACCEL_CREATED);
> +
>      machine_class = MACHINE_GET_CLASS(current_machine);
>      if (!qtest_enabled() && machine_class->deprecation_reason) {
>          warn_report("Machine type '%s' is deprecated: %s",
> -- 
> 1.8.3.1
>
Peter Xu Oct. 21, 2024, 4:20 p.m. UTC | #6
On Fri, Oct 18, 2024 at 03:15:56PM -0400, Steven Sistare wrote:
> I understand this now.  The old code worked in this order:
> 
>   qemu_create_early_backends()
>     ... creates "-object can-bus,id=canbus"
>   qemu_create_machine()
>   qemu_apply_machine_options()
>     applies link property "canbus0" with value canbus, finds canbus object
> 
> The new code fails:
> 
>   qemu_create_machine()
>   qemu_apply_machine_options()
>     applies link property "canbus0" with value canbus,
>     error because fails to find canbus object
>   ...
>   qemu_exit_precreate()
>     qemu_create_early_backends()
>       ... creates "-object can-bus,id=canbus"
> 
> The fix is to provide a new function, called before qemu_create_machine,
> which creates only the backends that are needed to create the machine.
> AFAIK can-bus is the only one, because the xlnx-zcu102 machine has
> link properties.

Wanna share more on the specific solution?  I wonder if the plan is to add
one more special window for creating -object just for can-bus, and how to
justify that extra phase.  Perhaps whatever that do not require fd to back
it (so not affected by CPR)?  But not sure whether that's too special.

I wished it could be simply put into the "very early" stage (pre-sandbox),
but I think object_create_pre_sandbox() did mention that we need explicit
reasons for those, and I'm not sure whether this reason justifies either
for why can-bus is so special so can be created without the sandboxing.
David Hildenbrand Oct. 22, 2024, 8:30 a.m. UTC | #7
On 18.10.24 21:15, Steven Sistare wrote:
> On 10/18/2024 11:40 AM, Steven Sistare wrote:
>> On 10/18/2024 11:32 AM, Steven Sistare wrote:
>>> On 10/18/2024 11:08 AM, Fabiano Rosas wrote:
>>>> Steve Sistare <steven.sistare@oracle.com> writes:
>>>>
>>>>> Make all global and compat properties available before the first objects
>>>>> are created.  Set accelerator compatibility properties in
>>>>> configure_accelerators, when the accelerator is chosen, and call
>>>>> configure_accelerators earlier.  Set machine options earlier.
>>>>>
>>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>>> ---
>>>>>    accel/accel-system.c |  2 --
>>>>>    system/vl.c          | 34 ++++++++++++++++++----------------
>>>>>    2 files changed, 18 insertions(+), 18 deletions(-)
>>>>>
>>>>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>>>>> index f6c947d..c8aeae4 100644
>>>>> --- a/accel/accel-system.c
>>>>> +++ b/accel/accel-system.c
>>>>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>>>>            ms->accelerator = NULL;
>>>>>            *(acc->allowed) = false;
>>>>>            object_unref(OBJECT(accel));
>>>>> -    } else {
>>>>> -        object_set_accelerator_compat_props(acc->compat_props);
>>>>>        }
>>>>>        return ret;
>>>>>    }
>>>>> diff --git a/system/vl.c b/system/vl.c
>>>>> index b94a6b9..bca2292 100644
>>>>> --- a/system/vl.c
>>>>> +++ b/system/vl.c
>>>>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>>>>            goto bad;
>>>>>        }
>>>>> +    object_set_accelerator_compat_props(ac->compat_props);
>>>>>        acs->accel = accel;
>>>>>        return 1;
>>>>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>>>>        parse_memory_options();
>>>>>        qemu_create_machine(machine_opts_dict);
>>>>> -
>>>>> -    suspend_mux_open();
>>>>> -
>>>>> -    qemu_disable_default_devices();
>>>>> -    qemu_setup_display();
>>>>> -    qemu_create_default_devices();
>>>>> -    qemu_create_early_backends();
>>>>> -
>>>>>        qemu_apply_legacy_machine_options(machine_opts_dict);
>>>>>        qemu_apply_machine_options(machine_opts_dict);
>>>>>        qobject_unref(machine_opts_dict);
>>>>> -    phase_advance(PHASE_MACHINE_CREATED);
>>>>> -    /*
>>>>> -     * Note: uses machine properties such as kernel-irqchip, must run
>>>>> -     * after qemu_apply_machine_options.
>>>>> -     */
>>>>>        accel = configure_accelerators(argv[0]);
>>>>> -    create_accelerator(accel);
>>>>> -    phase_advance(PHASE_ACCEL_CREATED);
>>>>>        /*
>>>>> -     * Beware, QOM objects created before this point miss global and
>>>>> +     * QOM objects created after this point see all global and
>>>>>         * compat properties.
>>>>>         *
>>>>>         * Global properties get set up by qdev_prop_register_global(),
>>>>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>>>>         * called from do_configure_accelerator().
>>>>>         */
>>>>> +    suspend_mux_open();
>>>>> +
>>>>> +    qemu_disable_default_devices();
>>>>> +    qemu_setup_display();
>>>>> +    qemu_create_default_devices();
>>>>> +    qemu_create_early_backends();
>>>>> +
>>>>> +    phase_advance(PHASE_MACHINE_CREATED);
>>>>> +
>>>>> +    /*
>>>>> +     * Note: uses machine properties such as kernel-irqchip, must run
>>>>> +     * after qemu_apply_machine_options.
>>>>> +     */
>>>>> +    create_accelerator(accel);
>>>>> +    phase_advance(PHASE_ACCEL_CREATED);
>>>>> +
>>>>>        machine_class = MACHINE_GET_CLASS(current_machine);
>>>>>        if (!qtest_enabled() && machine_class->deprecation_reason) {
>>>>>            warn_report("Machine type '%s' is deprecated: %s",
>>>>
>>>> Hi Steve,
>>>>
>>>> after this commit:
>>>>
>>>> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
>>>> # random seed: R02Saf9b44f2d88dd417052905692ee79981
>>>> 1..5
>>>> # Start of aarch64 tests
>>>> # Start of net tests
>>>> # Start of can tests
>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
>>>> qemu-system-aarch64: Device 'canbus' not found
>>>>
>>>> I tried briefly to figure out what the issue is, but I don't really
>>>> understand the dependencies involved. Hope you can tell us.
>>>
>>> Thanks! I forgot to define the preinit method for the qtest accelerator in patch 1.
>>> I'll verify that fixes the problem and send you a one-off patch if you want to continue
>>> testing.
>>
>> Actually that is not a problem.  qtest qtest_init_accel does nothing, so preinit will do
>> nothing, so it is OK to not define preinit.
>>
>> Still looking.
> 
> I understand this now.  The old code worked in this order:
> 
>     qemu_create_early_backends()
>       ... creates "-object can-bus,id=canbus"
>     qemu_create_machine()
>     qemu_apply_machine_options()
>       applies link property "canbus0" with value canbus, finds canbus object

Now I am confused.

I think the current code does:

qemu_create_machine(machine_opts_dict);
qemu_create_early_backends();
qemu_apply_machine_options(machine_opts_dict);

Isn't the relevant part that we may only apply the machine options after 
creating the early backends?
Paolo Bonzini Oct. 23, 2024, 4 p.m. UTC | #8
On 10/17/24 17:14, Steve Sistare wrote:
> Make all global and compat properties available before the first objects
> are created.  Set accelerator compatibility properties in
> configure_accelerators, when the accelerator is chosen, and call
> configure_accelerators earlier.  Set machine options earlier.
> 
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> ---
>   accel/accel-system.c |  2 --
>   system/vl.c          | 34 ++++++++++++++++++----------------
>   2 files changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/accel/accel-system.c b/accel/accel-system.c
> index f6c947d..c8aeae4 100644
> --- a/accel/accel-system.c
> +++ b/accel/accel-system.c
> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>           ms->accelerator = NULL;
>           *(acc->allowed) = false;
>           object_unref(OBJECT(accel));
> -    } else {
> -        object_set_accelerator_compat_props(acc->compat_props);
>       }
>       return ret;
>   }
> diff --git a/system/vl.c b/system/vl.c
> index b94a6b9..bca2292 100644
> --- a/system/vl.c
> +++ b/system/vl.c
> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>           goto bad;
>       }
>   
> +    object_set_accelerator_compat_props(ac->compat_props);
>       acs->accel = accel;
>       return 1;
>   
> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>       parse_memory_options();
>   
>       qemu_create_machine(machine_opts_dict);
> -
> -    suspend_mux_open();
> -
> -    qemu_disable_default_devices();
> -    qemu_setup_display();
> -    qemu_create_default_devices();
> -    qemu_create_early_backends();
> -
>       qemu_apply_legacy_machine_options(machine_opts_dict);
>       qemu_apply_machine_options(machine_opts_dict);

This makes it impossible to refer to a backend in a machine option from 
the command line.  While this is not done for now, it is not a 
limitation I'd like to introduce.

Could qemu_apply_machine_options() be moved after 
configure_accelerators(), and phase_advance(PHASE_MACHINE_CREATED) with it?

Paolo


>       qobject_unref(machine_opts_dict);
> -    phase_advance(PHASE_MACHINE_CREATED);
>   
> -    /*
> -     * Note: uses machine properties such as kernel-irqchip, must run
> -     * after qemu_apply_machine_options.
> -     */
>       accel = configure_accelerators(argv[0]);
> -    create_accelerator(accel);
> -    phase_advance(PHASE_ACCEL_CREATED);
>   
>       /*
> -     * Beware, QOM objects created before this point miss global and
> +     * QOM objects created after this point see all global and
>        * compat properties.
>        *
>        * Global properties get set up by qdev_prop_register_global(),
> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>        * called from do_configure_accelerator().
>        */
>   
> +    suspend_mux_open();
> +
> +    qemu_disable_default_devices();
> +    qemu_setup_display();
> +    qemu_create_default_devices();
> +    qemu_create_early_backends();
> +
> +    phase_advance(PHASE_MACHINE_CREATED);
> +
> +    /*
> +     * Note: uses machine properties such as kernel-irqchip, must run
> +     * after qemu_apply_machine_options.
> +     */
> +    create_accelerator(accel);
> +    phase_advance(PHASE_ACCEL_CREATED);
> +
>       machine_class = MACHINE_GET_CLASS(current_machine);
>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>           warn_report("Machine type '%s' is deprecated: %s",
Paolo Bonzini Oct. 23, 2024, 5:16 p.m. UTC | #9
On 10/21/24 18:20, Peter Xu wrote:
> On Fri, Oct 18, 2024 at 03:15:56PM -0400, Steven Sistare wrote:
>> I understand this now.  The old code worked in this order:
>>
>>    qemu_create_early_backends()
>>      ... creates "-object can-bus,id=canbus"
>>    qemu_create_machine()
>>    qemu_apply_machine_options()
>>      applies link property "canbus0" with value canbus, finds canbus object
>>
>> The new code fails:
>>
>>    qemu_create_machine()
>>    qemu_apply_machine_options()
>>      applies link property "canbus0" with value canbus,
>>      error because fails to find canbus object
>>    ...
>>    qemu_exit_precreate()
>>      qemu_create_early_backends()
>>        ... creates "-object can-bus,id=canbus"
>>
>> The fix is to provide a new function, called before qemu_create_machine,
>> which creates only the backends that are needed to create the machine.
>> AFAIK can-bus is the only one, because the xlnx-zcu102 machine has
>> link properties.
> 
> Wanna share more on the specific solution?  I wonder if the plan is to add
> one more special window for creating -object just for can-bus, and how to
> justify that extra phase.

Unfortunately, I don't think there's _anything_ that can justify an
extra phase of command line processing.  The only sensible way to do
precreate is to get rid of as much as possible of the command line.

There is an old thread explaining what was fixed in preconfig in 2022
and what was missing.  Start here:

https://patchew.org/QEMU/b31f442d28920447690a6b8cee865bdbacde1283.1635160056.git.mprivozn@redhat.com/#7f54174b-4f90-13bf-6905-6febb6203575@redhat.com

Already there I wrote "one thing I don't like of preconfig is that command line arguments linger until they are triggered by x-exit-preconfig".

Paolo

> Perhaps whatever that do not require fd to back
> it (so not affected by CPR)?  But not sure whether that's too special.
> 
> I wished it could be simply put into the "very early" stage (pre-sandbox),
> but I think object_create_pre_sandbox() did mention that we need explicit
> reasons for those, and I'm not sure whether this reason justifies either
> for why can-bus is so special so can be created without the sandboxing.
>
Paolo Bonzini Oct. 23, 2024, 5:18 p.m. UTC | #10
On Wed, Oct 23, 2024 at 6:00 PM Paolo Bonzini <pbonzini@redhat.com> wrote:
> This makes it impossible to refer to a backend in a machine option from
> the command line.  While this is not done for now, it is not a
> limitation I'd like to introduce.

I stand corrected; it's exactly what's happening with canbus.

Paolo
Steven Sistare Oct. 23, 2024, 8:28 p.m. UTC | #11
On 10/22/2024 4:30 AM, David Hildenbrand wrote:
> On 18.10.24 21:15, Steven Sistare wrote:
>> On 10/18/2024 11:40 AM, Steven Sistare wrote:
>>> On 10/18/2024 11:32 AM, Steven Sistare wrote:
>>>> On 10/18/2024 11:08 AM, Fabiano Rosas wrote:
>>>>> Steve Sistare <steven.sistare@oracle.com> writes:
>>>>>
>>>>>> Make all global and compat properties available before the first objects
>>>>>> are created.  Set accelerator compatibility properties in
>>>>>> configure_accelerators, when the accelerator is chosen, and call
>>>>>> configure_accelerators earlier.  Set machine options earlier.
>>>>>>
>>>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>>>> ---
>>>>>>    accel/accel-system.c |  2 --
>>>>>>    system/vl.c          | 34 ++++++++++++++++++----------------
>>>>>>    2 files changed, 18 insertions(+), 18 deletions(-)
>>>>>>
>>>>>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>>>>>> index f6c947d..c8aeae4 100644
>>>>>> --- a/accel/accel-system.c
>>>>>> +++ b/accel/accel-system.c
>>>>>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>>>>>            ms->accelerator = NULL;
>>>>>>            *(acc->allowed) = false;
>>>>>>            object_unref(OBJECT(accel));
>>>>>> -    } else {
>>>>>> -        object_set_accelerator_compat_props(acc->compat_props);
>>>>>>        }
>>>>>>        return ret;
>>>>>>    }
>>>>>> diff --git a/system/vl.c b/system/vl.c
>>>>>> index b94a6b9..bca2292 100644
>>>>>> --- a/system/vl.c
>>>>>> +++ b/system/vl.c
>>>>>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>>>>>            goto bad;
>>>>>>        }
>>>>>> +    object_set_accelerator_compat_props(ac->compat_props);
>>>>>>        acs->accel = accel;
>>>>>>        return 1;
>>>>>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>>>>>        parse_memory_options();
>>>>>>        qemu_create_machine(machine_opts_dict);
>>>>>> -
>>>>>> -    suspend_mux_open();
>>>>>> -
>>>>>> -    qemu_disable_default_devices();
>>>>>> -    qemu_setup_display();
>>>>>> -    qemu_create_default_devices();
>>>>>> -    qemu_create_early_backends();
>>>>>> -
>>>>>>        qemu_apply_legacy_machine_options(machine_opts_dict);
>>>>>>        qemu_apply_machine_options(machine_opts_dict);
>>>>>>        qobject_unref(machine_opts_dict);
>>>>>> -    phase_advance(PHASE_MACHINE_CREATED);
>>>>>> -    /*
>>>>>> -     * Note: uses machine properties such as kernel-irqchip, must run
>>>>>> -     * after qemu_apply_machine_options.
>>>>>> -     */
>>>>>>        accel = configure_accelerators(argv[0]);
>>>>>> -    create_accelerator(accel);
>>>>>> -    phase_advance(PHASE_ACCEL_CREATED);
>>>>>>        /*
>>>>>> -     * Beware, QOM objects created before this point miss global and
>>>>>> +     * QOM objects created after this point see all global and
>>>>>>         * compat properties.
>>>>>>         *
>>>>>>         * Global properties get set up by qdev_prop_register_global(),
>>>>>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>>>>>         * called from do_configure_accelerator().
>>>>>>         */
>>>>>> +    suspend_mux_open();
>>>>>> +
>>>>>> +    qemu_disable_default_devices();
>>>>>> +    qemu_setup_display();
>>>>>> +    qemu_create_default_devices();
>>>>>> +    qemu_create_early_backends();
>>>>>> +
>>>>>> +    phase_advance(PHASE_MACHINE_CREATED);
>>>>>> +
>>>>>> +    /*
>>>>>> +     * Note: uses machine properties such as kernel-irqchip, must run
>>>>>> +     * after qemu_apply_machine_options.
>>>>>> +     */
>>>>>> +    create_accelerator(accel);
>>>>>> +    phase_advance(PHASE_ACCEL_CREATED);
>>>>>> +
>>>>>>        machine_class = MACHINE_GET_CLASS(current_machine);
>>>>>>        if (!qtest_enabled() && machine_class->deprecation_reason) {
>>>>>>            warn_report("Machine type '%s' is deprecated: %s",
>>>>>
>>>>> Hi Steve,
>>>>>
>>>>> after this commit:
>>>>>
>>>>> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/xlnx-can-test
>>>>> # random seed: R02Saf9b44f2d88dd417052905692ee79981
>>>>> 1..5
>>>>> # Start of aarch64 tests
>>>>> # Start of net tests
>>>>> # Start of can tests
>>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-2396.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-2396.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine xlnx-zcu102 -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus -accel qtest
>>>>> qemu-system-aarch64: Device 'canbus' not found
>>>>>
>>>>> I tried briefly to figure out what the issue is, but I don't really
>>>>> understand the dependencies involved. Hope you can tell us.
>>>>
>>>> Thanks! I forgot to define the preinit method for the qtest accelerator in patch 1.
>>>> I'll verify that fixes the problem and send you a one-off patch if you want to continue
>>>> testing.
>>>
>>> Actually that is not a problem.  qtest qtest_init_accel does nothing, so preinit will do
>>> nothing, so it is OK to not define preinit.
>>>
>>> Still looking.
>>
>> I understand this now.  The old code worked in this order:
>>
>>     qemu_create_early_backends()
>>       ... creates "-object can-bus,id=canbus"
>>     qemu_create_machine()
>>     qemu_apply_machine_options()
>>       applies link property "canbus0" with value canbus, finds canbus object
> 
> Now I am confused.
> 
> I think the current code does:
> 
> qemu_create_machine(machine_opts_dict);
> qemu_create_early_backends();
> qemu_apply_machine_options(machine_opts_dict);
> 
> Isn't the relevant part that we may only apply the machine options after creating the early backends?

Yes, I showed the wrong order for the old code, but our explanations are equivalent.

Perhaps this could be fixed by moving qemu_apply_machine_options after
qemu_create_early_backends in qemu_exit_precreate.  But that seems risky and
fragile,  as there would be a large window of code between qemu_create_machine
and qemu_apply_machine_options where the machine has been created but the machine
options and not known.

- Steve
Steven Sistare Oct. 23, 2024, 8:29 p.m. UTC | #12
On 10/21/2024 11:19 AM, Peter Xu wrote:
> On Thu, Oct 17, 2024 at 08:14:05AM -0700, Steve Sistare wrote:
>> Make all global and compat properties available before the first objects
>> are created.  Set accelerator compatibility properties in
>> configure_accelerators, when the accelerator is chosen, and call
>> configure_accelerators earlier.  Set machine options earlier.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> ---
>>   accel/accel-system.c |  2 --
>>   system/vl.c          | 34 ++++++++++++++++++----------------
>>   2 files changed, 18 insertions(+), 18 deletions(-)
>>
>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>> index f6c947d..c8aeae4 100644
>> --- a/accel/accel-system.c
>> +++ b/accel/accel-system.c
>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>           ms->accelerator = NULL;
>>           *(acc->allowed) = false;
>>           object_unref(OBJECT(accel));
>> -    } else {
>> -        object_set_accelerator_compat_props(acc->compat_props);
>>       }
>>       return ret;
>>   }
>> diff --git a/system/vl.c b/system/vl.c
>> index b94a6b9..bca2292 100644
>> --- a/system/vl.c
>> +++ b/system/vl.c
>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>           goto bad;
>>       }
>>   
>> +    object_set_accelerator_compat_props(ac->compat_props);
> 
> This is the probe/preinit iterator, might be good to keep it simple to only
> make the decision of choosing one accel, then move this line over to
> configure_accelerators() at the end.

It's actually simpler to leave it here.  Hoisting object_set_accelerator_compat_props
would require extra code to derive the ac parameter.

- Steve

>>       acs->accel = accel;
>>       return 1;
>>   
>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>       parse_memory_options();
>>   
>>       qemu_create_machine(machine_opts_dict);
>> -
>> -    suspend_mux_open();
>> -
>> -    qemu_disable_default_devices();
>> -    qemu_setup_display();
>> -    qemu_create_default_devices();
>> -    qemu_create_early_backends();
>> -
>>       qemu_apply_legacy_machine_options(machine_opts_dict);
>>       qemu_apply_machine_options(machine_opts_dict);
>>       qobject_unref(machine_opts_dict);
>> -    phase_advance(PHASE_MACHINE_CREATED);
>>   
>> -    /*
>> -     * Note: uses machine properties such as kernel-irqchip, must run
>> -     * after qemu_apply_machine_options.
>> -     */
>>       accel = configure_accelerators(argv[0]);
>> -    create_accelerator(accel);
>> -    phase_advance(PHASE_ACCEL_CREATED);
>>   
>>       /*
>> -     * Beware, QOM objects created before this point miss global and
>> +     * QOM objects created after this point see all global and
>>        * compat properties.
>>        *
>>        * Global properties get set up by qdev_prop_register_global(),
>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>        * called from do_configure_accelerator().
>>        */
>>   
>> +    suspend_mux_open();
>> +
>> +    qemu_disable_default_devices();
>> +    qemu_setup_display();
>> +    qemu_create_default_devices();
>> +    qemu_create_early_backends();
>> +
>> +    phase_advance(PHASE_MACHINE_CREATED);
>> +
>> +    /*
>> +     * Note: uses machine properties such as kernel-irqchip, must run
>> +     * after qemu_apply_machine_options.
>> +     */
>> +    create_accelerator(accel);
>> +    phase_advance(PHASE_ACCEL_CREATED);
>> +
>>       machine_class = MACHINE_GET_CLASS(current_machine);
>>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>>           warn_report("Machine type '%s' is deprecated: %s",
>> -- 
>> 1.8.3.1
>>
>
Steven Sistare Oct. 23, 2024, 8:29 p.m. UTC | #13
On 10/23/2024 12:00 PM, Paolo Bonzini wrote:
> On 10/17/24 17:14, Steve Sistare wrote:
>> Make all global and compat properties available before the first objects
>> are created.  Set accelerator compatibility properties in
>> configure_accelerators, when the accelerator is chosen, and call
>> configure_accelerators earlier.  Set machine options earlier.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> ---
>>   accel/accel-system.c |  2 --
>>   system/vl.c          | 34 ++++++++++++++++++----------------
>>   2 files changed, 18 insertions(+), 18 deletions(-)
>>
>> diff --git a/accel/accel-system.c b/accel/accel-system.c
>> index f6c947d..c8aeae4 100644
>> --- a/accel/accel-system.c
>> +++ b/accel/accel-system.c
>> @@ -41,8 +41,6 @@ int accel_init_machine(AccelState *accel, MachineState *ms)
>>           ms->accelerator = NULL;
>>           *(acc->allowed) = false;
>>           object_unref(OBJECT(accel));
>> -    } else {
>> -        object_set_accelerator_compat_props(acc->compat_props);
>>       }
>>       return ret;
>>   }
>> diff --git a/system/vl.c b/system/vl.c
>> index b94a6b9..bca2292 100644
>> --- a/system/vl.c
>> +++ b/system/vl.c
>> @@ -2346,6 +2346,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
>>           goto bad;
>>       }
>> +    object_set_accelerator_compat_props(ac->compat_props);
>>       acs->accel = accel;
>>       return 1;
>> @@ -3728,29 +3729,14 @@ void qemu_init(int argc, char **argv)
>>       parse_memory_options();
>>       qemu_create_machine(machine_opts_dict);
>> -
>> -    suspend_mux_open();
>> -
>> -    qemu_disable_default_devices();
>> -    qemu_setup_display();
>> -    qemu_create_default_devices();
>> -    qemu_create_early_backends();
>> -
>>       qemu_apply_legacy_machine_options(machine_opts_dict);
>>       qemu_apply_machine_options(machine_opts_dict);
> 
> This makes it impossible to refer to a backend in a machine option from the command line.  While this is not done for now, it is not a limitation I'd like to introduce.
> 
> Could qemu_apply_machine_options() be moved after configure_accelerators(), 

Yes, but why?  I don't see any dependency between the two.
Keeping the machine and its options together would be nice.

> and phase_advance(PHASE_MACHINE_CREATED) with it?

Yes, I should phase_advance to PHASE_MACHINE_CREATED right after qemu_apply_machine_options.
I added PHASE_MACHINE_CREATED in qemu_exit_precreate for no good reason.

Yielding:

     qemu_create_machine_objects();          // TBD
     qemu_create_machine(machine_opts_dict);
     qemu_apply_legacy_machine_options(machine_opts_dict);
     qemu_apply_machine_options(machine_opts_dict);
     qobject_unref(machine_opts_dict);
     phase_advance(PHASE_MACHINE_CREATED)

     accel = configure_accelerators(argv[0]);

qemu_create_machine_objects is my proposed fix for the canbus dependency,
which I know you are not keen on.

- Steve

>>       qobject_unref(machine_opts_dict);
>> -    phase_advance(PHASE_MACHINE_CREATED);
>> -    /*
>> -     * Note: uses machine properties such as kernel-irqchip, must run
>> -     * after qemu_apply_machine_options.
>> -     */
>>       accel = configure_accelerators(argv[0]);
>> -    create_accelerator(accel);
>> -    phase_advance(PHASE_ACCEL_CREATED);
>>       /*
>> -     * Beware, QOM objects created before this point miss global and
>> +     * QOM objects created after this point see all global and
>>        * compat properties.
>>        *
>>        * Global properties get set up by qdev_prop_register_global(),
>> @@ -3765,6 +3751,22 @@ void qemu_init(int argc, char **argv)
>>        * called from do_configure_accelerator().
>>        */
>> +    suspend_mux_open();
>> +
>> +    qemu_disable_default_devices();
>> +    qemu_setup_display();
>> +    qemu_create_default_devices();
>> +    qemu_create_early_backends();
>> +
>> +    phase_advance(PHASE_MACHINE_CREATED);
>> +
>> +    /*
>> +     * Note: uses machine properties such as kernel-irqchip, must run
>> +     * after qemu_apply_machine_options.
>> +     */
>> +    create_accelerator(accel);
>> +    phase_advance(PHASE_ACCEL_CREATED);
>> +
>>       machine_class = MACHINE_GET_CLASS(current_machine);
>>       if (!qtest_enabled() && machine_class->deprecation_reason) {
>>           warn_report("Machine type '%s' is deprecated: %s",
>
diff mbox series

Patch

diff --git a/accel/accel-system.c b/accel/accel-system.c
index f6c947d..c8aeae4 100644
--- a/accel/accel-system.c
+++ b/accel/accel-system.c
@@ -41,8 +41,6 @@  int accel_init_machine(AccelState *accel, MachineState *ms)
         ms->accelerator = NULL;
         *(acc->allowed) = false;
         object_unref(OBJECT(accel));
-    } else {
-        object_set_accelerator_compat_props(acc->compat_props);
     }
     return ret;
 }
diff --git a/system/vl.c b/system/vl.c
index b94a6b9..bca2292 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2346,6 +2346,7 @@  static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
         goto bad;
     }
 
+    object_set_accelerator_compat_props(ac->compat_props);
     acs->accel = accel;
     return 1;
 
@@ -3728,29 +3729,14 @@  void qemu_init(int argc, char **argv)
     parse_memory_options();
 
     qemu_create_machine(machine_opts_dict);
-
-    suspend_mux_open();
-
-    qemu_disable_default_devices();
-    qemu_setup_display();
-    qemu_create_default_devices();
-    qemu_create_early_backends();
-
     qemu_apply_legacy_machine_options(machine_opts_dict);
     qemu_apply_machine_options(machine_opts_dict);
     qobject_unref(machine_opts_dict);
-    phase_advance(PHASE_MACHINE_CREATED);
 
-    /*
-     * Note: uses machine properties such as kernel-irqchip, must run
-     * after qemu_apply_machine_options.
-     */
     accel = configure_accelerators(argv[0]);
-    create_accelerator(accel);
-    phase_advance(PHASE_ACCEL_CREATED);
 
     /*
-     * Beware, QOM objects created before this point miss global and
+     * QOM objects created after this point see all global and
      * compat properties.
      *
      * Global properties get set up by qdev_prop_register_global(),
@@ -3765,6 +3751,22 @@  void qemu_init(int argc, char **argv)
      * called from do_configure_accelerator().
      */
 
+    suspend_mux_open();
+
+    qemu_disable_default_devices();
+    qemu_setup_display();
+    qemu_create_default_devices();
+    qemu_create_early_backends();
+
+    phase_advance(PHASE_MACHINE_CREATED);
+
+    /*
+     * Note: uses machine properties such as kernel-irqchip, must run
+     * after qemu_apply_machine_options.
+     */
+    create_accelerator(accel);
+    phase_advance(PHASE_ACCEL_CREATED);
+
     machine_class = MACHINE_GET_CLASS(current_machine);
     if (!qtest_enabled() && machine_class->deprecation_reason) {
         warn_report("Machine type '%s' is deprecated: %s",