aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/i387.h2
-rw-r--r--arch/x86/kernel/setup.c5
-rw-r--r--arch/x86/mm/srat_32.c4
-rw-r--r--arch/x86/platform/mrst/vrtc.c4
-rw-r--r--arch/x86/platform/visws/visws_quirks.c20
-rw-r--r--drivers/rtc/rtc-mrst.c7
-rw-r--r--kernel/irq/manage.c1
-rw-r--r--kernel/sched.c3
-rw-r--r--kernel/sched_fair.c16
-rw-r--r--tools/perf/util/probe-event.c19
-rw-r--r--tools/perf/util/probe-finder.c159
11 files changed, 151 insertions, 89 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index ef328901c802..c9e09ea05644 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -237,7 +237,7 @@ static inline void fpu_save_init(struct fpu *fpu)
237 } else if (use_fxsr()) { 237 } else if (use_fxsr()) {
238 fpu_fxsave(fpu); 238 fpu_fxsave(fpu);
239 } else { 239 } else {
240 asm volatile("fsave %[fx]; fwait" 240 asm volatile("fnsave %[fx]; fwait"
241 : [fx] "=m" (fpu->state->fsave)); 241 : [fx] "=m" (fpu->state->fsave));
242 return; 242 return;
243 } 243 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 5a0484a95ad6..4be9b398470e 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -976,6 +976,11 @@ void __init setup_arch(char **cmdline_p)
976 paging_init(); 976 paging_init();
977 x86_init.paging.pagetable_setup_done(swapper_pg_dir); 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#ifdef CONFIG_X86_32 984#ifdef CONFIG_X86_32
980 /* sync back kernel address range */ 985 /* sync back kernel address range */
981 clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY, 986 clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c
index 48651c6f657d..364f36bdfad8 100644
--- a/arch/x86/mm/srat_32.c
+++ b/arch/x86/mm/srat_32.c
@@ -211,10 +211,12 @@ int __init get_memcfg_from_srat(void)
211{ 211{
212 int i, j, nid; 212 int i, j, nid;
213 213
214
215 if (srat_disabled()) 214 if (srat_disabled())
216 goto out_fail; 215 goto out_fail;
217 216
217 if (acpi_numa_init() < 0)
218 goto out_fail;
219
218 if (num_memory_chunks == 0) { 220 if (num_memory_chunks == 0) {
219 printk(KERN_DEBUG 221 printk(KERN_DEBUG
220 "could not find any ACPI SRAT memory areas.\n"); 222 "could not find any ACPI SRAT memory areas.\n");
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c
index 04cf645feb92..73d70d65e76e 100644
--- a/arch/x86/platform/mrst/vrtc.c
+++ b/arch/x86/platform/mrst/vrtc.c
@@ -100,9 +100,11 @@ int vrtc_set_mmss(unsigned long nowtime)
100 100
101void __init mrst_rtc_init(void) 101void __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 sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc); 105 sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
106
107 vrtc_paddr = sfi_mrtc_array[0].phys_addr;
106 if (!sfi_mrtc_num || !vrtc_paddr) 108 if (!sfi_mrtc_num || !vrtc_paddr)
107 return; 109 return;
108 110
diff --git a/arch/x86/platform/visws/visws_quirks.c b/arch/x86/platform/visws/visws_quirks.c
index fe4cf8294878..c7abf13a213f 100644
--- a/arch/x86/platform/visws/visws_quirks.c
+++ b/arch/x86/platform/visws/visws_quirks.c
@@ -471,15 +471,7 @@ static unsigned int startup_piix4_master_irq(struct irq_data *data)
471{ 471{
472 legacy_pic->init(0); 472 legacy_pic->init(0);
473 enable_cobalt_irq(data); 473 enable_cobalt_irq(data);
474} 474 return 0;
475
476static 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} 475}
484 476
485static struct irq_chip piix4_master_irq_type = { 477static struct irq_chip piix4_master_irq_type = {
@@ -492,7 +484,7 @@ static void pii4_mask(struct irq_data *data) { }
492 484
493static struct irq_chip piix4_virtual_irq_type = { 485static struct irq_chip piix4_virtual_irq_type = {
494 .name = "PIIX4-virtual", 486 .name = "PIIX4-virtual",
495 .mask = pii4_mask, 487 .irq_mask = pii4_mask,
496}; 488};
497 489
498/* 490/*
@@ -580,9 +572,9 @@ static struct irqaction cascade_action = {
580 572
581static inline void set_piix4_virtual_irq_type(void) 573static inline void set_piix4_virtual_irq_type(void)
582{ 574{
583 piix4_virtual_irq_type.enable = i8259A_chip.unmask; 575 piix4_virtual_irq_type.irq_enable = i8259A_chip.irq_unmask;
584 piix4_virtual_irq_type.disable = i8259A_chip.mask; 576 piix4_virtual_irq_type.irq_disable = i8259A_chip.irq_mask;
585 piix4_virtual_irq_type.unmask = i8259A_chip.unmask; 577 piix4_virtual_irq_type.irq_unmask = i8259A_chip.irq_unmask;
586} 578}
587 579
588static void __init visws_pre_intr_init(void) 580static void __init visws_pre_intr_init(void)
@@ -599,7 +591,7 @@ static void __init visws_pre_intr_init(void)
599 else if (i == CO_IRQ_IDE0) 591 else if (i == CO_IRQ_IDE0)
600 chip = &cobalt_irq_type; 592 chip = &cobalt_irq_type;
601 else if (i == CO_IRQ_IDE1) 593 else if (i == CO_IRQ_IDE1)
602 >chip = &cobalt_irq_type; 594 chip = &cobalt_irq_type;
603 else if (i == CO_IRQ_8259) 595 else if (i == CO_IRQ_8259)
604 chip = &piix4_master_irq_type; 596 chip = &piix4_master_irq_type;
605 else if (i < CO_IRQ_APIC0) 597 else if (i < CO_IRQ_APIC0)
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index 332a2c4a891c..b2f096871a97 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -342,6 +342,8 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
342 342
343 mrst_rtc.irq = rtc_irq; 343 mrst_rtc.irq = rtc_irq;
344 mrst_rtc.iomem = iomem; 344 mrst_rtc.iomem = iomem;
345 mrst_rtc.dev = dev;
346 dev_set_drvdata(dev, &mrst_rtc);
345 347
346 mrst_rtc.rtc = rtc_device_register(driver_name, dev, 348 mrst_rtc.rtc = rtc_device_register(driver_name, dev,
347 &mrst_rtc_ops, THIS_MODULE); 349 &mrst_rtc_ops, THIS_MODULE);
@@ -350,8 +352,6 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
350 goto cleanup0; 352 goto cleanup0;
351 } 353 }
352 354
353 mrst_rtc.dev = dev;
354 dev_set_drvdata(dev, &mrst_rtc);
355 rename_region(iomem, dev_name(&mrst_rtc.rtc->dev)); 355 rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
356 356
357 spin_lock_irq(&rtc_lock); 357 spin_lock_irq(&rtc_lock);
@@ -376,9 +376,10 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
376 return 0; 376 return 0;
377 377
378cleanup1: 378cleanup1:
379 mrst_rtc.dev = NULL;
380 rtc_device_unregister(mrst_rtc.rtc); 379 rtc_device_unregister(mrst_rtc.rtc);
381cleanup0: 380cleanup0:
381 dev_set_drvdata(dev, NULL);
382 mrst_rtc.dev = NULL;
382 release_region(iomem->start, iomem->end + 1 - iomem->start); 383 release_region(iomem->start, iomem->end + 1 - iomem->start);
383 dev_err(dev, "rtc-mrst: unable to initialise\n"); 384 dev_err(dev, "rtc-mrst: unable to initialise\n");
384 return retval; 385 return retval;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 12a80fdae11c..07c1611f3899 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1051,6 +1051,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1051 register_irq_proc(irq, desc); 1051 register_irq_proc(irq, desc);
1052 new->dir = NULL; 1052 new->dir = NULL;
1053 register_handler_proc(irq, new); 1053 register_handler_proc(irq, new);
1054 free_cpumask_var(mask);
1054 1055
1055 return 0; 1056 return 0;
1056 1057
diff --git a/kernel/sched.c b/kernel/sched.c
index dc7ca5c2a7ab..48013633d792 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6331,6 +6331,9 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
6331 break; 6331 break;
6332#endif 6332#endif
6333 } 6333 }
6334
6335 update_max_interval();
6336
6334 return NOTIFY_OK; 6337 return NOTIFY_OK;
6335} 6338}
6336 6339
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 4104533d43ef..7f00772e57c9 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -3820,6 +3820,17 @@ void select_nohz_load_balancer(int stop_tick)
3820 3820
3821static DEFINE_SPINLOCK(balancing); 3821static DEFINE_SPINLOCK(balancing);
3822 3822
3823static 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 */
3829static void update_max_interval(void)
3830{
3831 max_load_balance_interval = HZ*num_online_cpus()/10;
3832}
3833
3823/* 3834/*
3824 * It checks each scheduling domain to see if it is due to be balanced, 3835 * It checks each scheduling domain to see if it is due to be balanced,
3825 * and initiates a balancing operation if so. 3836 * and initiates a balancing operation if so.
@@ -3849,10 +3860,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
3849 3860
3850 /* scale ms to jiffies */ 3861 /* scale ms to jiffies */
3851 interval = msecs_to_jiffies(interval); 3862 interval = msecs_to_jiffies(interval);
3852 if (unlikely(!interval)) 3863 interval = clamp(interval, 1UL, max_load_balance_interval);
3853 interval = 1;
3854 if (interval > HZ*num_online_cpus()/10)
3855 interval = HZ*num_online_cpus()/10;
3856 3864
3857 need_serialize = sd->flags & SD_SERIALIZE; 3865 need_serialize = sd->flags & SD_SERIALIZE;
3858 3866
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 5ddee66020a7..f0223166e761 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -234,7 +234,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
234 234
235 /* Searching trace events corresponding to probe event */ 235 /* Searching trace events corresponding to probe event */
236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs); 236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);
237 close(fd);
238 237
239 if (ntevs > 0) { /* Succeeded to find trace events */ 238 if (ntevs > 0) { /* Succeeded to find trace events */
240 pr_debug("find %d probe_trace_events.\n", ntevs); 239 pr_debug("find %d probe_trace_events.\n", ntevs);
@@ -388,7 +387,6 @@ int show_line_range(struct line_range *lr, const char *module)
388 } 387 }
389 388
390 ret = find_line_range(fd, lr); 389 ret = find_line_range(fd, lr);
391 close(fd);
392 if (ret == 0) { 390 if (ret == 0) {
393 pr_warning("Specified source line is not found.\n"); 391 pr_warning("Specified source line is not found.\n");
394 return -ENOENT; 392 return -ENOENT;
@@ -512,19 +510,18 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
512 if (ret < 0) 510 if (ret < 0)
513 return ret; 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 setup_pager(); 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 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter, 522 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
525 externs); 523 externs);
526 524 }
527 close(fd);
528 return ret; 525 return ret;
529} 526}
530 527
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 194f9e2a3285..b7c85ce466a1 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -273,6 +273,25 @@ static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
273 return dwarf_formstring(&attr); 273 return dwarf_formstring(&attr);
274} 274}
275 275
276/* Get a line number and file name for given address */
277static 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/* Compare diename and tname */ 295/* Compare diename and tname */
277static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 296static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
278{ 297{
@@ -497,7 +516,20 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
497static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 516static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
498 Dwarf_Die *die_mem) 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/* Walker on lines (Note: line number will not be sorted) */ 535/* 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)
1395 !die_compare_name(sp_die, pp->function)) 1427 !die_compare_name(sp_die, pp->function))
1396 return DWARF_CB_OK; 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 pf->fname = dwarf_decl_file(sp_die); 1434 pf->fname = dwarf_decl_file(sp_die);
1399 if (pp->line) { /* Function relative line */ 1435 if (pp->line) { /* Function relative line */
1400 dwarf_decl_line(sp_die, &pf->lno); 1436 dwarf_decl_line(sp_die, &pf->lno);
@@ -1451,6 +1487,7 @@ static int find_probes(int fd, struct probe_finder *pf)
1451 if (!dbg) { 1487 if (!dbg) {
1452 pr_warning("No debug information found in the vmlinux - " 1488 pr_warning("No debug information found in the vmlinux - "
1453 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1489 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1490 close(fd); /* Without dwfl_end(), fd isn't closed. */
1454 return -EBADF; 1491 return -EBADF;
1455 } 1492 }
1456 1493
@@ -1686,11 +1723,9 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1686 Dwarf_Die cudie, spdie, indie; 1723 Dwarf_Die cudie, spdie, indie;
1687 Dwarf *dbg = NULL; 1724 Dwarf *dbg = NULL;
1688 Dwfl *dwfl = NULL; 1725 Dwfl *dwfl = NULL;
1689 Dwarf_Line *line; 1726 Dwarf_Addr _addr, baseaddr, bias = 0;
1690 Dwarf_Addr laddr, eaddr, bias = 0; 1727 const char *fname = NULL, *func = NULL, *tmp;
1691 const char *tmp; 1728 int baseline = 0, lineno = 0, ret = 0;
1692 int lineno, ret = 0;
1693 bool found = false;
1694 1729
1695 /* Open the live linux kernel */ 1730 /* Open the live linux kernel */
1696 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias); 1731 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)
1711 goto end; 1746 goto end;
1712 } 1747 }
1713 1748
1714 /* Find a corresponding line */ 1749 /* Find a corresponding line (filename and lineno) */
1715 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr); 1750 cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1716 if (line) { 1751 /* Don't care whether it failed or not */
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 }
1732 1752
1733 /* Find a corresponding function */ 1753 /* Find a corresponding function (name, baseline and baseaddr) */
1734 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1754 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1755 /* Get function entry information */
1735 tmp = dwarf_diename(&spdie); 1756 tmp = dwarf_diename(&spdie);
1736 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0) 1757 if (!tmp ||
1737 goto end; 1758 dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1738 1759 dwarf_decl_line(&spdie, &baseline) != 0)
1739 if (ppt->line) { 1760 goto post;
1740 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, 1761 func = tmp;
1741 &indie)) { 1762
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 tmp = dwarf_diename(&indie); 1783 tmp = dwarf_diename(&indie);
1744 if (!tmp) 1784 if (tmp &&
1745 goto end; 1785 dwarf_decl_line(&spdie, &baseline) == 0)
1746 ret = dwarf_decl_line(&indie, &lineno); 1786 func = tmp;
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;
1758 } 1787 }
1759 } 1788 }
1760 /* We don't have a line number, let's use offset */ 1789 }
1761 ppt->offset = addr - (unsigned long)eaddr; 1790
1762found: 1791post:
1763 ppt->function = strdup(tmp); 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 if (ppt->function == NULL) { 1801 if (ppt->function == NULL) {
1765 ret = -ENOMEM; 1802 ret = -ENOMEM;
1766 goto end; 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 }
1771end: 1817end:
1772 if (dwfl) 1818 if (dwfl)
1773 dwfl_end(dwfl); 1819 dwfl_end(dwfl);
1774 if (ret >= 0) 1820 if (ret == 0 && (fname || func))
1775 ret = found ? 1 : 0; 1821 ret = 1; /* Found a point */
1776 return ret; 1822 return ret;
1777} 1823}
1778 1824
@@ -1840,6 +1886,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1840 struct line_finder *lf = param->data; 1886 struct line_finder *lf = param->data;
1841 struct line_range *lr = lf->lr; 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 if (dwarf_tag(sp_die) == DW_TAG_subprogram && 1893 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
1844 die_compare_name(sp_die, lr->function)) { 1894 die_compare_name(sp_die, lr->function)) {
1845 lf->fname = dwarf_decl_file(sp_die); 1895 lf->fname = dwarf_decl_file(sp_die);
@@ -1892,6 +1942,7 @@ int find_line_range(int fd, struct line_range *lr)
1892 if (!dbg) { 1942 if (!dbg) {
1893 pr_warning("No debug information found in the vmlinux - " 1943 pr_warning("No debug information found in the vmlinux - "
1894 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1944 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1945 close(fd); /* Without dwfl_end(), fd isn't closed. */
1895 return -EBADF; 1946 return -EBADF;
1896 } 1947 }
1897 1948