From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 553CF3EA976 for ; Thu, 25 Jun 2026 16:41:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782405692; cv=none; b=OjPQ8vjkZkWx9xKBqrwjPyTEPMwiPsorYF+hgiHe6Xs8+z+GM2KOLush7mKEiXsQySDLQrQ5DO/eRKnVLoAZPThZqa8uc0bI1n409Bi25uEY08dIeO6kKYGfp069Wq+iRWkJlNoesLNC+NadrhHhbLQTXCPQG0xq63Pc3iXcKDo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782405692; c=relaxed/simple; bh=hLEmOlbUVmiU1dB6Zf6CY7I1WImBgCsipfpO4aqzpn0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ODw6u+7e755TBqAFYBIupknSQohus1+Plro92zg7FCzVffxvIFeG9fk8hO7wdPolkNKqaI9jzkhiaauutwI/kftAzX4lKrwoP4G8T0sO/DHHQRZPbUxhn+nnVfAPKK3zVZxmlg+jeMoBxHkFH/P0UIFqJCZAep5bkcolJEsr+KA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gKmf00+d; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gKmf00+d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 09A071F00A3A; Thu, 25 Jun 2026 16:41:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1782405689; bh=eOjwckQOOSY8kIbYTY+Bj+sSyY2e0cjqe7EDVoG3o+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gKmf00+daZpZonJob8yrRFvAfPNryWYc04EVzxOU7yhRbwWUvU5mbBsBDx7H7rwcY zCcWJpFU6q1xwKx6va3+n2ZUJQvwSbzQIr9arnbbn3RcfBWlNaQ9oFxs23FemQhVbt 8Cb2Jey9cip2WKumWqg3k/rWFrJ4NiQds7UmEp+TOQaID3S/pirYXA0Hr14+OTIGEs B3+lI4mwtXtVkpELe63QFWC3aGwZ/JXU0KKbmWo//ddD7DOScuKG9LCw14Ow5m3qlj 1mN+yhY1yNQCTH/2+52VYbsaDket/bVgp7hLO8qOKYXq4S8opELwbP7Uob3eXmGr9z IjV1ac8bOdzAQ== From: Frederic Weisbecker To: Christian Loehle Cc: LKML , Frederic Weisbecker , Anna-Maria Behnsen , Sehee Jeong , Thomas Gleixner , Peter Zijlstra Subject: [PATCH 1/6] timers/migration: Revert per CPU capacity hierarchy Date: Thu, 25 Jun 2026 18:41:09 +0200 Message-ID: <20260625164114.51454-2-frederic@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260625164114.51454-1-frederic@kernel.org> References: <20260625164114.51454-1-frederic@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The per CPU-capacity hierarchies may not be the right answer to solve timers migrating too often to high capacity CPUs. Revert that in favour of later code that will gather groups per capacity under a common root and prefer lower capacity groups as migrators. Signed-off-by: Frederic Weisbecker --- include/trace/events/timer_migration.h | 24 +-- kernel/time/timer_migration.c | 241 ++++++------------------- kernel/time/timer_migration.h | 18 -- scripts/timer_migration_tree.py | 50 ++--- 4 files changed, 87 insertions(+), 246 deletions(-) diff --git a/include/trace/events/timer_migration.h b/include/trace/events/timer_migration.h index 0b135e9301b1..61171b13c687 100644 --- a/include/trace/events/timer_migration.h +++ b/include/trace/events/timer_migration.h @@ -33,16 +33,15 @@ TRACE_EVENT(tmigr_group_set, TRACE_EVENT(tmigr_connect_child_parent, - TP_PROTO(struct tmigr_hierarchy *hier, struct tmigr_group *child), + TP_PROTO(struct tmigr_group *child), - TP_ARGS(hier, child), + TP_ARGS(child), TP_STRUCT__entry( __field( void *, child ) __field( void *, parent ) __field( unsigned int, lvl ) __field( unsigned int, numa_node ) - __field( unsigned int, capacity ) __field( unsigned int, num_children ) __field( u32, groupmask ) ), @@ -52,28 +51,26 @@ TRACE_EVENT(tmigr_connect_child_parent, __entry->parent = child->parent; __entry->lvl = child->parent->level; __entry->numa_node = child->parent->numa_node; - __entry->capacity = hier->capacity; __entry->num_children = child->parent->num_children; __entry->groupmask = child->groupmask; ), - TP_printk("group=%p groupmask=%0x parent=%p lvl=%d numa=%d capacity=%d num_children=%d", - __entry->child, __entry->groupmask, __entry->parent, __entry->lvl, - __entry->numa_node, __entry->capacity, __entry->num_children) + TP_printk("group=%p groupmask=%0x parent=%p lvl=%d numa=%d num_children=%d", + __entry->child, __entry->groupmask, __entry->parent, + __entry->lvl, __entry->numa_node, __entry->num_children) ); TRACE_EVENT(tmigr_connect_cpu_parent, - TP_PROTO(struct tmigr_hierarchy *hier, struct tmigr_cpu *tmc), + TP_PROTO(struct tmigr_cpu *tmc), - TP_ARGS(hier, tmc), + TP_ARGS(tmc), TP_STRUCT__entry( __field( void *, parent ) __field( unsigned int, cpu ) __field( unsigned int, lvl ) __field( unsigned int, numa_node ) - __field( unsigned int, capacity ) __field( unsigned int, num_children ) __field( u32, groupmask ) ), @@ -83,14 +80,13 @@ TRACE_EVENT(tmigr_connect_cpu_parent, __entry->cpu = tmc->cpuevt.cpu; __entry->lvl = tmc->tmgroup->level; __entry->numa_node = tmc->tmgroup->numa_node; - __entry->capacity = hier->capacity; __entry->num_children = tmc->tmgroup->num_children; __entry->groupmask = tmc->groupmask; ), - TP_printk("cpu=%d groupmask=%0x parent=%p lvl=%d numa=%d capacity=%d num_children=%d", - __entry->cpu, __entry->groupmask, __entry->parent, __entry->lvl, - __entry->numa_node, __entry->capacity, __entry->num_children) + TP_printk("cpu=%d groupmask=%0x parent=%p lvl=%d numa=%d num_children=%d", + __entry->cpu, __entry->groupmask, __entry->parent, + __entry->lvl, __entry->numa_node, __entry->num_children) ); DECLARE_EVENT_CLASS(tmigr_group_and_cpu, diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 806c23cf71fc..52c15affdbff 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -102,7 +102,7 @@ * active CPU/group information atomic_try_cmpxchg() is used instead and only * the per CPU tmigr_cpu->lock is held. * - * During the setup of groups, hier->level_list is required. It is protected by + * During the setup of groups tmigr_level_list is required. It is protected by * @tmigr_mutex. * * When @timer_base->lock as well as tmigr related locks are required, the lock @@ -416,12 +416,13 @@ */ static DEFINE_MUTEX(tmigr_mutex); - -static LIST_HEAD(tmigr_hierarchy_list); +static struct list_head *tmigr_level_list __read_mostly; static unsigned int tmigr_hierarchy_levels __read_mostly; static unsigned int tmigr_crossnode_level __read_mostly; +static struct tmigr_group *tmigr_root; + static DEFINE_PER_CPU(struct tmigr_cpu, tmigr_cpu); /* @@ -1468,34 +1469,6 @@ static long tmigr_trigger_active(void *unused) return 0; } -static unsigned int tmigr_get_capacity(int cpu) -{ - /* - * nohz_full CPUs need to make sure there is always an available (online) - * and never idle migrator to handle all their global timers. That duty - * is served by the timekeeper which then never stops its tick. But the - * timekeeper must then belong to the same hierarchy as all the nohz_full - * CPUs. Simply turn off capacity awareness when nohz_full is running. - */ - if (tick_nohz_full_enabled() || !IS_ENABLED(CONFIG_BROKEN)) - return SCHED_CAPACITY_SCALE; - else - return arch_scale_cpu_capacity(cpu); -} - -static struct tmigr_hierarchy *__tmigr_get_hierarchy(int cpu) -{ - unsigned int capacity = tmigr_get_capacity(cpu); - struct tmigr_hierarchy *iter; - - list_for_each_entry(iter, &tmigr_hierarchy_list, node) { - if (iter->capacity == capacity) - return iter; - } - - return NULL; -} - static int tmigr_clear_cpu_available(unsigned int cpu) { struct tmigr_cpu *tmc = this_cpu_ptr(&tmigr_cpu); @@ -1520,21 +1493,8 @@ static int tmigr_clear_cpu_available(unsigned int cpu) } if (firstexp != KTIME_MAX) { - struct tmigr_hierarchy *hier = __tmigr_get_hierarchy(cpu); - - if (WARN_ON_ONCE(!hier)) - return -EINVAL; - - migrator = cpumask_any_and(tmigr_available_cpumask, hier->cpumask); - if (migrator < nr_cpu_ids) { - work_on_cpu(migrator, tmigr_trigger_active, NULL); - } else { - /* - * If deactivation returned an expiration, it belongs to an available - * nohz CPU in the hierarchy. - */ - WARN_ONCE(1, "Expected available CPU in the hierarchy\n"); - } + migrator = cpumask_any(tmigr_available_cpumask); + work_on_cpu(migrator, tmigr_trigger_active, NULL); } return 0; @@ -1697,14 +1657,14 @@ static void tmigr_init_group(struct tmigr_group *group, unsigned int lvl, group->groupevt.ignore = true; } -static struct tmigr_group *tmigr_get_group(struct tmigr_hierarchy *hier, int node, unsigned int lvl) +static struct tmigr_group *tmigr_get_group(int node, unsigned int lvl) { struct tmigr_group *tmp, *group = NULL; lockdep_assert_held(&tmigr_mutex); /* Try to attach to an existing group first */ - list_for_each_entry(tmp, &hier->level_list[lvl], list) { + list_for_each_entry(tmp, &tmigr_level_list[lvl], list) { /* * If @lvl is below the cross NUMA node level, check whether * this group belongs to the same NUMA node. @@ -1738,14 +1698,14 @@ static struct tmigr_group *tmigr_get_group(struct tmigr_hierarchy *hier, int nod tmigr_init_group(group, lvl, node); /* Setup successful. Add it to the hierarchy */ - list_add(&group->list, &hier->level_list[lvl]); + list_add(&group->list, &tmigr_level_list[lvl]); trace_tmigr_group_set(group); return group; } -static bool tmigr_init_root(struct tmigr_hierarchy *hier, struct tmigr_group *group, bool activate) +static bool tmigr_init_root(struct tmigr_group *group, bool activate) { - if (!group->parent && group != hier->root) { + if (!group->parent && group != tmigr_root) { /* * This is the new top-level, prepare its groupmask in advance * to avoid accidents where yet another new top-level is @@ -1761,10 +1721,11 @@ static bool tmigr_init_root(struct tmigr_hierarchy *hier, struct tmigr_group *gr } -static void tmigr_connect_child_parent(struct tmigr_hierarchy *hier, struct tmigr_group *child, - struct tmigr_group *parent, bool activate) +static void tmigr_connect_child_parent(struct tmigr_group *child, + struct tmigr_group *parent, + bool activate) { - if (tmigr_init_root(hier, parent, activate)) { + if (tmigr_init_root(parent, activate)) { /* * The previous top level had prepared its groupmask already, * simply account it in advance as the first child. If some groups @@ -1797,13 +1758,13 @@ static void tmigr_connect_child_parent(struct tmigr_hierarchy *hier, struct tmig */ smp_store_release(&child->parent, parent); - trace_tmigr_connect_child_parent(hier, child); + trace_tmigr_connect_child_parent(child); } -static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, - unsigned int node, struct tmigr_group *start, bool activate) +static int tmigr_setup_groups(unsigned int cpu, unsigned int node, + struct tmigr_group *start, bool activate) { - struct tmigr_group *root = hier->root, *group, *child, **stack; + struct tmigr_group *group, *child, **stack; int i, top = 0, err = 0, start_lvl = 0; bool root_mismatch = false; @@ -1816,11 +1777,11 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, start_lvl = start->level + 1; } - if (root) - root_mismatch = root->numa_node != node; + if (tmigr_root) + root_mismatch = tmigr_root->numa_node != node; for (i = start_lvl; i < tmigr_hierarchy_levels; i++) { - group = tmigr_get_group(hier, node, i); + group = tmigr_get_group(node, i); if (IS_ERR(group)) { err = PTR_ERR(group); i--; @@ -1842,7 +1803,7 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, if (group->parent) break; if ((!root_mismatch || i >= tmigr_crossnode_level) && - list_is_singular(&hier->level_list[i])) + list_is_singular(&tmigr_level_list[i])) break; } @@ -1870,15 +1831,15 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, tmc->tmgroup = group; tmc->groupmask = BIT(group->num_children++); - tmigr_init_root(hier, group, activate); + tmigr_init_root(group, activate); - trace_tmigr_connect_cpu_parent(hier, tmc); + trace_tmigr_connect_cpu_parent(tmc); /* There are no children that need to be connected */ continue; } else { child = stack[i - 1]; - tmigr_connect_child_parent(hier, child, group, activate); + tmigr_connect_child_parent(child, group, activate); } } @@ -1934,23 +1895,18 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, data.childmask = start->groupmask; __walk_groups_from(tmigr_active_up, &data, start, start->parent); } - } else if (start) { - union tmigr_state state; - - /* Remote activation assumes the whole target's hierarchy is inactive */ - state.state = atomic_read(&start->migr_state); - WARN_ON_ONCE(state.active); } /* Root update */ - if (list_is_singular(&hier->level_list[top])) { - group = list_first_entry(&hier->level_list[top], typeof(*group), list); + if (list_is_singular(&tmigr_level_list[top])) { + group = list_first_entry(&tmigr_level_list[top], + typeof(*group), list); WARN_ON_ONCE(group->parent); - if (root) { + if (tmigr_root) { /* Old root should be the same or below */ - WARN_ON_ONCE(root->level > top); + WARN_ON_ONCE(tmigr_root->level > top); } - hier->root = group; + tmigr_root = group; } out: kfree(stack); @@ -1958,123 +1914,34 @@ static int tmigr_setup_groups(struct tmigr_hierarchy *hier, unsigned int cpu, return err; } -static struct tmigr_hierarchy *tmigr_get_hierarchy(int cpu) -{ - struct tmigr_hierarchy *hier; - - hier = __tmigr_get_hierarchy(cpu); - - if (hier) - return hier; - - hier = kzalloc_flex(*hier, level_list, tmigr_hierarchy_levels); - if (!hier) - return ERR_PTR(-ENOMEM); - - hier->cpumask = kzalloc(cpumask_size(), GFP_KERNEL); - if (!hier->cpumask) { - kfree(hier); - return ERR_PTR(-ENOMEM); - } - - for (int i = 0; i < tmigr_hierarchy_levels; i++) - INIT_LIST_HEAD(&hier->level_list[i]); - - hier->capacity = tmigr_get_capacity(cpu); - list_add_tail(&hier->node, &tmigr_hierarchy_list); - - return hier; -} - -static int tmigr_connect_old_root(struct tmigr_hierarchy *hier, int cpu, - struct tmigr_group *old_root, bool activate) -{ - /* - * The target CPU must never do the prepare work, except - * on early boot when the boot CPU is the target. Otherwise - * it may spuriously activate the old top level group inside - * the new one (nevertheless whether old top level group is - * active or not) and/or release an uninitialized childmask. - */ - WARN_ON_ONCE(cpu == smp_processor_id()); - if (activate) { - /* - * The current CPU is expected to be online in the hierarchy, - * otherwise the old root may not be active as expected. - */ - WARN_ON_ONCE(!__this_cpu_read(tmigr_cpu.available)); - } - - return tmigr_setup_groups(hier, -1, old_root->numa_node, old_root, activate); -} - -static long connect_old_root_work(void *arg) -{ - struct tmigr_group *old_root = arg; - struct tmigr_hierarchy *hier; - int cpu = smp_processor_id(); - - hier = __tmigr_get_hierarchy(cpu); - if (WARN_ON_ONCE(!hier)) - return -EINVAL; - - return tmigr_connect_old_root(hier, cpu, old_root, true); -} - static int tmigr_add_cpu(unsigned int cpu) { - struct tmigr_hierarchy *hier; - struct tmigr_group *old_root; + struct tmigr_group *old_root = tmigr_root; int node = cpu_to_node(cpu); int ret; guard(mutex)(&tmigr_mutex); - hier = tmigr_get_hierarchy(cpu); - if (IS_ERR(hier)) - return PTR_ERR(hier); - - old_root = hier->root; - - ret = tmigr_setup_groups(hier, cpu, node, NULL, false); - - if (ret < 0) - return ret; + ret = tmigr_setup_groups(cpu, node, NULL, false); /* Root has changed? Connect the old one to the new */ - if (old_root && old_root != hier->root) { - guard(migrate)(); - - if (cpumask_test_cpu(smp_processor_id(), hier->cpumask)) { - /* - * If the target belong to the same hierarchy, the old root is expected - * to be active. Link and propagate to the new root. - */ - ret = tmigr_connect_old_root(hier, cpu, old_root, true); - } else { - int target = cpumask_first_and(hier->cpumask, tmigr_available_cpumask); - - if (target < nr_cpu_ids) { - /* - * If the target doesn't belong to the same hierarchy as the current - * CPU, activate from a relevant one to make sure the old root is - * active. - */ - ret = work_on_cpu(target, connect_old_root_work, old_root); - } else { - /* - * No other available CPUs in the remote hierarchy. Link the - * old root remotely but don't propagate activation since the - * old root is not expected to be active. - */ - ret = tmigr_connect_old_root(hier, cpu, old_root, false); - } - } + if (ret >= 0 && old_root && old_root != tmigr_root) { + /* + * The target CPU must never do the prepare work, except + * on early boot when the boot CPU is the target. Otherwise + * it may spuriously activate the old top level group inside + * the new one (nevertheless whether old top level group is + * active or not) and/or release an uninitialized childmask. + */ + WARN_ON_ONCE(cpu == raw_smp_processor_id()); + /* + * The (likely) current CPU is expected to be online in the hierarchy, + * otherwise the old root may not be active as expected. + */ + WARN_ON_ONCE(!per_cpu_ptr(&tmigr_cpu, raw_smp_processor_id())->available); + ret = tmigr_setup_groups(-1, old_root->numa_node, old_root, true); } - if (ret >= 0) - cpumask_set_cpu(cpu, hier->cpumask); - return ret; } @@ -2107,7 +1974,7 @@ static int tmigr_cpu_prepare(unsigned int cpu) static int __init tmigr_init(void) { - unsigned int cpulvl, nodelvl, cpus_per_node; + unsigned int cpulvl, nodelvl, cpus_per_node, i; unsigned int nnodes = num_possible_nodes(); unsigned int ncpus = num_possible_cpus(); int ret = -ENOMEM; @@ -2154,6 +2021,14 @@ static int __init tmigr_init(void) */ tmigr_crossnode_level = cpulvl; + tmigr_level_list = kzalloc_objs(struct list_head, + tmigr_hierarchy_levels); + if (!tmigr_level_list) + goto err; + + for (i = 0; i < tmigr_hierarchy_levels; i++) + INIT_LIST_HEAD(&tmigr_level_list[i]); + pr_info("Timer migration: %d hierarchy levels; %d children per group;" " %d crossnode level\n", tmigr_hierarchy_levels, TMIGR_CHILDREN_PER_GROUP, diff --git a/kernel/time/timer_migration.h b/kernel/time/timer_migration.h index 31735dd52327..4c0073f3d321 100644 --- a/kernel/time/timer_migration.h +++ b/kernel/time/timer_migration.h @@ -5,24 +5,6 @@ /* Per group capacity. Must be a power of 2! */ #define TMIGR_CHILDREN_PER_GROUP 8 -/** - * struct tmigr_hierarchy - a hierarchy associated to a given CPU capacity. - * Homogeneous systems have only one hierarchy. - * Heterogenous have one hierarchy per CPU capacity. - * @cpumask: CPUs belonging to this hierarchy - * @root: The current root of the hierarchy - * @capacity: CPU capacity associated to this hierarchy - * @node: Node in the global hierarchy list - * @level_list: Per level lists of tmigr groups - */ -struct tmigr_hierarchy { - struct cpumask *cpumask; - struct tmigr_group *root; - unsigned long capacity; - struct list_head node; - struct list_head level_list[]; -}; - /** * struct tmigr_event - a timer event associated to a CPU * @nextevt: The node to enqueue an event in the parent group queue diff --git a/scripts/timer_migration_tree.py b/scripts/timer_migration_tree.py index faac9de854bd..abb321b903c4 100755 --- a/scripts/timer_migration_tree.py +++ b/scripts/timer_migration_tree.py @@ -12,6 +12,7 @@ import re, sys from ete3 import Tree class Node: + node_list = { } def __init__(self, group): self.group = group self.children = [] @@ -45,29 +46,21 @@ class Node: parent_grp = "-" return "Group: %s mask: %s parent: %s lvl: %d numa: %d num_children: %d" % (self.group, self.groupmask, parent_grp, self.lvl, self.numa, self.num_children) -hierarchies = { } - -def get_hierarchy(capacity): - if capacity not in hierarchies: - hierarchies[capacity] = {} - return hierarchies[capacity] - -def get_node(capacity, group): - hier = get_hierarchy(capacity) - if group in hier: - return hier[group] +def get_node(group): + if group in Node.node_list: + return Node.node_list[group] else: n = Node(group) - hier[group] = n + Node.node_list[group] = n return n def tmigr_connect_cpu_parent(ts, line): - s = re.search("tmigr_connect_cpu_parent: cpu=([0-9]+) groupmask=([0-9a-zA-Z]+) parent=([0-9a-zA-Z]+) lvl=([0-9]+) numa=([-]?[0-9]+) capacity=([-]?[0-9]+) num_children=([0-9]+)", line) + s = re.search("tmigr_connect_cpu_parent: cpu=([0-9]+) groupmask=([0-9a-zA-Z]+) parent=([0-9a-zA-Z]+) lvl=([0-9]+) numa=([-]?[0-9]+) num_children=([0-9]+)", line) if s is None: return False - (cpu, groupmask, parent, lvl, numa, capacity, num_children) = (int(s.group(1)), s.group(2), s.group(3), int(s.group(4)), int(s.group(5)), int(s.group(6)), int(s.group(7))) - n = get_node(capacity, cpu) - p = get_node(capacity, parent) + (cpu, groupmask, parent, lvl, numa, num_children) = (int(s.group(1)), s.group(2), s.group(3), int(s.group(4)), int(s.group(5)), int(s.group(6))) + n = get_node(cpu) + p = get_node(parent) n.set_parent(p) n.set_groupmask(groupmask) n.set_lvl(-1) @@ -78,12 +71,12 @@ def tmigr_connect_cpu_parent(ts, line): p.add_child(n) def tmigr_connect_child_parent(ts, line): - s = re.search("tmigr_connect_child_parent: group=([0-9a-zA-Z]+) groupmask=([0-9a-zA-Z]+) parent=([0-9a-zA-Z]+) lvl=([0-9]+) numa=([-]?[0-9]+) capacity=([-]?[0-9]+) num_children=([0-9]+)", line) + s = re.search("tmigr_connect_child_parent: group=([0-9a-zA-Z]+) groupmask=([0-9a-zA-Z]+) parent=([0-9a-zA-Z]+) lvl=([0-9]+) numa=([-]?[0-9]+) num_children=([0-9]+)", line) if s is None: return False - (group, groupmask, parent, lvl, numa, capacity, num_children) = (s.group(1), s.group(2), s.group(3), int(s.group(4)), int(s.group(5)), int(s.group(6)), int(s.group(7))) - n = get_node(capacity, group) - p = get_node(capacity, parent) + (group, groupmask, parent, lvl, numa, num_children) = (s.group(1), s.group(2), s.group(3), int(s.group(4)), int(s.group(5)), int(s.group(6))) + n = get_node(group) + p = get_node(parent) n.set_parent(p) n.set_groupmask(groupmask) p.set_lvl(lvl) @@ -109,14 +102,9 @@ if __name__ == "__main__": if tmigr_connect_child_parent(float(s.group(1)), s.group(2)): continue - for cap in hierarchies: - h = hierarchies[cap] - print("Tree for capacity %d" % cap) - for k in h: - n = h[k] - while n.parent != None: - n = n.parent - root = Tree() - populate(root, n) - print(root.get_ascii(show_internal=True, attributes=["name", "numa", "lvl"])) - break + group = list(Node.node_list.values())[0] + while group.parent != None: + group = group.parent + root = Tree() + populate(root, group) + print(root.get_ascii(show_internal=True, attributes=["name", "numa", "lvl"])) -- 2.53.0