diff --git a/[refs] b/[refs] index 5f5d4ee19da0..3065446bf6b1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 747584be04bb98a856bab5cd1bfe56d341881b83 +refs/heads/master: 04a344069052d94b4ea1f95d930cbfa39b4ca292 diff --git a/trunk/arch/ia64/kernel/unwind.c b/trunk/arch/ia64/kernel/unwind.c index f47217b1bb37..fed6afa2e8a9 100644 --- a/trunk/arch/ia64/kernel/unwind.c +++ b/trunk/arch/ia64/kernel/unwind.c @@ -1531,7 +1531,7 @@ build_script (struct unw_frame_info *info) struct unw_labeled_state *ls, *next; unsigned long ip = info->ip; struct unw_state_record sr; - struct unw_table *table; + struct unw_table *table, *prev; struct unw_reg_info *r; struct unw_insn insn; u8 *dp, *desc_end; @@ -1560,11 +1560,26 @@ build_script (struct unw_frame_info *info) STAT(parse_start = ia64_get_itc()); + prev = NULL; for (table = unw.tables; table; table = table->next) { if (ip >= table->start && ip < table->end) { + /* + * Leave the kernel unwind table at the very front, + * lest moving it breaks some assumption elsewhere. + * Otherwise, move the matching table to the second + * position in the list so that traversals can benefit + * from commonality in backtrace paths. + */ + if (prev && prev != unw.tables) { + /* unw is safe - we're already spinlocked */ + prev->next = table->next; + table->next = unw.tables->next; + unw.tables->next = table; + } e = lookup(table, ip - table->segment_base); break; } + prev = table; } if (!e) { /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */