[PATCH] Linux: Avoid calling malloc indirectly from __get_nprocs
Florian Weimer
fweimer@redhat.com
Tue Jul 6 12:50:13 GMT 2021
* Adhemerval Zanella:
>> +/* Compute the population count of the entire array. */
>> +static int
>> +__get_nprocs_count (const unsigned long int *array, size_t length)
>> +{
>> + int count = 0;
>> + for (size_t i = 0; i < length; ++i)
>> + if (__builtin_add_overflow (count, __builtin_popcountl (array[i]),
>> + &count))
>> + return INT_MAX;
>> + return count;
>> +}
>
> Could we avoid replicate the same logic over different files? We have a
> countbits() on posix/sched_cpucount.c, so I think it would better to move
> it on a sched.h and use it instead (there is no need to really handle
> overflow here, it would require a *very* large buffer...).
Probably, yes.
Should I send a patch? I was busy with other stuff last week, but I
should be able to work on fixing this now.
>> +/* __get_nprocs with a large buffer. */
>> +static int
>> +__get_nprocs_large (void)
>> +{
>> + /* This code cannot use scratch_buffer because it is used during
>> + malloc initialization. */
>> + size_t pagesize = GLRO (dl_pagesize);
>> + unsigned long int *page = __mmap (0, pagesize, PROT_READ | PROT_WRITE,
>> + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
>> + if (page == MAP_FAILED)
>> + return 2;
>> + int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, pagesize, page);
>> + int count;
>> + if (r > 0)
>> + count = __get_nprocs_count (page, pagesize / sizeof (unsigned long int));
>> + else if (r == -EINVAL)
>> + /* One page is still not enough to store the bits. A more-or-less
>> + arbitrary value. This assumes t hat such large systems never
>> + happen in practice. */
>> + count = GLRO (dl_pagesize) * CHAR_BIT;
>> + else
>> + count = 2;
>> + __munmap (page, GLRO (dl_pagesize));
>
> Maybe use pagesize here since you are defining it.
Right.
> I would prefer that since now we don't iterate increasing the buffer
> size for sched_getaffinity we go for a simplified version and use a
> large buffer instead.
>
> Linux currently supports at maximum of 4096 cpus for most
> architectures:
I'm not sure if that's a good idea. I think some distributions patched
the defaults in the past. The limit isn't really set in stone.
Thanks,
Florian
More information about the Libc-alpha
mailing list