public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/1] cpumask: Don't waste memory for sysfs cpulist nodes
@ 2022-09-22 19:49 Andy Shevchenko
  2022-09-22 20:41 ` Yury Norov
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Andy Shevchenko @ 2022-09-22 19:49 UTC (permalink / raw)
  To: Yury Norov, linux-kernel; +Cc: Andy Shevchenko, Rasmus Villemoes, Phil Auld

Currently the approximation is used which wastes the more memory
the more CPUs are present on the system. Proposed change calculates
the exact maximum needed in the worst case:

  NR_CPUS	old		new
  -------	---		---
  1 .. 1170	4096		4096
  1171 .. 1860	4098 ..	6510	4096
  ...		...		...
  2*4096	28672		19925
  4*4096	57344		43597
  8*4096	114688		92749
  16*4096	229376		191053
  32*4096	458752		403197
  64*4096	917504		861949
  128*4096	1835008		1779453
  256*4096	3670016		3670016

Under the hood the reccurent formula is being used:
  (5 - 0) * 2 +
    (50 - 5) * 3 +
      (500 - 50) * 4 +
        (5000 - 500) * 5 +
          ...
            (X[i] - X[i-1]) * i

which allows to count the exact maximum length in the worst case,
i.e. when each second CPU is being listed. For backward compatibility
for more than 1170 and less than 1861 CPUs the page size is preserved.

For less than 1171 and more than 1 million CPUs the old is being used.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v2: described better the advantage for 1171..1860 CPUs cases
 include/linux/cpumask.h | 48 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 1b442fb2001f..12cf0905ca74 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -1122,6 +1122,21 @@ cpumap_print_list_to_buf(char *buf, const struct cpumask *mask,
  *
  * for cpumap NR_CPUS * 9/32 - 1 should be an exact length.
  *
+ * for cpulist the reccurent formula is being used:
+ *   (5 - 0) * 2 +
+ *     (50 - 5) * 3 +
+ *       (500 - 50) * 4 +
+ *         (5000 - 500) * 5 +
+ *           ...
+ *             (X[i] - X[i-1]) * i
+ *
+ * which allows to count the exact maximum length in the worst case,
+ * i.e. when each second CPU is being listed. For backward compatibility
+ * for more than 1170 and less than 1861 CPUs the page size is preserved.
+ *
+ * For less than 1171 and more than 1 million CPUs the old is being used
+ * as described below:
+ *
  * For cpulist 7 is (ceil(log10(NR_CPUS)) + 1) allowing for NR_CPUS to be up
  * to 2 orders of magnitude larger than 8192. And then we divide by 2 to
  * cover a worst-case of every other cpu being on one of two nodes for a
@@ -1132,6 +1147,39 @@ cpumap_print_list_to_buf(char *buf, const struct cpumask *mask,
  */
 #define CPUMAP_FILE_MAX_BYTES  (((NR_CPUS * 9)/32 > PAGE_SIZE) \
 					? (NR_CPUS * 9)/32 - 1 : PAGE_SIZE)
+
+#define __CPULIST_FOR_10(x)		(((x + 1) / 2 - 0)     * 2)
+#define __CPULIST_FOR_100(x)		(((x + 1) / 2 - 5)     * 3)
+#define __CPULIST_FOR_1000(x)		(((x + 1) / 2 - 50)    * 4)
+#define __CPULIST_FOR_10000(x)		(((x + 1) / 2 - 500)   * 5)
+#define __CPULIST_FOR_100000(x)		(((x + 1) / 2 - 5000)  * 6)
+#define __CPULIST_FOR_1000000(x)	(((x + 1) / 2 - 50000) * 7)
+
+#if NR_CPUS < 1861
+#define CPULIST_FILE_MAX_BYTES	PAGE_SIZE
+#elif NR_CPUS < 10000
+#define CPULIST_FILE_MAX_BYTES			\
+	 (__CPULIST_FOR_10(10) +		\
+	  __CPULIST_FOR_100(100) +		\
+	  __CPULIST_FOR_1000(1000) +		\
+	  __CPULIST_FOR_10000(NR_CPUS))
+#elif NR_CPUS < 100000
+#define CPULIST_FILE_MAX_BYTES			\
+	 (__CPULIST_FOR_10(10) +		\
+	  __CPULIST_FOR_100(100) +		\
+	  __CPULIST_FOR_1000(1000) +		\
+	  __CPULIST_FOR_10000(10000) +		\
+	  __CPULIST_FOR_100000(NR_CPUS))
+#elif NR_CPUS < 1000000
+#define CPULIST_FILE_MAX_BYTES			\
+	 (__CPULIST_FOR_10(10) +		\
+	  __CPULIST_FOR_100(100) +		\
+	  __CPULIST_FOR_1000(1000) +		\
+	  __CPULIST_FOR_10000(10000) +		\
+	  __CPULIST_FOR_100000(100000) +	\
+	  __CPULIST_FOR_1000000(NR_CPUS))
+#else
 #define CPULIST_FILE_MAX_BYTES  (((NR_CPUS * 7)/2 > PAGE_SIZE) ? (NR_CPUS * 7)/2 : PAGE_SIZE)
+#endif
 
 #endif /* __LINUX_CPUMASK_H */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-09-23 15:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-22 19:49 [PATCH v2 1/1] cpumask: Don't waste memory for sysfs cpulist nodes Andy Shevchenko
2022-09-22 20:41 ` Yury Norov
2022-09-22 21:43   ` Phil Auld
2022-09-22 22:07     ` Yury Norov
2022-09-23  6:30   ` Greg Kroah-Hartman
2022-09-23 15:23     ` Yury Norov
2022-09-23 10:01   ` Andy Shevchenko
2022-09-23  0:38 ` Phil Auld
2022-09-23  1:45   ` Yury Norov
2022-09-23 11:36     ` Phil Auld
2022-09-23 10:03   ` Andy Shevchenko
2022-09-23 12:19 ` Rasmus Villemoes
2022-09-23 15:07   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox