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 0x00000003 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 0x00000005
> 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 <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
@@ -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 >= 3) {
+    printf("testing at depth %d\n", (depth-1)/2);
     obj = NULL;
     while ((obj = hwloc_get_next_obj_by_depth(topology, (depth-1)/2, obj)) != NULL)
       checkall(obj->cpuset);
   }
 
   /* check at bottom level */
+  printf("testing at bottom level\n");
   obj = NULL;
   while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
     checkall(obj->cpuset);
_______________________________________________
hwloc-devel mailing list
hwloc-devel@lists.open-mpi.org
https://lists.open-mpi.org/mailman/listinfo/hwloc-devel

Reply via email to