Le 28/12/2017 à 16:18, Samuel Thibault a écrit :
> Samuel Thibault, on jeu. 28 déc. 2017 15:08:30 +0100, wrote:
>> Samuel Thibault, on mer. 20 déc. 2017 18:32:48 +0100, wrote:
>>> I have uploaded it to debian experimental, so when it passes NEW,
>>> various arch test results will show up on
>>>
>>> https://buildd.debian.org/status/package.php?p=hwloc&suite=experimental
>>>
>>> so you can check the results on odd systems :)
>> FI, the failure on m68k is due to a bug in qemu's linux-user emulation,
>> which I'm currently fixing.
> There is however an issue with the hwloc_get_last_cpu_location test when
> run inside qemu's linux-user emulation, because in that case qemu
> introduces a thread for its own purposes in addition to the normal
> thread, and then the test looks like this:
Can you clarify what this qemu linux-user emulation does? Is it
emulating each process of a "fake-VM" inside a dedicated process on the
host?
Any idea when this could be useful beside (I guess) cross-building
platforms?
> I'm tid 15573
> trying 0x0003 1
> setaffinity 15573 3 gave 0
> setaffinity 15606 3 gave 0
> getting last location for 15573
> got 0
> getting last location for 15606
> got 2
> got 0x0005
> hwloc_get_last_cpu_location: hwloc_get_last_cpu_location.c:38: check:
> Assertion `hwloc_bitmap_isincluded(last, set)' failed.
>
> I.e. when trying check(set, HWLOC_CPUBIND_PROCESS);, the
> hwloc_set_cpubind() call does bind the two threads of the process, and
> then looks for the CPU locations of the two threads, but probably thread
> 15606 didn't actually run in between, and thus the last CPU location is
> still with the old binding, and that fails the assertion.
>
> Of course, in the Debian package I could patch over this test to ignore
> the failure, possibly by blacklisting architectures which are known to
> be built inside qemu, but it could pose problem more generally. Perhaps
> we should use the attached patch, to try to check inclusion only from
> the result of the current-thread-only method?
If this failure isn't expected to matter in normal cases, I'd like to
keep the opportunity to check the process-wide cpulocation when possible.
I couldn't find an env var for detecting qemu user-emulation, but we can
add a hwloc env var to disable process-wide asserts. Something like the
attached patch (which adds lots of printf and just disables the assert
if flags!=THREAD or if HWLOC_TEST_DONTCHECK_PROC_CPULOCATION is set in
the env).
Brice
diff --git a/tests/hwloc/hwloc_get_last_cpu_location.c b/tests/hwloc/hwloc_get_last_cpu_location.c
index 03ab103b..01373a7d 100644
--- a/tests/hwloc/hwloc_get_last_cpu_location.c
+++ b/tests/hwloc/hwloc_get_last_cpu_location.c
@@ -5,6 +5,7 @@
*/
#include
+#include
#include
#include
@@ -13,21 +14,29 @@
hwloc_topology_t topology;
const struct hwloc_topology_support *support;
+static int checkprocincluded;
+
/* check that a bound process execs on a non-empty cpuset included in the binding */
static int check(hwloc_const_cpuset_t set, int flags)
{
hwloc_cpuset_t last;
int ret;
+ printf(" binding\n");
ret = hwloc_set_cpubind(topology, set, flags);
if (ret)
return 0;
+ printf(" getting cpu location\n");
last = hwloc_bitmap_alloc();
ret = hwloc_get_last_cpu_location(topology, last, flags);
assert(!ret);
assert(!hwloc_bitmap_iszero(last));
- assert(hwloc_bitmap_isincluded(last, set));
+
+ if (flags == HWLOC_CPUBIND_THREAD || checkprocincluded) {
+printf(" checking inclusion\n");
+assert(hwloc_bitmap_isincluded(last, set));
+ }
hwloc_bitmap_free(last);
return 0;
@@ -35,12 +44,18 @@ static int check(hwloc_const_cpuset_t set, int flags)
static int checkall(hwloc_const_cpuset_t set)
{
- if (support->cpubind->get_thisthread_last_cpu_location)
+ if (support->cpubind->get_thisthread_last_cpu_location) {
+printf(" with HWLOC_CPUBIND_THREAD...\n");
check(set, HWLOC_CPUBIND_THREAD);
- if (support->cpubind->get_thisproc_last_cpu_location)
+ }
+ if (support->cpubind->get_thisproc_last_cpu_location) {
+printf(" with HWLOC_CPUBIND_PROCESS...\n");
check(set, HWLOC_CPUBIND_PROCESS);
- if (support->cpubind->get_thisthread_last_cpu_location || support->cpubind->get_thisproc_last_cpu_location)
+ }
+ if (support->cpubind->get_thisthread_last_cpu_location || support->cpubind->get_thisproc_last_cpu_location) {
+printf(" with flags 0...\n");
check(set, 0);
+ }
return 0;
}
@@ -49,24 +64,29 @@ int main(void)
unsigned depth;
hwloc_obj_t obj;
+ checkprocincluded = (NULL == getenv("HWLOC_TEST_DONTCHECK_PROC_CPULOCATION"));
+
hwloc_topology_init(&topology);
hwloc_topology_load(topology);
support = hwloc_topology_get_support(topology);
/* check at top level */
+ printf("testing at top level\n");
obj = hwloc_get_root_obj(topology);
checkall(obj->cpuset);
depth = hwloc_topology_get_depth(topology);
/* check at intermediate level if it exists */
if (depth