Even though GL GPU doesn't support hotplugging today, free virgl
resources when GL device is unrealized. For consistency.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 11 +++++++++++
hw/display/virtio-gpu-virgl.c | 9 +++++++++
include/hw/virtio/virtio-gpu.h | 1 +
3 files changed, 21 insertions(+)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index e06be60dfbfc..0c0a8d136954 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -136,6 +136,16 @@ static Property virtio_gpu_gl_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
+{
+ VirtIOGPU *g = VIRTIO_GPU(qdev);
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
+
+ if (gl->renderer_inited) {
+ virtio_gpu_virgl_deinit(g);
+ }
+}
+
static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -149,6 +159,7 @@ static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
vdc->realize = virtio_gpu_gl_device_realize;
+ vdc->unrealize = virtio_gpu_gl_device_unrealize;
vdc->reset = virtio_gpu_gl_reset;
device_class_set_props(dc, virtio_gpu_gl_properties);
}
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 9f34d0e6619c..b0500eccf8e0 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -665,3 +665,12 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
return capset2_max_ver ? 2 : 1;
}
+
+void virtio_gpu_virgl_deinit(VirtIOGPU *g)
+{
+ if (g->fence_poll) {
+ timer_free(g->fence_poll);
+ }
+
+ virgl_renderer_cleanup(NULL);
+}
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index ed44cdad6b34..b657187159d9 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -336,6 +336,7 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
void virtio_gpu_virgl_reset(VirtIOGPU *g);
int virtio_gpu_virgl_init(VirtIOGPU *g);
+void virtio_gpu_virgl_deinit(VirtIOGPU *g);
int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
#endif
--
2.44.0
On 2024/05/12 3:22, Dmitry Osipenko wrote:
> Even though GL GPU doesn't support hotplugging today, free virgl
> resources when GL device is unrealized. For consistency.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-gl.c | 11 +++++++++++
> hw/display/virtio-gpu-virgl.c | 9 +++++++++
> include/hw/virtio/virtio-gpu.h | 1 +
> 3 files changed, 21 insertions(+)
>
> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
> index e06be60dfbfc..0c0a8d136954 100644
> --- a/hw/display/virtio-gpu-gl.c
> +++ b/hw/display/virtio-gpu-gl.c
> @@ -136,6 +136,16 @@ static Property virtio_gpu_gl_properties[] = {
> DEFINE_PROP_END_OF_LIST(),
> };
>
> +static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
> +{
> + VirtIOGPU *g = VIRTIO_GPU(qdev);
> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
> +
> + if (gl->renderer_inited) {
> + virtio_gpu_virgl_deinit(g);
> + }
> +}
> +
> static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -149,6 +159,7 @@ static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
> vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
>
> vdc->realize = virtio_gpu_gl_device_realize;
> + vdc->unrealize = virtio_gpu_gl_device_unrealize;
> vdc->reset = virtio_gpu_gl_reset;
> device_class_set_props(dc, virtio_gpu_gl_properties);
> }
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 9f34d0e6619c..b0500eccf8e0 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -665,3 +665,12 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
>
> return capset2_max_ver ? 2 : 1;
> }
> +
> +void virtio_gpu_virgl_deinit(VirtIOGPU *g)
> +{
> + if (g->fence_poll) {
Isn't g->fence_poll always non-NULL when this function is called?
> + timer_free(g->fence_poll);
> + }
> +
> + virgl_renderer_cleanup(NULL);
> +}
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index ed44cdad6b34..b657187159d9 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -336,6 +336,7 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
> void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
> void virtio_gpu_virgl_reset(VirtIOGPU *g);
> int virtio_gpu_virgl_init(VirtIOGPU *g);
> +void virtio_gpu_virgl_deinit(VirtIOGPU *g);
> int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
>
> #endif
On 5/13/24 11:44, Akihiko Odaki wrote:
> On 2024/05/12 3:22, Dmitry Osipenko wrote:
>> Even though GL GPU doesn't support hotplugging today, free virgl
>> resources when GL device is unrealized. For consistency.
>>
>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
>> ---
>> hw/display/virtio-gpu-gl.c | 11 +++++++++++
>> hw/display/virtio-gpu-virgl.c | 9 +++++++++
>> include/hw/virtio/virtio-gpu.h | 1 +
>> 3 files changed, 21 insertions(+)
>>
>> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
>> index e06be60dfbfc..0c0a8d136954 100644
>> --- a/hw/display/virtio-gpu-gl.c
>> +++ b/hw/display/virtio-gpu-gl.c
>> @@ -136,6 +136,16 @@ static Property virtio_gpu_gl_properties[] = {
>> DEFINE_PROP_END_OF_LIST(),
>> };
>> +static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
>> +{
>> + VirtIOGPU *g = VIRTIO_GPU(qdev);
>> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
>> +
>> + if (gl->renderer_inited) {
>> + virtio_gpu_virgl_deinit(g);
>> + }
>> +}
>> +
>> static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> @@ -149,6 +159,7 @@ static void virtio_gpu_gl_class_init(ObjectClass
>> *klass, void *data)
>> vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
>> vdc->realize = virtio_gpu_gl_device_realize;
>> + vdc->unrealize = virtio_gpu_gl_device_unrealize;
>> vdc->reset = virtio_gpu_gl_reset;
>> device_class_set_props(dc, virtio_gpu_gl_properties);
>> }
>> diff --git a/hw/display/virtio-gpu-virgl.c
>> b/hw/display/virtio-gpu-virgl.c
>> index 9f34d0e6619c..b0500eccf8e0 100644
>> --- a/hw/display/virtio-gpu-virgl.c
>> +++ b/hw/display/virtio-gpu-virgl.c
>> @@ -665,3 +665,12 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
>> return capset2_max_ver ? 2 : 1;
>> }
>> +
>> +void virtio_gpu_virgl_deinit(VirtIOGPU *g)
>> +{
>> + if (g->fence_poll) {
>
> Isn't g->fence_poll always non-NULL when this function is called?
virtio_gpu_virgl_init() is invoked when first cmd is executed, please
see virtio_gpu_gl_handle_ctrl() that invokes it. Hence g->fence_poll can
be NULL.
--
Best regards,
Dmitry
On 2024/05/16 1:18, Dmitry Osipenko wrote:
> On 5/13/24 11:44, Akihiko Odaki wrote:
>> On 2024/05/12 3:22, Dmitry Osipenko wrote:
>>> Even though GL GPU doesn't support hotplugging today, free virgl
>>> resources when GL device is unrealized. For consistency.
>>>
>>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
>>> ---
>>> hw/display/virtio-gpu-gl.c | 11 +++++++++++
>>> hw/display/virtio-gpu-virgl.c | 9 +++++++++
>>> include/hw/virtio/virtio-gpu.h | 1 +
>>> 3 files changed, 21 insertions(+)
>>>
>>> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
>>> index e06be60dfbfc..0c0a8d136954 100644
>>> --- a/hw/display/virtio-gpu-gl.c
>>> +++ b/hw/display/virtio-gpu-gl.c
>>> @@ -136,6 +136,16 @@ static Property virtio_gpu_gl_properties[] = {
>>> DEFINE_PROP_END_OF_LIST(),
>>> };
>>> +static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
>>> +{
>>> + VirtIOGPU *g = VIRTIO_GPU(qdev);
>>> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
>>> +
>>> + if (gl->renderer_inited) {
>>> + virtio_gpu_virgl_deinit(g);
>>> + }
>>> +}
>>> +
>>> static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
>>> {
>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>> @@ -149,6 +159,7 @@ static void virtio_gpu_gl_class_init(ObjectClass
>>> *klass, void *data)
>>> vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
>>> vdc->realize = virtio_gpu_gl_device_realize;
>>> + vdc->unrealize = virtio_gpu_gl_device_unrealize;
>>> vdc->reset = virtio_gpu_gl_reset;
>>> device_class_set_props(dc, virtio_gpu_gl_properties);
>>> }
>>> diff --git a/hw/display/virtio-gpu-virgl.c
>>> b/hw/display/virtio-gpu-virgl.c
>>> index 9f34d0e6619c..b0500eccf8e0 100644
>>> --- a/hw/display/virtio-gpu-virgl.c
>>> +++ b/hw/display/virtio-gpu-virgl.c
>>> @@ -665,3 +665,12 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
>>> return capset2_max_ver ? 2 : 1;
>>> }
>>> +
>>> +void virtio_gpu_virgl_deinit(VirtIOGPU *g)
>>> +{
>>> + if (g->fence_poll) {
>>
>> Isn't g->fence_poll always non-NULL when this function is called?
>
> virtio_gpu_virgl_init() is invoked when first cmd is executed, please
> see virtio_gpu_gl_handle_ctrl() that invokes it. Hence g->fence_poll can
> be NULL.
>
But it already checks renderer_inited, doesn't it? And I think it's
better to utilize one single flag to represent that virgl is enabled
instead of checking several variables (fence_poll and cmdq_resume_bh in
the future).
On 5/15/24 19:22, Akihiko Odaki wrote:
> On 2024/05/16 1:18, Dmitry Osipenko wrote:
>> On 5/13/24 11:44, Akihiko Odaki wrote:
>>> On 2024/05/12 3:22, Dmitry Osipenko wrote:
>>>> Even though GL GPU doesn't support hotplugging today, free virgl
>>>> resources when GL device is unrealized. For consistency.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
>>>> ---
>>>> hw/display/virtio-gpu-gl.c | 11 +++++++++++
>>>> hw/display/virtio-gpu-virgl.c | 9 +++++++++
>>>> include/hw/virtio/virtio-gpu.h | 1 +
>>>> 3 files changed, 21 insertions(+)
>>>>
>>>> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
>>>> index e06be60dfbfc..0c0a8d136954 100644
>>>> --- a/hw/display/virtio-gpu-gl.c
>>>> +++ b/hw/display/virtio-gpu-gl.c
>>>> @@ -136,6 +136,16 @@ static Property virtio_gpu_gl_properties[] = {
>>>> DEFINE_PROP_END_OF_LIST(),
>>>> };
>>>> +static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
>>>> +{
>>>> + VirtIOGPU *g = VIRTIO_GPU(qdev);
>>>> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
>>>> +
>>>> + if (gl->renderer_inited) {
>>>> + virtio_gpu_virgl_deinit(g);
>>>> + }
>>>> +}
>>>> +
>>>> static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
>>>> {
>>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>>> @@ -149,6 +159,7 @@ static void virtio_gpu_gl_class_init(ObjectClass
>>>> *klass, void *data)
>>>> vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
>>>> vdc->realize = virtio_gpu_gl_device_realize;
>>>> + vdc->unrealize = virtio_gpu_gl_device_unrealize;
>>>> vdc->reset = virtio_gpu_gl_reset;
>>>> device_class_set_props(dc, virtio_gpu_gl_properties);
>>>> }
>>>> diff --git a/hw/display/virtio-gpu-virgl.c
>>>> b/hw/display/virtio-gpu-virgl.c
>>>> index 9f34d0e6619c..b0500eccf8e0 100644
>>>> --- a/hw/display/virtio-gpu-virgl.c
>>>> +++ b/hw/display/virtio-gpu-virgl.c
>>>> @@ -665,3 +665,12 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
>>>> return capset2_max_ver ? 2 : 1;
>>>> }
>>>> +
>>>> +void virtio_gpu_virgl_deinit(VirtIOGPU *g)
>>>> +{
>>>> + if (g->fence_poll) {
>>>
>>> Isn't g->fence_poll always non-NULL when this function is called?
>>
>> virtio_gpu_virgl_init() is invoked when first cmd is executed, please
>> see virtio_gpu_gl_handle_ctrl() that invokes it. Hence g->fence_poll can
>> be NULL.
>>
>
> But it already checks renderer_inited, doesn't it? And I think it's
> better to utilize one single flag to represent that virgl is enabled
> instead of checking several variables (fence_poll and cmdq_resume_bh in
> the future).
The virtio_gpu_virgl_init() will have to be changed to do that because
virgl_renderer_init() can fail before fence_poll/cmdq_resume_bh are inited.
Though, the error returned by virtio_gpu_virgl_init() isn't checked by
virtio_gpu_gl_handle_ctrl(), which leads to a further Qemu crash due to
fence_poll=NULL. I'll try to improve it all in v12, thanks.
--
Best regards,
Dmitry
© 2016 - 2026 Red Hat, Inc.