Skip to contentSkip to conversation

clk: mvebu/clk-cpu.c: fix memory leakage

PATCH Superseded Cong Ding 4 participants 14 messages Jan 14, 2013 – Jan 23, 2013

Subsystems (2)
lore
Share & tools
lore

Cong Ding

author
#0 lore raw

PATCH 1/1 clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed.

---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +6 -3
index ff004578..1a0d84f 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto clk_name_out;
 
 		err = of_property_read_u32(dn, "reg", &cpu);
 		if (WARN_ON(err))
-			return;
+			goto bail_out;
 
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -166,7 +166,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	return;
 bail_out:
+	kfree(clk_name);
+clk_name_out:
 	kfree(clks);
+clks_out:
 	kfree(cpuclk);
 }
 
Signature · 1 line
1.7.9.5
#1 lore raw

Dear Cong Ding,

Quoted 2 lines · Cong Ding

the variable cpuclk and clk_name should be properly freed.

Thanks for reporting this memory leak and for your patch but I think we could do even better, see below:

Quoted 19 lines
---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +1 -1
index ff004578..1a0d84f 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 137

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +1 -1
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto clk_name_out;

I agree

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 141

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +1 -1
 		err = of_property_read_u32(dn, "reg", &cpu);
 		if (WARN_ON(err))
-			return;
+			goto bail_out;

I agree

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 169

Quoted 8 lines
drivers/clk/mvebu/clk-cpu.c +1 -0
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -166,7 +166,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	return;
 bail_out:
+	kfree(clk_name);

Here you free only one clk_name whereas we could have previous clk_name which have been already allocated during the for_each_node_by_type loop.

A more annoying thing is that you use clk_name whereas it is only valid in the for_each_node_by_type statement and then this patch breaks the compilation:

drivers/clk/mvebu/clk-cpu.c: In function ?of_cpu_clk_setup?:
drivers/clk/mvebu/clk-cpu.c:169:8: error: ?clk_name? undeclared (first use in this function) drivers/clk/mvebu/clk-cpu.c:169:8: note: each undeclared identifier is reported only once for each function it appears in

Thanks,

Gregory

author
#2 lore raw
Quoted 56 lines · Gregory CLEMENT

Dear Cong Ding,

Quoted 2 lines · Cong Ding

the variable cpuclk and clk_name should be properly freed.

Thanks for reporting this memory leak and for your patch but I think we could do even better, see below:

Quoted 19 lines
---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +1 -1
index ff004578..1a0d84f 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 137

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +1 -1
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto clk_name_out;

I agree

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 141

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +1 -1
 		err = of_property_read_u32(dn, "reg", &cpu);
 		if (WARN_ON(err))
-			return;
+			goto bail_out;

I agree

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 169

Quoted 8 lines
drivers/clk/mvebu/clk-cpu.c +1 -0
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -166,7 +166,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	return;
 bail_out:
+	kfree(clk_name);

Here you free only one clk_name whereas we could have previous clk_name which have been already allocated during the for_each_node_by_type loop.

Quoted 6 lines

A more annoying thing is that you use clk_name whereas it is only valid in the for_each_node_by_type statement and then this patch breaks the compilation:

drivers/clk/mvebu/clk-cpu.c: In function ?of_cpu_clk_setup?:
drivers/clk/mvebu/clk-cpu.c:169:8: error: ?clk_name? undeclared (first use in this function) drivers/clk/mvebu/clk-cpu.c:169:8: note: each undeclared identifier is reported only once for each function it appears in

sorry for the mistake, I am sending version 2.

thanks,
- cong

author
#3 lore raw

PATCH v2 1/1 clk: mvebu/clk-cpu.c: fix memory leakage

In reply to Gregory CLEMENT
Quoted 1 line

From 75c73077905b822be6e8a32a09d6b0cdb5e61763 Mon Sep 17 00:00:00 2001

From: Cong Ding <[email protected]>
Date: Mon, 14 Jan 2013 18:06:26 +0100
Subject: [PATCH v2] clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/mvebu/clk-cpu.c +10 -5
index ff004578..1066a43 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,13 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
 		err = of_property_read_u32(dn, "reg", &cpu);
-		if (WARN_ON(err))
-			return;
+		if (WARN_ON(err)) {
+			kfree(clk_name);
+			goto bail_out;
+		}
 
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -156,8 +158,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		init.num_parents = 1;
 
 		clk = clk_register(NULL, &cpuclk[cpu].hw);
-		if (WARN_ON(IS_ERR(clk)))
+		if (WARN_ON(IS_ERR(clk))) {
+			kfree(clk_name);
 			goto bail_out;
+		}
 		clks[cpu] = clk;
 	}
 	clk_data.clk_num = MAX_CPU;
@@ -167,6 +171,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+clks_out:
 	kfree(cpuclk);
 }
 
Signature · 1 line
1.7.9.5
Acked-by on v2 1/1
#4 lore raw

Mike,

Quoted 11 lines · Cong Ding

From 75c73077905b822be6e8a32a09d6b0cdb5e61763 Mon Sep 17 00:00:00 2001
From: Cong Ding <[email protected]>
Date: Mon, 14 Jan 2013 18:06:26 +0100
Subject: [PATCH v2] clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Do you want to take this fix through the clock tree? If so,

Otherwise, just let me know.

thx,

Jason.

Quoted 58 lines
drivers/clk/mvebu/clk-cpu.c +10 -5
index ff004578..1066a43 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,13 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
 		err = of_property_read_u32(dn, "reg", &cpu);
-		if (WARN_ON(err))
-			return;
+		if (WARN_ON(err)) {
+			kfree(clk_name);
+			goto bail_out;
+		}
 
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -156,8 +158,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		init.num_parents = 1;
 
 		clk = clk_register(NULL, &cpuclk[cpu].hw);
-		if (WARN_ON(IS_ERR(clk)))
+		if (WARN_ON(IS_ERR(clk))) {
+			kfree(clk_name);
 			goto bail_out;
+		}
 		clks[cpu] = clk;
 	}
 	clk_data.clk_num = MAX_CPU;
@@ -167,6 +171,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+clks_out:
 	kfree(cpuclk);
 }
 
Signature · 7 lines
1.7.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
#5 lore raw
Quoted 16 lines · Jason Cooper

Mike,

Quoted 11 lines · Cong Ding

From 75c73077905b822be6e8a32a09d6b0cdb5e61763 Mon Sep 17 00:00:00 2001
From: Cong Ding <[email protected]>
Date: Mon, 14 Jan 2013 18:06:26 +0100
Subject: [PATCH v2] clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
Quoted 4 lines

Do you want to take this fix through the clock tree? If so,

I also think it should go through the clock tree but before this I'd like we fix the last issue.

Cong Ding,

you didn't take in account the case when the allocation of the 1st clocks when the 2nd cpu clock failed. In this case there is still a memory leak with the clock_name of the first cpu clock. See below for my proposal:

Quoted 26 lines

Otherwise, just let me know.

thx,

Jason.

Quoted 20 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
index ff004578..1066a43 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,13 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
Quoted 6 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node)

Quoted 6 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
 		err = of_property_read_u32(dn, "reg", &cpu);
-		if (WARN_ON(err))
-			return;
+		if (WARN_ON(err)) {
 
+			kfree(clk_name);

we can free it later

Quoted 8 lines
Quoted 8 lines
drivers/clk/mvebu/clk-cpu.c +2 -0
+			goto bail_out;
+		}
 
 		sprintf(clk_name, "cpu%d", cpu);
drivers/clk/mvebu/clk-cpu.c +0 -0
 		parent_clk = of_clk_get(node, 0);
@@ -156,8 +158,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		init.num_parents = 1;
 
Quoted 5 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 162

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +2 -1
 		clk = clk_register(NULL, &cpuclk[cpu].hw);
-		if (WARN_ON(IS_ERR(clk)))
+		if (WARN_ON(IS_ERR(clk))) {
 
+			kfree(clk_name);

we can free it later

Quoted 10 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 174

Quoted 10 lines
drivers/clk/mvebu/clk-cpu.c +1 -0
 			goto bail_out;
+		}
 		clks[cpu] = clk;
 	}
drivers/clk/mvebu/clk-cpu.c +1 -0
 	clk_data.clk_num = MAX_CPU;
@@ -167,6 +171,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+clks_out:

as cpuclk is allocated with all its member set to 0, and kfree(0) is a valid call. We can add the following lines:

while(ncpus--)

	kfree(cpuclk[ncpus].clk_name);
Quoted 11 lines
Quoted 11 lines
drivers/clk/mvebu/clk-cpu.c +0 -0
 	kfree(cpuclk);
 }
 
Signature · 7 lines
1.7.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#6 lore raw
Quoted 94 lines · Gregory CLEMENT
Quoted 16 lines · Jason Cooper

Mike,

Quoted 11 lines · Cong Ding

From 75c73077905b822be6e8a32a09d6b0cdb5e61763 Mon Sep 17 00:00:00 2001
From: Cong Ding <[email protected]>
Date: Mon, 14 Jan 2013 18:06:26 +0100
Subject: [PATCH v2] clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
Quoted 4 lines

Do you want to take this fix through the clock tree? If so,

I also think it should go through the clock tree but before this I'd like we fix the last issue.

Cong Ding,

you didn't take in account the case when the allocation of the 1st clocks when the 2nd cpu clock failed. In this case there is still a memory leak with the clock_name of the first cpu clock. See below for my proposal:

Quoted 26 lines

Otherwise, just let me know.

thx,

Jason.

Quoted 20 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
index ff004578..1066a43 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,13 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
Quoted 6 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node)

Quoted 6 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
 		err = of_property_read_u32(dn, "reg", &cpu);
-		if (WARN_ON(err))
-			return;
+		if (WARN_ON(err)) {
 
+			kfree(clk_name);

we can free it later

Quoted 8 lines
Quoted 8 lines
drivers/clk/mvebu/clk-cpu.c +2 -0
+			goto bail_out;
+		}
 
 		sprintf(clk_name, "cpu%d", cpu);
drivers/clk/mvebu/clk-cpu.c +0 -0
 		parent_clk = of_clk_get(node, 0);
@@ -156,8 +158,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		init.num_parents = 1;
 
Quoted 5 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 162

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +2 -1
 		clk = clk_register(NULL, &cpuclk[cpu].hw);
-		if (WARN_ON(IS_ERR(clk)))
+		if (WARN_ON(IS_ERR(clk))) {
 
+			kfree(clk_name);

we can free it later

Quoted 10 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 174

Quoted 10 lines
drivers/clk/mvebu/clk-cpu.c +1 -0
 			goto bail_out;
+		}
 		clks[cpu] = clk;
 	}
drivers/clk/mvebu/clk-cpu.c +1 -0
 	clk_data.clk_num = MAX_CPU;
@@ -167,6 +171,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+clks_out:

as cpuclk is allocated with all its member set to 0, and kfree(0) is a valid call. We can add the following lines:
while(ncpus--)

Quoted 4 lines
	kfree(cpuclk[ncpus].clk_name);
Quoted 2 lines
Quoted 2 lines
drivers/clk/mvebu/clk-cpu.c +0 -0
 	kfree(cpuclk);
 }

I agree the version 2 patch still includes memory leakage in terms of clk_name, but I am wondering whether it is safe to call kfree(cpuclk[ncpus].clkname) directly or not. It's true that kfree(0) is valid, but cpuclk[ncpus].clkname might not be 0 when it is allocated by kzalloc. kzalloc just allocates the memory while doesn't ensure the initial value in this memory area is 0. So I am thinking we should call memset after the alloction or use a counter to remember the number of clk_names allocated?

- cong

#7 lore raw
Quoted 97 lines · Cong Ding
Quoted 96 lines · Gregory CLEMENT
Quoted 16 lines · Jason Cooper

Mike,

Quoted 11 lines · Cong Ding

From 75c73077905b822be6e8a32a09d6b0cdb5e61763 Mon Sep 17 00:00:00 2001
From: Cong Ding <[email protected]>
Date: Mon, 14 Jan 2013 18:06:26 +0100
Subject: [PATCH v2] clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
Quoted 4 lines

Do you want to take this fix through the clock tree? If so,

I also think it should go through the clock tree but before this I'd like we fix the last issue.

Cong Ding,

you didn't take in account the case when the allocation of the 1st clocks when the 2nd cpu clock failed. In this case there is still a memory leak with the clock_name of the first cpu clock. See below for my proposal:

Quoted 26 lines

Otherwise, just let me know.

thx,

Jason.

Quoted 20 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
index ff004578..1066a43 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,13 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
Quoted 6 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node)

Quoted 6 lines
drivers/clk/mvebu/clk-cpu.c +2 -2
 		err = of_property_read_u32(dn, "reg", &cpu);
-		if (WARN_ON(err))
-			return;
+		if (WARN_ON(err)) {
 
+			kfree(clk_name);

we can free it later

Quoted 8 lines
Quoted 8 lines
drivers/clk/mvebu/clk-cpu.c +2 -0
+			goto bail_out;
+		}
 
 		sprintf(clk_name, "cpu%d", cpu);
drivers/clk/mvebu/clk-cpu.c +0 -0
 		parent_clk = of_clk_get(node, 0);
@@ -156,8 +158,10 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		init.num_parents = 1;
 
Quoted 5 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 162

Quoted 5 lines
drivers/clk/mvebu/clk-cpu.c +2 -1
 		clk = clk_register(NULL, &cpuclk[cpu].hw);
-		if (WARN_ON(IS_ERR(clk)))
+		if (WARN_ON(IS_ERR(clk))) {
 
+			kfree(clk_name);

we can free it later

Quoted 10 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 174

Quoted 10 lines
drivers/clk/mvebu/clk-cpu.c +1 -0
 			goto bail_out;
+		}
 		clks[cpu] = clk;
 	}
drivers/clk/mvebu/clk-cpu.c +1 -0
 	clk_data.clk_num = MAX_CPU;
@@ -167,6 +171,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+clks_out:

as cpuclk is allocated with all its member set to 0, and kfree(0) is a valid call. We can add the following lines:
while(ncpus--)

	kfree(cpuclk[ncpus].clk_name);
Quoted 7 lines
Quoted 2 lines
Quoted 2 lines

drivers/clk/mvebu/clk-cpu.c void __init of_cpu_clk_setup(struct device_node *node) · line 176

Quoted 2 lines
drivers/clk/mvebu/clk-cpu.c +0 -0
 	kfree(cpuclk);
 }

I agree the version 2 patch still includes memory leakage in terms of clk_name, but I am wondering whether it is safe to call kfree(cpuclk[ncpus].clkname) directly or not. It's true that kfree(0) is valid, but cpuclk[ncpus].clkname might not be 0 when it is allocated by kzalloc. kzalloc just allocates the memory while doesn't ensure the initial value in this memory area is 0. So I

I think that you describe the behavior of kmalloc, but the main difference with kmalloc and kzalloc, is that kzalloc allocates _zeroed_ paged, so I am pretty sure that all the memory space allocated should be set to zero.

Quoted 5 lines

am thinking we should call memset after the alloction or use a counter to remember the number of clk_names allocated?

- cong

Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#8 lore raw

PATCH v3 1/1 clk: mvebu/clk-cpu.c: fix memory leakage

the variable cpuclk and clk_name should be properly freed when error happens.

---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +6 -3
index ff004578..9dd2551 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
 		err = of_property_read_u32(dn, "reg", &cpu);
 		if (WARN_ON(err))
-			return;
+			goto bail_out;
 
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -167,6 +167,9 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+	while(ncpus--)
+		kfree(cpuclk[ncpus].clk_name);
+clks_out:
 	kfree(cpuclk);
 }
 
Signature · 1 line
1.7.10.4
Acked-by on v3 1/1
#9 lore raw
Quoted 1 line · Cong Ding

the variable cpuclk and clk_name should be properly freed when error happens.

Dear Cong Ding,

Thanks for you efforts!
I am happy with this patch and I tested it on the Armada XP DB board, so you can now add my:

Mike,

could you take this patch for 3.8-rc fixes?

If you prefer, Jason agrees to take it, but you probably didn't notice it, because he uses your former(and no more valid) email when he wrote this.

Thanks,

Gregory

Quoted 45 lines
---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +6 -3
index ff004578..9dd2551 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
 	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
 	if (WARN_ON(!clks))
-		return;
+		goto clks_out;
 
 	for_each_node_by_type(dn, "cpu") {
 		struct clk_init_data init;
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
 		int cpu, err;
 
 		if (WARN_ON(!clk_name))
-			return;
+			goto bail_out;
 
 		err = of_property_read_u32(dn, "reg", &cpu);
 		if (WARN_ON(err))
-			return;
+			goto bail_out;
 
 		sprintf(clk_name, "cpu%d", cpu);
 		parent_clk = of_clk_get(node, 0);
@@ -167,6 +167,9 @@ void __init of_cpu_clk_setup(struct device_node *node)
 	return;
 bail_out:
 	kfree(clks);
+	while(ncpus--)
+		kfree(cpuclk[ncpus].clk_name);
+clks_out:
 	kfree(cpuclk);
 }
 
Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#10 lore raw
Quoted 2 lines · Gregory CLEMENT

If you prefer, Jason agrees to take it, but you probably didn't notice it, because he uses your former(and no more valid) email when he wrote this.

Actually, I caught that after I hit send. I resent (just to him), so he should have it in his inbox.

I've also updated my email alias accordingly.

thx,

Jason.

#11 lore raw
In reply to Gregory CLEMENT

Quoting Gregory CLEMENT (2013-01-15 12:46:03)

Quoted 8 lines · Cong Ding
Quoted 1 line

the variable cpuclk and clk_name should be properly freed when error happens.

Dear Cong Ding,

Thanks for you efforts!
I am happy with this patch and I tested it on the Armada XP DB board, so you can now add my:

Quoted 9 lines

Mike,

could you take this patch for 3.8-rc fixes?

If you prefer, Jason agrees to take it, but you probably didn't notice it, because he uses your former(and no more valid) email when he wrote this.

I don't have an existing clk-fixes branch. This patch is the first fix I've reviewed for this cycle. I'm happy if you want to take it and submit as part of any other mvebu fixes you have. Otherwise I can take it.

Let me know what you decide.

Thanks,
Mike

Quoted 56 lines

Thanks,

Gregory

Quoted 45 lines
---
 drivers/clk/mvebu/clk-cpu.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/mvebu/clk-cpu.c +6 -3
index ff004578..9dd2551 100644
@@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
      clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
      if (WARN_ON(!clks))
-             return;
+             goto clks_out;
 
      for_each_node_by_type(dn, "cpu") {
              struct clk_init_data init;
@@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)
              int cpu, err;
 
              if (WARN_ON(!clk_name))
-                     return;
+                     goto bail_out;
 
              err = of_property_read_u32(dn, "reg", &cpu);
              if (WARN_ON(err))
-                     return;
+                     goto bail_out;
 
              sprintf(clk_name, "cpu%d", cpu);
              parent_clk = of_clk_get(node, 0);
@@ -167,6 +167,9 @@ void __init of_cpu_clk_setup(struct device_node *node)
      return;
 bail_out:
      kfree(clks);
+     while(ncpus--)
+             kfree(cpuclk[ncpus].clk_name);
+clks_out:
      kfree(cpuclk);
 }
 
Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#12 lore raw
Quoted 19 lines · Mike Turquette

Quoting Gregory CLEMENT (2013-01-15 12:46:03)

Quoted 8 lines · Cong Ding
Quoted 1 line

the variable cpuclk and clk_name should be properly freed when error happens.

Dear Cong Ding,

Thanks for you efforts!
I am happy with this patch and I tested it on the Armada XP DB board, so you can now add my:

Quoted 9 lines

Mike,

could you take this patch for 3.8-rc fixes?

If you prefer, Jason agrees to take it, but you probably didn't notice it, because he uses your former(and no more valid) email when he wrote this.

Quoted 6 lines

I don't have an existing clk-fixes branch. This patch is the first fix I've reviewed for this cycle. I'm happy if you want to take it and submit as part of any other mvebu fixes you have. Otherwise I can take it.

I'll take it, no problem. Thanks for the Ack Mike,

Jason.