unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
To: Florian Weimer <fweimer@redhat.com>, libc-alpha@sourceware.org
Subject: Re: [PATCH v4 1/3] elf: Add CPU iteration support for future use in ld.so diagnostics
Date: Mon, 8 Apr 2024 14:32:59 +0100	[thread overview]
Message-ID: <ZhPyC/CyzTKIBBfR@arm.com> (raw)
In-Reply-To: <afcac701ac12c45cf830b4df0f13fc1d8835606a.1712574353.git.fweimer@redhat.com>

The 04/08/2024 13:07, Florian Weimer wrote:
> ---
> v4: Include <stdbool.h> in the generic version, to fix the Hurd build.

looks good.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>

> 
>  elf/dl-iterate_cpu.h                  | 136 ++++++++++++++++++++++++++
>  sysdeps/generic/dl-affinity.h         |  54 ++++++++++
>  sysdeps/unix/sysv/linux/dl-affinity.h |  46 +++++++++
>  3 files changed, 236 insertions(+)
>  create mode 100644 elf/dl-iterate_cpu.h
>  create mode 100644 sysdeps/generic/dl-affinity.h
>  create mode 100644 sysdeps/unix/sysv/linux/dl-affinity.h
> 
> diff --git a/elf/dl-iterate_cpu.h b/elf/dl-iterate_cpu.h
> new file mode 100644
> index 0000000000..60db167b13
> --- /dev/null
> +++ b/elf/dl-iterate_cpu.h
> @@ -0,0 +1,136 @@
> +/* Iterate over all CPUs, for CPU-specific diagnostics.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef DL_ITERATE_CPU_H
> +#define DL_ITERATE_CPU_H
> +
> +#include <dl-affinity.h>
> +#include <stdbool.h>
> +
> +struct dl_iterate_cpu
> +{
> +  /* Sequential iteration count, starting at 0.  */
> +  unsigned int processor_index;
> +
> +  /* Requested CPU.  Can be -1 if affinity could not be set.  */
> +  int requested_cpu;
> +
> +  /* Observed current CPU.  -1 if unavailable.  */
> +  int actual_cpu;
> +
> +  /* Observed node ID for the CPU.  -1 if unavailable.  */
> +  int actual_node;
> +
> +  /* Internal fields to implement the iteration.   */
> +
> +  /* Affinity as obtained by _dl_iterate_cpu_init, using
> +     _dl_getaffinity.  Space for 8,192 CPUs.  */
> +  unsigned long int mask_reference[8192 / sizeof (unsigned long int) / 8];
> +
> +  /* This array is used by _dl_setaffinity calls.  */
> +  unsigned long int mask_request[8192 / sizeof (unsigned long int) / 8];
> +
> +  /* Return value from the initial _dl_getaffinity call.   */
> +  int length_reference;
> +};
> +
> +static void
> +_dl_iterate_cpu_init (struct dl_iterate_cpu *dic)
> +{
> +  dic->length_reference
> +    = _dl_getaffinity (dic->mask_reference, sizeof (dic->mask_reference));
> +  /* Prepare for the first _dl_iterate_cpu_next call.  */
> +  dic->processor_index = -1;
> +  dic->requested_cpu = -1;
> +}
> +
> +static bool
> +_dl_iterate_cpu_next (struct dl_iterate_cpu *dic)
> +{
> +  ++dic->processor_index;
> +
> +  if (dic->length_reference > 0)
> +    {
> +      /* Search for the next CPU to switch to.  */
> +      while (true)
> +        {
> +          ++dic->requested_cpu;
> +
> +          /* Array index and bit number within the array.  */
> +          unsigned int long_index
> +            = dic->requested_cpu / sizeof (unsigned long int) / 8;
> +          unsigned int bit_index
> +            = dic->requested_cpu % (sizeof (unsigned long int) * 8);
> +
> +          if (long_index * sizeof (unsigned long int) >= dic->length_reference)
> +            /* All possible CPUs have been covered.  */
> +            return false;
> +
> +          unsigned long int bit = 1UL << bit_index;
> +          if (dic->mask_reference[long_index] & bit)
> +            {
> +              /* The CPU is available.  Try to select it.  */
> +              dic->mask_request[long_index] = bit;
> +              if (_dl_setaffinity (dic->mask_request,
> +                                   (long_index + 1)
> +                                   * sizeof (unsigned long int)) < 0)
> +                {
> +                  /* Record that we could not perform a CPU request.  */
> +                  dic->length_reference = -1;
> +
> +                  if (dic->processor_index > 0)
> +                    /* We already reported something.  There is no need to
> +                       continue because the new data is probably not useful.  */
> +                    return false;
> +                }
> +
> +              /* Clear the bit in case the next iteration switches to the
> +                 next long value.  */
> +              dic->mask_request[long_index] = 0;
> +
> +              /* We found a CPU to run on.  */
> +              break;
> +            }
> +        }
> +    }
> +  else
> +    {
> +      /* No way to set CPU affinity.  Iterate just once.  */
> +      if (dic->processor_index > 0)
> +        return false;
> +    }
> +
> +  /* Fill in the actual CPU information.  CPU pinning may not actually
> +     be effective, depending on the container host.  */
> +  unsigned int cpu, node;
> +  if (_dl_getcpu (&cpu, &node) < 0)
> +    {
> +      /* No CPU information available.  */
> +      dic->actual_cpu = -1;
> +      dic->actual_node = -1;
> +    }
> +  else
> +    {
> +      dic->actual_cpu = cpu;
> +      dic->actual_node = node;
> +    }
> +
> +  return true;
> +}
> +
> +#endif /* DL_ITERATE_CPU_H */
> diff --git a/sysdeps/generic/dl-affinity.h b/sysdeps/generic/dl-affinity.h
> new file mode 100644
> index 0000000000..d117f737e9
> --- /dev/null
> +++ b/sysdeps/generic/dl-affinity.h
> @@ -0,0 +1,54 @@
> +/* CPU affinity handling for the dynamic linker.  Stub version.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef DL_AFFINITY_H
> +#define DL_AFFINITY_H
> +
> +#include <errno.h>
> +#include <stddef.h>
> +
> +/* On success, write the current CPU ID to *CPU, and the current node
> +   ID to *NODE, and return 0.  Return a negative error code on
> +   failure.  */
> +static inline int
> +_dl_getcpu (unsigned int *cpu, unsigned int *node)
> +{
> +  return -ENOSYS;
> +}
> +
> +/* On success, write CPU ID affinity bits for the current thread to
> +   *BITS, which must be SIZE bytes long, and return the number of
> +   bytes updated, a multiple of sizeof (unsigned long int).  On
> +   failure, return a negative error code.  */
> +static int
> +_dl_getaffinity (unsigned long int *bits, size_t size)
> +{
> +  return -ENOSYS;
> +}
> +
> +/* Set the CPU affinity mask for the current thread to *BITS, using
> +   the SIZE bytes from that array, which should be a multiple of
> +   sizeof (unsigned long int).  Return 0 on success, and a negative
> +   error code on failure.  */
> +static int
> +_dl_setaffinity (const unsigned long int *bits, size_t size)
> +{
> +  return -ENOSYS;
> +}
> +
> +#endif /* DL_AFFINITY_H */
> diff --git a/sysdeps/unix/sysv/linux/dl-affinity.h b/sysdeps/unix/sysv/linux/dl-affinity.h
> new file mode 100644
> index 0000000000..bbfede7750
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/dl-affinity.h
> @@ -0,0 +1,46 @@
> +/* CPU affinity handling for the dynamic linker.  Linux version.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* See sysdeps/generic/dl-affinity.h for documentation of these interfaces.  */
> +
> +#ifndef DL_AFFINITY_H
> +#define DL_AFFINITY_H
> +
> +#include <sysdep.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +static inline int
> +_dl_getcpu (unsigned int *cpu, unsigned int *node)
> +{
> +  return INTERNAL_SYSCALL_CALL (getcpu, cpu, node);
> +}
> +
> +static int
> +_dl_getaffinity (unsigned long int *bits, size_t size)
> +{
> +  return INTERNAL_SYSCALL_CALL (sched_getaffinity, /* TID */ 0, size, bits);
> +}
> +
> +static int
> +_dl_setaffinity (const unsigned long int *bits, size_t size)
> +{
> +  return INTERNAL_SYSCALL_CALL (sched_setaffinity, /* TID */ 0, size, bits);
> +}
> +
> +#endif /* DL_AFFINITY_H */
> -- 
> 2.44.0
> 
> 

  reply	other threads:[~2024-04-08 13:33 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-08 11:07 [PATCH v4 0/3] Enhanced CPU diagnostics for ld.so Florian Weimer
2024-04-08 11:07 ` [PATCH v4 1/3] elf: Add CPU iteration support for future use in ld.so diagnostics Florian Weimer
2024-04-08 13:32   ` Szabolcs Nagy [this message]
2024-04-08 11:08 ` [PATCH v4 2/3] x86: Add generic CPUID data dumper to ld.so --list-diagnostics Florian Weimer
2024-04-08 11:08 ` [PATCH v4 3/3] aarch64: Enhanced CPU diagnostics for ld.so Florian Weimer
2024-04-08 13:16   ` Szabolcs Nagy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZhPyC/CyzTKIBBfR@arm.com \
    --to=szabolcs.nagy@arm.com \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).