Current versions of ODP linux-generic use sched_getaffinity() and / or pthread_getaffinity_np() to obtain counts and sets of CPUs for use by ODP tasks. This method returns inappropriate results when the underlying kernel is compiled with NO_HZ_FULL support, as are the current LNG kernels. (See Linaro BUG 2027 for details.)
In the process of correcting this erroneous behavior in ODP linux-generic it was discovered that some of the validation and performance tests were using deprecated methods for determining counts of available CPUs. This led to these tests hanging in barrier_wait() because their barriers were initialized to expect more tasks than available worker CPUs could support. Since these tests are used to validate ODP linux-generic code changes, fixing the tests became a prerequisite to submitting patches to address BUG 2027... so patch 1 in this series addresses the test faults. These test changes were confirmed to work properly whether the bug 2027 fix is in place or not - they do not depend on the bug fix. As to the bug fix itself, the 'getaffinity' CPU detection logic is replaced by code which mines the /sysfs pseudo-filesystem for info about the CPUs detected on the system at boot time. Additionally, the new CPU detection method uses this information to map 'primary' CPUs separately from any 'thread sibling' CPUs (AKA 'hyperthreads') sharing the same hardware core. Since some core hardware may be shared between 'thread siblings', worker tasks running on a given CPU may experience performance degredation if other tasks are scheduled on 'thread sibling' CPUs from the same hardware core. The new CPU detection logic attempts to mitigate this by omitting the 'thread siblings' of worker CPUs from the CPUs available to ODP. Control tasks expect to share resources, so any thread siblings found for 'primary' CPUs designated as control CPUs are included in the corresponding cpumask. As a consequence of the 'thread sibling' adjustments, on a system with 'hyperthreaded' CPUs present, the default cpumasks returned by the new CPU detection logic will have an increased number of control CPUs and a decreased number of worker CPUs... but will be better optimized for worker performance. On a system without 'hyperthread' CPUs, the new CPU detection logic will default to allocating CPU 0 for control and the rest for workers - just as the old logic was expected to do. Per a suggestion by Petri S. the cpumask generation is moved from the odp_cpumask_default_control() and odp_cpumask_default_worker() functions into the odp_init_global() function. The odp_cpumask_default*() functions now use the cpumasks supplied by odp_init_global() without modification (except for returning only the number of CPUs requested or the number available - whichever is fewer - when asked to provide a default worker cpumask). As a bonus the bug fix cpumask generation logic also reduces the number of changes required in order to support an anticipated ODP API change which would allow ODP to accept and use control and worker cpumasks specified by an external entity such as a provisioning executive or a command-line argument parser. Gary S. Robertson (2): Correct worker count calculation in tests Make cpu detection work with NO_HZ_FULL platform/linux-generic/include/odp_internal.h | 31 ++-- platform/linux-generic/odp_cpumask_task.c | 45 +++-- platform/linux-generic/odp_init.c | 230 +++++++++++++++++++++++++- platform/linux-generic/odp_system_info.c | 14 +- test/api_test/odp_common.c | 4 +- test/api_test/odp_ring_test.c | 4 +- test/performance/odp_atomic.c | 9 +- test/validation/cpumask/cpumask.c | 2 +- test/validation/shmem/shmem.c | 5 +- test/validation/timer/timer.c | 16 +- 10 files changed, 298 insertions(+), 62 deletions(-) -- 1.9.1 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp