[PATCH v11 01/10] virtio-gpu: Unrealize GL device

Dmitry Osipenko posted 10 patches 6 months, 2 weeks ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Thomas Huth <thuth@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
There is a newer version of this series
[PATCH v11 01/10] virtio-gpu: Unrealize GL device
Posted by Dmitry Osipenko 6 months, 2 weeks ago
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
Re: [PATCH v11 01/10] virtio-gpu: Unrealize GL device
Posted by Akihiko Odaki 6 months, 2 weeks ago
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
Re: [PATCH v11 01/10] virtio-gpu: Unrealize GL device
Posted by Dmitry Osipenko 6 months, 1 week ago
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


Re: [PATCH v11 01/10] virtio-gpu: Unrealize GL device
Posted by Akihiko Odaki 6 months, 1 week ago
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).

Re: [PATCH v11 01/10] virtio-gpu: Unrealize GL device
Posted by Dmitry Osipenko 6 months, 1 week ago
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