public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Siddhesh Poyarekar <siddhesh@sourceware.org>
Cc: Florian Weimer <fweimer@redhat.com>,
	 "H.J. Lu via Libc-alpha" <libc-alpha@sourceware.org>
Subject: V5 [PATCH] Set tunable value as well as min/max values
Date: Tue, 29 Sep 2020 07:54:35 -0700	[thread overview]
Message-ID: <CAMe9rOqKnrsWvT_y=vOicSitjT7mJSz1XnyY_zXBbwSmJ980qA@mail.gmail.com> (raw)
In-Reply-To: <8046ee6e-b0e9-405a-b266-3f28ad75165d@sourceware.org>

[-- Attachment #1: Type: text/plain, Size: 3020 bytes --]

On Tue, Sep 29, 2020 at 6:50 AM Siddhesh Poyarekar
<siddhesh@sourceware.org> wrote:
>
> On 29/09/20 18:00, H.J. Lu wrote:
> > Here is the updated patch with TUNABLE_SET_BOUNDS_IF_VALID.
> >
> > OK for master?
>
> I don't think TUNABLE_SET_BOUNDS_IF_VALID is doing what it intends to do.
>
> > +#define TUNABLE_SET_BOUNDS_IF_VALID(__cur, __maxp, __minp, __type)         \
>
> minp and maxp are switched around.

Fixed.

> > +({                                                                         \
> > +  __type min = __minp ? *((__type *) __minp) : (__cur)->type.min;          \
> > +  __type max = __maxp ? *((__type *) __maxp) : (__cur)->type.max;          \
> > +  if (__minp)                                                                      \
> > +    {                                                                              \
> > +      if (__maxp)                                                          \
> > +     {                                                                     \
> > +       if (max > min)                                                      \
> > +         {                                                                 \
> > +           (__cur)->type.min = min;                                        \
> > +           (__cur)->type.max = max;                                        \
> > +         }                                                                 \
>
> When both minp and maxp are specified, it checks if they're sane with
> respect to each other but it should also check whether the range they
> describe is a *subset* of (__cur)->type.min and (__cur)->type.max.
>
> > +     }                                                                     \
> > +      else if (max > min)                                                  \
> > +     (__cur)->type.min = min;                                              \
>
> You also need to make sure that (__cur)->type.min < min to ensure a more
> restrictive range.
>
> > +    }                                                                              \
> > +  else if (max > min)                                                              \
> > +    (__cur)->type.max = min;                                               \
>
> I did not understand this one.
>
> Basically, this is what it should look like:
>
>     if (__minp != NULL
>         && *__minp <= *__maxp

__maxp may be NULL.

>         && *__minp >= (__cur)->type.min
>         && *__minp <= (__cur)->type.max)
>       (__cur)->type.min = *__minp;
>
>     if (__maxp != NULL
>         && *__minp <= *_maxp

__minp may be NULL.

>         && *__maxp >= (__cur)->type.min
>         && *__maxp <= (__cur)->type.max)
>       (__cur)->type.max = *maxp;
>
> You could collapse some of these conditions if we assume that maxp and
> minp are always either NULL or not NULL together.
>

I don't think we should make such assumptions.  Here is the
updated patch with the check for the subset of (__cur)->type.min
and (__cur)->type.max.


-- 
H.J.

[-- Attachment #2: 0001-Set-tunable-value-as-well-as-min-max-values.patch --]
[-- Type: text/x-patch, Size: 7832 bytes --]

From 9dd6abbb94c1589f58b12c8dbb5159cc51e6b08e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 1 Jun 2020 14:11:32 -0700
Subject: [PATCH] Set tunable value as well as min/max values

Some tunable values and their minimum/maximum values must be determinted
at run-time.  Add TUNABLE_SET_WITH_BOUNDS and TUNABLE_SET_WITH_BOUNDS_FULL
to update tunable value together with minimum and maximum values.
__tunable_set_val is updated to set tunable value as well as min/max
values.
---
 elf/dl-tunables.c      | 45 ++++++++++++++++++++++++++++++++++++++----
 elf/dl-tunables.h      | 21 ++++++++++++++++++--
 manual/README.tunables | 24 ++++++++++++++++++++--
 3 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 26e6e26612..2ba2844075 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -100,8 +100,42 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
     }									      \
 })
 
+#define TUNABLE_SET_BOUNDS_IF_VALID(__cur, __minp, __maxp, __type)	      \
+({									      \
+  if (__minp != NULL)							      \
+    {									      \
+      /* MIN is specified.  */						      \
+      __type min = *((__type *) __minp);				      \
+      if (__maxp != NULL)						      \
+	{								      \
+	   /* Both MIN and MAX are specified.  */			      \
+	    __type max = *((__type *) __maxp);				      \
+	  if (max >= min						      \
+	      && max <= (__cur)->type.max				      \
+	      && min >= (__cur)->type.min)				      \
+	    {								      \
+	      (__cur)->type.min = min;					      \
+	      (__cur)->type.max = max;					      \
+	    }								      \
+	}								      \
+      else if (min > (__cur)->type.min && min <= (__cur)->type.max)	      \
+	{								      \
+	  /* Only MIN is specified.  */					      \
+	  (__cur)->type.min = min;					      \
+	}								      \
+    }									      \
+  else if (__maxp != NULL)						      \
+    {									      \
+      /* Only MAX is specified.  */					      \
+      __type max = *((__type *) __maxp);				      \
+      if (max < (__cur)->type.max && max >= (__cur)->type.min)		      \
+	(__cur)->type.max = max;					      \
+    }									      \
+})
+
 static void
-do_tunable_update_val (tunable_t *cur, const void *valp)
+do_tunable_update_val (tunable_t *cur, const void *valp,
+		       const void *minp, const void *maxp)
 {
   uint64_t val;
 
@@ -112,16 +146,19 @@ do_tunable_update_val (tunable_t *cur, const void *valp)
     {
     case TUNABLE_TYPE_INT_32:
 	{
+	  TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, int64_t);
 	  TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
 	  break;
 	}
     case TUNABLE_TYPE_UINT_64:
 	{
+	  TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
 	  TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
 	  break;
 	}
     case TUNABLE_TYPE_SIZE_T:
 	{
+	  TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
 	  TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
 	  break;
 	}
@@ -153,15 +190,15 @@ tunable_initialize (tunable_t *cur, const char *strval)
       cur->initialized = true;
       valp = strval;
     }
-  do_tunable_update_val (cur, valp);
+  do_tunable_update_val (cur, valp, NULL, NULL);
 }
 
 void
-__tunable_set_val (tunable_id_t id, void *valp)
+__tunable_set_val (tunable_id_t id, void *valp, void *minp, void *maxp)
 {
   tunable_t *cur = &tunable_list[id];
 
-  do_tunable_update_val (cur, valp);
+  do_tunable_update_val (cur, valp, minp, maxp);
 }
 
 #if TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring
diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
index f05eb50c2f..550b0cc7f4 100644
--- a/elf/dl-tunables.h
+++ b/elf/dl-tunables.h
@@ -70,9 +70,10 @@ typedef struct _tunable tunable_t;
 
 extern void __tunables_init (char **);
 extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
-extern void __tunable_set_val (tunable_id_t, void *);
+extern void __tunable_set_val (tunable_id_t, void *, void *, void *);
 rtld_hidden_proto (__tunables_init)
 rtld_hidden_proto (__tunable_get_val)
+rtld_hidden_proto (__tunable_set_val)
 
 /* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
    TUNABLE_NAMESPACE are defined.  This is useful shorthand to get and set
@@ -82,11 +83,18 @@ rtld_hidden_proto (__tunable_get_val)
   TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
 # define TUNABLE_SET(__id, __type, __val) \
   TUNABLE_SET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __val)
+# define TUNABLE_SET_WITH_BOUNDS(__id, __type, __val, __min, __max) \
+  TUNABLE_SET_WITH_BOUNDS_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, \
+				__type, __val, __min, __max)
 #else
 # define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
   TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
 # define TUNABLE_SET(__top, __ns, __id, __type, __val) \
   TUNABLE_SET_FULL (__top, __ns, __id, __type, __val)
+# define TUNABLE_SET_WITH_BOUNDS(__top, __ns, __id, __type, __val, \
+				 __min, __max) \
+  TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __type, __val, \
+				__min, __max)
 #endif
 
 /* Get and return a tunable value.  If the tunable was set externally and __CB
@@ -103,7 +111,16 @@ rtld_hidden_proto (__tunable_get_val)
 # define TUNABLE_SET_FULL(__top, __ns, __id, __type, __val) \
 ({									      \
   __tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id),		      \
-			& (__type) {__val});				      \
+		     & (__type) {__val}, NULL, NULL);			      \
+})
+
+/* Set a tunable value together with min/max values.  */
+# define TUNABLE_SET_WITH_BOUNDS_FULL(__top, __ns, __id, __type, __val,	      \
+				      __min, __max)			      \
+({									      \
+  __tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id),		      \
+		     & (__type) {__val},  & (__type) {__min},		      \
+		     & (__type) {__max});				      \
 })
 
 /* Namespace sanity for callback functions.  Use this macro to keep the
diff --git a/manual/README.tunables b/manual/README.tunables
index f87a31a65e..fff6c2a87e 100644
--- a/manual/README.tunables
+++ b/manual/README.tunables
@@ -67,7 +67,7 @@ The list of allowed attributes are:
 				     non-AT_SECURE subprocesses.
 			NONE: Read all the time.
 
-2. Use TUNABLE_GET/TUNABLE_SET to get and set tunables.
+2. Use TUNABLE_GET/TUNABLE_SET/TUNABLE_SET_WITH_BOUNDS to get and set tunables.
 
 3. OPTIONAL: If tunables in a namespace are being used multiple times within a
    specific module, set the TUNABLE_NAMESPACE macro to reduce the amount of
@@ -112,9 +112,29 @@ form of the macros as follows:
 where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
 remaining arguments are the same as the short form macros.
 
+The minimum and maximum values can updated together with the tunable value
+using:
+
+  TUNABLE_SET_WITH_BOUNDS (check, int32_t, val, min, max)
+
+where 'check' is the tunable name, 'int32_t' is the C type of the tunable,
+'val' is a value of same type, 'min' and 'max' are the minimum and maximum
+values of the tunable.
+
+To set the minimum and maximum values of tunables in a different namespace
+from that module, use the full form of the macros as follows:
+
+  val = TUNABLE_GET_FULL (glibc, cpu, hwcap_mask, uint64_t, NULL)
+
+  TUNABLE_SET_WITH_BOUNDS_FULL (glibc, cpu, hwcap_mask, uint64_t, val, min, max)
+
+where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
+remaining arguments are the same as the short form macros.
+
 When TUNABLE_NAMESPACE is not defined in a module, TUNABLE_GET is equivalent to
 TUNABLE_GET_FULL, so you will need to provide full namespace information for
-both macros.  Likewise for TUNABLE_SET and TUNABLE_SET_FULL.
+both macros.  Likewise for TUNABLE_SET, TUNABLE_SET_FULL,
+TUNABLE_SET_WITH_BOUNDS and TUNABLE_SET_WITH_BOUNDS_FULL.
 
 ** IMPORTANT NOTE **
 
-- 
2.26.2


  reply	other threads:[~2020-09-29 14:55 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-18 16:07 V2 [PATCH 0/4] ld.so: Add --list-tunables to print tunable values H.J. Lu
2020-09-18 16:07 ` [PATCH 1/4] x86: Initialize CPU info via IFUNC relocation [BZ 26203] H.J. Lu
2020-09-28 13:08   ` Florian Weimer
2020-09-28 13:48     ` H.J. Lu
2020-09-28 14:05       ` Florian Weimer
2020-09-28 14:20         ` H.J. Lu
2020-09-28 14:22           ` Florian Weimer
2020-09-28 14:39             ` H.J. Lu
2020-09-28 14:47               ` Florian Weimer
2020-09-28 17:54                 ` V3 [PATCH] " H.J. Lu
2020-09-29  7:53                   ` Florian Weimer
2020-09-29 11:44                     ` H.J. Lu
2020-10-01  8:46                       ` Florian Weimer
2020-10-01 19:50                         ` V4 " H.J. Lu
2020-10-08 13:22                           ` PING: " H.J. Lu
2020-10-15 12:53                             ` PING^2: " H.J. Lu
2022-05-02 13:59                               ` Sunil Pandey
2022-05-03 18:51                                 ` Sunil Pandey
2020-09-18 16:07 ` [PATCH 2/4] Set tunable value as well as min/max values H.J. Lu
2020-09-28 13:35   ` Florian Weimer
2020-09-28 13:53     ` H.J. Lu
2020-09-28 14:03       ` Florian Weimer
2020-09-28 17:30     ` Siddhesh Poyarekar
2020-09-29  4:00       ` V3 [PATCH] " H.J. Lu
2020-09-29  4:45         ` Siddhesh Poyarekar
2020-09-29  4:47           ` Siddhesh Poyarekar
2020-09-29 12:30             ` V4 " H.J. Lu
2020-09-29 13:50               ` Siddhesh Poyarekar
2020-09-29 14:54                 ` H.J. Lu [this message]
2020-09-29 15:58                   ` V5 " Siddhesh Poyarekar
2020-09-18 16:07 ` [PATCH 3/4] x86: Move x86 processor cache info to cpu_features H.J. Lu
2020-09-18 16:07 ` [PATCH 4/4] ld.so: Add --list-tunables to print tunable values H.J. Lu
2020-09-21  8:25   ` Florian Weimer

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

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

  git send-email \
    --in-reply-to='CAMe9rOqKnrsWvT_y=vOicSitjT7mJSz1XnyY_zXBbwSmJ980qA@mail.gmail.com' \
    --to=hjl.tools@gmail.com \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    --cc=siddhesh@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).