diff mbox series

powercap: intel_rapl: Optimize rp->domains memory allocation

Message ID 20230404083656.713825-1-xiongxin@kylinos.cn
State New
Headers show
Series powercap: intel_rapl: Optimize rp->domains memory allocation | expand

Commit Message

Xiong Xin April 4, 2023, 8:36 a.m. UTC
In the memory allocation of rp->domains in rapl_detect_domains(), there
is an additional memory of struct rapl_domain allocated to prevent the
pointer out of bounds called later.

Optimize the code here to save sizeof(struct rapl_domain) bytes of
memory.

Test in Intel NUC (i5-1135G7).

Signed-off-by: xiongxin <xiongxin@kylinos.cn>
Tested-by: xiongxin <xiongxin@kylinos.cn>
---
 drivers/powercap/intel_rapl_common.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

Comments

Xiong Xin April 6, 2023, 1:22 a.m. UTC | #1
在 2023/4/5 00:30, Rafael J. Wysocki 写道:
> On Tue, Apr 4, 2023 at 10:37 AM xiongxin <xiongxin@kylinos.cn> wrote:
>>
>> In the memory allocation of rp->domains in rapl_detect_domains(), there
>> is an additional memory of struct rapl_domain allocated to prevent the
>> pointer out of bounds called later.
>>
>> Optimize the code here to save sizeof(struct rapl_domain) bytes of
>> memory.
>>
>> Test in Intel NUC (i5-1135G7).
>>
>> Signed-off-by: xiongxin <xiongxin@kylinos.cn>
>> Tested-by: xiongxin <xiongxin@kylinos.cn>
>> ---
>>   drivers/powercap/intel_rapl_common.c | 15 ++++++++-------
>>   1 file changed, 8 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
>> index 8970c7b80884..f8971282498a 100644
>> --- a/drivers/powercap/intel_rapl_common.c
>> +++ b/drivers/powercap/intel_rapl_common.c
>> @@ -1171,13 +1171,14 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
>>   {
>>          struct rapl_domain *rd;
>>          struct powercap_zone *power_zone = NULL;
>> -       int nr_pl, ret;
>> +       int nr_pl, ret, i;
>>
>>          /* Update the domain data of the new package */
>>          rapl_update_domain_data(rp);
>>
>>          /* first we register package domain as the parent zone */
>> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
>> +       for (i = 0; i < rp->nr_domains; i++) {
>> +               rd = &rp->domains[i];
>>                  if (rd->id == RAPL_DOMAIN_PACKAGE) {
>>                          nr_pl = find_nr_power_limit(rd);
>>                          pr_debug("register package domain %s\n", rp->name);
>> @@ -1201,8 +1202,9 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
>>                  return -ENODEV;
>>          }
>>          /* now register domains as children of the socket/package */
>> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
>> +       for (i = 0; i < rp->nr_domains; i++) {
>>                  struct powercap_zone *parent = rp->power_zone;
>> +               rd = &rp->domains[i];
>>
>>                  if (rd->id == RAPL_DOMAIN_PACKAGE)
>>                          continue;
>> @@ -1302,7 +1304,6 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd)
>>    */
>>   static int rapl_detect_domains(struct rapl_package *rp, int cpu)
>>   {
>> -       struct rapl_domain *rd;
>>          int i;
>>
>>          for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
>> @@ -1319,15 +1320,15 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
>>          }
>>          pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
>>
>> -       rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
>> +       rp->domains = kcalloc(rp->nr_domains, sizeof(struct rapl_domain),
>>                                GFP_KERNEL);
> 
> Why can't you modify just the above statement alone?  What would break
> if you did that?
At the beginning, I just didn't understand what this '+1' was for, but
contacting the for loop behind, here '+1', just because the rd pointer
will not point outside the memory of 'rp->domains' before the for loop
exits.

if '+1' is to prevent the invalidation of the rd pointer, and apply for
an additional struct rapl_domains here, then my patch may not be 
completely modified.

> 
>>          if (!rp->domains)
>>                  return -ENOMEM;
>>
>>          rapl_init_domains(rp);
>>
>> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
>> -               rapl_detect_powerlimit(rd);

If '+1' is directly removed, before the for loop exits, the rd pointer 
has already pointed to outside the memory of rp->domains.

>> +       for (i = 0; i < rp->nr_domains; i++)
>> +               rapl_detect_powerlimit(&rp->domains[i]);
>>
>>          return 0;
>>   }
>> --
>> 2.34.1
>>
Rafael J. Wysocki April 6, 2023, 10:04 a.m. UTC | #2
On Thu, Apr 6, 2023 at 3:23 AM TGSP <xiongxin@kylinos.cn> wrote:
>
> 在 2023/4/5 00:30, Rafael J. Wysocki 写道:
> > On Tue, Apr 4, 2023 at 10:37 AM xiongxin <xiongxin@kylinos.cn> wrote:
> >>
> >> In the memory allocation of rp->domains in rapl_detect_domains(), there
> >> is an additional memory of struct rapl_domain allocated to prevent the
> >> pointer out of bounds called later.
> >>
> >> Optimize the code here to save sizeof(struct rapl_domain) bytes of
> >> memory.
> >>
> >> Test in Intel NUC (i5-1135G7).
> >>
> >> Signed-off-by: xiongxin <xiongxin@kylinos.cn>
> >> Tested-by: xiongxin <xiongxin@kylinos.cn>
> >> ---
> >>   drivers/powercap/intel_rapl_common.c | 15 ++++++++-------
> >>   1 file changed, 8 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
> >> index 8970c7b80884..f8971282498a 100644
> >> --- a/drivers/powercap/intel_rapl_common.c
> >> +++ b/drivers/powercap/intel_rapl_common.c
> >> @@ -1171,13 +1171,14 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
> >>   {
> >>          struct rapl_domain *rd;
> >>          struct powercap_zone *power_zone = NULL;
> >> -       int nr_pl, ret;
> >> +       int nr_pl, ret, i;
> >>
> >>          /* Update the domain data of the new package */
> >>          rapl_update_domain_data(rp);
> >>
> >>          /* first we register package domain as the parent zone */
> >> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
> >> +       for (i = 0; i < rp->nr_domains; i++) {
> >> +               rd = &rp->domains[i];
> >>                  if (rd->id == RAPL_DOMAIN_PACKAGE) {
> >>                          nr_pl = find_nr_power_limit(rd);
> >>                          pr_debug("register package domain %s\n", rp->name);
> >> @@ -1201,8 +1202,9 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
> >>                  return -ENODEV;
> >>          }
> >>          /* now register domains as children of the socket/package */
> >> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
> >> +       for (i = 0; i < rp->nr_domains; i++) {
> >>                  struct powercap_zone *parent = rp->power_zone;
> >> +               rd = &rp->domains[i];
> >>
> >>                  if (rd->id == RAPL_DOMAIN_PACKAGE)
> >>                          continue;
> >> @@ -1302,7 +1304,6 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd)
> >>    */
> >>   static int rapl_detect_domains(struct rapl_package *rp, int cpu)
> >>   {
> >> -       struct rapl_domain *rd;
> >>          int i;
> >>
> >>          for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
> >> @@ -1319,15 +1320,15 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
> >>          }
> >>          pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
> >>
> >> -       rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
> >> +       rp->domains = kcalloc(rp->nr_domains, sizeof(struct rapl_domain),
> >>                                GFP_KERNEL);
> >
> > Why can't you modify just the above statement alone?  What would break
> > if you did that?
> At the beginning, I just didn't understand what this '+1' was for, but
> contacting the for loop behind, here '+1', just because the rd pointer
> will not point outside the memory of 'rp->domains' before the for loop
> exits.
>
> if '+1' is to prevent the invalidation of the rd pointer, and apply for
> an additional struct rapl_domains here, then my patch may not be
> completely modified.
>
> >
> >>          if (!rp->domains)
> >>                  return -ENOMEM;
> >>
> >>          rapl_init_domains(rp);
> >>
> >> -       for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
> >> -               rapl_detect_powerlimit(rd);
>
> If '+1' is directly removed, before the for loop exits, the rd pointer
> has already pointed to outside the memory of rp->domains.

But that value is never dereferenced AFAICS.

> >> +       for (i = 0; i < rp->nr_domains; i++)
> >> +               rapl_detect_powerlimit(&rp->domains[i]);
> >>
> >>          return 0;
> >>   }
> >> --
diff mbox series

Patch

diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
index 8970c7b80884..f8971282498a 100644
--- a/drivers/powercap/intel_rapl_common.c
+++ b/drivers/powercap/intel_rapl_common.c
@@ -1171,13 +1171,14 @@  static int rapl_package_register_powercap(struct rapl_package *rp)
 {
 	struct rapl_domain *rd;
 	struct powercap_zone *power_zone = NULL;
-	int nr_pl, ret;
+	int nr_pl, ret, i;
 
 	/* Update the domain data of the new package */
 	rapl_update_domain_data(rp);
 
 	/* first we register package domain as the parent zone */
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
+	for (i = 0; i < rp->nr_domains; i++) {
+		rd = &rp->domains[i];
 		if (rd->id == RAPL_DOMAIN_PACKAGE) {
 			nr_pl = find_nr_power_limit(rd);
 			pr_debug("register package domain %s\n", rp->name);
@@ -1201,8 +1202,9 @@  static int rapl_package_register_powercap(struct rapl_package *rp)
 		return -ENODEV;
 	}
 	/* now register domains as children of the socket/package */
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
+	for (i = 0; i < rp->nr_domains; i++) {
 		struct powercap_zone *parent = rp->power_zone;
+		rd = &rp->domains[i];
 
 		if (rd->id == RAPL_DOMAIN_PACKAGE)
 			continue;
@@ -1302,7 +1304,6 @@  static void rapl_detect_powerlimit(struct rapl_domain *rd)
  */
 static int rapl_detect_domains(struct rapl_package *rp, int cpu)
 {
-	struct rapl_domain *rd;
 	int i;
 
 	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
@@ -1319,15 +1320,15 @@  static int rapl_detect_domains(struct rapl_package *rp, int cpu)
 	}
 	pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
 
-	rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
+	rp->domains = kcalloc(rp->nr_domains, sizeof(struct rapl_domain),
 			      GFP_KERNEL);
 	if (!rp->domains)
 		return -ENOMEM;
 
 	rapl_init_domains(rp);
 
-	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++)
-		rapl_detect_powerlimit(rd);
+	for (i = 0; i < rp->nr_domains; i++)
+		rapl_detect_powerlimit(&rp->domains[i]);
 
 	return 0;
 }