@@ -651,6 +651,7 @@ hwloc__duplicate_object(struct hwloc_topology *newtopology,
651651{
652652 struct hwloc_tma * tma = newtopology -> tma ;
653653 hwloc_obj_t * level ;
654+ unsigned level_width ;
654655 size_t len ;
655656 unsigned i ;
656657 hwloc_obj_t child ;
@@ -700,20 +701,30 @@ hwloc__duplicate_object(struct hwloc_topology *newtopology,
700701 if ((int ) src -> depth < 0 ) {
701702 i = HWLOC_SLEVEL_FROM_DEPTH (src -> depth );
702703 level = newtopology -> slevels [i ].objs ;
704+ level_width = newtopology -> slevels [i ].nbobjs ;
703705 /* deal with first/last pointers of special levels, even if not really needed */
704706 if (!newobj -> logical_index )
705707 newtopology -> slevels [i ].first = newobj ;
706708 if (newobj -> logical_index == newtopology -> slevels [i ].nbobjs - 1 )
707709 newtopology -> slevels [i ].last = newobj ;
708710 } else {
709711 level = newtopology -> levels [src -> depth ];
712+ level_width = newtopology -> level_nbobjects [src -> depth ];
710713 }
711- /* place us for real and link to previous cousin */
714+ /* place us for real */
715+ assert (newobj -> logical_index < level_width );
712716 level [newobj -> logical_index ] = newobj ;
713- if (newobj -> logical_index ) {
717+ /* link to already-inserted cousins
718+ * (hwloc_pci_belowroot_apply_locality() can cause out-of-order logical indexes)
719+ */
720+ if (newobj -> logical_index > 0 && level [newobj -> logical_index - 1 ]) {
714721 newobj -> prev_cousin = level [newobj -> logical_index - 1 ];
715722 level [newobj -> logical_index - 1 ]-> next_cousin = newobj ;
716723 }
724+ if (newobj -> logical_index < level_width - 1 && level [newobj -> logical_index + 1 ]) {
725+ newobj -> next_cousin = level [newobj -> logical_index + 1 ];
726+ level [newobj -> logical_index + 1 ]-> prev_cousin = newobj ;
727+ }
717728
718729 /* prepare for children */
719730 if (src -> arity ) {
0 commit comments