History

Merge branches 'x86-fixes-for-linus', 'sched-fixes-for-linus', 'timers-fixes-for-linus', 'irq-fixes-for-linus' and 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86-32, fpu: Fix FPU exception handling on non-SSE systems x86, hibernate: Initialize mmu_cr4_features during boot x86-32, NUMA: Fix ACPI NUMA init broken by recent x86-64 change x86: visws: Fixup irq overhaul fallout * 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: sched: Clean up rebalance_domains() load-balance interval calculation * 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86/mrst/vrtc: Fix boot crash in mrst_rtc_init() rtc, x86/mrst/vrtc: Fix boot crash in rtc_read_alarm() * 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: genirq: Fix cpumask leak in __setup_irq() * 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf probe: Fix listing incorrect line number with inline function perf probe: Fix to find recursively inlined function perf probe: Fix multiple --vars options behavior perf probe: Fix to remove redundant close perf probe: Fix to ensure function declared file

Linus Torvalds committed 15 years ago

Commit 8b9686f6 parents df9b29d f994d99 49c022e 09552b2 4f5058c f64fac811 files · +151 −89Browse files

Unified · Split

11 files
  1. arch/x86/include/asm/i387.h +1 −1
  2. arch/x86/kernel/setup.c +5 −0
  3. arch/x86/mm/srat_32.c +3 −1
  4. arch/x86/platform/mrst/vrtc.c +3 −1
  5. arch/x86/platform/visws/visws_quirks.c +6 −14
  6. drivers/rtc/rtc-mrst.c +4 −3
  7. kernel/irq/manage.c +1 −0
  8. kernel/sched.c +3 −0
  9. kernel/sched_fair.c +12 −4
  10. tools/perf/util/probe-event.c +8 −11
  11. tools/perf/util/probe-finder.c +105 −54
arch/x86/include/asm/i387.h+1−1
@@ -237,7 +237,7 @@ static inline void fpu_save_init(struct fpu *fpu) · 236 unmodified lines
237237 } else if (use_fxsr()) {
238238 fpu_fxsave(fpu);
239239 } else {
240− asm volatile("fsave %[fx]; fwait"
240+ asm volatile("fnsave %[fx]; fwait"
241241 : [fx] "=m" (fpu->state->fsave));
242242 return;
243243 }
arch/x86/kernel/setup.c+5−0
@@ -976,6 +976,11 @@ void __init setup_arch(char **cmdline_p) · 975 unmodified lines
976976 paging_init();
977977 x86_init.paging.pagetable_setup_done(swapper_pg_dir);
978978
979+ if (boot_cpu_data.cpuid_level >= 0) {
980+ /* A CPU has %cr4 if and only if it has CPUID */
981+ mmu_cr4_features = read_cr4();
982+ }
983+
979984 #ifdef CONFIG_X86_32
980985 /* sync back kernel address range */
981986 clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
arch/x86/mm/srat_32.c+3−1
@@ -211,10 +211,12 @@ int __init get_memcfg_from_srat(void) · 210 unmodified lines
211211 {
212212 int i, j, nid;
213213
214−
215214 if (srat_disabled())
216215 goto out_fail;
217216
217+ if (acpi_numa_init() < 0)
218+ goto out_fail;
219+
218220 if (num_memory_chunks == 0) {
219221 printk(KERN_DEBUG
220222 "could not find any ACPI SRAT memory areas.\n");
arch/x86/platform/mrst/vrtc.c+3−1
@@ -100,9 +100,11 @@ int vrtc_set_mmss(unsigned long nowtime) · 99 unmodified lines
100100
101101 void __init mrst_rtc_init(void)
102102 {
103− unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr;
103+ unsigned long vrtc_paddr;
104104
105105 sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
106+
107+ vrtc_paddr = sfi_mrtc_array[0].phys_addr;
106108 if (!sfi_mrtc_num || !vrtc_paddr)
107109 return;
108110
arch/x86/platform/visws/visws_quirks.c+6−14
@@ -471,15 +471,7 @@ static unsigned int startup_piix4_master_irq(struct irq_data *data) · 470 unmodified lines
471471 {
472472 legacy_pic->init(0);
473473 enable_cobalt_irq(data);
474−}
475−
476−static void end_piix4_master_irq(struct irq_data *data)
477−{
478− unsigned long flags;
479−
480− spin_lock_irqsave(&cobalt_lock, flags);
481− enable_cobalt_irq(data);
482− spin_unlock_irqrestore(&cobalt_lock, flags);
474+ return 0;
483475 }
484476
485477 static struct irq_chip piix4_master_irq_type = {
@@ -492,7 +484,7 @@ static void pii4_mask(struct irq_data *data) { } · 6 unmodified lines
492484
493485 static struct irq_chip piix4_virtual_irq_type = {
494486 .name = "PIIX4-virtual",
495− .mask = pii4_mask,
487+ .irq_mask = pii4_mask,
496488 };
497489
498490 /*
@@ -580,9 +572,9 @@ static struct irqaction cascade_action = { · 81 unmodified lines
580572
581573 static inline void set_piix4_virtual_irq_type(void)
582574 {
583− piix4_virtual_irq_type.enable = i8259A_chip.unmask;
584− piix4_virtual_irq_type.disable = i8259A_chip.mask;
585− piix4_virtual_irq_type.unmask = i8259A_chip.unmask;
575+ piix4_virtual_irq_type.irq_enable = i8259A_chip.irq_unmask;
576+ piix4_virtual_irq_type.irq_disable = i8259A_chip.irq_mask;
577+ piix4_virtual_irq_type.irq_unmask = i8259A_chip.irq_unmask;
586578 }
587579
588580 static void __init visws_pre_intr_init(void)
@@ -599,7 +591,7 @@ static void __init visws_pre_intr_init(void) · 10 unmodified lines
599591 else if (i == CO_IRQ_IDE0)
600592 chip = &cobalt_irq_type;
601593 else if (i == CO_IRQ_IDE1)
602− >chip = &cobalt_irq_type;
594+ chip = &cobalt_irq_type;
603595 else if (i == CO_IRQ_8259)
604596 chip = &piix4_master_irq_type;
605597 else if (i < CO_IRQ_APIC0)
drivers/rtc/rtc-mrst.c+4−3
@@ -342,6 +342,8 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) · 341 unmodified lines
342342
343343 mrst_rtc.irq = rtc_irq;
344344 mrst_rtc.iomem = iomem;
345+ mrst_rtc.dev = dev;
346+ dev_set_drvdata(dev, &mrst_rtc);
345347
346348 mrst_rtc.rtc = rtc_device_register(driver_name, dev,
347349 &mrst_rtc_ops, THIS_MODULE);
@@ -350,8 +352,6 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) · 2 unmodified lines
350352 goto cleanup0;
351353 }
352354
353− mrst_rtc.dev = dev;
354− dev_set_drvdata(dev, &mrst_rtc);
355355 rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
356356
357357 spin_lock_irq(&rtc_lock);
@@ -376,9 +376,10 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) · 18 unmodified lines
376376 return 0;
377377
378378 cleanup1:
379− mrst_rtc.dev = NULL;
380379 rtc_device_unregister(mrst_rtc.rtc);
381380 cleanup0:
381+ dev_set_drvdata(dev, NULL);
382+ mrst_rtc.dev = NULL;
382383 release_region(iomem->start, iomem->end + 1 - iomem->start);
383384 dev_err(dev, "rtc-mrst: unable to initialise\n");
384385 return retval;
kernel/irq/manage.c+1−0
@@ -1051,6 +1051,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) · 1050 unmodified lines
10511051 register_irq_proc(irq, desc);
10521052 new->dir = NULL;
10531053 register_handler_proc(irq, new);
1054+ free_cpumask_var(mask);
10541055
10551056 return 0;
10561057
kernel/sched.c+3−0
@@ -6331,6 +6331,9 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) · 6330 unmodified lines
63316331 break;
63326332 #endif
63336333 }
6334+
6335+ update_max_interval();
6336+
63346337 return NOTIFY_OK;
63356338 }
63366339
kernel/sched_fair.c+12−4
@@ -3820,6 +3820,17 @@ void select_nohz_load_balancer(int stop_tick) · 3819 unmodified lines
38203820
38213821 static DEFINE_SPINLOCK(balancing);
38223822
3823+static unsigned long __read_mostly max_load_balance_interval = HZ/10;
3824+
3825+/*
3826+ * Scale the max load_balance interval with the number of CPUs in the system.
3827+ * This trades load-balance latency on larger machines for less cross talk.
3828+ */
3829+static void update_max_interval(void)
3830+{
3831+ max_load_balance_interval = HZ*num_online_cpus()/10;
3832+}
3833+
38233834 /*
38243835 * It checks each scheduling domain to see if it is due to be balanced,
38253836 * and initiates a balancing operation if so.
@@ -3849,10 +3860,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) · 23 unmodified lines
38493860
38503861 /* scale ms to jiffies */
38513862 interval = msecs_to_jiffies(interval);
3852− if (unlikely(!interval))
3853− interval = 1;
3854− if (interval > HZ*num_online_cpus()/10)
3855− interval = HZ*num_online_cpus()/10;
3863+ interval = clamp(interval, 1UL, max_load_balance_interval);
38563864
38573865 need_serialize = sd->flags & SD_SERIALIZE;
38583866
tools/perf/util/probe-event.c+8−11
@@ -234,7 +234,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, · 233 unmodified lines
234234
235235 /* Searching trace events corresponding to probe event */
236236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);
237− close(fd);
238237
239238 if (ntevs > 0) { /* Succeeded to find trace events */
240239 pr_debug("find %d probe_trace_events.\n", ntevs);
@@ -388,7 +387,6 @@ int show_line_range(struct line_range *lr, const char *module) · 147 unmodified lines
388387 }
389388
390389 ret = find_line_range(fd, lr);
391− close(fd);
392390 if (ret == 0) {
393391 pr_warning("Specified source line is not found.\n");
394392 return -ENOENT;
@@ -512,19 +510,18 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, · 117 unmodified lines
512510 if (ret < 0)
513511 return ret;
514512
515− fd = open_vmlinux(module);
516− if (fd < 0) {
517− pr_warning("Failed to open debug information file.\n");
518− return fd;
519− }
520−
521513 setup_pager();
522514
523− for (i = 0; i < npevs && ret >= 0; i++)
515+ for (i = 0; i < npevs && ret >= 0; i++) {
516+ fd = open_vmlinux(module);
517+ if (fd < 0) {
518+ pr_warning("Failed to open debug information file.\n");
519+ ret = fd;
520+ break;
521+ }
524522 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
525523 externs);
526−
527− close(fd);
524+ }
528525 return ret;
529526 }
530527
tools/perf/util/probe-finder.c+105−54
@@ -273,6 +273,25 @@ static const char *cu_get_comp_dir(Dwarf_Die *cu_die) · 272 unmodified lines
273273 return dwarf_formstring(&attr);
274274 }
275275
276+/* Get a line number and file name for given address */
277+static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
278+ const char **fname, int *lineno)
279+{
280+ Dwarf_Line *line;
281+ Dwarf_Addr laddr;
282+
283+ line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr);
284+ if (line && dwarf_lineaddr(line, &laddr) == 0 &&
285+ addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
286+ *fname = dwarf_linesrc(line, NULL, NULL);
287+ if (!*fname)
288+ /* line number is useless without filename */
289+ *lineno = 0;
290+ }
291+
292+ return *lineno ?: -ENOENT;
293+}
294+
276295 /* Compare diename and tname */
277296 static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
278297 {
@@ -497,7 +516,20 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) · 218 unmodified lines
497516 static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
498517 Dwarf_Die *die_mem)
499518 {
500− return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
519+ Dwarf_Die tmp_die;
520+
521+ sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
522+ if (!sp_die)
523+ return NULL;
524+
525+ /* Inlined function could be recursive. Trace it until fail */
526+ while (sp_die) {
527+ memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
528+ sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
529+ &tmp_die);
530+ }
531+
532+ return die_mem;
501533 }
502534
503535 /* Walker on lines (Note: line number will not be sorted) */
@@ -1395,6 +1427,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) · 891 unmodified lines
13951427 !die_compare_name(sp_die, pp->function))
13961428 return DWARF_CB_OK;
13971429
1430+ /* Check declared file */
1431+ if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
1432+ return DWARF_CB_OK;
1433+
13981434 pf->fname = dwarf_decl_file(sp_die);
13991435 if (pp->line) { /* Function relative line */
14001436 dwarf_decl_line(sp_die, &pf->lno);
@@ -1451,6 +1487,7 @@ static int find_probes(int fd, struct probe_finder *pf) · 50 unmodified lines
14511487 if (!dbg) {
14521488 pr_warning("No debug information found in the vmlinux - "
14531489 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1490+ close(fd); /* Without dwfl_end(), fd isn't closed. */
14541491 return -EBADF;
14551492 }
14561493
@@ -1686,11 +1723,9 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) · 229 unmodified lines
16861723 Dwarf_Die cudie, spdie, indie;
16871724 Dwarf *dbg = NULL;
16881725 Dwfl *dwfl = NULL;
1689− Dwarf_Line *line;
1690− Dwarf_Addr laddr, eaddr, bias = 0;
1691− const char *tmp;
1692− int lineno, ret = 0;
1693− bool found = false;
1726+ Dwarf_Addr _addr, baseaddr, bias = 0;
1727+ const char *fname = NULL, *func = NULL, *tmp;
1728+ int baseline = 0, lineno = 0, ret = 0;
16941729
16951730 /* Open the live linux kernel */
16961731 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
@@ -1711,68 +1746,79 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) · 14 unmodified lines
17111746 goto end;
17121747 }
17131748
1714− /* Find a corresponding line */
1715− line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
1716− if (line) {
1717− if (dwarf_lineaddr(line, &laddr) == 0 &&
1718− (Dwarf_Addr)addr == laddr &&
1719− dwarf_lineno(line, &lineno) == 0) {
1720− tmp = dwarf_linesrc(line, NULL, NULL);
1721− if (tmp) {
1722− ppt->line = lineno;
1723− ppt->file = strdup(tmp);
1724− if (ppt->file == NULL) {
1725− ret = -ENOMEM;
1726− goto end;
1727− }
1728− found = true;
1729− }
1730− }
1731− }
1749+ /* Find a corresponding line (filename and lineno) */
1750+ cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1751+ /* Don't care whether it failed or not */
17321752
1733− /* Find a corresponding function */
1753+ /* Find a corresponding function (name, baseline and baseaddr) */
17341754 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1755+ /* Get function entry information */
17351756 tmp = dwarf_diename(&spdie);
1736− if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
1737− goto end;
1738−
1739− if (ppt->line) {
1740− if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1741− &indie)) {
1742− /* addr in an inline function */
1757+ if (!tmp ||
1758+ dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1759+ dwarf_decl_line(&spdie, &baseline) != 0)
1760+ goto post;
1761+ func = tmp;
1762+
1763+ if (addr == (unsigned long)baseaddr)
1764+ /* Function entry - Relative line number is 0 */
1765+ lineno = baseline;
1766+ else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1767+ &indie)) {
1768+ if (dwarf_entrypc(&indie, &_addr) == 0 &&
1769+ _addr == addr)
1770+ /*
1771+ * addr is at an inline function entry.
1772+ * In this case, lineno should be the call-site
1773+ * line number.
1774+ */
1775+ lineno = die_get_call_lineno(&indie);
1776+ else {
1777+ /*
1778+ * addr is in an inline function body.
1779+ * Since lineno points one of the lines
1780+ * of the inline function, baseline should
1781+ * be the entry line of the inline function.
1782+ */
17431783 tmp = dwarf_diename(&indie);
1744− if (!tmp)
1745− goto end;
1746− ret = dwarf_decl_line(&indie, &lineno);
1747− } else {
1748− if (eaddr == addr) { /* Function entry */
1749− lineno = ppt->line;
1750− ret = 0;
1751− } else
1752− ret = dwarf_decl_line(&spdie, &lineno);
1753− }
1754− if (ret == 0) {
1755− /* Make a relative line number */
1756− ppt->line -= lineno;
1757− goto found;
1784+ if (tmp &&
1785+ dwarf_decl_line(&spdie, &baseline) == 0)
1786+ func = tmp;
17581787 }
17591788 }
1760− /* We don't have a line number, let's use offset */
1761− ppt->offset = addr - (unsigned long)eaddr;
1762−found:
1763− ppt->function = strdup(tmp);
1789+ }
1790+
1791+post:
1792+ /* Make a relative line number or an offset */
1793+ if (lineno)
1794+ ppt->line = lineno - baseline;
1795+ else if (func)
1796+ ppt->offset = addr - (unsigned long)baseaddr;
1797+
1798+ /* Duplicate strings */
1799+ if (func) {
1800+ ppt->function = strdup(func);
17641801 if (ppt->function == NULL) {
17651802 ret = -ENOMEM;
17661803 goto end;
17671804 }
1768− found = true;
17691805 }
1770−
1806+ if (fname) {
1807+ ppt->file = strdup(fname);
1808+ if (ppt->file == NULL) {
1809+ if (ppt->function) {
1810+ free(ppt->function);
1811+ ppt->function = NULL;
1812+ }
1813+ ret = -ENOMEM;
1814+ goto end;
1815+ }
1816+ }
17711817 end:
17721818 if (dwfl)
17731819 dwfl_end(dwfl);
1774− if (ret >= 0)
1775− ret = found ? 1 : 0;
1820+ if (ret == 0 && (fname || func))
1821+ ret = 1; /* Found a point */
17761822 return ret;
17771823 }
17781824
@@ -1840,6 +1886,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) · 61 unmodified lines
18401886 struct line_finder *lf = param->data;
18411887 struct line_range *lr = lf->lr;
18421888
1889+ /* Check declared file */
1890+ if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1891+ return DWARF_CB_OK;
1892+
18431893 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
18441894 die_compare_name(sp_die, lr->function)) {
18451895 lf->fname = dwarf_decl_file(sp_die);
@@ -1892,6 +1942,7 @@ int find_line_range(int fd, struct line_range *lr) · 46 unmodified lines
18921942 if (!dbg) {
18931943 pr_warning("No debug information found in the vmlinux - "
18941944 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1945+ close(fd); /* Without dwfl_end(), fd isn't closed. */
18951946 return -EBADF;
18961947 }
18971948

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t