chiark / gitweb /
util: introduce more accurate definitions of TASKS_MAX
authorLennart Poettering <lennart@poettering.net>
Wed, 17 Jan 2018 14:31:23 +0000 (15:31 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:50:16 +0000 (07:50 +0200)
The maximum number of processes a tasks on the system is usually lower
than what pid_t would allow, and is compiled into the kernel (and
documented in proc(5)). Let's add proper defines for that, so that
we can adjust the pid_max sysctl without fearing invalid accesses.

src/basic/process-util.h
src/basic/util.c

index 2ccb8e8f39a2a3b591b859da9537f135cef7d7a2..7eae183d3e5297b2d40b9a3d6cc04c5abbceb928 100644 (file)
@@ -126,13 +126,8 @@ int sched_policy_to_string_alloc(int i, char **s);
 int sched_policy_from_string(const char *s);
 #endif // 0
 
-static inline pid_t PTR_TO_PID(const void *p) {
-        return (pid_t) ((uintptr_t) p);
-}
-
-static inline void* PID_TO_PTR(pid_t pid) {
-        return (void*) ((uintptr_t) pid);
-}
+#define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p))
+#define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
 
 void valgrind_summary_hack(void);
 
@@ -198,3 +193,22 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
 }
 
 int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *pid, const char *path, ...);
+
+#if SIZEOF_PID_T == 4
+/* The highest possibly (theoretic) pid_t value on this architecture. */
+#define PID_T_MAX ((pid_t) INT32_MAX)
+/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value
+ * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the
+ * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by
+ * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since
+ * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at
+ * least to define them here too. */
+#define TASKS_MAX 4194303U
+#elif SIZEOF_PID_T == 2
+#define PID_T_MAX ((pid_t) INT16_MAX)
+#define TASKS_MAX 32767U
+#else
+#error "Unknown pid_t size"
+#endif
+
+assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX)
index e23266ba346876d347a6103d8dc6fefd8823d63d..086ef429ad5f8e6ebb8b9159a5bca9965d55f201 100644 (file)
@@ -479,23 +479,16 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
 
 uint64_t system_tasks_max(void) {
 
-#if SIZEOF_PID_T == 4
-#define TASKS_MAX ((uint64_t) (INT32_MAX-1))
-#elif SIZEOF_PID_T == 2
-#define TASKS_MAX ((uint64_t) (INT16_MAX-1))
 #else
-#error "Unknown pid_t size"
-#endif
-
         _cleanup_free_ char *value = NULL, *root = NULL;
         uint64_t a = TASKS_MAX, b = TASKS_MAX;
 
         /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this
          * limit:
          *
-         * a) the maximum value for the pid_t type
+         * a) the maximum tasks value the kernel allows on this architecture
          * b) the cgroups pids_max attribute for the system
-         * c) the kernel's configure maximum PID value
+         * c) the kernel's configured maximum PID value
          *
          * And then pick the smallest of the three */