Skip to contentSkip to conversation

agp/uninorth: fix a memleak in create_gatt_table

PATCH Applied Denis Kirjanov 3 participants 9 messages Jun 12, 2015 – Oct 12, 2015 Agpgart driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 agp/uninorth: fix a memleak in create_gatt_table

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

---
 drivers/char/agp/uninorth-agp.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/char/agp/uninorth-agp.c +10 -6
index a56ee9b..0575544 100644
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
+static struct {
+	struct page **pages_arr;
+} uninorth_priv;
+
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
 	char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	int i;
 	void *temp;
 	struct page *page;
-	struct page **pages;
 
 	/* We can't handle 2 level gatt's */
 	if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	if (table == NULL)
 		return -ENOMEM;
 
-	pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
-	if (pages == NULL)
+	uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
+	if (uninorth_priv.pages_arr == NULL)
 		goto enomem;
 
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
 	     page++, i++) {
 		SetPageReserved(page);
-		pages[i] = page;
+		uninorth_priv.pages_arr[i] = page;
 	}
 
 	bridge->gatt_table_real = (u32 *) table;
 	/* Need to clear out any dirty data still sitting in caches */
 	flush_dcache_range((unsigned long)table,
 			   (unsigned long)table_end + 1);
-	bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
+	bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0, PAGE_KERNEL_NCG);
 
 	if (bridge->gatt_table == NULL)
 		goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	return 0;
 
 enomem:
-	kfree(pages);
+	kfree(uninorth_priv.pages_arr);
 	if (table)
 		free_pages((unsigned long)table, page_order);
 	return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
 	 */
 
 	vunmap(bridge->gatt_table);
+	kfree(uninorth_priv.pages_arr);
 	table = (char *) bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
Signature · 1 line
2.4.0
#1 lore raw
Quoted 5 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

Thanks

Quoted 84 lines
---
 drivers/char/agp/uninorth-agp.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/char/agp/uninorth-agp.c +4 -1
index a56ee9b..0575544 100644
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
+static struct {
+	struct page **pages_arr;
+} uninorth_priv;
+
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
 	char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	int i;
 	void *temp;
 	struct page *page;
-	struct page **pages;
 
 	/* We can't handle 2 level gatt's */
drivers/char/agp/uninorth-agp.c +2 -2
 	if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	if (table == NULL)
 		return -ENOMEM;
 
-	pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
-	if (pages == NULL)
+	uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct
 page*), GFP_KERNEL);
+	if (uninorth_priv.pages_arr == NULL)
 		goto enomem;
drivers/char/agp/uninorth-agp.c +2 -2
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
 	     page++, i++) {
 		SetPageReserved(page);
-		pages[i] = page;
+		uninorth_priv.pages_arr[i] = page;
 	}
 
 	bridge->gatt_table_real = (u32 *) table;
 	/* Need to clear out any dirty data still sitting in caches */
 	flush_dcache_range((unsigned long)table,
 			   (unsigned long)table_end + 1);
-	bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
+	bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0,
 PAGE_KERNEL_NCG);
 
drivers/char/agp/uninorth-agp.c +1 -1
 	if (bridge->gatt_table == NULL)
 		goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	return 0;
 
 enomem:
-	kfree(pages);
+	kfree(uninorth_priv.pages_arr);
 	if (table)
 		free_pages((unsigned long)table, page_order);
drivers/char/agp/uninorth-agp.c +1 -1
 	return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct
 agp_bridge_data *bridge)
 	 */
 
 	vunmap(bridge->gatt_table);
+	kfree(uninorth_priv.pages_arr);
 	table = (char *) bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
--

2.4.0

#2 lore raw
Quoted 11 lines · Denis Kirjanov
Quoted 5 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

I haven't had a chance to review yet...

Ben.

Quoted 85 lines

Thanks

Quoted 84 lines
---
 drivers/char/agp/uninorth-agp.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/char/agp/uninorth-agp.c +4 -1
index a56ee9b..0575544 100644
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
+static struct {
+	struct page **pages_arr;
+} uninorth_priv;
+
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
 	char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	int i;
 	void *temp;
 	struct page *page;
-	struct page **pages;
 
 	/* We can't handle 2 level gatt's */
drivers/char/agp/uninorth-agp.c +2 -2
 	if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	if (table == NULL)
 		return -ENOMEM;
 
-	pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
-	if (pages == NULL)
+	uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct
 page*), GFP_KERNEL);
+	if (uninorth_priv.pages_arr == NULL)
 		goto enomem;
drivers/char/agp/uninorth-agp.c +2 -2
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
 	     page++, i++) {
 		SetPageReserved(page);
-		pages[i] = page;
+		uninorth_priv.pages_arr[i] = page;
 	}
 
 	bridge->gatt_table_real = (u32 *) table;
 	/* Need to clear out any dirty data still sitting in caches */
 	flush_dcache_range((unsigned long)table,
 			   (unsigned long)table_end + 1);
-	bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
+	bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0,
 PAGE_KERNEL_NCG);
 
drivers/char/agp/uninorth-agp.c +1 -1
 	if (bridge->gatt_table == NULL)
 		goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	return 0;
 
 enomem:
-	kfree(pages);
+	kfree(uninorth_priv.pages_arr);
 	if (table)
 		free_pages((unsigned long)table, page_order);
drivers/char/agp/uninorth-agp.c +1 -1
 	return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct
 agp_bridge_data *bridge)
 	 */
 
 	vunmap(bridge->gatt_table);
+	kfree(uninorth_priv.pages_arr);
 	table = (char *) bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
--

2.4.0

#3 lore raw
Quoted 6 lines · Benjamin Herrenschmidt
Quoted 5 lines · Denis Kirjanov
Quoted 4 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

I haven't had a chance to review yet...

Ping...

Quoted 96 lines

Ben.

Quoted 90 lines

Thanks

Quoted 89 lines
---
 drivers/char/agp/uninorth-agp.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/char/agp/uninorth-agp.c +4 -0
index a56ee9b..0575544 100644
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev
 *pdev)
 }
 #endif /* CONFIG_PM */
 
+static struct {
+	struct page **pages_arr;
+} uninorth_priv;
+
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
drivers/char/agp/uninorth-agp.c +0 -1
 	char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	int i;
 	void *temp;
 	struct page *page;
-	struct page **pages;
 
 	/* We can't handle 2 level gatt's */
drivers/char/agp/uninorth-agp.c +2 -2
 	if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	if (table == NULL)
 		return -ENOMEM;
 
-	pages = kmalloc((1 << page_order) * sizeof(struct page*),
 GFP_KERNEL);
-	if (pages == NULL)
+	uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct
 page*), GFP_KERNEL);
+	if (uninorth_priv.pages_arr == NULL)
drivers/char/agp/uninorth-agp.c +2 -2
 		goto enomem;
 
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	for (page = virt_to_page(table), i = 0; page <=
 virt_to_page(table_end);
 	     page++, i++) {
 		SetPageReserved(page);
-		pages[i] = page;
+		uninorth_priv.pages_arr[i] = page;
 	}
 
 	bridge->gatt_table_real = (u32 *) table;
 	/* Need to clear out any dirty data still sitting in caches */
 	flush_dcache_range((unsigned long)table,
 			   (unsigned long)table_end + 1);
-	bridge->gatt_table = vmap(pages, (1 << page_order), 0,
 PAGE_KERNEL_NCG);
+	bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order),

0,
PAGE_KERNEL_NCG);

drivers/char/agp/uninorth-agp.c +1 -1
 	if (bridge->gatt_table == NULL)
 		goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct
 agp_bridge_data *bridge)
 	return 0;
 
 enomem:
-	kfree(pages);
+	kfree(uninorth_priv.pages_arr);
 	if (table)
 		free_pages((unsigned long)table, page_order);
drivers/char/agp/uninorth-agp.c +1 -1
 	return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct
 agp_bridge_data *bridge)
 	 */
 
 	vunmap(bridge->gatt_table);
+	kfree(uninorth_priv.pages_arr);
 	table = (char *) bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
--

2.4.0

#4 lore raw
Quoted 9 lines · Denis Kirjanov
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 7 lines · Denis Kirjanov
Quoted 5 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

I haven't had a chance to review yet...

Ping...

Hi Denis,

Have you built and/or boot tested this?

cheers

#5 lore raw
Quoted 15 lines · Michael Ellerman
Quoted 14 lines · Denis Kirjanov
Quoted 13 lines · Benjamin Herrenschmidt
Quoted 11 lines · Denis Kirjanov
Quoted 5 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

I haven't had a chance to review yet...

Ping...

Hi Denis,

Have you built and/or boot tested this?

Hi,

yes, sure. Actually I've spotted this through the kmemleak. With the patch applied scanner is happy :)

Quoted 4 lines

cheers

#6 lore raw
Quoted 20 lines · Denis Kirjanov
Quoted 19 lines · Michael Ellerman
Quoted 17 lines · Denis Kirjanov
Quoted 6 lines · Benjamin Herrenschmidt
Quoted 5 lines · Denis Kirjanov
Quoted 4 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

Hi Ben, Michael

Will you take the patch through your trees or do I need to send it to Dave Airlie?

I haven't had a chance to review yet...

Ping...

Quoted 8 lines
Quoted 3 lines

Hi Denis,

Have you built and/or boot tested this?

Hi,

yes, sure. Actually I've spotted this through the kmemleak. With the patch applied scanner is happy :)

OK thanks. I'll merge it then, and if Ben ever reviews it and dislikes your changes he can send patches to fix it :)

cheers

#7 lore raw
Quoted 26 lines · Michael Ellerman
Quoted 25 lines · Denis Kirjanov
Quoted 23 lines · Michael Ellerman
Quoted 11 lines · Denis Kirjanov
Quoted 10 lines · Benjamin Herrenschmidt
Quoted 9 lines · Denis Kirjanov
Quoted 5 lines · Denis Kirjanov

Fix the memory leak in create_gatt_table:
we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table

Hi Ben, Michael

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

Will you take the patch through your trees or do I need to send it to
Dave Airlie?

I haven't had a chance to review yet...

Ping...

Hi Denis,

Have you built and/or boot tested this?

Quoted 7 lines
Quoted 4 lines

Hi,

yes, sure. Actually I've spotted this through the kmemleak. With the patch applied scanner is happy :)

OK thanks. I'll merge it then, and if Ben ever reviews it and dislikes your changes he can send patches to fix it :)

Hi Michael,
could you please apply the patch to fixes branch?

Thanks!

Quoted 5 lines

cheers