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

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.

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 | 51 ++++++++++++++++++++++++--------
 hw/display/virtio-gpu.c          | 27 ++++++++++++++---
 3 files changed, 65 insertions(+), 16 deletions(-)


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



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

* [PATCH v2 1/3] hw/display/virtio-gpu.c: use reset_bh class method
  2024-01-29 15:45 [PATCH v2 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
@ 2024-01-29 15:45 ` Manos Pitsidianakis
  2024-01-29 15:45 ` [PATCH v2 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
  2024-01-29 15:45 ` [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
  2 siblings, 0 replies; 11+ messages in thread
From: Manos Pitsidianakis @ 2024-01-29 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross,
	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] 11+ messages in thread

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

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.

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] 11+ messages in thread

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

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 | 51 ++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
index 9e67f9bd51..6ac0776005 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -148,14 +148,42 @@ 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;
+    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) ? : "");
+        }
+    }
+
+    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 +192,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 +1126,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] 11+ messages in thread

* Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-29 15:45 ` [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
@ 2024-01-30  1:26   ` Gurchetan Singh
  2024-01-30  6:53     ` Manos Pitsidianakis
  2024-01-30 12:50   ` Marc-André Lureau
  1 sibling, 1 reply; 11+ messages in thread
From: Gurchetan Singh @ 2024-01-30  1:26 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: qemu-devel, Marc-André Lureau, Philippe Mathieu-Daudé,
	Gerd Hoffmann, Michael S. Tsirkin, Alyssa Ross

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

On Mon, Jan 29, 2024 at 7:46 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.
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
>  1 file changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-rutabaga.c
> b/hw/display/virtio-gpu-rutabaga.c
> index 9e67f9bd51..6ac0776005 100644
> --- a/hw/display/virtio-gpu-rutabaga.c
> +++ b/hw/display/virtio-gpu-rutabaga.c
> @@ -148,14 +148,42 @@ 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;
> +    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) ? :
> "");
> +        }
>

Can't we rely on virtio_gpu_rutabaga_debug_cb(..) to report an error when
the resource ID is not found?



> +    }
> +
> +    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 +192,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 +1126,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: 4967 bytes --]

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

* Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-30  1:26   ` Gurchetan Singh
@ 2024-01-30  6:53     ` Manos Pitsidianakis
  0 siblings, 0 replies; 11+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30  6:53 UTC (permalink / raw)
  To: Gurchetan Singh
  Cc: qemu-devel, Marc-André Lureau, Philippe Mathieu-Daudé ,
	Gerd Hoffmann, Michael S. Tsirkin, Alyssa Ross

On Tue, 30 Jan 2024 03:26, Gurchetan Singh <gurchetansingh@chromium.org> wrote:
>On Mon, Jan 29, 2024 at 7:46 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.
>>
>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> ---
>>  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
>>  1 file changed, 39 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/display/virtio-gpu-rutabaga.c
>> b/hw/display/virtio-gpu-rutabaga.c
>> index 9e67f9bd51..6ac0776005 100644
>> --- a/hw/display/virtio-gpu-rutabaga.c
>> +++ b/hw/display/virtio-gpu-rutabaga.c
>> @@ -148,14 +148,42 @@ 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;
>> +    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) ? :
>> "");
>> +        }
>>
>
>Can't we rely on virtio_gpu_rutabaga_debug_cb(..) to report an error when
>the resource ID is not found?


IIUC that callback is called from the external library, and uses its own 
type (const struct rutabaga *debug) which is not how the interface works 
here. rutabaga_resource_unref() returns an int32_t. Besides this isn't a 
debug print but an error print.

>
>> +    }
>> +
>> +    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 +192,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 +1126,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	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 2/3] virtio-gpu.c: add resource_destroy class method
  2024-01-29 15:45 ` [PATCH v2 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
@ 2024-01-30 12:46   ` Marc-André Lureau
  0 siblings, 0 replies; 11+ messages in thread
From: Marc-André Lureau @ 2024-01-30 12:46 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: qemu-devel, Philippe Mathieu-Daudé, Gerd Hoffmann,
	Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross

Hi

On Mon, Jan 29, 2024 at 7:46 PM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> 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.
>
> 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);

&error_fatal would be better.

>  }
>
>  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;
> --
> γαῖα πυρί μιχθήτω
>

otherwise,
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

-- 
Marc-André Lureau


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

* Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-29 15:45 ` [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
  2024-01-30  1:26   ` Gurchetan Singh
@ 2024-01-30 12:50   ` Marc-André Lureau
  2024-01-30 13:01     ` Manos Pitsidianakis
  1 sibling, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2024-01-30 12:50 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: qemu-devel, Philippe Mathieu-Daudé, Gerd Hoffmann,
	Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross

Hi

On Mon, Jan 29, 2024 at 7:46 PM 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.
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
>  1 file changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
> index 9e67f9bd51..6ac0776005 100644
> --- a/hw/display/virtio-gpu-rutabaga.c
> +++ b/hw/display/virtio-gpu-rutabaga.c
> @@ -148,14 +148,42 @@ 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;
> +    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) ? : "");
> +        }
> +    }

There is error_setg_errno()

> +
> +    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 +192,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 +1126,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);
>  }
> --
> γαῖα πυρί μιχθήτω
>


-- 
Marc-André Lureau


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

* Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-30 12:50   ` Marc-André Lureau
@ 2024-01-30 13:01     ` Manos Pitsidianakis
  2024-01-30 13:09       ` Marc-André Lureau
  0 siblings, 1 reply; 11+ messages in thread
From: Manos Pitsidianakis @ 2024-01-30 13:01 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Gerd Hoffmann,
	Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross

On Tue, 30 Jan 2024 at 14:50, Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
>
> Hi
>
> On Mon, Jan 29, 2024 at 7:46 PM 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.
> >
> > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > ---
> >  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
> >  1 file changed, 39 insertions(+), 12 deletions(-)
> >
> > diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
> > index 9e67f9bd51..6ac0776005 100644
> > --- a/hw/display/virtio-gpu-rutabaga.c
> > +++ b/hw/display/virtio-gpu-rutabaga.c
> > @@ -148,14 +148,42 @@ 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;
> > +    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) ? : "");
> > +        }
> > +    }
>
> There is error_setg_errno()

I did not use it on purpose because I was not certain if rutabaga_gfx
starts using other error numbers in the future. I don't like my
approach but I don't like assuming it's an errno either to be
honest... Which one seems better to you?

Thanks,
Manos

> > +
> > +    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 +192,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 +1126,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);
> >  }
> > --
> > γαῖα πυρί μιχθήτω
> >
>
>
> --
> Marc-André Lureau


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

* Re: [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method
  2024-01-30 13:01     ` Manos Pitsidianakis
@ 2024-01-30 13:09       ` Marc-André Lureau
  2024-01-30 13:50         ` Manos Pitsidianakis
  0 siblings, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2024-01-30 13:09 UTC (permalink / raw)
  To: Manos Pitsidianakis
  Cc: qemu-devel, Philippe Mathieu-Daudé, Gerd Hoffmann,
	Michael S. Tsirkin, Gurchetan Singh, Alyssa Ross

Hi

On Tue, Jan 30, 2024 at 5:01 PM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> On Tue, 30 Jan 2024 at 14:50, Marc-André Lureau
> <marcandre.lureau@gmail.com> wrote:
> >
> > Hi
> >
> > On Mon, Jan 29, 2024 at 7:46 PM 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.
> > >
> > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > > ---
> > >  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
> > >  1 file changed, 39 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
> > > index 9e67f9bd51..6ac0776005 100644
> > > --- a/hw/display/virtio-gpu-rutabaga.c
> > > +++ b/hw/display/virtio-gpu-rutabaga.c
> > > @@ -148,14 +148,42 @@ 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;
> > > +    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) ? : "");
> > > +        }
> > > +    }
> >
> > There is error_setg_errno()
>
> I did not use it on purpose because I was not certain if rutabaga_gfx
> starts using other error numbers in the future. I don't like my
> approach but I don't like assuming it's an errno either to be
> honest... Which one seems better to you?
>

In that case, don't use strerrordesc_np() either :)

I think we can assume they will keep using errno though, unless they
clearly communicate this and break API, which seems unlikely to me.

> Thanks,
> Manos
>
> > > +
> > > +    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 +192,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 +1126,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);
> > >  }
> > > --
> > > γαῖα πυρί μιχθήτω
> > >
> >
> >
> > --
> > Marc-André Lureau



-- 
Marc-André Lureau


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

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

On Tue, 30 Jan 2024 at 15:10, Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
>
> Hi
>
> On Tue, Jan 30, 2024 at 5:01 PM Manos Pitsidianakis
> <manos.pitsidianakis@linaro.org> wrote:
> >
> > On Tue, 30 Jan 2024 at 14:50, Marc-André Lureau
> > <marcandre.lureau@gmail.com> wrote:
> > >
> > > Hi
> > >
> > > On Mon, Jan 29, 2024 at 7:46 PM 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.
> > > >
> > > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > > > ---
> > > >  hw/display/virtio-gpu-rutabaga.c | 51 ++++++++++++++++++++++++--------
> > > >  1 file changed, 39 insertions(+), 12 deletions(-)
> > > >
> > > > diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
> > > > index 9e67f9bd51..6ac0776005 100644
> > > > --- a/hw/display/virtio-gpu-rutabaga.c
> > > > +++ b/hw/display/virtio-gpu-rutabaga.c
> > > > @@ -148,14 +148,42 @@ 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;
> > > > +    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) ? : "");
> > > > +        }
> > > > +    }
> > >
> > > There is error_setg_errno()
> >
> > I did not use it on purpose because I was not certain if rutabaga_gfx
> > starts using other error numbers in the future. I don't like my
> > approach but I don't like assuming it's an errno either to be
> > honest... Which one seems better to you?
> >
>
> In that case, don't use strerrordesc_np() either :)

strerrordesc_np will be valid if strerrorname_np() does not return NULL.

> I think we can assume they will keep using errno though, unless they
> clearly communicate this and break API, which seems unlikely to me.

I will use error_setg_errno then, thanks!

Manos

> > Thanks,
> > Manos
> >
> > > > +
> > > > +    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 +192,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 +1126,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);
> > > >  }
> > > > --
> > > > γαῖα πυρί μιχθήτω
> > > >
> > >
> > >
> > > --
> > > Marc-André Lureau
>
>
>
> --
> Marc-André Lureau


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

end of thread, other threads:[~2024-01-30 13:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-29 15:45 [PATCH v2 0/3] Fix resource freeing bugs in virtio-gpu-rutabaga Manos Pitsidianakis
2024-01-29 15:45 ` [PATCH v2 1/3] hw/display/virtio-gpu.c: use reset_bh class method Manos Pitsidianakis
2024-01-29 15:45 ` [PATCH v2 2/3] virtio-gpu.c: add resource_destroy " Manos Pitsidianakis
2024-01-30 12:46   ` Marc-André Lureau
2024-01-29 15:45 ` [PATCH v2 3/3] virtio-gpu-rutabaga.c: override resource_destroy method Manos Pitsidianakis
2024-01-30  1:26   ` Gurchetan Singh
2024-01-30  6:53     ` Manos Pitsidianakis
2024-01-30 12:50   ` Marc-André Lureau
2024-01-30 13:01     ` Manos Pitsidianakis
2024-01-30 13:09       ` Marc-André Lureau
2024-01-30 13:50         ` Manos Pitsidianakis

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).