diff mbox

[PATCHv4] platform: linux-generic: reading cpu affinity from cpuset

Message ID 1481033749-4729-1-git-send-email-balakrishna.garapati@linaro.org
State Accepted
Commit 320bb2e9a29256de37bfdb10b9dde3fd0f0d4a5d
Headers show

Commit Message

Balakrishna Garapati Dec. 6, 2016, 2:15 p.m. UTC
With this new proposal cpu affinity is read correctly especially
when using cgroups otherwise wrong cpu mask is set.

Fixes bug: https://bugs.linaro.org/show_bug.cgi?id=2472

Signed-off-by: Balakrishna Garapati <balakrishna.garapati@linaro.org>

---

 since v3: Renaming function call

 platform/linux-generic/odp_cpumask.c | 73 +++++++++---------------------------
 1 file changed, 18 insertions(+), 55 deletions(-)

--
1.9.1

Comments

Yi He Dec. 7, 2016, 3:36 a.m. UTC | #1
Reviewed-and-tested-by: Yi He <yi.he@linaro.org>


On 6 December 2016 at 22:15, Balakrishna Garapati <
balakrishna.garapati@linaro.org> wrote:

> With this new proposal cpu affinity is read correctly especially

> when using cgroups otherwise wrong cpu mask is set.

>

> Fixes bug: https://bugs.linaro.org/show_bug.cgi?id=2472

>

> Signed-off-by: Balakrishna Garapati <balakrishna.garapati@linaro.org>

> ---

>

>  since v3: Renaming function call

>

>  platform/linux-generic/odp_cpumask.c | 73 +++++++++---------------------

> ------

>  1 file changed, 18 insertions(+), 55 deletions(-)

>

> diff --git a/platform/linux-generic/odp_cpumask.c

> b/platform/linux-generic/odp_cpumask.c

> index 6bf2632..64559a6 100644

> --- a/platform/linux-generic/odp_cpumask.c

> +++ b/platform/linux-generic/odp_cpumask.c

> @@ -225,73 +225,36 @@ int odp_cpumask_next(const odp_cpumask_t *mask, int

> cpu)

>   * This function obtains system information specifying which cpus are

>   * available at boot time.

>   */

> -static int get_installed_cpus(void)

> +static int get_available_cpus(void)

>  {

> -       char *numptr;

> -       char *endptr;

> -       long int cpu_idnum;

> -       DIR  *d;

> -       struct dirent *dir;

> +       int cpu_idnum;

> +       cpu_set_t cpuset;

> +       int ret;

>

>         /* Clear the global cpumasks for control and worker CPUs */

>         odp_cpumask_zero(&odp_global_data.control_cpus);

>         odp_cpumask_zero(&odp_global_data.worker_cpus);

>

> -       /*

> -        * Scan the /sysfs pseudo-filesystem for CPU info directories.

> -        * There should be one subdirectory for each installed logical CPU

> -        */

> -       d = opendir("/sys/devices/system/cpu");

> -       if (d) {

> -               while ((dir = readdir(d)) != NULL) {

> -                       cpu_idnum = CPU_SETSIZE;

> -

> -                       /*

> -                        * If the current directory entry doesn't represent

> -                        * a CPU info subdirectory then skip to the next

> entry.

> -                        */

> -                       if (dir->d_type == DT_DIR) {

> -                               if (!strncmp(dir->d_name, "cpu", 3)) {

> -                                       /*

> -                                        * Directory name starts with

> "cpu"...

> -                                        * Try to extract a CPU ID number

> -                                        * from the remainder of the

> dirname.

> -                                        */

> -                                       errno = 0;

> -                                       numptr = dir->d_name;

> -                                       numptr += 3;

> -                                       cpu_idnum = strtol(numptr, &endptr,

> -                                                          10);

> -                                       if (errno || (endptr == numptr))

> -                                               continue;

> -                               } else {

> -                                       continue;

> -                               }

> -                       } else {

> -                               continue;

> -                       }

> -                       /*

> -                        * If we get here the current directory entry

> specifies

> -                        * a CPU info subdir for the CPU indexed by

> cpu_idnum.

> -                        */

> +       CPU_ZERO(&cpuset);

> +       ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);

>

> -                       /* Track number of logical CPUs discovered */

> -                       if (odp_global_data.num_cpus_installed <

> -                           (int)(cpu_idnum + 1))

> -                               odp_global_data.num_cpus_installed =

> -                                               (int)(cpu_idnum + 1);

> +       if (ret < 0) {

> +               ODP_ERR("Failed to get cpu affinity");

> +                       return -1;

> +       }

>

> +       for (cpu_idnum = 0; cpu_idnum < CPU_SETSIZE - 1; cpu_idnum++) {

> +               if (CPU_ISSET(cpu_idnum, &cpuset)) {

> +                       odp_global_data.num_cpus_installed++;

>                         /* Add the CPU to our default cpumasks */

>                         odp_cpumask_set(&odp_global_data.control_cpus,

> -                                       (int)cpu_idnum);

> +                                               (int)cpu_idnum);

>                         odp_cpumask_set(&odp_global_data.worker_cpus,

> -                                       (int)cpu_idnum);

> +                                               (int)cpu_idnum);

>                 }

> -               closedir(d);

> -               return 0;

> -       } else {

> -               return -1;

>         }

> +

> +       return 0;

>  }

>

>  /*

> @@ -429,7 +392,7 @@ int odp_cpumask_init_global(const odp_init_t *params)

>          * Initialize the global control and worker cpumasks with lists of

>          * all installed CPUs.  Return an error if this procedure fails.

>          */

> -       if (!get_installed_cpus()) {

> +       if (!get_available_cpus()) {

>                 if (params) {

>                         if (params->control_cpus) {

>                                 /*

> --

> 1.9.1

>

>
Maxim Uvarov Dec. 9, 2016, 12:48 p.m. UTC | #2
Merged,
Maxim.

On 12/07/16 06:36, Yi He wrote:
> Reviewed-and-tested-by: Yi He <yi.he@linaro.org>

> 

> 

> On 6 December 2016 at 22:15, Balakrishna Garapati <

> balakrishna.garapati@linaro.org> wrote:

> 

>> With this new proposal cpu affinity is read correctly especially

>> when using cgroups otherwise wrong cpu mask is set.

>>

>> Fixes bug: https://bugs.linaro.org/show_bug.cgi?id=2472

>>

>> Signed-off-by: Balakrishna Garapati <balakrishna.garapati@linaro.org>

>> ---

>>

>>  since v3: Renaming function call

>>

>>  platform/linux-generic/odp_cpumask.c | 73 +++++++++---------------------

>> ------

>>  1 file changed, 18 insertions(+), 55 deletions(-)

>>

>> diff --git a/platform/linux-generic/odp_cpumask.c

>> b/platform/linux-generic/odp_cpumask.c

>> index 6bf2632..64559a6 100644

>> --- a/platform/linux-generic/odp_cpumask.c

>> +++ b/platform/linux-generic/odp_cpumask.c

>> @@ -225,73 +225,36 @@ int odp_cpumask_next(const odp_cpumask_t *mask, int

>> cpu)

>>   * This function obtains system information specifying which cpus are

>>   * available at boot time.

>>   */

>> -static int get_installed_cpus(void)

>> +static int get_available_cpus(void)

>>  {

>> -       char *numptr;

>> -       char *endptr;

>> -       long int cpu_idnum;

>> -       DIR  *d;

>> -       struct dirent *dir;

>> +       int cpu_idnum;

>> +       cpu_set_t cpuset;

>> +       int ret;

>>

>>         /* Clear the global cpumasks for control and worker CPUs */

>>         odp_cpumask_zero(&odp_global_data.control_cpus);

>>         odp_cpumask_zero(&odp_global_data.worker_cpus);

>>

>> -       /*

>> -        * Scan the /sysfs pseudo-filesystem for CPU info directories.

>> -        * There should be one subdirectory for each installed logical CPU

>> -        */

>> -       d = opendir("/sys/devices/system/cpu");

>> -       if (d) {

>> -               while ((dir = readdir(d)) != NULL) {

>> -                       cpu_idnum = CPU_SETSIZE;

>> -

>> -                       /*

>> -                        * If the current directory entry doesn't represent

>> -                        * a CPU info subdirectory then skip to the next

>> entry.

>> -                        */

>> -                       if (dir->d_type == DT_DIR) {

>> -                               if (!strncmp(dir->d_name, "cpu", 3)) {

>> -                                       /*

>> -                                        * Directory name starts with

>> "cpu"...

>> -                                        * Try to extract a CPU ID number

>> -                                        * from the remainder of the

>> dirname.

>> -                                        */

>> -                                       errno = 0;

>> -                                       numptr = dir->d_name;

>> -                                       numptr += 3;

>> -                                       cpu_idnum = strtol(numptr, &endptr,

>> -                                                          10);

>> -                                       if (errno || (endptr == numptr))

>> -                                               continue;

>> -                               } else {

>> -                                       continue;

>> -                               }

>> -                       } else {

>> -                               continue;

>> -                       }

>> -                       /*

>> -                        * If we get here the current directory entry

>> specifies

>> -                        * a CPU info subdir for the CPU indexed by

>> cpu_idnum.

>> -                        */

>> +       CPU_ZERO(&cpuset);

>> +       ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);

>>

>> -                       /* Track number of logical CPUs discovered */

>> -                       if (odp_global_data.num_cpus_installed <

>> -                           (int)(cpu_idnum + 1))

>> -                               odp_global_data.num_cpus_installed =

>> -                                               (int)(cpu_idnum + 1);

>> +       if (ret < 0) {

>> +               ODP_ERR("Failed to get cpu affinity");

>> +                       return -1;

>> +       }

>>

>> +       for (cpu_idnum = 0; cpu_idnum < CPU_SETSIZE - 1; cpu_idnum++) {

>> +               if (CPU_ISSET(cpu_idnum, &cpuset)) {

>> +                       odp_global_data.num_cpus_installed++;

>>                         /* Add the CPU to our default cpumasks */

>>                         odp_cpumask_set(&odp_global_data.control_cpus,

>> -                                       (int)cpu_idnum);

>> +                                               (int)cpu_idnum);

>>                         odp_cpumask_set(&odp_global_data.worker_cpus,

>> -                                       (int)cpu_idnum);

>> +                                               (int)cpu_idnum);

>>                 }

>> -               closedir(d);

>> -               return 0;

>> -       } else {

>> -               return -1;

>>         }

>> +

>> +       return 0;

>>  }

>>

>>  /*

>> @@ -429,7 +392,7 @@ int odp_cpumask_init_global(const odp_init_t *params)

>>          * Initialize the global control and worker cpumasks with lists of

>>          * all installed CPUs.  Return an error if this procedure fails.

>>          */

>> -       if (!get_installed_cpus()) {

>> +       if (!get_available_cpus()) {

>>                 if (params) {

>>                         if (params->control_cpus) {

>>                                 /*

>> --

>> 1.9.1

>>

>>
diff mbox

Patch

diff --git a/platform/linux-generic/odp_cpumask.c b/platform/linux-generic/odp_cpumask.c
index 6bf2632..64559a6 100644
--- a/platform/linux-generic/odp_cpumask.c
+++ b/platform/linux-generic/odp_cpumask.c
@@ -225,73 +225,36 @@  int odp_cpumask_next(const odp_cpumask_t *mask, int cpu)
  * This function obtains system information specifying which cpus are
  * available at boot time.
  */
-static int get_installed_cpus(void)
+static int get_available_cpus(void)
 {
-	char *numptr;
-	char *endptr;
-	long int cpu_idnum;
-	DIR  *d;
-	struct dirent *dir;
+	int cpu_idnum;
+	cpu_set_t cpuset;
+	int ret;

 	/* Clear the global cpumasks for control and worker CPUs */
 	odp_cpumask_zero(&odp_global_data.control_cpus);
 	odp_cpumask_zero(&odp_global_data.worker_cpus);

-	/*
-	 * Scan the /sysfs pseudo-filesystem for CPU info directories.
-	 * There should be one subdirectory for each installed logical CPU
-	 */
-	d = opendir("/sys/devices/system/cpu");
-	if (d) {
-		while ((dir = readdir(d)) != NULL) {
-			cpu_idnum = CPU_SETSIZE;
-
-			/*
-			 * If the current directory entry doesn't represent
-			 * a CPU info subdirectory then skip to the next entry.
-			 */
-			if (dir->d_type == DT_DIR) {
-				if (!strncmp(dir->d_name, "cpu", 3)) {
-					/*
-					 * Directory name starts with "cpu"...
-					 * Try to extract a CPU ID number
-					 * from the remainder of the dirname.
-					 */
-					errno = 0;
-					numptr = dir->d_name;
-					numptr += 3;
-					cpu_idnum = strtol(numptr, &endptr,
-							   10);
-					if (errno || (endptr == numptr))
-						continue;
-				} else {
-					continue;
-				}
-			} else {
-				continue;
-			}
-			/*
-			 * If we get here the current directory entry specifies
-			 * a CPU info subdir for the CPU indexed by cpu_idnum.
-			 */
+	CPU_ZERO(&cpuset);
+	ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);

-			/* Track number of logical CPUs discovered */
-			if (odp_global_data.num_cpus_installed <
-			    (int)(cpu_idnum + 1))
-				odp_global_data.num_cpus_installed =
-						(int)(cpu_idnum + 1);
+	if (ret < 0) {
+		ODP_ERR("Failed to get cpu affinity");
+			return -1;
+	}

+	for (cpu_idnum = 0; cpu_idnum < CPU_SETSIZE - 1; cpu_idnum++) {
+		if (CPU_ISSET(cpu_idnum, &cpuset)) {
+			odp_global_data.num_cpus_installed++;
 			/* Add the CPU to our default cpumasks */
 			odp_cpumask_set(&odp_global_data.control_cpus,
-					(int)cpu_idnum);
+						(int)cpu_idnum);
 			odp_cpumask_set(&odp_global_data.worker_cpus,
-					(int)cpu_idnum);
+						(int)cpu_idnum);
 		}
-		closedir(d);
-		return 0;
-	} else {
-		return -1;
 	}
+
+	return 0;
 }

 /*
@@ -429,7 +392,7 @@  int odp_cpumask_init_global(const odp_init_t *params)
 	 * Initialize the global control and worker cpumasks with lists of
 	 * all installed CPUs.  Return an error if this procedure fails.
 	 */
-	if (!get_installed_cpus()) {
+	if (!get_available_cpus()) {
 		if (params) {
 			if (params->control_cpus) {
 				/*