qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga
@ 2024-01-30 14:59 Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 1/3] hw/display/virtio-gpu.c: use reset_bh class method Manos Pitsidianakis
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30 14:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross,
	Alex Bennée

While testing the rutabaga gpu device, we noticed that if the device is
reset, it stops working and complains about missing resource ids. A
quick investigation discovered that the generic VirtIOGPU implementation
frees all resources, but for Rutabaga, they are tied with rutabaga
objects that need to be destroyed as well.

This series adds a resource_destroy class method that the Rutabaga
device can override and do its own bookkeeping.

v2 -> v3 differences:
- use error_setg_errno in virtio-gpu-rutabaga.c
  resource_destroy method. (Thanks Marc-André
  Lureau <marcandre.lureau@gmail.com> !)

v1 -> v2 differences:
- addressed review comments re: using the Error API for the
  resource_destroy method.

Manos Pitsidianakis (3):
  hw/display/virtio-gpu.c: use reset_bh class method
  virtio-gpu.c: add resource_destroy class method
  virtio-gpu-rutabaga.c: override resource_destroy method

 include/hw/virtio/virtio-gpu.h   |  3 ++
 hw/display/virtio-gpu-rutabaga.c | 47 ++++++++++++++++++++++++--------
 hw/display/virtio-gpu.c          | 27 +++++++++++++++---
 3 files changed, 61 insertions(+), 16 deletions(-)

Range-diff against v2:
1:  5893fb45d1 = 1:  87fb4fa72c hw/display/virtio-gpu.c: use reset_bh class method
2:  78b15e8f7e ! 2:  b0a86630c4 virtio-gpu.c: add resource_destroy class method
    @@ Commit message
         This commit adds a class method so that virtio-gpu-rutabaga can override
         it in the next commit.
     
    +    Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
         Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## include/hw/virtio/virtio-gpu.h ##
3:  926db899be ! 3:  e3778e44c9 virtio-gpu-rutabaga.c: override resource_destroy method
    @@ hw/display/virtio-gpu-rutabaga.c: rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
     +                                   Error **errp)
     +{
     +    int32_t result;
    -+    const char *strerror = NULL;
     +    VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
     +
     +    result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
     +    if (result) {
    -+        error_setg(errp, "%s: rutabaga_resource_unref returned %"PRIi32
    -+                   " for resource_id = %"PRIu32, __func__, result,
    -+                   res->resource_id);
    -+        strerror = strerrorname_np((int)result);
    -+        if (strerror != NULL) {
    -+            error_append_hint(errp, "%s: %s\n",
    -+                              strerror, strerrordesc_np((int)result) ? : "");
    -+        }
    ++        error_setg_errno(errp,
    ++                        (int)result,
    ++                        "%s: rutabaga_resource_unref returned %"PRIi32
    ++                        " for resource_id = %"PRIu32, __func__, result,
    ++                        res->resource_id);
     +    }
     +
     +    if (res->image) {

base-commit: 11be70677c70fdccd452a3233653949b79e97908
-- 
γαῖα πυρί μιχθήτω



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/3] hw/display/virtio-gpu.c: use reset_bh class method
  2024-01-30 14:59 [PATCH v3 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
@ 2024-01-30 14:59 ` Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
  2 siblings, 0 replies; 5+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30 14:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross,
	Alex Bennée, Marc-André Lureau

While the VirtioGPU type has a reset_bh field to specify a reset
callback, it's never used. virtio_gpu_reset() calls the general
virtio_gpu_reset_bh() function for all devices that inherit from
VirtioGPU.

While no devices override reset_bh at the moment, a device reset might
require special logic for implementations in the future.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
 hw/display/virtio-gpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f8a675eb30..2b73ae585b 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1515,7 +1515,7 @@ void virtio_gpu_reset(VirtIODevice *vdev)
             qemu_cond_wait_bql(&g->reset_cond);
         }
     } else {
-        virtio_gpu_reset_bh(g);
+        aio_bh_call(g->reset_bh);
     }
 
     while (!QTAILQ_EMPTY(&g->cmdq)) {
-- 
γαῖα πυρί μιχθήτω



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/3] virtio-gpu.c: add resource_destroy class method
  2024-01-30 14:59 [PATCH v3 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 1/3] hw/display/virtio-gpu.c: use reset_bh class method Manos Pitsidianakis
@ 2024-01-30 14:59 ` Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
  2 siblings, 0 replies; 5+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30 14:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross,
	Alex Bennée, Marc-André Lureau

When destroying/unrefing resources, devices such as virtio-gpu-rutabaga
need to do their own bookkeeping (free rutabaga resources that are
associated with the virtio_gpu_simple_resource).

This commit adds a class method so that virtio-gpu-rutabaga can override
it in the next commit.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
 include/hw/virtio/virtio-gpu.h |  3 +++
 hw/display/virtio-gpu.c        | 25 ++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 584ba2ed73..b28e7ef0d2 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -219,6 +219,9 @@ struct VirtIOGPUClass {
     void (*update_cursor_data)(VirtIOGPU *g,
                                struct virtio_gpu_scanout *s,
                                uint32_t resource_id);
+    void (*resource_destroy)(VirtIOGPU *g,
+                             struct virtio_gpu_simple_resource *res,
+                             Error **errp);
 };
 
 struct VirtIOGPUGL {
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 2b73ae585b..1c1ee230b3 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -402,7 +402,8 @@ static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
 }
 
 static void virtio_gpu_resource_destroy(VirtIOGPU *g,
-                                        struct virtio_gpu_simple_resource *res)
+                                        struct virtio_gpu_simple_resource *res,
+                                        Error **errp)
 {
     int i;
 
@@ -438,7 +439,11 @@ static void virtio_gpu_resource_unref(VirtIOGPU *g,
         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
         return;
     }
-    virtio_gpu_resource_destroy(g, res);
+    /*
+     * virtio_gpu_resource_destroy does not set any errors, so pass a NULL errp
+     * to ignore them.
+     */
+    virtio_gpu_resource_destroy(g, res, NULL);
 }
 
 static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
@@ -1488,11 +1493,24 @@ static void virtio_gpu_device_unrealize(DeviceState *qdev)
 static void virtio_gpu_reset_bh(void *opaque)
 {
     VirtIOGPU *g = VIRTIO_GPU(opaque);
+    VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
     struct virtio_gpu_simple_resource *res, *tmp;
+    uint32_t resource_id;
+    Error *local_err = NULL;
     int i = 0;
 
     QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
-        virtio_gpu_resource_destroy(g, res);
+        resource_id = res->resource_id;
+        vgc->resource_destroy(g, res, &local_err);
+        if (local_err) {
+            error_append_hint(&local_err, "%s: %s resource_destroy"
+                              "for resource_id = %"PRIu32" failed.\n",
+                              __func__, object_get_typename(OBJECT(g)),
+                              resource_id);
+            /* error_report_err frees the error object for us */
+            error_report_err(local_err);
+            local_err = NULL;
+        }
     }
 
     for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
@@ -1632,6 +1650,7 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data)
     vgc->handle_ctrl = virtio_gpu_handle_ctrl;
     vgc->process_cmd = virtio_gpu_simple_process_cmd;
     vgc->update_cursor_data = virtio_gpu_update_cursor_data;
+    vgc->resource_destroy = virtio_gpu_resource_destroy;
     vgbc->gl_flushed = virtio_gpu_handle_gl_flushed;
 
     vdc->realize = virtio_gpu_device_realize;
-- 
γαῖα πυρί μιχθήτω



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-30 14:59 [PATCH v3 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 1/3] hw/display/virtio-gpu.c: use reset_bh class method Manos Pitsidianakis
  2024-01-30 14:59 ` [PATCH v3 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
@ 2024-01-30 14:59 ` Manos Pitsidianakis
  2024-01-31  3:09   ` Gurchetan Singh
  2 siblings, 1 reply; 5+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30 14:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross,
	Alex Bennée

When the Rutabaga GPU device frees resources, it calls
rutabaga_resource_unref for that resource_id. However, when the generic
VirtIOGPU functions destroys resources, it only removes the
virtio_gpu_simple_resource from the device's VirtIOGPU->reslist list.
The rutabaga resource associated with that resource_id is then leaked.

This commit overrides the resource_destroy class method introduced in
the previous commit to fix this.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
 hw/display/virtio-gpu-rutabaga.c | 47 ++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
index 9e67f9bd51..17bf701a21 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -148,14 +148,38 @@ rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
 }
 
 static void
+virtio_gpu_rutabaga_resource_unref(VirtIOGPU *g,
+                                   struct virtio_gpu_simple_resource *res,
+                                   Error **errp)
+{
+    int32_t result;
+    VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
+
+    result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
+    if (result) {
+        error_setg_errno(errp,
+                        (int)result,
+                        "%s: rutabaga_resource_unref returned %"PRIi32
+                        " for resource_id = %"PRIu32, __func__, result,
+                        res->resource_id);
+    }
+
+    if (res->image) {
+        pixman_image_unref(res->image);
+    }
+
+    QTAILQ_REMOVE(&g->reslist, res, next);
+    g_free(res);
+}
+
+static void
 rutabaga_cmd_resource_unref(VirtIOGPU *g,
                             struct virtio_gpu_ctrl_command *cmd)
 {
-    int32_t result;
+    int32_t result = 0;
     struct virtio_gpu_simple_resource *res;
     struct virtio_gpu_resource_unref unref;
-
-    VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
+    Error *local_err = NULL;
 
     VIRTIO_GPU_FILL_CMD(unref);
 
@@ -164,15 +188,14 @@ rutabaga_cmd_resource_unref(VirtIOGPU *g,
     res = virtio_gpu_find_resource(g, unref.resource_id);
     CHECK(res, cmd);
 
-    result = rutabaga_resource_unref(vr->rutabaga, unref.resource_id);
-    CHECK(!result, cmd);
-
-    if (res->image) {
-        pixman_image_unref(res->image);
+    virtio_gpu_rutabaga_resource_unref(g, res, &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+        /* local_err was freed, do not reuse it. */
+        local_err = NULL;
+        result = 1;
     }
-
-    QTAILQ_REMOVE(&g->reslist, res, next);
-    g_free(res);
+    CHECK(!result, cmd);
 }
 
 static void
@@ -1099,7 +1122,7 @@ static void virtio_gpu_rutabaga_class_init(ObjectClass *klass, void *data)
     vgc->handle_ctrl = virtio_gpu_rutabaga_handle_ctrl;
     vgc->process_cmd = virtio_gpu_rutabaga_process_cmd;
     vgc->update_cursor_data = virtio_gpu_rutabaga_update_cursor;
-
+    vgc->resource_destroy = virtio_gpu_rutabaga_resource_unref;
     vdc->realize = virtio_gpu_rutabaga_realize;
     device_class_set_props(dc, virtio_gpu_rutabaga_properties);
 }
-- 
γαῖα πυρί μιχθήτω



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-30 14:59 ` [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
@ 2024-01-31  3:09   ` Gurchetan Singh
  0 siblings, 0 replies; 5+ messages in thread
From: Gurchetan Singh @ 2024-01-31  3:09 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: qemu-devel, Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Alyssa Ross, Alex Bennée

[-- Attachment #1: Type: text/plain, Size: 3641 bytes --]

On Tue, Jan 30, 2024 at 7:00 AM Manos Pitsidianakis <
manos.pitsidianakis@linaro.org> wrote:

> When the Rutabaga GPU device frees resources, it calls
> rutabaga_resource_unref for that resource_id. However, when the generic
> VirtIOGPU functions destroys resources, it only removes the
> virtio_gpu_simple_resource from the device's VirtIOGPU->reslist list.
> The rutabaga resource associated with that resource_id is then leaked.
>
> This commit overrides the resource_destroy class method introduced in
> the previous commit to fix this.
>

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>


>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  hw/display/virtio-gpu-rutabaga.c | 47 ++++++++++++++++++++++++--------
>  1 file changed, 35 insertions(+), 12 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-rutabaga.c
> b/hw/display/virtio-gpu-rutabaga.c
> index 9e67f9bd51..17bf701a21 100644
> --- a/hw/display/virtio-gpu-rutabaga.c
> +++ b/hw/display/virtio-gpu-rutabaga.c
> @@ -148,14 +148,38 @@ rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
>  }
>
>  static void
> +virtio_gpu_rutabaga_resource_unref(VirtIOGPU *g,
> +                                   struct virtio_gpu_simple_resource *res,
> +                                   Error **errp)
> +{
> +    int32_t result;
> +    VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
> +
> +    result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
> +    if (result) {
> +        error_setg_errno(errp,
> +                        (int)result,
> +                        "%s: rutabaga_resource_unref returned %"PRIi32
> +                        " for resource_id = %"PRIu32, __func__, result,
> +                        res->resource_id);
> +    }
> +
> +    if (res->image) {
> +        pixman_image_unref(res->image);
> +    }
> +
> +    QTAILQ_REMOVE(&g->reslist, res, next);
> +    g_free(res);
> +}

+
> +static void
>  rutabaga_cmd_resource_unref(VirtIOGPU *g,
>                              struct virtio_gpu_ctrl_command *cmd)
>  {
> -    int32_t result;
> +    int32_t result = 0;
>      struct virtio_gpu_simple_resource *res;
>      struct virtio_gpu_resource_unref unref;
> -
> -    VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
> +    Error *local_err = NULL;
>
>      VIRTIO_GPU_FILL_CMD(unref);
>
> @@ -164,15 +188,14 @@ rutabaga_cmd_resource_unref(VirtIOGPU *g,
>      res = virtio_gpu_find_resource(g, unref.resource_id);
>      CHECK(res, cmd);
>
> -    result = rutabaga_resource_unref(vr->rutabaga, unref.resource_id);
> -    CHECK(!result, cmd);
> -
> -    if (res->image) {
> -        pixman_image_unref(res->image);
> +    virtio_gpu_rutabaga_resource_unref(g, res, &local_err);
> +    if (local_err) {
> +        error_report_err(local_err);
> +        /* local_err was freed, do not reuse it. */
> +        local_err = NULL;
> +        result = 1;
>      }
> -
> -    QTAILQ_REMOVE(&g->reslist, res, next);
> -    g_free(res);
> +    CHECK(!result, cmd);
>  }
>
>  static void
> @@ -1099,7 +1122,7 @@ static void
> virtio_gpu_rutabaga_class_init(ObjectClass *klass, void *data)
>      vgc->handle_ctrl = virtio_gpu_rutabaga_handle_ctrl;
>      vgc->process_cmd = virtio_gpu_rutabaga_process_cmd;
>      vgc->update_cursor_data = virtio_gpu_rutabaga_update_cursor;
> -
> +    vgc->resource_destroy = virtio_gpu_rutabaga_resource_unref;
>      vdc->realize = virtio_gpu_rutabaga_realize;
>      device_class_set_props(dc, virtio_gpu_rutabaga_properties);
>  }
> --
> γαῖα πυρί μιχθήτω
>
>

[-- Attachment #2: Type: text/html, Size: 4869 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-01-31  3:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-30 14:59 [PATCH v3 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
2024-01-30 14:59 ` [PATCH v3 1/3] hw/display/virtio-gpu.c: use reset_bh class method Manos Pitsidianakis
2024-01-30 14:59 ` [PATCH v3 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
2024-01-30 14:59 ` [PATCH v3 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
2024-01-31  3:09   ` Gurchetan Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).