Merge branch 'linus'
Merge in the relevant upstream merge point to queue up dependent patch. Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
474a83b76f
3
CREDITS
3
CREDITS
@ -2808,8 +2808,7 @@ S: Ottawa, Ontario
|
|||||||
S: Canada K2P 0X8
|
S: Canada K2P 0X8
|
||||||
|
|
||||||
N: Mikael Pettersson
|
N: Mikael Pettersson
|
||||||
E: mikpe@it.uu.se
|
E: mikpelinux@gmail.com
|
||||||
W: http://user.it.uu.se/~mikpe/linux/
|
|
||||||
D: Miscellaneous fixes
|
D: Miscellaneous fixes
|
||||||
|
|
||||||
N: Reed H. Petty
|
N: Reed H. Petty
|
||||||
|
@ -6596,7 +6596,7 @@ S: Obsolete
|
|||||||
F: drivers/net/wireless/prism54/
|
F: drivers/net/wireless/prism54/
|
||||||
|
|
||||||
PROMISE SATA TX2/TX4 CONTROLLER LIBATA DRIVER
|
PROMISE SATA TX2/TX4 CONTROLLER LIBATA DRIVER
|
||||||
M: Mikael Pettersson <mikpe@it.uu.se>
|
M: Mikael Pettersson <mikpelinux@gmail.com>
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/ata/sata_promise.*
|
F: drivers/ata/sata_promise.*
|
||||||
|
@ -1883,9 +1883,9 @@ static struct pmu pmu = {
|
|||||||
|
|
||||||
void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
|
void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
|
||||||
{
|
{
|
||||||
userpg->cap_usr_time = 0;
|
userpg->cap_user_time = 0;
|
||||||
userpg->cap_usr_time_zero = 0;
|
userpg->cap_user_time_zero = 0;
|
||||||
userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc;
|
userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
|
||||||
userpg->pmc_width = x86_pmu.cntval_bits;
|
userpg->pmc_width = x86_pmu.cntval_bits;
|
||||||
|
|
||||||
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
|
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
|
||||||
@ -1894,13 +1894,13 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
|
|||||||
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
|
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
userpg->cap_usr_time = 1;
|
userpg->cap_user_time = 1;
|
||||||
userpg->time_mult = this_cpu_read(cyc2ns);
|
userpg->time_mult = this_cpu_read(cyc2ns);
|
||||||
userpg->time_shift = CYC2NS_SCALE_FACTOR;
|
userpg->time_shift = CYC2NS_SCALE_FACTOR;
|
||||||
userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
|
userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
|
||||||
|
|
||||||
if (sched_clock_stable && !check_tsc_disabled()) {
|
if (sched_clock_stable && !check_tsc_disabled()) {
|
||||||
userpg->cap_usr_time_zero = 1;
|
userpg->cap_user_time_zero = 1;
|
||||||
userpg->time_zero = this_cpu_read(cyc2ns_offset);
|
userpg->time_zero = this_cpu_read(cyc2ns_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2325,6 +2325,7 @@ __init int intel_pmu_init(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 55: /* Atom 22nm "Silvermont" */
|
case 55: /* Atom 22nm "Silvermont" */
|
||||||
|
case 77: /* Avoton "Silvermont" */
|
||||||
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
|
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
|
||||||
sizeof(hw_cache_event_ids));
|
sizeof(hw_cache_event_ids));
|
||||||
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
|
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
|
||||||
|
@ -2706,14 +2706,14 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
|
|||||||
box->hrtimer.function = uncore_pmu_hrtimer;
|
box->hrtimer.function = uncore_pmu_hrtimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu)
|
static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
|
||||||
{
|
{
|
||||||
struct intel_uncore_box *box;
|
struct intel_uncore_box *box;
|
||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
|
size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
|
||||||
|
|
||||||
box = kzalloc_node(size, GFP_KERNEL, cpu_to_node(cpu));
|
box = kzalloc_node(size, GFP_KERNEL, node);
|
||||||
if (!box)
|
if (!box)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -3031,7 +3031,7 @@ static int uncore_validate_group(struct intel_uncore_pmu *pmu,
|
|||||||
struct intel_uncore_box *fake_box;
|
struct intel_uncore_box *fake_box;
|
||||||
int ret = -EINVAL, n;
|
int ret = -EINVAL, n;
|
||||||
|
|
||||||
fake_box = uncore_alloc_box(pmu->type, smp_processor_id());
|
fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
|
||||||
if (!fake_box)
|
if (!fake_box)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -3294,7 +3294,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
|
|||||||
}
|
}
|
||||||
|
|
||||||
type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
|
type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
|
||||||
box = uncore_alloc_box(type, 0);
|
box = uncore_alloc_box(type, NUMA_NO_NODE);
|
||||||
if (!box)
|
if (!box)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -3499,7 +3499,7 @@ static int uncore_cpu_prepare(int cpu, int phys_id)
|
|||||||
if (pmu->func_id < 0)
|
if (pmu->func_id < 0)
|
||||||
pmu->func_id = j;
|
pmu->func_id = j;
|
||||||
|
|
||||||
box = uncore_alloc_box(type, cpu);
|
box = uncore_alloc_box(type, cpu_to_node(cpu));
|
||||||
if (!box)
|
if (!box)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -352,12 +352,28 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
|||||||
},
|
},
|
||||||
{ /* Handle problems with rebooting on the Precision M6600. */
|
{ /* Handle problems with rebooting on the Precision M6600. */
|
||||||
.callback = set_pci_reboot,
|
.callback = set_pci_reboot,
|
||||||
.ident = "Dell OptiPlex 990",
|
.ident = "Dell Precision M6600",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ /* Handle problems with rebooting on the Dell PowerEdge C6100. */
|
||||||
|
.callback = set_pci_reboot,
|
||||||
|
.ident = "Dell PowerEdge C6100",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ /* Some C6100 machines were shipped with vendor being 'Dell'. */
|
||||||
|
.callback = set_pci_reboot,
|
||||||
|
.ident = "Dell PowerEdge C6100",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -912,10 +912,13 @@ void __init efi_enter_virtual_mode(void)
|
|||||||
|
|
||||||
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
||||||
md = p;
|
md = p;
|
||||||
if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
|
if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
|
||||||
md->type != EFI_BOOT_SERVICES_CODE &&
|
#ifdef CONFIG_X86_64
|
||||||
md->type != EFI_BOOT_SERVICES_DATA)
|
if (md->type != EFI_BOOT_SERVICES_CODE &&
|
||||||
continue;
|
md->type != EFI_BOOT_SERVICES_DATA)
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
size = md->num_pages << EFI_PAGE_SHIFT;
|
size = md->num_pages << EFI_PAGE_SHIFT;
|
||||||
end = md->phys_addr + size;
|
end = md->phys_addr + size;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* sata_promise.c - Promise SATA
|
* sata_promise.c - Promise SATA
|
||||||
*
|
*
|
||||||
* Maintained by: Tejun Heo <tj@kernel.org>
|
* Maintained by: Tejun Heo <tj@kernel.org>
|
||||||
* Mikael Pettersson <mikpe@it.uu.se>
|
* Mikael Pettersson
|
||||||
* Please ALWAYS copy linux-ide@vger.kernel.org
|
* Please ALWAYS copy linux-ide@vger.kernel.org
|
||||||
* on emails.
|
* on emails.
|
||||||
*
|
*
|
||||||
|
@ -380,10 +380,13 @@ struct perf_event_mmap_page {
|
|||||||
union {
|
union {
|
||||||
__u64 capabilities;
|
__u64 capabilities;
|
||||||
struct {
|
struct {
|
||||||
__u64 cap_usr_time : 1,
|
__u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */
|
||||||
cap_usr_rdpmc : 1,
|
cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */
|
||||||
cap_usr_time_zero : 1,
|
|
||||||
cap_____res : 61;
|
cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */
|
||||||
|
cap_user_time : 1, /* The time_* fields are used */
|
||||||
|
cap_user_time_zero : 1, /* The time_zero field is used */
|
||||||
|
cap_____res : 59;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -442,12 +445,13 @@ struct perf_event_mmap_page {
|
|||||||
* ((rem * time_mult) >> time_shift);
|
* ((rem * time_mult) >> time_shift);
|
||||||
*/
|
*/
|
||||||
__u64 time_zero;
|
__u64 time_zero;
|
||||||
|
__u32 size; /* Header size up to __reserved[] fields. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hole for extension of the self monitor capabilities
|
* Hole for extension of the self monitor capabilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__u64 __reserved[119]; /* align to 1k */
|
__u8 __reserved[118*8+4]; /* align to 1k. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control data for the mmap() data buffer.
|
* Control data for the mmap() data buffer.
|
||||||
@ -528,6 +532,7 @@ enum perf_event_type {
|
|||||||
* u64 len;
|
* u64 len;
|
||||||
* u64 pgoff;
|
* u64 pgoff;
|
||||||
* char filename[];
|
* char filename[];
|
||||||
|
* struct sample_id sample_id;
|
||||||
* };
|
* };
|
||||||
*/
|
*/
|
||||||
PERF_RECORD_MMAP = 1,
|
PERF_RECORD_MMAP = 1,
|
||||||
|
@ -3660,6 +3660,26 @@ static void calc_timer_values(struct perf_event *event,
|
|||||||
*running = ctx_time - event->tstamp_running;
|
*running = ctx_time - event->tstamp_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void perf_event_init_userpage(struct perf_event *event)
|
||||||
|
{
|
||||||
|
struct perf_event_mmap_page *userpg;
|
||||||
|
struct ring_buffer *rb;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
rb = rcu_dereference(event->rb);
|
||||||
|
if (!rb)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
userpg = rb->user_page;
|
||||||
|
|
||||||
|
/* Allow new userspace to detect that bit 0 is deprecated */
|
||||||
|
userpg->cap_bit0_is_deprecated = 1;
|
||||||
|
userpg->size = offsetof(struct perf_event_mmap_page, __reserved);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
|
void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -4044,6 +4064,7 @@ again:
|
|||||||
ring_buffer_attach(event, rb);
|
ring_buffer_attach(event, rb);
|
||||||
rcu_assign_pointer(event->rb, rb);
|
rcu_assign_pointer(event->rb, rb);
|
||||||
|
|
||||||
|
perf_event_init_userpage(event);
|
||||||
perf_event_update_userpage(event);
|
perf_event_update_userpage(event);
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
|
@ -4242,7 +4242,7 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!se) {
|
if (!se) {
|
||||||
cfs_rq->h_load = rq->avg.load_avg_contrib;
|
cfs_rq->h_load = cfs_rq->runnable_load_avg;
|
||||||
cfs_rq->last_h_load_update = now;
|
cfs_rq->last_h_load_update = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4823,8 +4823,8 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
|
|||||||
(busiest->load_per_task * SCHED_POWER_SCALE) /
|
(busiest->load_per_task * SCHED_POWER_SCALE) /
|
||||||
busiest->group_power;
|
busiest->group_power;
|
||||||
|
|
||||||
if (busiest->avg_load - local->avg_load + scaled_busy_load_per_task >=
|
if (busiest->avg_load + scaled_busy_load_per_task >=
|
||||||
(scaled_busy_load_per_task * imbn)) {
|
local->avg_load + (scaled_busy_load_per_task * imbn)) {
|
||||||
env->imbalance = busiest->load_per_task;
|
env->imbalance = busiest->load_per_task;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4896,7 +4896,8 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
|
|||||||
* max load less than avg load(as we skip the groups at or below
|
* max load less than avg load(as we skip the groups at or below
|
||||||
* its cpu_power, while calculating max_load..)
|
* its cpu_power, while calculating max_load..)
|
||||||
*/
|
*/
|
||||||
if (busiest->avg_load < sds->avg_load) {
|
if (busiest->avg_load <= sds->avg_load ||
|
||||||
|
local->avg_load >= sds->avg_load) {
|
||||||
env->imbalance = 0;
|
env->imbalance = 0;
|
||||||
return fix_small_imbalance(env, sds);
|
return fix_small_imbalance(env, sds);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <linux/magic.h>
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
#include "debugfs.h"
|
#include "debugfs.h"
|
||||||
|
@ -32,7 +32,7 @@ u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
|
|||||||
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
||||||
struct perf_tsc_conversion *tc)
|
struct perf_tsc_conversion *tc)
|
||||||
{
|
{
|
||||||
bool cap_usr_time_zero;
|
bool cap_user_time_zero;
|
||||||
u32 seq;
|
u32 seq;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
|||||||
tc->time_mult = pc->time_mult;
|
tc->time_mult = pc->time_mult;
|
||||||
tc->time_shift = pc->time_shift;
|
tc->time_shift = pc->time_shift;
|
||||||
tc->time_zero = pc->time_zero;
|
tc->time_zero = pc->time_zero;
|
||||||
cap_usr_time_zero = pc->cap_usr_time_zero;
|
cap_user_time_zero = pc->cap_user_time_zero;
|
||||||
rmb();
|
rmb();
|
||||||
if (pc->lock == seq && !(seq & 1))
|
if (pc->lock == seq && !(seq & 1))
|
||||||
break;
|
break;
|
||||||
@ -52,7 +52,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cap_usr_time_zero)
|
if (!cap_user_time_zero)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -321,8 +321,6 @@ found:
|
|||||||
return perf_event__repipe(tool, event_sw, &sample_sw, machine);
|
return perf_event__repipe(tool, event_sw, &sample_sw, machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern volatile int session_done;
|
|
||||||
|
|
||||||
static void sig_handler(int sig __maybe_unused)
|
static void sig_handler(int sig __maybe_unused)
|
||||||
{
|
{
|
||||||
session_done = 1;
|
session_done = 1;
|
||||||
|
@ -401,8 +401,6 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern volatile int session_done;
|
|
||||||
|
|
||||||
static void sig_handler(int sig __maybe_unused)
|
static void sig_handler(int sig __maybe_unused)
|
||||||
{
|
{
|
||||||
session_done = 1;
|
session_done = 1;
|
||||||
@ -568,6 +566,9 @@ static int __cmd_report(struct perf_report *rep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session_done())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (nr_samples == 0) {
|
if (nr_samples == 0) {
|
||||||
ui__error("The %s file has no samples!\n", session->filename);
|
ui__error("The %s file has no samples!\n", session->filename);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -553,8 +553,6 @@ static struct perf_tool perf_script = {
|
|||||||
.ordering_requires_timestamps = true,
|
.ordering_requires_timestamps = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern volatile int session_done;
|
|
||||||
|
|
||||||
static void sig_handler(int sig __maybe_unused)
|
static void sig_handler(int sig __maybe_unused)
|
||||||
{
|
{
|
||||||
session_done = 1;
|
session_done = 1;
|
||||||
|
@ -16,6 +16,23 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
|
|
||||||
|
/* For older distros: */
|
||||||
|
#ifndef MAP_STACK
|
||||||
|
# define MAP_STACK 0x20000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MADV_HWPOISON
|
||||||
|
# define MADV_HWPOISON 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MADV_MERGEABLE
|
||||||
|
# define MADV_MERGEABLE 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MADV_UNMERGEABLE
|
||||||
|
# define MADV_UNMERGEABLE 13
|
||||||
|
#endif
|
||||||
|
|
||||||
static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
|
static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
|
||||||
unsigned long arg,
|
unsigned long arg,
|
||||||
u8 arg_idx __maybe_unused,
|
u8 arg_idx __maybe_unused,
|
||||||
|
@ -180,6 +180,9 @@ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
|
|||||||
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
|
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
|
||||||
CFLAGS += -DLIBELF_MMAP
|
CFLAGS += -DLIBELF_MMAP
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y)
|
||||||
|
CFLAGS += -DHAVE_ELF_GETPHDRNUM
|
||||||
|
endif
|
||||||
|
|
||||||
# include ARCH specific config
|
# include ARCH specific config
|
||||||
-include $(src-perf)/arch/$(ARCH)/Makefile
|
-include $(src-perf)/arch/$(ARCH)/Makefile
|
||||||
|
@ -61,6 +61,15 @@ int main(void)
|
|||||||
}
|
}
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define SOURCE_ELF_GETPHDRNUM
|
||||||
|
#include <libelf.h>
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
size_t dst;
|
||||||
|
return elf_getphdrnum(0, &dst);
|
||||||
|
}
|
||||||
|
endef
|
||||||
|
|
||||||
ifndef NO_SLANG
|
ifndef NO_SLANG
|
||||||
define SOURCE_SLANG
|
define SOURCE_SLANG
|
||||||
#include <slang.h>
|
#include <slang.h>
|
||||||
@ -210,6 +219,7 @@ define SOURCE_LIBAUDIT
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
printf(\"error message: %s\n\", audit_errno_to_name(0));
|
||||||
return audit_open();
|
return audit_open();
|
||||||
}
|
}
|
||||||
endef
|
endef
|
||||||
|
@ -809,7 +809,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
|
|||||||
end = map__rip_2objdump(map, sym->end);
|
end = map__rip_2objdump(map, sym->end);
|
||||||
|
|
||||||
offset = line_ip - start;
|
offset = line_ip - start;
|
||||||
if (offset < 0 || (u64)line_ip > end)
|
if ((u64)line_ip < start || (u64)line_ip > end)
|
||||||
offset = -1;
|
offset = -1;
|
||||||
else
|
else
|
||||||
parsed_line = tmp2 + 1;
|
parsed_line = tmp2 + 1;
|
||||||
|
@ -262,6 +262,21 @@ bool die_is_signed_type(Dwarf_Die *tp_die)
|
|||||||
ret == DW_ATE_signed_fixed);
|
ret == DW_ATE_signed_fixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* die_is_func_def - Ensure that this DIE is a subprogram and definition
|
||||||
|
* @dw_die: a DIE
|
||||||
|
*
|
||||||
|
* Ensure that this DIE is a subprogram and NOT a declaration. This
|
||||||
|
* returns true if @dw_die is a function definition.
|
||||||
|
**/
|
||||||
|
bool die_is_func_def(Dwarf_Die *dw_die)
|
||||||
|
{
|
||||||
|
Dwarf_Attribute attr;
|
||||||
|
|
||||||
|
return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
|
||||||
|
dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* die_get_data_member_location - Get the data-member offset
|
* die_get_data_member_location - Get the data-member offset
|
||||||
* @mb_die: a DIE of a member of a data structure
|
* @mb_die: a DIE of a member of a data structure
|
||||||
@ -392,6 +407,10 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
|
|||||||
{
|
{
|
||||||
struct __addr_die_search_param *ad = data;
|
struct __addr_die_search_param *ad = data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since a declaration entry doesn't has given pc, this always returns
|
||||||
|
* function definition entry.
|
||||||
|
*/
|
||||||
if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
|
if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
|
||||||
dwarf_haspc(fn_die, ad->addr)) {
|
dwarf_haspc(fn_die, ad->addr)) {
|
||||||
memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
|
memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
|
||||||
|
@ -38,6 +38,9 @@ extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
|
|||||||
extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
int (*callback)(Dwarf_Die *, void *), void *data);
|
int (*callback)(Dwarf_Die *, void *), void *data);
|
||||||
|
|
||||||
|
/* Ensure that this DIE is a subprogram and definition (not declaration) */
|
||||||
|
extern bool die_is_func_def(Dwarf_Die *dw_die);
|
||||||
|
|
||||||
/* Compare diename and tname */
|
/* Compare diename and tname */
|
||||||
extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
|
extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
|
||||||
|
|
||||||
|
@ -199,9 +199,11 @@ static int write_buildid(char *name, size_t name_len, u8 *build_id,
|
|||||||
return write_padded(fd, name, name_len + 1, len);
|
return write_padded(fd, name, name_len + 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
|
static int __dsos__write_buildid_table(struct list_head *head,
|
||||||
u16 misc, int fd)
|
struct machine *machine,
|
||||||
|
pid_t pid, u16 misc, int fd)
|
||||||
{
|
{
|
||||||
|
char nm[PATH_MAX];
|
||||||
struct dso *pos;
|
struct dso *pos;
|
||||||
|
|
||||||
dsos__for_each_with_build_id(pos, head) {
|
dsos__for_each_with_build_id(pos, head) {
|
||||||
@ -215,6 +217,10 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
|
|||||||
if (is_vdso_map(pos->short_name)) {
|
if (is_vdso_map(pos->short_name)) {
|
||||||
name = (char *) VDSO__MAP_NAME;
|
name = (char *) VDSO__MAP_NAME;
|
||||||
name_len = sizeof(VDSO__MAP_NAME) + 1;
|
name_len = sizeof(VDSO__MAP_NAME) + 1;
|
||||||
|
} else if (dso__is_kcore(pos)) {
|
||||||
|
machine__mmap_name(machine, nm, sizeof(nm));
|
||||||
|
name = nm;
|
||||||
|
name_len = strlen(nm) + 1;
|
||||||
} else {
|
} else {
|
||||||
name = pos->long_name;
|
name = pos->long_name;
|
||||||
name_len = pos->long_name_len + 1;
|
name_len = pos->long_name_len + 1;
|
||||||
@ -240,10 +246,10 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
|
|||||||
umisc = PERF_RECORD_MISC_GUEST_USER;
|
umisc = PERF_RECORD_MISC_GUEST_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid,
|
err = __dsos__write_buildid_table(&machine->kernel_dsos, machine,
|
||||||
kmisc, fd);
|
machine->pid, kmisc, fd);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
err = __dsos__write_buildid_table(&machine->user_dsos,
|
err = __dsos__write_buildid_table(&machine->user_dsos, machine,
|
||||||
machine->pid, umisc, fd);
|
machine->pid, umisc, fd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -375,23 +381,31 @@ out_free:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dso__cache_build_id(struct dso *dso, const char *debugdir)
|
static int dso__cache_build_id(struct dso *dso, struct machine *machine,
|
||||||
|
const char *debugdir)
|
||||||
{
|
{
|
||||||
bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
|
bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
|
||||||
bool is_vdso = is_vdso_map(dso->short_name);
|
bool is_vdso = is_vdso_map(dso->short_name);
|
||||||
|
char *name = dso->long_name;
|
||||||
|
char nm[PATH_MAX];
|
||||||
|
|
||||||
return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id),
|
if (dso__is_kcore(dso)) {
|
||||||
dso->long_name, debugdir,
|
is_kallsyms = true;
|
||||||
is_kallsyms, is_vdso);
|
machine__mmap_name(machine, nm, sizeof(nm));
|
||||||
|
name = nm;
|
||||||
|
}
|
||||||
|
return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name,
|
||||||
|
debugdir, is_kallsyms, is_vdso);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
|
static int __dsos__cache_build_ids(struct list_head *head,
|
||||||
|
struct machine *machine, const char *debugdir)
|
||||||
{
|
{
|
||||||
struct dso *pos;
|
struct dso *pos;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
dsos__for_each_with_build_id(pos, head)
|
dsos__for_each_with_build_id(pos, head)
|
||||||
if (dso__cache_build_id(pos, debugdir))
|
if (dso__cache_build_id(pos, machine, debugdir))
|
||||||
err = -1;
|
err = -1;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -399,8 +413,9 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
|
|||||||
|
|
||||||
static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
|
static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
|
||||||
{
|
{
|
||||||
int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir);
|
int ret = __dsos__cache_build_ids(&machine->kernel_dsos, machine,
|
||||||
ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir);
|
debugdir);
|
||||||
|
ret |= __dsos__cache_build_ids(&machine->user_dsos, machine, debugdir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,6 +611,8 @@ void hists__collapse_resort(struct hists *hists)
|
|||||||
next = rb_first(root);
|
next = rb_first(root);
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
|
if (session_done())
|
||||||
|
break;
|
||||||
n = rb_entry(next, struct hist_entry, rb_node_in);
|
n = rb_entry(next, struct hist_entry, rb_node_in);
|
||||||
next = rb_next(&n->rb_node_in);
|
next = rb_next(&n->rb_node_in);
|
||||||
|
|
||||||
|
@ -734,7 +734,7 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If not a real subprogram, find a real one */
|
/* If not a real subprogram, find a real one */
|
||||||
if (dwarf_tag(sc_die) != DW_TAG_subprogram) {
|
if (!die_is_func_def(sc_die)) {
|
||||||
if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
|
if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
|
||||||
pr_warning("Failed to find probe point in any "
|
pr_warning("Failed to find probe point in any "
|
||||||
"functions.\n");
|
"functions.\n");
|
||||||
@ -980,12 +980,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
|
|||||||
struct dwarf_callback_param *param = data;
|
struct dwarf_callback_param *param = data;
|
||||||
struct probe_finder *pf = param->data;
|
struct probe_finder *pf = param->data;
|
||||||
struct perf_probe_point *pp = &pf->pev->point;
|
struct perf_probe_point *pp = &pf->pev->point;
|
||||||
Dwarf_Attribute attr;
|
|
||||||
|
|
||||||
/* Check tag and diename */
|
/* Check tag and diename */
|
||||||
if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
|
if (!die_is_func_def(sp_die) ||
|
||||||
!die_compare_name(sp_die, pp->function) ||
|
!die_compare_name(sp_die, pp->function))
|
||||||
dwarf_attr(sp_die, DW_AT_declaration, &attr))
|
|
||||||
return DWARF_CB_OK;
|
return DWARF_CB_OK;
|
||||||
|
|
||||||
/* Check declared file */
|
/* Check declared file */
|
||||||
@ -1474,7 +1472,7 @@ static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search function from function name */
|
/* Search function definition from function name */
|
||||||
static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
|
static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
|
||||||
{
|
{
|
||||||
struct dwarf_callback_param *param = data;
|
struct dwarf_callback_param *param = data;
|
||||||
@ -1485,7 +1483,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
|
|||||||
if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
|
if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
|
||||||
return DWARF_CB_OK;
|
return DWARF_CB_OK;
|
||||||
|
|
||||||
if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
|
if (die_is_func_def(sp_die) &&
|
||||||
die_compare_name(sp_die, lr->function)) {
|
die_compare_name(sp_die, lr->function)) {
|
||||||
lf->fname = dwarf_decl_file(sp_die);
|
lf->fname = dwarf_decl_file(sp_die);
|
||||||
dwarf_decl_line(sp_die, &lr->offset);
|
dwarf_decl_line(sp_die, &lr->offset);
|
||||||
|
@ -531,6 +531,9 @@ static int flush_sample_queue(struct perf_session *s,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
list_for_each_entry_safe(iter, tmp, head, list) {
|
list_for_each_entry_safe(iter, tmp, head, list) {
|
||||||
|
if (session_done())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (iter->timestamp > limit)
|
if (iter->timestamp > limit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1160,7 +1163,6 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define session_done() (*(volatile int *)(&session_done))
|
|
||||||
volatile int session_done;
|
volatile int session_done;
|
||||||
|
|
||||||
static int __perf_session__process_pipe_events(struct perf_session *self,
|
static int __perf_session__process_pipe_events(struct perf_session *self,
|
||||||
@ -1372,10 +1374,13 @@ more:
|
|||||||
"Processing events...");
|
"Processing events...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
if (session_done())
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
if (file_pos < file_size)
|
if (file_pos < file_size)
|
||||||
goto more;
|
goto more;
|
||||||
|
|
||||||
err = 0;
|
|
||||||
/* do the final flush for ordered samples */
|
/* do the final flush for ordered samples */
|
||||||
session->ordered_samples.next_flush = ULLONG_MAX;
|
session->ordered_samples.next_flush = ULLONG_MAX;
|
||||||
err = flush_sample_queue(session, tool);
|
err = flush_sample_queue(session, tool);
|
||||||
|
@ -124,4 +124,8 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
|
|||||||
|
|
||||||
#define perf_session__set_tracepoints_handlers(session, array) \
|
#define perf_session__set_tracepoints_handlers(session, array) \
|
||||||
__perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array))
|
__perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array))
|
||||||
|
|
||||||
|
extern volatile int session_done;
|
||||||
|
|
||||||
|
#define session_done() (*(volatile int *)(&session_done))
|
||||||
#endif /* __PERF_SESSION_H */
|
#endif /* __PERF_SESSION_H */
|
||||||
|
@ -8,6 +8,22 @@
|
|||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_ELF_GETPHDRNUM
|
||||||
|
static int elf_getphdrnum(Elf *elf, size_t *dst)
|
||||||
|
{
|
||||||
|
GElf_Ehdr gehdr;
|
||||||
|
GElf_Ehdr *ehdr;
|
||||||
|
|
||||||
|
ehdr = gelf_getehdr(elf, &gehdr);
|
||||||
|
if (!ehdr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*dst = ehdr->e_phnum;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NT_GNU_BUILD_ID
|
#ifndef NT_GNU_BUILD_ID
|
||||||
#define NT_GNU_BUILD_ID 3
|
#define NT_GNU_BUILD_ID 3
|
||||||
#endif
|
#endif
|
||||||
|
@ -186,7 +186,7 @@ void parse_proc_kallsyms(struct pevent *pevent,
|
|||||||
char *next = NULL;
|
char *next = NULL;
|
||||||
char *addr_str;
|
char *addr_str;
|
||||||
char *mod;
|
char *mod;
|
||||||
char *fmt;
|
char *fmt = NULL;
|
||||||
|
|
||||||
line = strtok_r(file, "\n", &next);
|
line = strtok_r(file, "\n", &next);
|
||||||
while (line) {
|
while (line) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user