Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Alexei Starovoitov

On 7/23/15 6:54 PM, xiakaixu wrote:

于 2015/7/24 6:59, Alexei Starovoitov 写道:

On 7/23/15 2:42 AM, Kaixu Xia wrote:

This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia 

...

+struct bpf_map_def SEC("maps") my_map = {
+.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+.key_size = sizeof(int),
+.value_size = sizeof(unsigned long),
+.max_entries = 32,
+};


wait. how did it work here? value_size should be u32.


I tested the whole thing on ARM board. You are ringt, it
should be u32.
When create the array map, we choose the array->elem_size as
round_up(attr->value_size, 8), why 8?


because from user space point of view we're storing FDs
which are u32, but kernel stores pointers.
but round_up(attr->value_size, 8) is done because there
can be 8 byte fields in there and we have 8-byte load/store insns.
So whether pointer is 32 or 64-bit they still fit.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread xiakaixu
于 2015/7/24 6:59, Alexei Starovoitov 写道:
> On 7/23/15 2:42 AM, Kaixu Xia wrote:
>> This is a simple example and shows how to use the new ability
>> to get the selected Hardware PMU counter value.
>>
>> Signed-off-by: Kaixu Xia 
> ...
>> +struct bpf_map_def SEC("maps") my_map = {
>> +.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
>> +.key_size = sizeof(int),
>> +.value_size = sizeof(unsigned long),
>> +.max_entries = 32,
>> +};
> 
> wait. how did it work here? value_size should be u32.

I tested the whole thing on ARM board. You are ringt, it
should be u32.
When create the array map, we choose the array->elem_size as
round_up(attr->value_size, 8), why 8?

Thanks!
> 
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Alexei Starovoitov

On 7/23/15 2:42 AM, Kaixu Xia wrote:

This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia 

...

+struct bpf_map_def SEC("maps") my_map = {
+   .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+   .key_size = sizeof(int),
+   .value_size = sizeof(unsigned long),
+   .max_entries = 32,
+};


wait. how did it work here? value_size should be u32.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Kaixu Xia
This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia 
---
 samples/bpf/Makefile   |  4 +++
 samples/bpf/bpf_helpers.h  |  2 ++
 samples/bpf/tracex6_kern.c | 26 ++
 samples/bpf/tracex6_user.c | 67 ++
 4 files changed, 99 insertions(+)
 create mode 100644 samples/bpf/tracex6_kern.c
 create mode 100644 samples/bpf/tracex6_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 4450fed..63e7d50 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -12,6 +12,7 @@ hostprogs-y += tracex2
 hostprogs-y += tracex3
 hostprogs-y += tracex4
 hostprogs-y += tracex5
+hostprogs-y += tracex6
 hostprogs-y += lathist
 
 test_verifier-objs := test_verifier.o libbpf.o
@@ -25,6 +26,7 @@ tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
 tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
 tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
 tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
+tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
 lathist-objs := bpf_load.o libbpf.o lathist_user.o
 
 # Tell kbuild to always build the programs
@@ -37,6 +39,7 @@ always += tracex2_kern.o
 always += tracex3_kern.o
 always += tracex4_kern.o
 always += tracex5_kern.o
+always += tracex6_kern.o
 always += tcbpf1_kern.o
 always += lathist_kern.o
 
@@ -51,6 +54,7 @@ HOSTLOADLIBES_tracex2 += -lelf
 HOSTLOADLIBES_tracex3 += -lelf
 HOSTLOADLIBES_tracex4 += -lelf -lrt
 HOSTLOADLIBES_tracex5 += -lelf
+HOSTLOADLIBES_tracex6 += -lelf
 HOSTLOADLIBES_lathist += -lelf
 
 # point this to your LLVM backend with bpf support
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h
index bdf1c16..c8a3594 100644
--- a/samples/bpf/bpf_helpers.h
+++ b/samples/bpf/bpf_helpers.h
@@ -31,6 +31,8 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) =
(void *) BPF_FUNC_get_current_uid_gid;
 static int (*bpf_get_current_comm)(void *buf, int buf_size) =
(void *) BPF_FUNC_get_current_comm;
+static int (*bpf_perf_event_read)(void *map, int index) =
+   (void *) BPF_FUNC_perf_event_read;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/samples/bpf/tracex6_kern.c b/samples/bpf/tracex6_kern.c
new file mode 100644
index 000..d213161
--- /dev/null
+++ b/samples/bpf/tracex6_kern.c
@@ -0,0 +1,26 @@
+#include 
+#include 
+#include "bpf_helpers.h"
+
+struct bpf_map_def SEC("maps") my_map = {
+   .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+   .key_size = sizeof(int),
+   .value_size = sizeof(unsigned long),
+   .max_entries = 32,
+};
+
+SEC("kprobe/sys_write")
+int bpf_prog1(struct pt_regs *ctx)
+{
+   u64 count;
+   u32 key = bpf_get_smp_processor_id();
+   char fmt[] = "CPU-%d   %llu\n";
+
+   count = bpf_perf_event_read(_map, );
+   bpf_trace_printk(fmt, sizeof(fmt), key, count);
+
+   return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/tracex6_user.c b/samples/bpf/tracex6_user.c
new file mode 100644
index 000..30307c9
--- /dev/null
+++ b/samples/bpf/tracex6_user.c
@@ -0,0 +1,67 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "libbpf.h"
+#include "bpf_load.h"
+
+static void test_bpf_perf_event(void)
+{
+   int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+   int *pmu_fd = malloc(nr_cpus * sizeof(int));
+   unsigned long value;
+   int i;
+
+   struct perf_event_attr attr_insn_pmu = {
+   .freq = 0,
+   .sample_period = 0x7fffULL,
+   .inherit = 0,
+   .type = PERF_TYPE_HARDWARE,
+   .read_format = 0,
+   .sample_type = 0,
+   .config = 0,/* PMU: cycles */
+   };
+
+   for(i = 0; i < nr_cpus; i++) {
+   pmu_fd[i] = perf_event_open(_insn_pmu, -1/*pid*/, 
i/*cpu*/, -1/*group_fd*/, 0);
+   if (pmu_fd[i] < 0)
+   printf("event syscall failed \n");
+
+   bpf_update_elem(map_fd[0], , (pmu_fd + i), BPF_ANY);
+
+   ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
+   }
+
+   system("ls");
+   system("pwd");
+   system("sleep 2");
+
+   for(i = 0; i < nr_cpus; i++)
+close(pmu_fd[i]);
+
+   close(map_fd);
+
+   free(pmu_fd);
+}
+
+int main(int argc, char **argv)
+{
+   char filename[256];
+
+   snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+   if (load_bpf_file(filename)) {
+   printf("%s", bpf_log_buf);
+   return 1;
+   }
+
+   test_bpf_perf_event();
+
+   return 0;
+}
-- 
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo 

Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Alexei Starovoitov

On 7/23/15 2:42 AM, Kaixu Xia wrote:

This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia xiaka...@huawei.com

...

+struct bpf_map_def SEC(maps) my_map = {
+   .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+   .key_size = sizeof(int),
+   .value_size = sizeof(unsigned long),
+   .max_entries = 32,
+};


wait. how did it work here? value_size should be u32.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread xiakaixu
于 2015/7/24 6:59, Alexei Starovoitov 写道:
 On 7/23/15 2:42 AM, Kaixu Xia wrote:
 This is a simple example and shows how to use the new ability
 to get the selected Hardware PMU counter value.

 Signed-off-by: Kaixu Xia xiaka...@huawei.com
 ...
 +struct bpf_map_def SEC(maps) my_map = {
 +.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
 +.key_size = sizeof(int),
 +.value_size = sizeof(unsigned long),
 +.max_entries = 32,
 +};
 
 wait. how did it work here? value_size should be u32.

I tested the whole thing on ARM board. You are ringt, it
should be u32.
When create the array map, we choose the array-elem_size as
round_up(attr-value_size, 8), why 8?

Thanks!
 
 
 


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Alexei Starovoitov

On 7/23/15 6:54 PM, xiakaixu wrote:

于 2015/7/24 6:59, Alexei Starovoitov 写道:

On 7/23/15 2:42 AM, Kaixu Xia wrote:

This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia xiaka...@huawei.com

...

+struct bpf_map_def SEC(maps) my_map = {
+.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+.key_size = sizeof(int),
+.value_size = sizeof(unsigned long),
+.max_entries = 32,
+};


wait. how did it work here? value_size should be u32.


I tested the whole thing on ARM board. You are ringt, it
should be u32.
When create the array map, we choose the array-elem_size as
round_up(attr-value_size, 8), why 8?


because from user space point of view we're storing FDs
which are u32, but kernel stores pointers.
but round_up(attr-value_size, 8) is done because there
can be 8 byte fields in there and we have 8-byte load/store insns.
So whether pointer is 32 or 64-bit they still fit.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] samples/bpf: example of get selected PMU counter value

2015-07-23 Thread Kaixu Xia
This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.

Signed-off-by: Kaixu Xia xiaka...@huawei.com
---
 samples/bpf/Makefile   |  4 +++
 samples/bpf/bpf_helpers.h  |  2 ++
 samples/bpf/tracex6_kern.c | 26 ++
 samples/bpf/tracex6_user.c | 67 ++
 4 files changed, 99 insertions(+)
 create mode 100644 samples/bpf/tracex6_kern.c
 create mode 100644 samples/bpf/tracex6_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 4450fed..63e7d50 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -12,6 +12,7 @@ hostprogs-y += tracex2
 hostprogs-y += tracex3
 hostprogs-y += tracex4
 hostprogs-y += tracex5
+hostprogs-y += tracex6
 hostprogs-y += lathist
 
 test_verifier-objs := test_verifier.o libbpf.o
@@ -25,6 +26,7 @@ tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
 tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
 tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
 tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
+tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
 lathist-objs := bpf_load.o libbpf.o lathist_user.o
 
 # Tell kbuild to always build the programs
@@ -37,6 +39,7 @@ always += tracex2_kern.o
 always += tracex3_kern.o
 always += tracex4_kern.o
 always += tracex5_kern.o
+always += tracex6_kern.o
 always += tcbpf1_kern.o
 always += lathist_kern.o
 
@@ -51,6 +54,7 @@ HOSTLOADLIBES_tracex2 += -lelf
 HOSTLOADLIBES_tracex3 += -lelf
 HOSTLOADLIBES_tracex4 += -lelf -lrt
 HOSTLOADLIBES_tracex5 += -lelf
+HOSTLOADLIBES_tracex6 += -lelf
 HOSTLOADLIBES_lathist += -lelf
 
 # point this to your LLVM backend with bpf support
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h
index bdf1c16..c8a3594 100644
--- a/samples/bpf/bpf_helpers.h
+++ b/samples/bpf/bpf_helpers.h
@@ -31,6 +31,8 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) =
(void *) BPF_FUNC_get_current_uid_gid;
 static int (*bpf_get_current_comm)(void *buf, int buf_size) =
(void *) BPF_FUNC_get_current_comm;
+static int (*bpf_perf_event_read)(void *map, int index) =
+   (void *) BPF_FUNC_perf_event_read;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/samples/bpf/tracex6_kern.c b/samples/bpf/tracex6_kern.c
new file mode 100644
index 000..d213161
--- /dev/null
+++ b/samples/bpf/tracex6_kern.c
@@ -0,0 +1,26 @@
+#include linux/version.h
+#include uapi/linux/bpf.h
+#include bpf_helpers.h
+
+struct bpf_map_def SEC(maps) my_map = {
+   .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+   .key_size = sizeof(int),
+   .value_size = sizeof(unsigned long),
+   .max_entries = 32,
+};
+
+SEC(kprobe/sys_write)
+int bpf_prog1(struct pt_regs *ctx)
+{
+   u64 count;
+   u32 key = bpf_get_smp_processor_id();
+   char fmt[] = CPU-%d   %llu\n;
+
+   count = bpf_perf_event_read(my_map, key);
+   bpf_trace_printk(fmt, sizeof(fmt), key, count);
+
+   return 0;
+}
+
+char _license[] SEC(license) = GPL;
+u32 _version SEC(version) = LINUX_VERSION_CODE;
diff --git a/samples/bpf/tracex6_user.c b/samples/bpf/tracex6_user.c
new file mode 100644
index 000..30307c9
--- /dev/null
+++ b/samples/bpf/tracex6_user.c
@@ -0,0 +1,67 @@
+#include stdio.h
+#include unistd.h
+#include stdlib.h
+#include stdbool.h
+#include string.h
+#include fcntl.h
+#include poll.h
+#include sys/ioctl.h
+#include linux/perf_event.h
+#include linux/bpf.h
+#include libbpf.h
+#include bpf_load.h
+
+static void test_bpf_perf_event(void)
+{
+   int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+   int *pmu_fd = malloc(nr_cpus * sizeof(int));
+   unsigned long value;
+   int i;
+
+   struct perf_event_attr attr_insn_pmu = {
+   .freq = 0,
+   .sample_period = 0x7fffULL,
+   .inherit = 0,
+   .type = PERF_TYPE_HARDWARE,
+   .read_format = 0,
+   .sample_type = 0,
+   .config = 0,/* PMU: cycles */
+   };
+
+   for(i = 0; i  nr_cpus; i++) {
+   pmu_fd[i] = perf_event_open(attr_insn_pmu, -1/*pid*/, 
i/*cpu*/, -1/*group_fd*/, 0);
+   if (pmu_fd[i]  0)
+   printf(event syscall failed \n);
+
+   bpf_update_elem(map_fd[0], i, (pmu_fd + i), BPF_ANY);
+
+   ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
+   }
+
+   system(ls);
+   system(pwd);
+   system(sleep 2);
+
+   for(i = 0; i  nr_cpus; i++)
+close(pmu_fd[i]);
+
+   close(map_fd);
+
+   free(pmu_fd);
+}
+
+int main(int argc, char **argv)
+{
+   char filename[256];
+
+   snprintf(filename, sizeof(filename), %s_kern.o, argv[0]);
+
+   if (load_bpf_file(filename)) {
+   printf(%s, bpf_log_buf);
+   return 1;
+   }
+
+   test_bpf_perf_event();
+
+   return 0;
+}
-- 
1.8.3.4

--
To unsubscribe from