Commit 8b9686ff4ddfdf45662024edd567920e6db87beb
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
Showing 11 changed files Side-by-side Diff
arch/x86/include/asm/i387.h
arch/x86/kernel/setup.c
... | ... | @@ -976,6 +976,11 @@ |
976 | 976 | paging_init(); |
977 | 977 | x86_init.paging.pagetable_setup_done(swapper_pg_dir); |
978 | 978 | |
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 | + | |
979 | 984 | #ifdef CONFIG_X86_32 |
980 | 985 | /* sync back kernel address range */ |
981 | 986 | clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY, |
arch/x86/mm/srat_32.c
arch/x86/platform/mrst/vrtc.c
... | ... | @@ -100,9 +100,11 @@ |
100 | 100 | |
101 | 101 | void __init mrst_rtc_init(void) |
102 | 102 | { |
103 | - unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr; | |
103 | + unsigned long vrtc_paddr; | |
104 | 104 | |
105 | 105 | sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc); |
106 | + | |
107 | + vrtc_paddr = sfi_mrtc_array[0].phys_addr; | |
106 | 108 | if (!sfi_mrtc_num || !vrtc_paddr) |
107 | 109 | return; |
108 | 110 |
arch/x86/platform/visws/visws_quirks.c
... | ... | @@ -471,17 +471,9 @@ |
471 | 471 | { |
472 | 472 | legacy_pic->init(0); |
473 | 473 | enable_cobalt_irq(data); |
474 | + return 0; | |
474 | 475 | } |
475 | 476 | |
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); | |
483 | -} | |
484 | - | |
485 | 477 | static struct irq_chip piix4_master_irq_type = { |
486 | 478 | .name = "PIIX4-master", |
487 | 479 | .irq_startup = startup_piix4_master_irq, |
... | ... | @@ -492,7 +484,7 @@ |
492 | 484 | |
493 | 485 | static struct irq_chip piix4_virtual_irq_type = { |
494 | 486 | .name = "PIIX4-virtual", |
495 | - .mask = pii4_mask, | |
487 | + .irq_mask = pii4_mask, | |
496 | 488 | }; |
497 | 489 | |
498 | 490 | /* |
... | ... | @@ -580,9 +572,9 @@ |
580 | 572 | |
581 | 573 | static inline void set_piix4_virtual_irq_type(void) |
582 | 574 | { |
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; | |
586 | 578 | } |
587 | 579 | |
588 | 580 | static void __init visws_pre_intr_init(void) |
... | ... | @@ -599,7 +591,7 @@ |
599 | 591 | else if (i == CO_IRQ_IDE0) |
600 | 592 | chip = &cobalt_irq_type; |
601 | 593 | else if (i == CO_IRQ_IDE1) |
602 | - >chip = &cobalt_irq_type; | |
594 | + chip = &cobalt_irq_type; | |
603 | 595 | else if (i == CO_IRQ_8259) |
604 | 596 | chip = &piix4_master_irq_type; |
605 | 597 | else if (i < CO_IRQ_APIC0) |
drivers/rtc/rtc-mrst.c
... | ... | @@ -342,6 +342,8 @@ |
342 | 342 | |
343 | 343 | mrst_rtc.irq = rtc_irq; |
344 | 344 | mrst_rtc.iomem = iomem; |
345 | + mrst_rtc.dev = dev; | |
346 | + dev_set_drvdata(dev, &mrst_rtc); | |
345 | 347 | |
346 | 348 | mrst_rtc.rtc = rtc_device_register(driver_name, dev, |
347 | 349 | &mrst_rtc_ops, THIS_MODULE); |
... | ... | @@ -350,8 +352,6 @@ |
350 | 352 | goto cleanup0; |
351 | 353 | } |
352 | 354 | |
353 | - mrst_rtc.dev = dev; | |
354 | - dev_set_drvdata(dev, &mrst_rtc); | |
355 | 355 | rename_region(iomem, dev_name(&mrst_rtc.rtc->dev)); |
356 | 356 | |
357 | 357 | spin_lock_irq(&rtc_lock); |
358 | 358 | |
... | ... | @@ -376,9 +376,10 @@ |
376 | 376 | return 0; |
377 | 377 | |
378 | 378 | cleanup1: |
379 | - mrst_rtc.dev = NULL; | |
380 | 379 | rtc_device_unregister(mrst_rtc.rtc); |
381 | 380 | cleanup0: |
381 | + dev_set_drvdata(dev, NULL); | |
382 | + mrst_rtc.dev = NULL; | |
382 | 383 | release_region(iomem->start, iomem->end + 1 - iomem->start); |
383 | 384 | dev_err(dev, "rtc-mrst: unable to initialise\n"); |
384 | 385 | return retval; |
kernel/irq/manage.c
kernel/sched.c
kernel/sched_fair.c
... | ... | @@ -3820,7 +3820,18 @@ |
3820 | 3820 | |
3821 | 3821 | static DEFINE_SPINLOCK(balancing); |
3822 | 3822 | |
3823 | +static unsigned long __read_mostly max_load_balance_interval = HZ/10; | |
3824 | + | |
3823 | 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 | + | |
3834 | +/* | |
3824 | 3835 | * It checks each scheduling domain to see if it is due to be balanced, |
3825 | 3836 | * and initiates a balancing operation if so. |
3826 | 3837 | * |
... | ... | @@ -3849,10 +3860,7 @@ |
3849 | 3860 | |
3850 | 3861 | /* scale ms to jiffies */ |
3851 | 3862 | 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); | |
3856 | 3864 | |
3857 | 3865 | need_serialize = sd->flags & SD_SERIALIZE; |
3858 | 3866 |
tools/perf/util/probe-event.c
... | ... | @@ -234,7 +234,6 @@ |
234 | 234 | |
235 | 235 | /* Searching trace events corresponding to probe event */ |
236 | 236 | ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs); |
237 | - close(fd); | |
238 | 237 | |
239 | 238 | if (ntevs > 0) { /* Succeeded to find trace events */ |
240 | 239 | pr_debug("find %d probe_trace_events.\n", ntevs); |
... | ... | @@ -388,7 +387,6 @@ |
388 | 387 | } |
389 | 388 | |
390 | 389 | ret = find_line_range(fd, lr); |
391 | - close(fd); | |
392 | 390 | if (ret == 0) { |
393 | 391 | pr_warning("Specified source line is not found.\n"); |
394 | 392 | return -ENOENT; |
395 | 393 | |
396 | 394 | |
... | ... | @@ -512,19 +510,18 @@ |
512 | 510 | if (ret < 0) |
513 | 511 | return ret; |
514 | 512 | |
515 | - fd = open_vmlinux(module); | |
516 | - if (fd < 0) { | |
517 | - pr_warning("Failed to open debug information file.\n"); | |
518 | - return fd; | |
519 | - } | |
520 | - | |
521 | 513 | setup_pager(); |
522 | 514 | |
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 | + } | |
524 | 522 | ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter, |
525 | 523 | externs); |
526 | - | |
527 | - close(fd); | |
524 | + } | |
528 | 525 | return ret; |
529 | 526 | } |
530 | 527 |
tools/perf/util/probe-finder.c
... | ... | @@ -273,6 +273,25 @@ |
273 | 273 | return dwarf_formstring(&attr); |
274 | 274 | } |
275 | 275 | |
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 | + | |
276 | 295 | /* Compare diename and tname */ |
277 | 296 | static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) |
278 | 297 | { |
... | ... | @@ -497,7 +516,20 @@ |
497 | 516 | static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
498 | 517 | Dwarf_Die *die_mem) |
499 | 518 | { |
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; | |
501 | 533 | } |
502 | 534 | |
503 | 535 | /* Walker on lines (Note: line number will not be sorted) */ |
... | ... | @@ -1395,6 +1427,10 @@ |
1395 | 1427 | !die_compare_name(sp_die, pp->function)) |
1396 | 1428 | return DWARF_CB_OK; |
1397 | 1429 | |
1430 | + /* Check declared file */ | |
1431 | + if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die))) | |
1432 | + return DWARF_CB_OK; | |
1433 | + | |
1398 | 1434 | pf->fname = dwarf_decl_file(sp_die); |
1399 | 1435 | if (pp->line) { /* Function relative line */ |
1400 | 1436 | dwarf_decl_line(sp_die, &pf->lno); |
... | ... | @@ -1451,6 +1487,7 @@ |
1451 | 1487 | if (!dbg) { |
1452 | 1488 | pr_warning("No debug information found in the vmlinux - " |
1453 | 1489 | "please rebuild with CONFIG_DEBUG_INFO=y.\n"); |
1490 | + close(fd); /* Without dwfl_end(), fd isn't closed. */ | |
1454 | 1491 | return -EBADF; |
1455 | 1492 | } |
1456 | 1493 | |
... | ... | @@ -1686,11 +1723,9 @@ |
1686 | 1723 | Dwarf_Die cudie, spdie, indie; |
1687 | 1724 | Dwarf *dbg = NULL; |
1688 | 1725 | 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; | |
1694 | 1729 | |
1695 | 1730 | /* Open the live linux kernel */ |
1696 | 1731 | dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias); |
1697 | 1732 | |
1698 | 1733 | |
1699 | 1734 | |
1700 | 1735 | |
1701 | 1736 | |
1702 | 1737 | |
1703 | 1738 | |
1704 | 1739 | |
1705 | 1740 | |
1706 | 1741 | |
... | ... | @@ -1711,68 +1746,79 @@ |
1711 | 1746 | goto end; |
1712 | 1747 | } |
1713 | 1748 | |
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 */ | |
1732 | 1752 | |
1733 | - /* Find a corresponding function */ | |
1753 | + /* Find a corresponding function (name, baseline and baseaddr) */ | |
1734 | 1754 | if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { |
1755 | + /* Get function entry information */ | |
1735 | 1756 | tmp = dwarf_diename(&spdie); |
1736 | - if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0) | |
1737 | - goto end; | |
1757 | + if (!tmp || | |
1758 | + dwarf_entrypc(&spdie, &baseaddr) != 0 || | |
1759 | + dwarf_decl_line(&spdie, &baseline) != 0) | |
1760 | + goto post; | |
1761 | + func = tmp; | |
1738 | 1762 | |
1739 | - if (ppt->line) { | |
1740 | - if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, | |
1741 | - &indie)) { | |
1742 | - /* addr in an inline function */ | |
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 | + */ | |
1743 | 1783 | 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); | |
1784 | + if (tmp && | |
1785 | + dwarf_decl_line(&spdie, &baseline) == 0) | |
1786 | + func = tmp; | |
1753 | 1787 | } |
1754 | - if (ret == 0) { | |
1755 | - /* Make a relative line number */ | |
1756 | - ppt->line -= lineno; | |
1757 | - goto found; | |
1758 | - } | |
1759 | 1788 | } |
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); | |
1764 | 1801 | if (ppt->function == NULL) { |
1765 | 1802 | ret = -ENOMEM; |
1766 | 1803 | goto end; |
1767 | 1804 | } |
1768 | - found = true; | |
1769 | 1805 | } |
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 | + } | |
1771 | 1817 | end: |
1772 | 1818 | if (dwfl) |
1773 | 1819 | dwfl_end(dwfl); |
1774 | - if (ret >= 0) | |
1775 | - ret = found ? 1 : 0; | |
1820 | + if (ret == 0 && (fname || func)) | |
1821 | + ret = 1; /* Found a point */ | |
1776 | 1822 | return ret; |
1777 | 1823 | } |
1778 | 1824 | |
... | ... | @@ -1840,6 +1886,10 @@ |
1840 | 1886 | struct line_finder *lf = param->data; |
1841 | 1887 | struct line_range *lr = lf->lr; |
1842 | 1888 | |
1889 | + /* Check declared file */ | |
1890 | + if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) | |
1891 | + return DWARF_CB_OK; | |
1892 | + | |
1843 | 1893 | if (dwarf_tag(sp_die) == DW_TAG_subprogram && |
1844 | 1894 | die_compare_name(sp_die, lr->function)) { |
1845 | 1895 | lf->fname = dwarf_decl_file(sp_die); |
... | ... | @@ -1892,6 +1942,7 @@ |
1892 | 1942 | if (!dbg) { |
1893 | 1943 | pr_warning("No debug information found in the vmlinux - " |
1894 | 1944 | "please rebuild with CONFIG_DEBUG_INFO=y.\n"); |
1945 | + close(fd); /* Without dwfl_end(), fd isn't closed. */ | |
1895 | 1946 | return -EBADF; |
1896 | 1947 | } |
1897 | 1948 |