Skip to content

Commit ac8f29a

Browse files
jgunthorpeKAGA-KOKO
authored andcommitted
genirq/msi: Free the fwnode created by msi_create_device_irq_domain()
msi_create_device_irq_domain() creates a firmware node for the new domain, which is never freed. kmemleak reports: unreferenced object 0xffff888120ba9a00 (size 96): comm "systemd-modules", pid 221, jiffies 4294893411 (age 635.732s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 e0 19 8b 83 ff ff ff ff ................ 00 00 00 00 00 00 00 00 18 9a ba 20 81 88 ff ff ........... .... backtrace: [<000000008cdbc98d>] __irq_domain_alloc_fwnode+0x51/0x2b0 [<00000000c57acf9d>] msi_create_device_irq_domain+0x283/0x670 [<000000009b567982>] __pci_enable_msix_range+0x49e/0xdb0 [<0000000077cc1445>] pci_alloc_irq_vectors_affinity+0x11f/0x1c0 [<00000000532e9ef5>] mlx5_irq_table_create+0x24c/0x940 [mlx5_core] [<00000000fabd2b80>] mlx5_load+0x1fa/0x680 [mlx5_core] [<000000006bb22ae4>] mlx5_init_one+0x485/0x670 [mlx5_core] [<00000000eaa5e1ad>] probe_one+0x4c2/0x720 [mlx5_core] [<00000000df8efb43>] local_pci_probe+0xd6/0x170 [<0000000085cb9924>] pci_device_probe+0x231/0x6e0 Use the proper free operation for the firmware wnode so the name is freed during error unwind of msi_create_device_irq_domain() and also free the node in msi_remove_device_irq_domain() if it was automatically allocated. To avoid extra NULL pointer checks make irq_domain_free_fwnode() tolerant of NULL. Fixes: 27a6dea ("genirq/msi: Provide msi_create/free_device_irq_domain()") Reported-by: Omri Barazi <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Kalle Valo <[email protected]> Tested-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5dc4c99 commit ac8f29a

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

kernel/irq/irqdomain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
114114
{
115115
struct irqchip_fwid *fwid;
116116

117-
if (WARN_ON(!is_fwnode_irqchip(fwnode)))
117+
if (!fwnode || WARN_ON(!is_fwnode_irqchip(fwnode)))
118118
return;
119119

120120
fwid = container_of(fwnode, struct irqchip_fwid, fwnode);

kernel/irq/msi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
10001000
fail:
10011001
msi_unlock_descs(dev);
10021002
free_fwnode:
1003-
kfree(fwnode);
1003+
irq_domain_free_fwnode(fwnode);
10041004
free_bundle:
10051005
kfree(bundle);
10061006
return false;
@@ -1013,6 +1013,7 @@ bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
10131013
*/
10141014
void msi_remove_device_irq_domain(struct device *dev, unsigned int domid)
10151015
{
1016+
struct fwnode_handle *fwnode = NULL;
10161017
struct msi_domain_info *info;
10171018
struct irq_domain *domain;
10181019

@@ -1025,7 +1026,10 @@ void msi_remove_device_irq_domain(struct device *dev, unsigned int domid)
10251026

10261027
dev->msi.data->__domains[domid].domain = NULL;
10271028
info = domain->host_data;
1029+
if (irq_domain_is_msi_device(domain))
1030+
fwnode = domain->fwnode;
10281031
irq_domain_remove(domain);
1032+
irq_domain_free_fwnode(fwnode);
10291033
kfree(container_of(info, struct msi_domain_template, info));
10301034

10311035
unlock:

0 commit comments

Comments
 (0)