[PATCH v2] hw: fix memory leak in IRQState allocation

Matheus Tavares Bernardino posted 1 patch 2 months ago
hw/core/irq.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
[PATCH v2] hw: fix memory leak in IRQState allocation
Posted by Matheus Tavares Bernardino 2 months ago
At e72a7f65c1 (hw: Move declaration of IRQState to header and add init
function, 2024-06-29), we've changed qemu_allocate_irq() to use a
combination of g_new() + object_initialize() instead of
IRQ(object_new()). The latter sets obj->free, so that that the memory is
properly cleaned when the object is finalized, but the former doesn't.

Fixes: e72a7f65c1 (hw: Move declaration of IRQState to header and add init function)
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
---
In v2: adjusted function init_irq_fields name to reflect it is not
public and added BALATON's Reviewed-by

 hw/core/irq.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index db95ffc18f..7d5b0038c1 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -34,13 +34,19 @@ void qemu_set_irq(qemu_irq irq, int level)
     irq->handler(irq->opaque, irq->n, level);
 }
 
+static void init_irq_fields(IRQState *irq, qemu_irq_handler handler,
+                            void *opaque, int n)
+{
+    irq->handler = handler;
+    irq->opaque = opaque;
+    irq->n = n;
+}
+
 void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
                    int n)
 {
     object_initialize(irq, sizeof(*irq), TYPE_IRQ);
-    irq->handler = handler;
-    irq->opaque = opaque;
-    irq->n = n;
+    init_irq_fields(irq, handler, opaque, n);
 }
 
 qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
@@ -66,11 +72,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
 
 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
 {
-    IRQState *irq;
-
-    irq = g_new(IRQState, 1);
-    qemu_init_irq(irq, handler, opaque, n);
-
+    IRQState *irq = IRQ(object_new(TYPE_IRQ));
+    init_irq_fields(irq, handler, opaque, n);
     return irq;
 }
 
-- 
2.37.2
Re: [PATCH v2] hw: fix memory leak in IRQState allocation
Posted by Peter Maydell 1 month, 3 weeks ago
On Wed, 18 Sept 2024 at 16:44, Matheus Tavares Bernardino
<quic_mathbern@quicinc.com> wrote:
>
> At e72a7f65c1 (hw: Move declaration of IRQState to header and add init
> function, 2024-06-29), we've changed qemu_allocate_irq() to use a
> combination of g_new() + object_initialize() instead of
> IRQ(object_new()). The latter sets obj->free, so that that the memory is
> properly cleaned when the object is finalized, but the former doesn't.
>
> Fixes: e72a7f65c1 (hw: Move declaration of IRQState to header and add init function)
> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
> Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> In v2: adjusted function init_irq_fields name to reflect it is not
> public and added BALATON's Reviewed-by

I'll pick this one up via target-arm.next, unless anybody
would prefer it to go via some other route.

thanks
-- PMM
Re: [PATCH v2] hw: fix memory leak in IRQState allocation
Posted by Brian Cain 2 months ago
On 9/18/2024 10:43 AM, Matheus Tavares Bernardino wrote:
> At e72a7f65c1 (hw: Move declaration of IRQState to header and add init
> function, 2024-06-29), we've changed qemu_allocate_irq() to use a
> combination of g_new() + object_initialize() instead of
> IRQ(object_new()). The latter sets obj->free, so that that the memory is
> properly cleaned when the object is finalized, but the former doesn't.
>
> Fixes: e72a7f65c1 (hw: Move declaration of IRQState to header and add init function)
> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
> Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
Reviewed-by: Brian Cain <bcain@quicinc.com>
> In v2: adjusted function init_irq_fields name to reflect it is not
> public and added BALATON's Reviewed-by
>
>   hw/core/irq.c | 19 +++++++++++--------
>   1 file changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index db95ffc18f..7d5b0038c1 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -34,13 +34,19 @@ void qemu_set_irq(qemu_irq irq, int level)
>       irq->handler(irq->opaque, irq->n, level);
>   }
>   
> +static void init_irq_fields(IRQState *irq, qemu_irq_handler handler,
> +                            void *opaque, int n)
> +{
> +    irq->handler = handler;
> +    irq->opaque = opaque;
> +    irq->n = n;
> +}
> +
>   void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
>                      int n)
>   {
>       object_initialize(irq, sizeof(*irq), TYPE_IRQ);
> -    irq->handler = handler;
> -    irq->opaque = opaque;
> -    irq->n = n;
> +    init_irq_fields(irq, handler, opaque, n);
>   }
>   
>   qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
> @@ -66,11 +72,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
>   
>   qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
>   {
> -    IRQState *irq;
> -
> -    irq = g_new(IRQState, 1);
> -    qemu_init_irq(irq, handler, opaque, n);
> -
> +    IRQState *irq = IRQ(object_new(TYPE_IRQ));
> +    init_irq_fields(irq, handler, opaque, n);
>       return irq;
>   }
>