mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 06:49:29 -04:00
Merge branch 'linus' into locking/kcsan, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -512,6 +512,8 @@
|
||||
#define MSR_K7_HWCR 0xc0010015
|
||||
#define MSR_K7_HWCR_SMMLOCK_BIT 0
|
||||
#define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT)
|
||||
#define MSR_K7_HWCR_IRPERF_EN_BIT 30
|
||||
#define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
|
||||
#define MSR_K7_FID_VID_CTL 0xc0010041
|
||||
#define MSR_K7_FID_VID_STATUS 0xc0010042
|
||||
|
||||
|
||||
@@ -390,6 +390,7 @@ struct kvm_sync_regs {
|
||||
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
|
||||
#define KVM_STATE_NESTED_RUN_PENDING 0x00000002
|
||||
#define KVM_STATE_NESTED_EVMCS 0x00000004
|
||||
#define KVM_STATE_NESTED_MTF_PENDING 0x00000008
|
||||
|
||||
#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
|
||||
#define KVM_STATE_NESTED_SMM_VMXON 0x00000002
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* controllable printf */
|
||||
extern int pr_output;
|
||||
#define printk(fmt, ...) \
|
||||
(pr_output ? printf(fmt, ##__VA_ARGS__) : 0)
|
||||
#define printk(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
||||
|
||||
#define pr_err printk
|
||||
#define pr_warn printk
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bootconfig.h>
|
||||
|
||||
int pr_output = 1;
|
||||
|
||||
static int xbc_show_array(struct xbc_node *node)
|
||||
{
|
||||
const char *val;
|
||||
@@ -131,15 +129,26 @@ int load_xbc_from_initrd(int fd, char **buf)
|
||||
struct stat stat;
|
||||
int ret;
|
||||
u32 size = 0, csum = 0, rcsum;
|
||||
char magic[BOOTCONFIG_MAGIC_LEN];
|
||||
|
||||
ret = fstat(fd, &stat);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
if (stat.st_size < 8)
|
||||
if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
|
||||
return 0;
|
||||
|
||||
if (lseek(fd, -8, SEEK_END) < 0) {
|
||||
if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
|
||||
return -errno;
|
||||
/* Check the bootconfig magic bytes */
|
||||
if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
|
||||
return 0;
|
||||
|
||||
if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
@@ -150,11 +159,14 @@ int load_xbc_from_initrd(int fd, char **buf)
|
||||
if (read(fd, &csum, sizeof(u32)) < 0)
|
||||
return -errno;
|
||||
|
||||
/* Wrong size, maybe no boot config here */
|
||||
if (stat.st_size < size + 8)
|
||||
return 0;
|
||||
/* Wrong size error */
|
||||
if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
|
||||
pr_err("bootconfig size is too big\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
if (lseek(fd, stat.st_size - 8 - size, SEEK_SET) < 0) {
|
||||
if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
|
||||
SEEK_SET) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
@@ -163,17 +175,17 @@ int load_xbc_from_initrd(int fd, char **buf)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Wrong Checksum, maybe no boot config here */
|
||||
/* Wrong Checksum */
|
||||
rcsum = checksum((unsigned char *)*buf, size);
|
||||
if (csum != rcsum) {
|
||||
pr_err("checksum error: %d != %d\n", csum, rcsum);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = xbc_init(*buf);
|
||||
/* Wrong data, maybe no boot config here */
|
||||
/* Wrong data */
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
return size;
|
||||
}
|
||||
@@ -213,20 +225,15 @@ int delete_xbc(const char *path)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppress error messages in xbc_init() because it can be just a
|
||||
* data which concidentally matches the size and checksum footer.
|
||||
*/
|
||||
pr_output = 0;
|
||||
size = load_xbc_from_initrd(fd, &buf);
|
||||
pr_output = 1;
|
||||
if (size < 0) {
|
||||
ret = size;
|
||||
pr_err("Failed to load a boot config from initrd: %d\n", ret);
|
||||
} else if (size > 0) {
|
||||
ret = fstat(fd, &stat);
|
||||
if (!ret)
|
||||
ret = ftruncate(fd, stat.st_size - size - 8);
|
||||
ret = ftruncate(fd, stat.st_size
|
||||
- size - 8 - BOOTCONFIG_MAGIC_LEN);
|
||||
if (ret)
|
||||
ret = -errno;
|
||||
} /* Ignore if there is no boot config in initrd */
|
||||
@@ -295,6 +302,12 @@ int apply_xbc(const char *path, const char *xbc_path)
|
||||
pr_err("Failed to apply a boot config: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
/* Write a magic word of the bootconfig */
|
||||
ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to apply a boot config magic: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
close(fd);
|
||||
free(data);
|
||||
|
||||
|
||||
3
tools/bootconfig/samples/bad-mixed-kv1.bconf
Normal file
3
tools/bootconfig/samples/bad-mixed-kv1.bconf
Normal file
@@ -0,0 +1,3 @@
|
||||
# value -> subkey pattern
|
||||
key = value
|
||||
key.subkey = another-value
|
||||
3
tools/bootconfig/samples/bad-mixed-kv2.bconf
Normal file
3
tools/bootconfig/samples/bad-mixed-kv2.bconf
Normal file
@@ -0,0 +1,3 @@
|
||||
# subkey -> value pattern
|
||||
key.subkey = value
|
||||
key = another-value
|
||||
6
tools/bootconfig/samples/bad-samekey.bconf
Normal file
6
tools/bootconfig/samples/bad-samekey.bconf
Normal file
@@ -0,0 +1,6 @@
|
||||
# Same key value is not allowed
|
||||
key {
|
||||
foo = value
|
||||
bar = value2
|
||||
}
|
||||
key.foo = value
|
||||
@@ -9,7 +9,7 @@ TEMPCONF=`mktemp temp-XXXX.bconf`
|
||||
NG=0
|
||||
|
||||
cleanup() {
|
||||
rm -f $INITRD $TEMPCONF
|
||||
rm -f $INITRD $TEMPCONF $OUTFILE
|
||||
exit $NG
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ xpass $BOOTCONF -a $TEMPCONF $INITRD
|
||||
new_size=$(stat -c %s $INITRD)
|
||||
|
||||
echo "File size check"
|
||||
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9)
|
||||
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)
|
||||
|
||||
echo "Apply command repeat test"
|
||||
xpass $BOOTCONF -a $TEMPCONF $INITRD
|
||||
@@ -71,7 +71,6 @@ printf " \0\0\0 \0\0\0" >> $INITRD
|
||||
$BOOTCONF -a $TEMPCONF $INITRD > $OUTFILE 2>&1
|
||||
xfail grep -i "failed" $OUTFILE
|
||||
xfail grep -i "error" $OUTFILE
|
||||
rm $OUTFILE
|
||||
|
||||
echo "Max node number check"
|
||||
|
||||
@@ -96,6 +95,19 @@ truncate -s 32764 $TEMPCONF
|
||||
echo "\"" >> $TEMPCONF # add 2 bytes + terminal ('\"\n\0')
|
||||
xpass $BOOTCONF -a $TEMPCONF $INITRD
|
||||
|
||||
echo "Adding same-key values"
|
||||
cat > $TEMPCONF << EOF
|
||||
key = bar, baz
|
||||
key += qux
|
||||
EOF
|
||||
echo > $INITRD
|
||||
|
||||
xpass $BOOTCONF -a $TEMPCONF $INITRD
|
||||
$BOOTCONF $INITRD > $OUTFILE
|
||||
xpass grep -q "bar" $OUTFILE
|
||||
xpass grep -q "baz" $OUTFILE
|
||||
xpass grep -q "qux" $OUTFILE
|
||||
|
||||
echo "=== expected failure cases ==="
|
||||
for i in samples/bad-* ; do
|
||||
xfail $BOOTCONF -a $i $INITRD
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include "../../arch/x86/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/x86/include/uapi/asm/errno.h"
|
||||
#elif defined(__powerpc__)
|
||||
#include "../../arch/powerpc/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/powerpc/include/uapi/asm/errno.h"
|
||||
#elif defined(__sparc__)
|
||||
#include "../../arch/sparc/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/sparc/include/uapi/asm/errno.h"
|
||||
#elif defined(__alpha__)
|
||||
#include "../../arch/alpha/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/alpha/include/uapi/asm/errno.h"
|
||||
#elif defined(__mips__)
|
||||
#include "../../arch/mips/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/mips/include/uapi/asm/errno.h"
|
||||
#elif defined(__ia64__)
|
||||
#include "../../arch/ia64/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/ia64/include/uapi/asm/errno.h"
|
||||
#elif defined(__xtensa__)
|
||||
#include "../../arch/xtensa/include/uapi/asm/errno.h"
|
||||
#include "../../../arch/xtensa/include/uapi/asm/errno.h"
|
||||
#else
|
||||
#include <asm-generic/errno.h>
|
||||
#endif
|
||||
|
||||
@@ -239,7 +239,6 @@ buildid.*::
|
||||
set buildid.dir to /dev/null. The default is $HOME/.debug
|
||||
|
||||
annotate.*::
|
||||
These options work only for TUI.
|
||||
These are in control of addresses, jump function, source code
|
||||
in lines of assembly code from a specific program.
|
||||
|
||||
@@ -269,6 +268,8 @@ annotate.*::
|
||||
│ mov (%rdi),%rdx
|
||||
│ return n;
|
||||
|
||||
This option works with tui, stdio2 browsers.
|
||||
|
||||
annotate.use_offset::
|
||||
Basing on a first address of a loaded function, offset can be used.
|
||||
Instead of using original addresses of assembly code,
|
||||
@@ -287,6 +288,8 @@ annotate.*::
|
||||
|
||||
368:│ mov 0x8(%r14),%rdi
|
||||
|
||||
This option works with tui, stdio2 browsers.
|
||||
|
||||
annotate.jump_arrows::
|
||||
There can be jump instruction among assembly code.
|
||||
Depending on a boolean value of jump_arrows,
|
||||
@@ -306,6 +309,8 @@ annotate.*::
|
||||
│1330: mov %r15,%r10
|
||||
│1333: cmp %r15,%r14
|
||||
|
||||
This option works with tui browser.
|
||||
|
||||
annotate.show_linenr::
|
||||
When showing source code if this option is 'true',
|
||||
line numbers are printed as below.
|
||||
@@ -325,6 +330,8 @@ annotate.*::
|
||||
│ array++;
|
||||
│ }
|
||||
|
||||
This option works with tui, stdio2 browsers.
|
||||
|
||||
annotate.show_nr_jumps::
|
||||
Let's see a part of assembly code.
|
||||
|
||||
@@ -335,6 +342,8 @@ annotate.*::
|
||||
|
||||
│1 1382: movb $0x1,-0x270(%rbp)
|
||||
|
||||
This option works with tui, stdio2 browsers.
|
||||
|
||||
annotate.show_total_period::
|
||||
To compare two records on an instruction base, with this option
|
||||
provided, display total number of samples that belong to a line
|
||||
@@ -348,11 +357,30 @@ annotate.*::
|
||||
|
||||
99.93 │ mov %eax,%eax
|
||||
|
||||
This option works with tui, stdio2, stdio browsers.
|
||||
|
||||
annotate.show_nr_samples::
|
||||
By default perf annotate shows percentage of samples. This option
|
||||
can be used to print absolute number of samples. Ex, when set as
|
||||
false:
|
||||
|
||||
Percent│
|
||||
74.03 │ mov %fs:0x28,%rax
|
||||
|
||||
When set as true:
|
||||
|
||||
Samples│
|
||||
6 │ mov %fs:0x28,%rax
|
||||
|
||||
This option works with tui, stdio2, stdio browsers.
|
||||
|
||||
annotate.offset_level::
|
||||
Default is '1', meaning just jump targets will have offsets show right beside
|
||||
the instruction. When set to '2' 'call' instructions will also have its offsets
|
||||
shown, 3 or higher will show offsets for all instructions.
|
||||
|
||||
This option works with tui, stdio2 browsers.
|
||||
|
||||
hist.*::
|
||||
hist.percentage::
|
||||
This option control the way to calculate overhead of filtered entries -
|
||||
@@ -490,6 +518,12 @@ top.*::
|
||||
column by default.
|
||||
The default is 'true'.
|
||||
|
||||
top.call-graph::
|
||||
This is identical to 'call-graph.record-mode', except it is
|
||||
applicable only for 'top' subcommand. This option ONLY setup
|
||||
the unwind method. To enable 'perf top' to actually use it,
|
||||
the command line option -g must be specified.
|
||||
|
||||
man.*::
|
||||
man.viewer::
|
||||
This option can assign a tool to view manual pages when 'help'
|
||||
@@ -517,6 +551,16 @@ record.*::
|
||||
But if this option is 'no-cache', it will not update the build-id cache.
|
||||
'skip' skips post-processing and does not update the cache.
|
||||
|
||||
record.call-graph::
|
||||
This is identical to 'call-graph.record-mode', except it is
|
||||
applicable only for 'record' subcommand. This option ONLY setup
|
||||
the unwind method. To enable 'perf record' to actually use it,
|
||||
the command line option -g must be specified.
|
||||
|
||||
record.aio::
|
||||
Use 'n' control blocks in asynchronous (Posix AIO) trace writing
|
||||
mode ('n' default: 1, max: 4).
|
||||
|
||||
diff.*::
|
||||
diff.order::
|
||||
This option sets the number of columns to sort the result.
|
||||
@@ -566,6 +610,11 @@ trace.*::
|
||||
"libbeauty", the default, to use the same argument beautifiers used in the
|
||||
strace-like sys_enter+sys_exit lines.
|
||||
|
||||
ftrace.*::
|
||||
ftrace.tracer::
|
||||
Can be used to select the default tracer. Possible values are
|
||||
'function' and 'function_graph'.
|
||||
|
||||
llvm.*::
|
||||
llvm.clang-path::
|
||||
Path to clang. If omit, search it from $PATH.
|
||||
@@ -610,6 +659,29 @@ scripts.*::
|
||||
The script gets the same options passed as a full perf script,
|
||||
in particular -i perfdata file, --cpu, --tid
|
||||
|
||||
convert.*::
|
||||
|
||||
convert.queue-size::
|
||||
Limit the size of ordered_events queue, so we could control
|
||||
allocation size of perf data files without proper finished
|
||||
round events.
|
||||
|
||||
intel-pt.*::
|
||||
|
||||
intel-pt.cache-divisor::
|
||||
|
||||
intel-pt.mispred-all::
|
||||
If set, Intel PT decoder will set the mispred flag on all
|
||||
branches.
|
||||
|
||||
auxtrace.*::
|
||||
|
||||
auxtrace.dumpdir::
|
||||
s390 only. The directory to save the auxiliary trace buffer
|
||||
can be changed using this option. Ex, auxtrace.dumpdir=/tmp.
|
||||
If the directory does not exist or has the wrong file type,
|
||||
the current directory is used.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf[1]
|
||||
|
||||
@@ -858,21 +858,6 @@ static void cs_etm_recording_free(struct auxtrace_record *itr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
|
||||
{
|
||||
struct cs_etm_recording *ptr =
|
||||
container_of(itr, struct cs_etm_recording, itr);
|
||||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(ptr->evlist, evsel) {
|
||||
if (evsel->core.attr.type == ptr->cs_etm_pmu->type)
|
||||
return perf_evlist__enable_event_idx(ptr->evlist,
|
||||
evsel, idx);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct auxtrace_record *cs_etm_record_init(int *err)
|
||||
{
|
||||
struct perf_pmu *cs_etm_pmu;
|
||||
@@ -892,6 +877,7 @@ struct auxtrace_record *cs_etm_record_init(int *err)
|
||||
}
|
||||
|
||||
ptr->cs_etm_pmu = cs_etm_pmu;
|
||||
ptr->itr.pmu = cs_etm_pmu;
|
||||
ptr->itr.parse_snapshot_options = cs_etm_parse_snapshot_options;
|
||||
ptr->itr.recording_options = cs_etm_recording_options;
|
||||
ptr->itr.info_priv_size = cs_etm_info_priv_size;
|
||||
@@ -901,7 +887,7 @@ struct auxtrace_record *cs_etm_record_init(int *err)
|
||||
ptr->itr.snapshot_finish = cs_etm_snapshot_finish;
|
||||
ptr->itr.reference = cs_etm_reference;
|
||||
ptr->itr.free = cs_etm_recording_free;
|
||||
ptr->itr.read_finish = cs_etm_read_finish;
|
||||
ptr->itr.read_finish = auxtrace_record__read_finish;
|
||||
|
||||
*err = 0;
|
||||
return &ptr->itr;
|
||||
|
||||
@@ -11,17 +11,17 @@
|
||||
#include <linux/zalloc.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../../util/cpumap.h"
|
||||
#include "../../util/event.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/session.h"
|
||||
#include "../../../util/cpumap.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/evsel.h"
|
||||
#include "../../../util/evlist.h"
|
||||
#include "../../../util/session.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/auxtrace.h"
|
||||
#include "../../util/record.h"
|
||||
#include "../../util/arm-spe.h"
|
||||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/auxtrace.h"
|
||||
#include "../../../util/record.h"
|
||||
#include "../../../util/arm-spe.h"
|
||||
|
||||
#define KiB(x) ((x) * 1024)
|
||||
#define MiB(x) ((x) * 1024 * 1024)
|
||||
@@ -158,20 +158,6 @@ static void arm_spe_recording_free(struct auxtrace_record *itr)
|
||||
free(sper);
|
||||
}
|
||||
|
||||
static int arm_spe_read_finish(struct auxtrace_record *itr, int idx)
|
||||
{
|
||||
struct arm_spe_recording *sper =
|
||||
container_of(itr, struct arm_spe_recording, itr);
|
||||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(sper->evlist, evsel) {
|
||||
if (evsel->core.attr.type == sper->arm_spe_pmu->type)
|
||||
return perf_evlist__enable_event_idx(sper->evlist,
|
||||
evsel, idx);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct auxtrace_record *arm_spe_recording_init(int *err,
|
||||
struct perf_pmu *arm_spe_pmu)
|
||||
{
|
||||
@@ -189,12 +175,13 @@ struct auxtrace_record *arm_spe_recording_init(int *err,
|
||||
}
|
||||
|
||||
sper->arm_spe_pmu = arm_spe_pmu;
|
||||
sper->itr.pmu = arm_spe_pmu;
|
||||
sper->itr.recording_options = arm_spe_recording_options;
|
||||
sper->itr.info_priv_size = arm_spe_info_priv_size;
|
||||
sper->itr.info_fill = arm_spe_info_fill;
|
||||
sper->itr.free = arm_spe_recording_free;
|
||||
sper->itr.reference = arm_spe_reference;
|
||||
sper->itr.read_finish = arm_spe_read_finish;
|
||||
sper->itr.read_finish = auxtrace_record__read_finish;
|
||||
sper->itr.alignment = 0;
|
||||
|
||||
*err = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "../../util/perf_regs.h"
|
||||
#include "../../../util/perf_regs.h"
|
||||
|
||||
const struct sample_reg sample_reg_masks[] = {
|
||||
SMPL_REG_END
|
||||
|
||||
@@ -517,3 +517,5 @@
|
||||
433 common fspick sys_fspick
|
||||
434 common pidfd_open sys_pidfd_open
|
||||
435 nospu clone3 ppc_clone3
|
||||
437 common openat2 sys_openat2
|
||||
438 common pidfd_getfd sys_pidfd_getfd
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <regex.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
||||
#include "../../util/perf_regs.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../../util/perf_regs.h"
|
||||
#include "../../../util/debug.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../util/header.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/auxtrace.h"
|
||||
#include "../../util/intel-pt.h"
|
||||
#include "../../util/intel-bts.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../../util/header.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/auxtrace.h"
|
||||
#include "../../../util/intel-pt.h"
|
||||
#include "../../../util/intel-bts.h"
|
||||
#include "../../../util/evlist.h"
|
||||
|
||||
static
|
||||
struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist,
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
||||
#include "../../util/event.h"
|
||||
#include "../../util/synthetic-events.h"
|
||||
#include "../../util/machine.h"
|
||||
#include "../../util/tool.h"
|
||||
#include "../../util/map.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/synthetic-events.h"
|
||||
#include "../../../util/machine.h"
|
||||
#include "../../../util/tool.h"
|
||||
#include "../../../util/map.h"
|
||||
#include "../../../util/debug.h"
|
||||
|
||||
#if defined(__x86_64__)
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/header.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/header.h"
|
||||
|
||||
static inline void
|
||||
cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c,
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
#include <linux/log2.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
||||
#include "../../util/cpumap.h"
|
||||
#include "../../util/event.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/mmap.h"
|
||||
#include "../../util/session.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/record.h"
|
||||
#include "../../util/tsc.h"
|
||||
#include "../../util/auxtrace.h"
|
||||
#include "../../util/intel-bts.h"
|
||||
#include "../../../util/cpumap.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/evsel.h"
|
||||
#include "../../../util/evlist.h"
|
||||
#include "../../../util/mmap.h"
|
||||
#include "../../../util/session.h"
|
||||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/record.h"
|
||||
#include "../../../util/tsc.h"
|
||||
#include "../../../util/auxtrace.h"
|
||||
#include "../../../util/intel-bts.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
|
||||
#define KiB(x) ((x) * 1024)
|
||||
@@ -413,20 +413,6 @@ static int intel_bts_find_snapshot(struct auxtrace_record *itr, int idx,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int intel_bts_read_finish(struct auxtrace_record *itr, int idx)
|
||||
{
|
||||
struct intel_bts_recording *btsr =
|
||||
container_of(itr, struct intel_bts_recording, itr);
|
||||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(btsr->evlist, evsel) {
|
||||
if (evsel->core.attr.type == btsr->intel_bts_pmu->type)
|
||||
return perf_evlist__enable_event_idx(btsr->evlist,
|
||||
evsel, idx);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct auxtrace_record *intel_bts_recording_init(int *err)
|
||||
{
|
||||
struct perf_pmu *intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME);
|
||||
@@ -447,6 +433,7 @@ struct auxtrace_record *intel_bts_recording_init(int *err)
|
||||
}
|
||||
|
||||
btsr->intel_bts_pmu = intel_bts_pmu;
|
||||
btsr->itr.pmu = intel_bts_pmu;
|
||||
btsr->itr.recording_options = intel_bts_recording_options;
|
||||
btsr->itr.info_priv_size = intel_bts_info_priv_size;
|
||||
btsr->itr.info_fill = intel_bts_info_fill;
|
||||
@@ -456,7 +443,7 @@ struct auxtrace_record *intel_bts_recording_init(int *err)
|
||||
btsr->itr.find_snapshot = intel_bts_find_snapshot;
|
||||
btsr->itr.parse_snapshot_options = intel_bts_parse_snapshot_options;
|
||||
btsr->itr.reference = intel_bts_reference;
|
||||
btsr->itr.read_finish = intel_bts_read_finish;
|
||||
btsr->itr.read_finish = auxtrace_record__read_finish;
|
||||
btsr->itr.alignment = sizeof(struct branch);
|
||||
return &btsr->itr;
|
||||
}
|
||||
|
||||
@@ -13,23 +13,23 @@
|
||||
#include <linux/zalloc.h>
|
||||
#include <cpuid.h>
|
||||
|
||||
#include "../../util/session.h"
|
||||
#include "../../util/event.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/evsel_config.h"
|
||||
#include "../../util/cpumap.h"
|
||||
#include "../../util/mmap.h"
|
||||
#include "../../../util/session.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/evlist.h"
|
||||
#include "../../../util/evsel.h"
|
||||
#include "../../../util/evsel_config.h"
|
||||
#include "../../../util/cpumap.h"
|
||||
#include "../../../util/mmap.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "../../util/parse-events.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/auxtrace.h"
|
||||
#include "../../util/record.h"
|
||||
#include "../../util/target.h"
|
||||
#include "../../util/tsc.h"
|
||||
#include "../../../util/parse-events.h"
|
||||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/auxtrace.h"
|
||||
#include "../../../util/record.h"
|
||||
#include "../../../util/target.h"
|
||||
#include "../../../util/tsc.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/intel-pt.h"
|
||||
#include "../../../util/intel-pt.h"
|
||||
|
||||
#define KiB(x) ((x) * 1024)
|
||||
#define MiB(x) ((x) * 1024 * 1024)
|
||||
@@ -1166,20 +1166,6 @@ static u64 intel_pt_reference(struct auxtrace_record *itr __maybe_unused)
|
||||
return rdtsc();
|
||||
}
|
||||
|
||||
static int intel_pt_read_finish(struct auxtrace_record *itr, int idx)
|
||||
{
|
||||
struct intel_pt_recording *ptr =
|
||||
container_of(itr, struct intel_pt_recording, itr);
|
||||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(ptr->evlist, evsel) {
|
||||
if (evsel->core.attr.type == ptr->intel_pt_pmu->type)
|
||||
return perf_evlist__enable_event_idx(ptr->evlist, evsel,
|
||||
idx);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct auxtrace_record *intel_pt_recording_init(int *err)
|
||||
{
|
||||
struct perf_pmu *intel_pt_pmu = perf_pmu__find(INTEL_PT_PMU_NAME);
|
||||
@@ -1200,6 +1186,7 @@ struct auxtrace_record *intel_pt_recording_init(int *err)
|
||||
}
|
||||
|
||||
ptr->intel_pt_pmu = intel_pt_pmu;
|
||||
ptr->itr.pmu = intel_pt_pmu;
|
||||
ptr->itr.recording_options = intel_pt_recording_options;
|
||||
ptr->itr.info_priv_size = intel_pt_info_priv_size;
|
||||
ptr->itr.info_fill = intel_pt_info_fill;
|
||||
@@ -1209,7 +1196,7 @@ struct auxtrace_record *intel_pt_recording_init(int *err)
|
||||
ptr->itr.find_snapshot = intel_pt_find_snapshot;
|
||||
ptr->itr.parse_snapshot_options = intel_pt_parse_snapshot_options;
|
||||
ptr->itr.reference = intel_pt_reference;
|
||||
ptr->itr.read_finish = intel_pt_read_finish;
|
||||
ptr->itr.read_finish = auxtrace_record__read_finish;
|
||||
/*
|
||||
* Decoding starts at a PSB packet. Minimum PSB period is 2K so 4K
|
||||
* should give at least 1 PSB per sample.
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/machine.h"
|
||||
#include "../../util/map.h"
|
||||
#include "../../util/symbol.h"
|
||||
#include "../../../util/machine.h"
|
||||
#include "../../../util/map.h"
|
||||
#include "../../../util/symbol.h"
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include <symbol/kallsyms.h>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
||||
#include "../../perf-sys.h"
|
||||
#include "../../util/perf_regs.h"
|
||||
#include "../../util/debug.h"
|
||||
#include "../../util/event.h"
|
||||
#include "../../../perf-sys.h"
|
||||
#include "../../../util/perf_regs.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/event.h"
|
||||
|
||||
const struct sample_reg sample_reg_masks[] = {
|
||||
SMPL_REG(AX, PERF_REG_X86_AX),
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
||||
#include "../../util/intel-pt.h"
|
||||
#include "../../util/intel-bts.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../../util/intel-pt.h"
|
||||
#include "../../../util/intel-bts.h"
|
||||
#include "../../../util/pmu.h"
|
||||
|
||||
struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#ifndef BENCH_H
|
||||
#define BENCH_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
extern struct timeval bench__start, bench__end, bench__runtime;
|
||||
|
||||
/*
|
||||
* The madvise transparent hugepage constants were added in glibc
|
||||
* 2.13. For compatibility with older versions of glibc, define these
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
static unsigned int nthreads = 0;
|
||||
static unsigned int nsecs = 8;
|
||||
struct timeval start, end, runtime;
|
||||
static bool done, __verbose, randomize;
|
||||
|
||||
/*
|
||||
@@ -94,8 +93,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &runtime);
|
||||
gettimeofday(&bench__end, NULL);
|
||||
timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void nest_epollfd(void)
|
||||
@@ -313,6 +312,7 @@ int bench_epoll_ctl(int argc, const char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
@@ -361,7 +361,7 @@ int bench_epoll_ctl(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
gettimeofday(&bench__start, NULL);
|
||||
|
||||
do_threads(worker, cpu);
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
|
||||
static unsigned int nthreads = 0;
|
||||
static unsigned int nsecs = 8;
|
||||
struct timeval start, end, runtime;
|
||||
static bool wdone, done, __verbose, randomize, nonblocking;
|
||||
|
||||
/*
|
||||
@@ -276,8 +275,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &runtime);
|
||||
gettimeofday(&bench__end, NULL);
|
||||
timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void print_summary(void)
|
||||
@@ -287,7 +286,7 @@ static void print_summary(void)
|
||||
|
||||
printf("\nAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
avg, rel_stddev_stats(stddev, avg),
|
||||
(int) runtime.tv_sec);
|
||||
(int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
static int do_threads(struct worker *worker, struct perf_cpu_map *cpu)
|
||||
@@ -427,6 +426,7 @@ int bench_epoll_wait(int argc, const char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
@@ -479,7 +479,7 @@ int bench_epoll_wait(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
gettimeofday(&bench__start, NULL);
|
||||
|
||||
do_threads(worker, cpu);
|
||||
|
||||
@@ -519,7 +519,7 @@ int bench_epoll_wait(int argc, const char **argv)
|
||||
qsort(worker, nthreads, sizeof(struct worker), cmpworker);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ static unsigned int nfutexes = 1024;
|
||||
static bool fshared = false, done = false, silent = false;
|
||||
static int futex_flag = 0;
|
||||
|
||||
struct timeval start, end, runtime;
|
||||
struct timeval bench__start, bench__end, bench__runtime;
|
||||
static pthread_mutex_t thread_lock;
|
||||
static unsigned int threads_starting;
|
||||
static struct stats throughput_stats;
|
||||
@@ -103,8 +103,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &runtime);
|
||||
gettimeofday(&bench__end, NULL);
|
||||
timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void print_summary(void)
|
||||
@@ -114,7 +114,7 @@ static void print_summary(void)
|
||||
|
||||
printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
!silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
|
||||
(int) runtime.tv_sec);
|
||||
(int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
int bench_futex_hash(int argc, const char **argv)
|
||||
@@ -137,6 +137,7 @@ int bench_futex_hash(int argc, const char **argv)
|
||||
if (!cpu)
|
||||
goto errmem;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
@@ -161,7 +162,7 @@ int bench_futex_hash(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
pthread_attr_init(&thread_attr);
|
||||
gettimeofday(&start, NULL);
|
||||
gettimeofday(&bench__start, NULL);
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
worker[i].tid = i;
|
||||
worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex));
|
||||
@@ -204,7 +205,7 @@ int bench_futex_hash(int argc, const char **argv)
|
||||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent) {
|
||||
if (nfutexes == 1)
|
||||
|
||||
@@ -37,7 +37,6 @@ static bool silent = false, multi = false;
|
||||
static bool done = false, fshared = false;
|
||||
static unsigned int nthreads = 0;
|
||||
static int futex_flag = 0;
|
||||
struct timeval start, end, runtime;
|
||||
static pthread_mutex_t thread_lock;
|
||||
static unsigned int threads_starting;
|
||||
static struct stats throughput_stats;
|
||||
@@ -64,7 +63,7 @@ static void print_summary(void)
|
||||
|
||||
printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
!silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
|
||||
(int) runtime.tv_sec);
|
||||
(int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
static void toggle_done(int sig __maybe_unused,
|
||||
@@ -73,8 +72,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &runtime);
|
||||
gettimeofday(&bench__end, NULL);
|
||||
timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void *workerfn(void *arg)
|
||||
@@ -161,6 +160,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
||||
if (!cpu)
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
@@ -185,7 +185,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
pthread_attr_init(&thread_attr);
|
||||
gettimeofday(&start, NULL);
|
||||
gettimeofday(&bench__start, NULL);
|
||||
|
||||
create_threads(worker, thread_attr, cpu);
|
||||
pthread_attr_destroy(&thread_attr);
|
||||
@@ -211,7 +211,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
||||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent)
|
||||
|
||||
@@ -128,6 +128,7 @@ int bench_futex_requeue(int argc, const char **argv)
|
||||
if (!cpu)
|
||||
err(EXIT_FAILURE, "cpu_map__new");
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
||||
@@ -234,6 +234,7 @@ int bench_futex_wake_parallel(int argc, const char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
||||
@@ -43,7 +43,7 @@ static bool done = false, silent = false, fshared = false;
|
||||
static pthread_mutex_t thread_lock;
|
||||
static pthread_cond_t thread_parent, thread_worker;
|
||||
static struct stats waketime_stats, wakeup_stats;
|
||||
static unsigned int ncpus, threads_starting, nthreads = 0;
|
||||
static unsigned int threads_starting, nthreads = 0;
|
||||
static int futex_flag = 0;
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -136,12 +136,13 @@ int bench_futex_wake(int argc, const char **argv)
|
||||
if (!cpu)
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_sigaction = toggle_done;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
||||
if (!nthreads)
|
||||
nthreads = ncpus;
|
||||
nthreads = cpu->nr;
|
||||
|
||||
worker = calloc(nthreads, sizeof(*worker));
|
||||
if (!worker)
|
||||
|
||||
@@ -566,6 +566,8 @@ int cmd_annotate(int argc, const char **argv)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
annotation_config__init(&annotate.opts);
|
||||
|
||||
argc = parse_options(argc, argv, options, annotate_usage, 0);
|
||||
if (argc) {
|
||||
/*
|
||||
@@ -605,8 +607,6 @@ int cmd_annotate(int argc, const char **argv)
|
||||
if (ret < 0)
|
||||
goto out_delete;
|
||||
|
||||
annotation_config__init();
|
||||
|
||||
symbol_conf.try_vmlinux_path = true;
|
||||
|
||||
ret = symbol__init(&annotate.session->header.env);
|
||||
|
||||
@@ -1312,7 +1312,8 @@ static int cycles_printf(struct hist_entry *he, struct hist_entry *pair,
|
||||
end_line = map__srcline(he->ms.map, bi->sym->start + bi->end,
|
||||
he->ms.sym);
|
||||
|
||||
if ((start_line != SRCLINE_UNKNOWN) && (end_line != SRCLINE_UNKNOWN)) {
|
||||
if ((strncmp(start_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) &&
|
||||
(strncmp(end_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)) {
|
||||
scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld",
|
||||
start_line, end_line, block_he->diff.cycles);
|
||||
} else {
|
||||
|
||||
@@ -449,7 +449,8 @@ static int perf_del_probe_events(struct strfilter *filter)
|
||||
ret = probe_file__del_strlist(kfd, klist);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
}
|
||||
} else if (ret == -ENOMEM)
|
||||
goto error;
|
||||
|
||||
ret2 = probe_file__get_events(ufd, filter, ulist);
|
||||
if (ret2 == 0) {
|
||||
@@ -459,7 +460,8 @@ static int perf_del_probe_events(struct strfilter *filter)
|
||||
ret2 = probe_file__del_strlist(ufd, ulist);
|
||||
if (ret2 < 0)
|
||||
goto error;
|
||||
}
|
||||
} else if (ret2 == -ENOMEM)
|
||||
goto error;
|
||||
|
||||
if (ret == -ENOENT && ret2 == -ENOENT)
|
||||
pr_warning("\"%s\" does not hit any event.\n", str);
|
||||
|
||||
@@ -1507,7 +1507,7 @@ int cmd_report(int argc, const char **argv)
|
||||
symbol_conf.priv_size += sizeof(u32);
|
||||
symbol_conf.sort_by_name = true;
|
||||
}
|
||||
annotation_config__init();
|
||||
annotation_config__init(&report.annotation_opts);
|
||||
}
|
||||
|
||||
if (symbol__init(&session->header.env) < 0)
|
||||
|
||||
@@ -143,7 +143,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = symbol__annotate(&he->ms, evsel, 0, &top->annotation_opts, NULL);
|
||||
err = symbol__annotate(&he->ms, evsel, &top->annotation_opts, NULL);
|
||||
if (err == 0) {
|
||||
top->sym_filter_entry = he;
|
||||
} else {
|
||||
@@ -684,7 +684,9 @@ static void *display_thread(void *arg)
|
||||
delay_msecs = top->delay_secs * MSEC_PER_SEC;
|
||||
set_term_quiet_input(&save);
|
||||
/* trash return*/
|
||||
getc(stdin);
|
||||
clearerr(stdin);
|
||||
if (poll(&stdin_poll, 1, 0) > 0)
|
||||
getc(stdin);
|
||||
|
||||
while (!done) {
|
||||
perf_top__print_sym_table(top);
|
||||
@@ -1683,7 +1685,7 @@ int cmd_top(int argc, const char **argv)
|
||||
if (status < 0)
|
||||
goto out_delete_evlist;
|
||||
|
||||
annotation_config__init();
|
||||
annotation_config__init(&top.annotation_opts);
|
||||
|
||||
symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
|
||||
status = symbol__init(NULL);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef _PERF_BPF_PID_FILTER_
|
||||
#define _PERF_BPF_PID_FILTER_
|
||||
|
||||
#include <bpf/bpf.h>
|
||||
#include <bpf.h>
|
||||
|
||||
#define pid_filter(name) pid_map(name, bool)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <bpf/bpf.h>
|
||||
#include <bpf.h>
|
||||
|
||||
struct bpf_map SEC("maps") __bpf_stdout__ = {
|
||||
.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1
|
||||
|
||||
#include <bpf/bpf.h>
|
||||
#include <bpf.h>
|
||||
|
||||
static int (*bpf_get_current_pid_tgid)(void) = (void *)BPF_FUNC_get_current_pid_tgid;
|
||||
|
||||
|
||||
@@ -1082,10 +1082,9 @@ static int process_one_file(const char *fpath, const struct stat *sb,
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int rc, ret = 0;
|
||||
int maxfds;
|
||||
char ldirname[PATH_MAX];
|
||||
|
||||
const char *arch;
|
||||
const char *output_file;
|
||||
const char *start_dirname;
|
||||
@@ -1156,7 +1155,8 @@ int main(int argc, char *argv[])
|
||||
/* Make build fail */
|
||||
fclose(eventsfp);
|
||||
free_arch_std_events();
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto out_free_mapfile;
|
||||
} else if (rc) {
|
||||
goto empty_map;
|
||||
}
|
||||
@@ -1174,14 +1174,17 @@ int main(int argc, char *argv[])
|
||||
/* Make build fail */
|
||||
fclose(eventsfp);
|
||||
free_arch_std_events();
|
||||
return 1;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
goto out_free_mapfile;
|
||||
|
||||
empty_map:
|
||||
fclose(eventsfp);
|
||||
create_empty_mapping(output_file);
|
||||
free_arch_std_events();
|
||||
return 0;
|
||||
out_free_mapfile:
|
||||
free(mapfile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "../perf-sys.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
volatile long the_var;
|
||||
static volatile long the_var;
|
||||
|
||||
static noinline int test_function(void)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ add_probe_vfs_getname() {
|
||||
if [ $had_vfs_getname -eq 1 ] ; then
|
||||
line=$(perf probe -L getname_flags 2>&1 | egrep 'result.*=.*filename;' | sed -r 's/[[:space:]]+([[:digit:]]+)[[:space:]]+result->uptr.*/\1/')
|
||||
perf probe -q "vfs_getname=getname_flags:${line} pathname=result->name:string" || \
|
||||
perf probe $verbose "vfs_getname=getname_flags:${line} pathname=filename:string"
|
||||
perf probe $verbose "vfs_getname=getname_flags:${line} pathname=filename:ustring"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -754,10 +754,9 @@ static int annotate_browser__run(struct annotate_browser *browser,
|
||||
"? Search string backwards\n");
|
||||
continue;
|
||||
case 'r':
|
||||
{
|
||||
script_browse(NULL, NULL);
|
||||
continue;
|
||||
}
|
||||
script_browse(NULL, NULL);
|
||||
annotate_browser__show(&browser->b, title, help);
|
||||
continue;
|
||||
case 'k':
|
||||
notes->options->show_linenr = !notes->options->show_linenr;
|
||||
break;
|
||||
@@ -834,13 +833,13 @@ static int annotate_browser__run(struct annotate_browser *browser,
|
||||
map_symbol__annotation_dump(ms, evsel, browser->opts);
|
||||
continue;
|
||||
case 't':
|
||||
if (notes->options->show_total_period) {
|
||||
notes->options->show_total_period = false;
|
||||
notes->options->show_nr_samples = true;
|
||||
} else if (notes->options->show_nr_samples)
|
||||
notes->options->show_nr_samples = false;
|
||||
if (symbol_conf.show_total_period) {
|
||||
symbol_conf.show_total_period = false;
|
||||
symbol_conf.show_nr_samples = true;
|
||||
} else if (symbol_conf.show_nr_samples)
|
||||
symbol_conf.show_nr_samples = false;
|
||||
else
|
||||
notes->options->show_total_period = true;
|
||||
symbol_conf.show_total_period = true;
|
||||
annotation__update_column_widths(notes);
|
||||
continue;
|
||||
case 'c':
|
||||
|
||||
@@ -174,7 +174,7 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||
if (ms->map->dso->annotate_warned)
|
||||
return -1;
|
||||
|
||||
err = symbol__annotate(ms, evsel, 0, &annotation__default_options, NULL);
|
||||
err = symbol__annotate(ms, evsel, &annotation__default_options, NULL);
|
||||
if (err) {
|
||||
char msg[BUFSIZ];
|
||||
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
|
||||
|
||||
@@ -1143,93 +1143,70 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp)
|
||||
}
|
||||
|
||||
struct annotate_args {
|
||||
size_t privsize;
|
||||
struct arch *arch;
|
||||
struct map_symbol ms;
|
||||
struct evsel *evsel;
|
||||
struct arch *arch;
|
||||
struct map_symbol ms;
|
||||
struct evsel *evsel;
|
||||
struct annotation_options *options;
|
||||
s64 offset;
|
||||
char *line;
|
||||
int line_nr;
|
||||
s64 offset;
|
||||
char *line;
|
||||
int line_nr;
|
||||
};
|
||||
|
||||
static void annotation_line__delete(struct annotation_line *al)
|
||||
static void annotation_line__init(struct annotation_line *al,
|
||||
struct annotate_args *args,
|
||||
int nr)
|
||||
{
|
||||
void *ptr = (void *) al - al->privsize;
|
||||
|
||||
free_srcline(al->path);
|
||||
zfree(&al->line);
|
||||
free(ptr);
|
||||
al->offset = args->offset;
|
||||
al->line = strdup(args->line);
|
||||
al->line_nr = args->line_nr;
|
||||
al->data_nr = nr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocating the annotation line data with following
|
||||
* structure:
|
||||
*
|
||||
* --------------------------------------
|
||||
* private space | struct annotation_line
|
||||
* --------------------------------------
|
||||
*
|
||||
* Size of the private space is stored in 'struct annotation_line'.
|
||||
*
|
||||
*/
|
||||
static struct annotation_line *
|
||||
annotation_line__new(struct annotate_args *args, size_t privsize)
|
||||
static void annotation_line__exit(struct annotation_line *al)
|
||||
{
|
||||
free_srcline(al->path);
|
||||
zfree(&al->line);
|
||||
}
|
||||
|
||||
static size_t disasm_line_size(int nr)
|
||||
{
|
||||
struct annotation_line *al;
|
||||
struct evsel *evsel = args->evsel;
|
||||
size_t size = privsize + sizeof(*al);
|
||||
int nr = 1;
|
||||
|
||||
if (perf_evsel__is_group_event(evsel))
|
||||
nr = evsel->core.nr_members;
|
||||
|
||||
size += sizeof(al->data[0]) * nr;
|
||||
|
||||
al = zalloc(size);
|
||||
if (al) {
|
||||
al = (void *) al + privsize;
|
||||
al->privsize = privsize;
|
||||
al->offset = args->offset;
|
||||
al->line = strdup(args->line);
|
||||
al->line_nr = args->line_nr;
|
||||
al->data_nr = nr;
|
||||
}
|
||||
|
||||
return al;
|
||||
return (sizeof(struct disasm_line) + (sizeof(al->data[0]) * nr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocating the disasm annotation line data with
|
||||
* following structure:
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* privsize space | struct disasm_line | struct annotation_line
|
||||
* ------------------------------------------------------------
|
||||
* -------------------------------------------
|
||||
* struct disasm_line | struct annotation_line
|
||||
* -------------------------------------------
|
||||
*
|
||||
* We have 'struct annotation_line' member as last member
|
||||
* of 'struct disasm_line' to have an easy access.
|
||||
*
|
||||
*/
|
||||
static struct disasm_line *disasm_line__new(struct annotate_args *args)
|
||||
{
|
||||
struct disasm_line *dl = NULL;
|
||||
struct annotation_line *al;
|
||||
size_t privsize = args->privsize + offsetof(struct disasm_line, al);
|
||||
int nr = 1;
|
||||
|
||||
al = annotation_line__new(args, privsize);
|
||||
if (al != NULL) {
|
||||
dl = disasm_line(al);
|
||||
if (perf_evsel__is_group_event(args->evsel))
|
||||
nr = args->evsel->core.nr_members;
|
||||
|
||||
if (dl->al.line == NULL)
|
||||
goto out_delete;
|
||||
dl = zalloc(disasm_line_size(nr));
|
||||
if (!dl)
|
||||
return NULL;
|
||||
|
||||
if (args->offset != -1) {
|
||||
if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0)
|
||||
goto out_free_line;
|
||||
annotation_line__init(&dl->al, args, nr);
|
||||
if (dl->al.line == NULL)
|
||||
goto out_delete;
|
||||
|
||||
disasm_line__init_ins(dl, args->arch, &args->ms);
|
||||
}
|
||||
if (args->offset != -1) {
|
||||
if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0)
|
||||
goto out_free_line;
|
||||
|
||||
disasm_line__init_ins(dl, args->arch, &args->ms);
|
||||
}
|
||||
|
||||
return dl;
|
||||
@@ -1248,7 +1225,8 @@ void disasm_line__free(struct disasm_line *dl)
|
||||
else
|
||||
ins__delete(&dl->ops);
|
||||
zfree(&dl->ins.name);
|
||||
annotation_line__delete(&dl->al);
|
||||
annotation_line__exit(&dl->al);
|
||||
free(dl);
|
||||
}
|
||||
|
||||
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name)
|
||||
@@ -2149,13 +2127,12 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel)
|
||||
annotation__calc_percent(notes, evsel, symbol__size(sym));
|
||||
}
|
||||
|
||||
int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, size_t privsize,
|
||||
int symbol__annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||
struct annotation_options *options, struct arch **parch)
|
||||
{
|
||||
struct symbol *sym = ms->sym;
|
||||
struct annotation *notes = symbol__annotation(sym);
|
||||
struct annotate_args args = {
|
||||
.privsize = privsize,
|
||||
.evsel = evsel,
|
||||
.options = options,
|
||||
};
|
||||
@@ -2644,6 +2621,8 @@ void annotation__set_offsets(struct annotation *notes, s64 size)
|
||||
struct annotation_line *al;
|
||||
|
||||
notes->max_line_len = 0;
|
||||
notes->nr_entries = 0;
|
||||
notes->nr_asm_entries = 0;
|
||||
|
||||
list_for_each_entry(al, ¬es->src->source, node) {
|
||||
size_t line_len = strlen(al->line);
|
||||
@@ -2790,7 +2769,7 @@ int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||
struct symbol *sym = ms->sym;
|
||||
struct rb_root source_line = RB_ROOT;
|
||||
|
||||
if (symbol__annotate(ms, evsel, 0, opts, NULL) < 0)
|
||||
if (symbol__annotate(ms, evsel, opts, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
symbol__calc_percent(sym, evsel);
|
||||
@@ -2915,9 +2894,9 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
|
||||
percent = annotation_data__percent(&al->data[i], percent_type);
|
||||
|
||||
obj__set_percent_color(obj, percent, current_entry);
|
||||
if (notes->options->show_total_period) {
|
||||
if (symbol_conf.show_total_period) {
|
||||
obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period);
|
||||
} else if (notes->options->show_nr_samples) {
|
||||
} else if (symbol_conf.show_nr_samples) {
|
||||
obj__printf(obj, "%6" PRIu64 " ",
|
||||
al->data[i].he.nr_samples);
|
||||
} else {
|
||||
@@ -2931,8 +2910,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
|
||||
obj__printf(obj, "%-*s", pcnt_width, " ");
|
||||
else {
|
||||
obj__printf(obj, "%-*s", pcnt_width,
|
||||
notes->options->show_total_period ? "Period" :
|
||||
notes->options->show_nr_samples ? "Samples" : "Percent");
|
||||
symbol_conf.show_total_period ? "Period" :
|
||||
symbol_conf.show_nr_samples ? "Samples" : "Percent");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3070,7 +3049,7 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
|
||||
if (perf_evsel__is_group_event(evsel))
|
||||
nr_pcnt = evsel->core.nr_members;
|
||||
|
||||
err = symbol__annotate(ms, evsel, 0, options, parch);
|
||||
err = symbol__annotate(ms, evsel, options, parch);
|
||||
if (err)
|
||||
goto out_free_offsets;
|
||||
|
||||
@@ -3094,69 +3073,46 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
|
||||
return err;
|
||||
}
|
||||
|
||||
#define ANNOTATION__CFG(n) \
|
||||
{ .name = #n, .value = &annotation__default_options.n, }
|
||||
|
||||
/*
|
||||
* Keep the entries sorted, they are bsearch'ed
|
||||
*/
|
||||
static struct annotation_config {
|
||||
const char *name;
|
||||
void *value;
|
||||
} annotation__configs[] = {
|
||||
ANNOTATION__CFG(hide_src_code),
|
||||
ANNOTATION__CFG(jump_arrows),
|
||||
ANNOTATION__CFG(offset_level),
|
||||
ANNOTATION__CFG(show_linenr),
|
||||
ANNOTATION__CFG(show_nr_jumps),
|
||||
ANNOTATION__CFG(show_nr_samples),
|
||||
ANNOTATION__CFG(show_total_period),
|
||||
ANNOTATION__CFG(use_offset),
|
||||
};
|
||||
|
||||
#undef ANNOTATION__CFG
|
||||
|
||||
static int annotation_config__cmp(const void *name, const void *cfgp)
|
||||
static int annotation__config(const char *var, const char *value, void *data)
|
||||
{
|
||||
const struct annotation_config *cfg = cfgp;
|
||||
|
||||
return strcmp(name, cfg->name);
|
||||
}
|
||||
|
||||
static int annotation__config(const char *var, const char *value,
|
||||
void *data __maybe_unused)
|
||||
{
|
||||
struct annotation_config *cfg;
|
||||
const char *name;
|
||||
struct annotation_options *opt = data;
|
||||
|
||||
if (!strstarts(var, "annotate."))
|
||||
return 0;
|
||||
|
||||
name = var + 9;
|
||||
cfg = bsearch(name, annotation__configs, ARRAY_SIZE(annotation__configs),
|
||||
sizeof(struct annotation_config), annotation_config__cmp);
|
||||
if (!strcmp(var, "annotate.offset_level")) {
|
||||
perf_config_u8(&opt->offset_level, "offset_level", value);
|
||||
|
||||
if (cfg == NULL)
|
||||
pr_debug("%s variable unknown, ignoring...", var);
|
||||
else if (strcmp(var, "annotate.offset_level") == 0) {
|
||||
perf_config_int(cfg->value, name, value);
|
||||
|
||||
if (*(int *)cfg->value > ANNOTATION__MAX_OFFSET_LEVEL)
|
||||
*(int *)cfg->value = ANNOTATION__MAX_OFFSET_LEVEL;
|
||||
else if (*(int *)cfg->value < ANNOTATION__MIN_OFFSET_LEVEL)
|
||||
*(int *)cfg->value = ANNOTATION__MIN_OFFSET_LEVEL;
|
||||
if (opt->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
|
||||
opt->offset_level = ANNOTATION__MAX_OFFSET_LEVEL;
|
||||
else if (opt->offset_level < ANNOTATION__MIN_OFFSET_LEVEL)
|
||||
opt->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
|
||||
} else if (!strcmp(var, "annotate.hide_src_code")) {
|
||||
opt->hide_src_code = perf_config_bool("hide_src_code", value);
|
||||
} else if (!strcmp(var, "annotate.jump_arrows")) {
|
||||
opt->jump_arrows = perf_config_bool("jump_arrows", value);
|
||||
} else if (!strcmp(var, "annotate.show_linenr")) {
|
||||
opt->show_linenr = perf_config_bool("show_linenr", value);
|
||||
} else if (!strcmp(var, "annotate.show_nr_jumps")) {
|
||||
opt->show_nr_jumps = perf_config_bool("show_nr_jumps", value);
|
||||
} else if (!strcmp(var, "annotate.show_nr_samples")) {
|
||||
symbol_conf.show_nr_samples = perf_config_bool("show_nr_samples",
|
||||
value);
|
||||
} else if (!strcmp(var, "annotate.show_total_period")) {
|
||||
symbol_conf.show_total_period = perf_config_bool("show_total_period",
|
||||
value);
|
||||
} else if (!strcmp(var, "annotate.use_offset")) {
|
||||
opt->use_offset = perf_config_bool("use_offset", value);
|
||||
} else {
|
||||
*(bool *)cfg->value = perf_config_bool(name, value);
|
||||
pr_debug("%s variable unknown, ignoring...", var);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void annotation_config__init(void)
|
||||
void annotation_config__init(struct annotation_options *opt)
|
||||
{
|
||||
perf_config(annotation__config, NULL);
|
||||
|
||||
annotation__default_options.show_total_period = symbol_conf.show_total_period;
|
||||
annotation__default_options.show_nr_samples = symbol_conf.show_nr_samples;
|
||||
perf_config(annotation__config, opt);
|
||||
}
|
||||
|
||||
static unsigned int parse_percent_type(char *str1, char *str2)
|
||||
|
||||
@@ -83,8 +83,6 @@ struct annotation_options {
|
||||
full_path,
|
||||
show_linenr,
|
||||
show_nr_jumps,
|
||||
show_nr_samples,
|
||||
show_total_period,
|
||||
show_minmax_cycle,
|
||||
show_asm_raw,
|
||||
annotate_src;
|
||||
@@ -141,7 +139,6 @@ struct annotation_line {
|
||||
u64 cycles;
|
||||
u64 cycles_max;
|
||||
u64 cycles_min;
|
||||
size_t privsize;
|
||||
char *path;
|
||||
u32 idx;
|
||||
int idx_asm;
|
||||
@@ -309,7 +306,7 @@ static inline int annotation__cycles_width(struct annotation *notes)
|
||||
|
||||
static inline int annotation__pcnt_width(struct annotation *notes)
|
||||
{
|
||||
return (notes->options->show_total_period ? 12 : 7) * notes->nr_events;
|
||||
return (symbol_conf.show_total_period ? 12 : 7) * notes->nr_events;
|
||||
}
|
||||
|
||||
static inline bool annotation_line__filter(struct annotation_line *al, struct annotation *notes)
|
||||
@@ -352,7 +349,7 @@ struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists);
|
||||
void symbol__annotate_zero_histograms(struct symbol *sym);
|
||||
|
||||
int symbol__annotate(struct map_symbol *ms,
|
||||
struct evsel *evsel, size_t privsize,
|
||||
struct evsel *evsel,
|
||||
struct annotation_options *options,
|
||||
struct arch **parch);
|
||||
int symbol__annotate2(struct map_symbol *ms,
|
||||
@@ -413,7 +410,7 @@ static inline int symbol__tui_annotate(struct map_symbol *ms __maybe_unused,
|
||||
}
|
||||
#endif
|
||||
|
||||
void annotation_config__init(void);
|
||||
void annotation_config__init(struct annotation_options *opt);
|
||||
|
||||
int annotate_parse_percent_type(const struct option *opt, const char *_str,
|
||||
int unset);
|
||||
|
||||
@@ -629,8 +629,10 @@ int auxtrace_record__options(struct auxtrace_record *itr,
|
||||
struct evlist *evlist,
|
||||
struct record_opts *opts)
|
||||
{
|
||||
if (itr)
|
||||
if (itr) {
|
||||
itr->evlist = evlist;
|
||||
return itr->recording_options(itr, evlist, opts);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -664,6 +666,24 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int auxtrace_record__read_finish(struct auxtrace_record *itr, int idx)
|
||||
{
|
||||
struct evsel *evsel;
|
||||
|
||||
if (!itr->evlist || !itr->pmu)
|
||||
return -EINVAL;
|
||||
|
||||
evlist__for_each_entry(itr->evlist, evsel) {
|
||||
if (evsel->core.attr.type == itr->pmu->type) {
|
||||
if (evsel->disabled)
|
||||
return 0;
|
||||
return perf_evlist__enable_event_idx(itr->evlist, evsel,
|
||||
idx);
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Event record size is 16-bit which results in a maximum size of about 64KiB.
|
||||
* Allow about 4KiB for the rest of the sample record, to give a maximum
|
||||
|
||||
@@ -29,6 +29,7 @@ struct record_opts;
|
||||
struct perf_record_auxtrace_error;
|
||||
struct perf_record_auxtrace_info;
|
||||
struct events_stats;
|
||||
struct perf_pmu;
|
||||
|
||||
enum auxtrace_error_type {
|
||||
PERF_AUXTRACE_ERROR_ITRACE = 1,
|
||||
@@ -322,6 +323,8 @@ struct auxtrace_mmap_params {
|
||||
* @read_finish: called after reading from an auxtrace mmap
|
||||
* @alignment: alignment (if any) for AUX area data
|
||||
* @default_aux_sample_size: default sample size for --aux sample option
|
||||
* @pmu: associated pmu
|
||||
* @evlist: selected events list
|
||||
*/
|
||||
struct auxtrace_record {
|
||||
int (*recording_options)(struct auxtrace_record *itr,
|
||||
@@ -346,6 +349,8 @@ struct auxtrace_record {
|
||||
int (*read_finish)(struct auxtrace_record *itr, int idx);
|
||||
unsigned int alignment;
|
||||
unsigned int default_aux_sample_size;
|
||||
struct perf_pmu *pmu;
|
||||
struct evlist *evlist;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -537,6 +542,7 @@ int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx,
|
||||
struct auxtrace_mmap *mm,
|
||||
unsigned char *data, u64 *head, u64 *old);
|
||||
u64 auxtrace_record__reference(struct auxtrace_record *itr);
|
||||
int auxtrace_record__read_finish(struct auxtrace_record *itr, int idx);
|
||||
|
||||
int auxtrace_index__auxtrace_event(struct list_head *head, union perf_event *event,
|
||||
off_t file_offset);
|
||||
|
||||
@@ -295,7 +295,8 @@ static int block_range_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
|
||||
end_line = map__srcline(he->ms.map, bi->sym->start + bi->end,
|
||||
he->ms.sym);
|
||||
|
||||
if ((start_line != SRCLINE_UNKNOWN) && (end_line != SRCLINE_UNKNOWN)) {
|
||||
if ((strncmp(start_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) &&
|
||||
(strncmp(end_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)) {
|
||||
scnprintf(buf, sizeof(buf), "[%s -> %s]",
|
||||
start_line, end_line);
|
||||
} else {
|
||||
|
||||
@@ -374,6 +374,18 @@ int perf_config_int(int *dest, const char *name, const char *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int perf_config_u8(u8 *dest, const char *name, const char *value)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
if (!perf_parse_long(value, &ret)) {
|
||||
bad_config(name);
|
||||
return -1;
|
||||
}
|
||||
*dest = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef int (*config_fn_t)(const char *, const char *, void *);
|
||||
int perf_default_config(const char *, const char *, void *);
|
||||
int perf_config(config_fn_t fn, void *);
|
||||
int perf_config_int(int *dest, const char *, const char *);
|
||||
int perf_config_u8(u8 *dest, const char *name, const char *value);
|
||||
int perf_config_u64(u64 *dest, const char *, const char *);
|
||||
int perf_config_bool(const char *, const char *);
|
||||
int config_error_nonbool(const char *);
|
||||
|
||||
@@ -343,11 +343,11 @@ static const char *normalize_arch(char *arch)
|
||||
|
||||
const char *perf_env__arch(struct perf_env *env)
|
||||
{
|
||||
struct utsname uts;
|
||||
char *arch_name;
|
||||
|
||||
if (!env || !env->arch) { /* Assume local operation */
|
||||
if (uname(&uts) < 0)
|
||||
static struct utsname uts = { .machine[0] = '\0', };
|
||||
if (uts.machine[0] == '\0' && uname(&uts) < 0)
|
||||
return NULL;
|
||||
arch_name = uts.machine;
|
||||
} else
|
||||
|
||||
@@ -431,7 +431,7 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
|
||||
|
||||
if (map && map->dso) {
|
||||
char *srcline = map__srcline(map, addr, NULL);
|
||||
if (srcline != SRCLINE_UNKNOWN)
|
||||
if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)
|
||||
ret = fprintf(fp, "%s%s", prefix, srcline);
|
||||
free_srcline(srcline);
|
||||
}
|
||||
|
||||
@@ -257,21 +257,15 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
|
||||
path = zalloc(sizeof(*path));
|
||||
if (!path)
|
||||
return NULL;
|
||||
path->system = malloc(MAX_EVENT_LENGTH);
|
||||
if (!path->system) {
|
||||
if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
path->name = malloc(MAX_EVENT_LENGTH);
|
||||
if (!path->name) {
|
||||
if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) {
|
||||
zfree(&path->system);
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
strncpy(path->system, sys_dirent->d_name,
|
||||
MAX_EVENT_LENGTH);
|
||||
strncpy(path->name, evt_dirent->d_name,
|
||||
MAX_EVENT_LENGTH);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,10 +301,15 @@ int probe_file__get_events(int fd, struct strfilter *filter,
|
||||
p = strchr(ent->s, ':');
|
||||
if ((p && strfilter__compare(filter, p + 1)) ||
|
||||
strfilter__compare(filter, ent->s)) {
|
||||
strlist__add(plist, ent->s);
|
||||
ret = strlist__add(plist, ent->s);
|
||||
if (ret == -ENOMEM) {
|
||||
pr_err("strlist__add failed with -ENOMEM\n");
|
||||
goto out;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
out:
|
||||
strlist__delete(namelist);
|
||||
|
||||
return ret;
|
||||
@@ -511,7 +516,11 @@ static int probe_cache__load(struct probe_cache *pcache)
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
strlist__add(entry->tevlist, buf);
|
||||
ret = strlist__add(entry->tevlist, buf);
|
||||
if (ret == -ENOMEM) {
|
||||
pr_err("strlist__add failed with -ENOMEM\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
@@ -672,7 +681,12 @@ int probe_cache__add_entry(struct probe_cache *pcache,
|
||||
command = synthesize_probe_trace_command(&tevs[i]);
|
||||
if (!command)
|
||||
goto out_err;
|
||||
strlist__add(entry->tevlist, command);
|
||||
ret = strlist__add(entry->tevlist, command);
|
||||
if (ret == -ENOMEM) {
|
||||
pr_err("strlist__add failed with -ENOMEM\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
free(command);
|
||||
}
|
||||
list_add_tail(&entry->node, &pcache->entries);
|
||||
@@ -853,9 +867,15 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
|
||||
break;
|
||||
}
|
||||
|
||||
strlist__add(entry->tevlist, buf);
|
||||
ret = strlist__add(entry->tevlist, buf);
|
||||
|
||||
free(buf);
|
||||
entry = NULL;
|
||||
|
||||
if (ret == -ENOMEM) {
|
||||
pr_err("strlist__add failed with -ENOMEM\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
list_del_init(&entry->node);
|
||||
|
||||
@@ -1622,7 +1622,12 @@ int dso__load(struct dso *dso, struct map *map)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dso->kernel) {
|
||||
kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
|
||||
|
||||
if (dso->kernel && !kmod) {
|
||||
if (dso->kernel == DSO_TYPE_KERNEL)
|
||||
ret = dso__load_kernel_sym(dso, map);
|
||||
else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||
@@ -1650,12 +1655,6 @@ int dso__load(struct dso *dso, struct map *map)
|
||||
if (!name)
|
||||
goto out;
|
||||
|
||||
kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
|
||||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
|
||||
|
||||
|
||||
/*
|
||||
* Read the build id if possible. This is required for
|
||||
* DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
|
||||
|
||||
@@ -82,7 +82,7 @@ static struct pci_access *pci_acc;
|
||||
static struct pci_dev *amd_fam14h_pci_dev;
|
||||
static int nbp1_entered;
|
||||
|
||||
struct timespec start_time;
|
||||
static struct timespec start_time;
|
||||
static unsigned long long timediff;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -19,7 +19,7 @@ struct cpuidle_monitor cpuidle_sysfs_monitor;
|
||||
|
||||
static unsigned long long **previous_count;
|
||||
static unsigned long long **current_count;
|
||||
struct timespec start_time;
|
||||
static struct timespec start_time;
|
||||
static unsigned long long timediff;
|
||||
|
||||
static int cpuidle_get_count_percent(unsigned int id, double *percent,
|
||||
|
||||
@@ -27,6 +27,8 @@ struct cpuidle_monitor *all_monitors[] = {
|
||||
0
|
||||
};
|
||||
|
||||
int cpu_count;
|
||||
|
||||
static struct cpuidle_monitor *monitors[MONITORS_MAX];
|
||||
static unsigned int avail_monitors;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#endif
|
||||
#define CSTATE_DESC_LEN 60
|
||||
|
||||
int cpu_count;
|
||||
extern int cpu_count;
|
||||
|
||||
/* Hard to define the right names ...: */
|
||||
enum power_range_e {
|
||||
|
||||
@@ -30,7 +30,7 @@ my %default = (
|
||||
"EMAIL_WHEN_STARTED" => 0,
|
||||
"NUM_TESTS" => 1,
|
||||
"TEST_TYPE" => "build",
|
||||
"BUILD_TYPE" => "randconfig",
|
||||
"BUILD_TYPE" => "oldconfig",
|
||||
"MAKE_CMD" => "make",
|
||||
"CLOSE_CONSOLE_SIGNAL" => "INT",
|
||||
"TIMEOUT" => 120,
|
||||
@@ -1030,7 +1030,7 @@ sub __read_config {
|
||||
}
|
||||
|
||||
if (!$skip && $rest !~ /^\s*$/) {
|
||||
die "$name: $.: Gargbage found after $type\n$_";
|
||||
die "$name: $.: Garbage found after $type\n$_";
|
||||
}
|
||||
|
||||
if ($skip && $type eq "TEST_START") {
|
||||
@@ -1063,7 +1063,7 @@ sub __read_config {
|
||||
}
|
||||
|
||||
if ($rest !~ /^\s*$/) {
|
||||
die "$name: $.: Gargbage found after DEFAULTS\n$_";
|
||||
die "$name: $.: Garbage found after DEFAULTS\n$_";
|
||||
}
|
||||
|
||||
} elsif (/^\s*INCLUDE\s+(\S+)/) {
|
||||
@@ -1154,7 +1154,7 @@ sub __read_config {
|
||||
# on of these sections that have SKIP defined.
|
||||
# The save variable can be
|
||||
# defined multiple times and the new one simply overrides
|
||||
# the prevous one.
|
||||
# the previous one.
|
||||
set_variable($lvalue, $rvalue);
|
||||
|
||||
} else {
|
||||
@@ -1234,7 +1234,7 @@ sub read_config {
|
||||
foreach my $option (keys %not_used) {
|
||||
print "$option\n";
|
||||
}
|
||||
print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
|
||||
print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
|
||||
if (!read_yn "Do you want to continue?") {
|
||||
exit -1;
|
||||
}
|
||||
@@ -1345,7 +1345,7 @@ sub eval_option {
|
||||
# Check for recursive evaluations.
|
||||
# 100 deep should be more than enough.
|
||||
if ($r++ > 100) {
|
||||
die "Over 100 evaluations accurred with $option\n" .
|
||||
die "Over 100 evaluations occurred with $option\n" .
|
||||
"Check for recursive variables\n";
|
||||
}
|
||||
$prev = $option;
|
||||
@@ -1383,7 +1383,7 @@ sub reboot {
|
||||
|
||||
} else {
|
||||
# Make sure everything has been written to disk
|
||||
run_ssh("sync");
|
||||
run_ssh("sync", 10);
|
||||
|
||||
if (defined($time)) {
|
||||
start_monitor;
|
||||
@@ -1461,7 +1461,7 @@ sub get_test_name() {
|
||||
|
||||
sub dodie {
|
||||
|
||||
# avoid recusion
|
||||
# avoid recursion
|
||||
return if ($in_die);
|
||||
$in_die = 1;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
|
||||
# Options set in the beginning of the file are considered to be
|
||||
# default options. These options can be overriden by test specific
|
||||
# default options. These options can be overridden by test specific
|
||||
# options, with the following exceptions:
|
||||
#
|
||||
# LOG_FILE
|
||||
@@ -204,7 +204,7 @@
|
||||
#
|
||||
# This config file can also contain "config variables".
|
||||
# These are assigned with ":=" instead of the ktest option
|
||||
# assigment "=".
|
||||
# assignment "=".
|
||||
#
|
||||
# The difference between ktest options and config variables
|
||||
# is that config variables can be used multiple times,
|
||||
@@ -263,7 +263,7 @@
|
||||
#### Using options in other options ####
|
||||
#
|
||||
# Options that are defined in the config file may also be used
|
||||
# by other options. All options are evaulated at time of
|
||||
# by other options. All options are evaluated at time of
|
||||
# use (except that config variables are evaluated at config
|
||||
# processing time).
|
||||
#
|
||||
@@ -505,7 +505,7 @@
|
||||
#TEST = ssh user@machine /root/run_test
|
||||
|
||||
# The build type is any make config type or special command
|
||||
# (default randconfig)
|
||||
# (default oldconfig)
|
||||
# nobuild - skip the clean and build step
|
||||
# useconfig:/path/to/config - use the given config and run
|
||||
# oldconfig on it.
|
||||
@@ -707,7 +707,7 @@
|
||||
|
||||
# Line to define a successful boot up in console output.
|
||||
# This is what the line contains, not the entire line. If you need
|
||||
# the entire line to match, then use regural expression syntax like:
|
||||
# the entire line to match, then use regular expression syntax like:
|
||||
# (do not add any quotes around it)
|
||||
#
|
||||
# SUCCESS_LINE = ^MyBox Login:$
|
||||
@@ -839,7 +839,7 @@
|
||||
# (ignored if POWEROFF_ON_SUCCESS is set)
|
||||
#REBOOT_ON_SUCCESS = 1
|
||||
|
||||
# In case there are isses with rebooting, you can specify this
|
||||
# In case there are issues with rebooting, you can specify this
|
||||
# to always powercycle after this amount of time after calling
|
||||
# reboot.
|
||||
# Note, POWERCYCLE_AFTER_REBOOT = 0 does NOT disable it. It just
|
||||
@@ -848,7 +848,7 @@
|
||||
# (default undefined)
|
||||
#POWERCYCLE_AFTER_REBOOT = 5
|
||||
|
||||
# In case there's isses with halting, you can specify this
|
||||
# In case there's issues with halting, you can specify this
|
||||
# to always poweroff after this amount of time after calling
|
||||
# halt.
|
||||
# Note, POWEROFF_AFTER_HALT = 0 does NOT disable it. It just
|
||||
@@ -972,7 +972,7 @@
|
||||
#
|
||||
# PATCHCHECK_START is required and is the first patch to
|
||||
# test (the SHA1 of the commit). You may also specify anything
|
||||
# that git checkout allows (branch name, tage, HEAD~3).
|
||||
# that git checkout allows (branch name, tag, HEAD~3).
|
||||
#
|
||||
# PATCHCHECK_END is the last patch to check (default HEAD)
|
||||
#
|
||||
@@ -994,7 +994,7 @@
|
||||
# IGNORE_WARNINGS is set for the given commit's sha1
|
||||
#
|
||||
# IGNORE_WARNINGS can be used to disable the failure of patchcheck
|
||||
# on a particuler commit (SHA1). You can add more than one commit
|
||||
# on a particular commit (SHA1). You can add more than one commit
|
||||
# by adding a list of SHA1s that are space delimited.
|
||||
#
|
||||
# If BUILD_NOCLEAN is set, then make mrproper will not be run on
|
||||
@@ -1093,7 +1093,7 @@
|
||||
# whatever reason. (Can't reboot, want to inspect each iteration)
|
||||
# Doing a BISECT_MANUAL will have the test wait for you to
|
||||
# tell it if the test passed or failed after each iteration.
|
||||
# This is basicall the same as running git bisect yourself
|
||||
# This is basically the same as running git bisect yourself
|
||||
# but ktest will rebuild and install the kernel for you.
|
||||
#
|
||||
# BISECT_CHECK = 1 (optional, default 0)
|
||||
@@ -1239,7 +1239,7 @@
|
||||
#
|
||||
# CONFIG_BISECT_EXEC (optional)
|
||||
# The config bisect is a separate program that comes with ktest.pl.
|
||||
# By befault, it will look for:
|
||||
# By default, it will look for:
|
||||
# `pwd`/config-bisect.pl # the location ktest.pl was executed from.
|
||||
# If it does not find it there, it will look for:
|
||||
# `dirname <ktest.pl>`/config-bisect.pl # The directory that holds ktest.pl
|
||||
|
||||
@@ -24,6 +24,8 @@ KunitResult = namedtuple('KunitResult', ['status','result'])
|
||||
|
||||
KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', 'build_dir', 'defconfig'])
|
||||
|
||||
KernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0]
|
||||
|
||||
class KunitStatus(Enum):
|
||||
SUCCESS = auto()
|
||||
CONFIG_FAILURE = auto()
|
||||
@@ -35,6 +37,13 @@ def create_default_kunitconfig():
|
||||
shutil.copyfile('arch/um/configs/kunit_defconfig',
|
||||
kunit_kernel.kunitconfig_path)
|
||||
|
||||
def get_kernel_root_path():
|
||||
parts = sys.argv[0] if not __file__ else __file__
|
||||
parts = os.path.realpath(parts).split('tools/testing/kunit')
|
||||
if len(parts) != 2:
|
||||
sys.exit(1)
|
||||
return parts[0]
|
||||
|
||||
def run_tests(linux: kunit_kernel.LinuxSourceTree,
|
||||
request: KunitRequest) -> KunitResult:
|
||||
config_start = time.time()
|
||||
@@ -114,6 +123,9 @@ def main(argv, linux=None):
|
||||
cli_args = parser.parse_args(argv)
|
||||
|
||||
if cli_args.subcommand == 'run':
|
||||
if get_kernel_root_path():
|
||||
os.chdir(get_kernel_root_path())
|
||||
|
||||
if cli_args.build_dir:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
@@ -93,6 +93,20 @@ class LinuxSourceTree(object):
|
||||
return False
|
||||
return True
|
||||
|
||||
def validate_config(self, build_dir):
|
||||
kconfig_path = get_kconfig_path(build_dir)
|
||||
validated_kconfig = kunit_config.Kconfig()
|
||||
validated_kconfig.read_from_file(kconfig_path)
|
||||
if not self._kconfig.is_subset_of(validated_kconfig):
|
||||
invalid = self._kconfig.entries() - validated_kconfig.entries()
|
||||
message = 'Provided Kconfig is not contained in validated .config. Following fields found in kunitconfig, ' \
|
||||
'but not in .config: %s' % (
|
||||
', '.join([str(e) for e in invalid])
|
||||
)
|
||||
logging.error(message)
|
||||
return False
|
||||
return True
|
||||
|
||||
def build_config(self, build_dir):
|
||||
kconfig_path = get_kconfig_path(build_dir)
|
||||
if build_dir and not os.path.exists(build_dir):
|
||||
@@ -103,12 +117,7 @@ class LinuxSourceTree(object):
|
||||
except ConfigError as e:
|
||||
logging.error(e)
|
||||
return False
|
||||
validated_kconfig = kunit_config.Kconfig()
|
||||
validated_kconfig.read_from_file(kconfig_path)
|
||||
if not self._kconfig.is_subset_of(validated_kconfig):
|
||||
logging.error('Provided Kconfig is not contained in validated .config!')
|
||||
return False
|
||||
return True
|
||||
return self.validate_config(build_dir)
|
||||
|
||||
def build_reconfig(self, build_dir):
|
||||
"""Creates a new .config if it is not a subset of the .kunitconfig."""
|
||||
@@ -133,12 +142,7 @@ class LinuxSourceTree(object):
|
||||
except (ConfigError, BuildError) as e:
|
||||
logging.error(e)
|
||||
return False
|
||||
used_kconfig = kunit_config.Kconfig()
|
||||
used_kconfig.read_from_file(get_kconfig_path(build_dir))
|
||||
if not self._kconfig.is_subset_of(used_kconfig):
|
||||
logging.error('Provided Kconfig is not contained in final config!')
|
||||
return False
|
||||
return True
|
||||
return self.validate_config(build_dir)
|
||||
|
||||
def run_kernel(self, args=[], timeout=None, build_dir=''):
|
||||
args.extend(['mem=256M'])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
all:
|
||||
|
||||
TEST_PROGS := ftracetest
|
||||
TEST_FILES := test.d
|
||||
TEST_FILES := test.d settings
|
||||
EXTRA_CLEAN := $(OUTPUT)/logs/*
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
@@ -8,4 +8,6 @@ TEST_PROGS := \
|
||||
test-state.sh \
|
||||
test-ftrace.sh
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
2
tools/testing/selftests/lkdtm/.gitignore
vendored
Normal file
2
tools/testing/selftests/lkdtm/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.sh
|
||||
!run.sh
|
||||
@@ -1041,6 +1041,27 @@ ipv6_addr_metric_test()
|
||||
fi
|
||||
log_test $rc 0 "Prefix route with metric on link up"
|
||||
|
||||
# verify peer metric added correctly
|
||||
set -e
|
||||
run_cmd "$IP -6 addr flush dev dummy2"
|
||||
run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
|
||||
set +e
|
||||
|
||||
check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
|
||||
log_test $? 0 "Set metric with peer route on local side"
|
||||
log_test $? 0 "User specified metric on local address"
|
||||
check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
|
||||
log_test $? 0 "Set metric with peer route on peer side"
|
||||
|
||||
set -e
|
||||
run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
|
||||
set +e
|
||||
|
||||
check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
|
||||
log_test $? 0 "Modify metric and peer address on local side"
|
||||
check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
|
||||
log_test $? 0 "Modify metric and peer address on peer side"
|
||||
|
||||
$IP li del dummy1
|
||||
$IP li del dummy2
|
||||
cleanup
|
||||
@@ -1457,13 +1478,20 @@ ipv4_addr_metric_test()
|
||||
|
||||
run_cmd "$IP addr flush dev dummy2"
|
||||
run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
|
||||
run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 261"
|
||||
rc=$?
|
||||
if [ $rc -eq 0 ]; then
|
||||
check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
|
||||
check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
|
||||
rc=$?
|
||||
fi
|
||||
log_test $rc 0 "Modify metric of address with peer route"
|
||||
log_test $rc 0 "Set metric of address with peer route"
|
||||
|
||||
run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
|
||||
rc=$?
|
||||
if [ $rc -eq 0 ]; then
|
||||
check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
|
||||
rc=$?
|
||||
fi
|
||||
log_test $rc 0 "Modify metric and peer address for peer route"
|
||||
|
||||
$IP li del dummy1
|
||||
$IP li del dummy2
|
||||
|
||||
@@ -8,6 +8,8 @@ TEST_PROGS := mptcp_connect.sh
|
||||
|
||||
TEST_GEN_FILES = mptcp_connect
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
EXTRA_CLEAN := *.pcap
|
||||
|
||||
include ../../lib.mk
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
KSELFTEST_SKIP=4
|
||||
|
||||
# Available test groups:
|
||||
# - reported_issues: check for issues that were reported in the past
|
||||
# - correctness: check that packets match given entries, and only those
|
||||
# - concurrency: attempt races between insertion, deletion and lookup
|
||||
# - timeout: check that packets match entries until they expire
|
||||
# - performance: estimate matching rate, compare with rbtree and hash baselines
|
||||
TESTS="correctness concurrency timeout"
|
||||
TESTS="reported_issues correctness concurrency timeout"
|
||||
[ "${quicktest}" != "1" ] && TESTS="${TESTS} performance"
|
||||
|
||||
# Set types, defined by TYPE_ variables below
|
||||
@@ -25,6 +26,9 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
|
||||
net_port_net net_mac net_mac_icmp net6_mac_icmp net6_port_net6_port
|
||||
net_port_mac_proto_net"
|
||||
|
||||
# Reported bugs, also described by TYPE_ variables below
|
||||
BUGS="flush_remove_add"
|
||||
|
||||
# List of possible paths to pktgen script from kernel tree for performance tests
|
||||
PKTGEN_SCRIPT_PATHS="
|
||||
../../../samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
|
||||
@@ -327,6 +331,12 @@ flood_spec ip daddr . tcp dport . meta l4proto . ip saddr
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
# Definition of tests for bugs reported in the past:
|
||||
# display display text for test report
|
||||
TYPE_flush_remove_add="
|
||||
display Add two elements, flush, re-add
|
||||
"
|
||||
|
||||
# Set template for all tests, types and rules are filled in depending on test
|
||||
set_template='
|
||||
flush ruleset
|
||||
@@ -440,6 +450,8 @@ setup_set() {
|
||||
|
||||
# Check that at least one of the needed tools is available
|
||||
check_tools() {
|
||||
[ -z "${tools}" ] && return 0
|
||||
|
||||
__tools=
|
||||
for tool in ${tools}; do
|
||||
if [ "${tool}" = "nc" ] && [ "${proto}" = "udp6" ] && \
|
||||
@@ -1025,7 +1037,7 @@ format_noconcat() {
|
||||
add() {
|
||||
if ! nft add element inet filter test "${1}"; then
|
||||
err "Failed to add ${1} given ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -1045,7 +1057,7 @@ add_perf() {
|
||||
add_perf_norange() {
|
||||
if ! nft add element netdev perf norange "${1}"; then
|
||||
err "Failed to add ${1} given ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -1054,7 +1066,7 @@ add_perf_norange() {
|
||||
add_perf_noconcat() {
|
||||
if ! nft add element netdev perf noconcat "${1}"; then
|
||||
err "Failed to add ${1} given ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -1063,7 +1075,7 @@ add_perf_noconcat() {
|
||||
del() {
|
||||
if ! nft delete element inet filter test "${1}"; then
|
||||
err "Failed to delete ${1} given ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -1134,7 +1146,7 @@ send_match() {
|
||||
err " $(for f in ${src}; do
|
||||
eval format_\$f "${2}"; printf ' '; done)"
|
||||
err "should have matched ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
nft reset counter inet filter test >/dev/null
|
||||
@@ -1160,7 +1172,7 @@ send_nomatch() {
|
||||
err " $(for f in ${src}; do
|
||||
eval format_\$f "${2}"; printf ' '; done)"
|
||||
err "should not have matched ruleset:"
|
||||
err "$(nft list ruleset -a)"
|
||||
err "$(nft -a list ruleset)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -1430,6 +1442,23 @@ test_performance() {
|
||||
kill "${perf_pid}"
|
||||
}
|
||||
|
||||
test_bug_flush_remove_add() {
|
||||
set_cmd='{ set s { type ipv4_addr . inet_service; flags interval; }; }'
|
||||
elem1='{ 10.0.0.1 . 22-25, 10.0.0.1 . 10-20 }'
|
||||
elem2='{ 10.0.0.1 . 10-20, 10.0.0.1 . 22-25 }'
|
||||
for i in `seq 1 100`; do
|
||||
nft add table t ${set_cmd} || return ${KSELFTEST_SKIP}
|
||||
nft add element t s ${elem1} 2>/dev/null || return 1
|
||||
nft flush set t s 2>/dev/null || return 1
|
||||
nft add element t s ${elem2} 2>/dev/null || return 1
|
||||
done
|
||||
nft flush ruleset
|
||||
}
|
||||
|
||||
test_reported_issues() {
|
||||
eval test_bug_"${subtest}"
|
||||
}
|
||||
|
||||
# Run everything in a separate network namespace
|
||||
[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; }
|
||||
tmp="$(mktemp)"
|
||||
@@ -1438,9 +1467,15 @@ trap cleanup EXIT
|
||||
# Entry point for test runs
|
||||
passed=0
|
||||
for name in ${TESTS}; do
|
||||
printf "TEST: %s\n" "${name}"
|
||||
for type in ${TYPES}; do
|
||||
eval desc=\$TYPE_"${type}"
|
||||
printf "TEST: %s\n" "$(echo ${name} | tr '_' ' ')"
|
||||
if [ "${name}" = "reported_issues" ]; then
|
||||
SUBTESTS="${BUGS}"
|
||||
else
|
||||
SUBTESTS="${TYPES}"
|
||||
fi
|
||||
|
||||
for subtest in ${SUBTESTS}; do
|
||||
eval desc=\$TYPE_"${subtest}"
|
||||
IFS='
|
||||
'
|
||||
for __line in ${desc}; do
|
||||
|
||||
1
tools/testing/selftests/pidfd/.gitignore
vendored
1
tools/testing/selftests/pidfd/.gitignore
vendored
@@ -2,4 +2,5 @@ pidfd_open_test
|
||||
pidfd_poll_test
|
||||
pidfd_test
|
||||
pidfd_wait
|
||||
pidfd_fdinfo_test
|
||||
pidfd_getfd_test
|
||||
|
||||
@@ -4,7 +4,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
|
||||
CLANG_FLAGS += -no-integrated-as
|
||||
endif
|
||||
|
||||
CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ \
|
||||
CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \
|
||||
$(CLANG_FLAGS)
|
||||
LDLIBS += -lpthread
|
||||
|
||||
@@ -19,6 +19,8 @@ TEST_GEN_PROGS_EXTENDED = librseq.so
|
||||
|
||||
TEST_PROGS = run_param_test.sh
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
$(OUTPUT)/librseq.so: rseq.c rseq.h rseq-*.h
|
||||
|
||||
@@ -6,4 +6,6 @@ TEST_GEN_PROGS = rtctest
|
||||
|
||||
TEST_GEN_PROGS_EXTENDED = setdate
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
@@ -57,3 +57,4 @@ CONFIG_NET_IFE_SKBMARK=m
|
||||
CONFIG_NET_IFE_SKBPRIO=m
|
||||
CONFIG_NET_IFE_SKBTCINDEX=m
|
||||
CONFIG_NET_SCH_FIFO=y
|
||||
CONFIG_NET_SCH_ETS=m
|
||||
|
||||
Reference in New Issue
Block a user