Re: [PATCH RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-15 Thread Alexei Starovoitov
On Thu, Aug 14, 2014 at 3:13 PM, Brendan Gregg
 wrote:
> On Wed, Aug 13, 2014 at 12:57 AM, Alexei Starovoitov  
> wrote:
>> this example has two probes in C that use two different maps.
>>
>> 1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint 
>> and
>> count number of packet drops at different locations
>>
>> 2nd probe attaches to kprobe/sys_write and computes a histogram of different
>> write sizes
>>
>> Usage:
>> $ sudo ex2
>>
>> Should see:
>> writing bpf-5 -> /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
>> writing bpf-8 -> /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
>> location 0x816efc67 count 1
>>
>> location 0x815d8030 count 1
>> location 0x816efc67 count 3
>>
>> location 0x815d8030 count 4
>> location 0x816efc67 count 9
>>
>>syscall write() stats
>>  byte_size   : count distribution
>>1 -> 1: 3141 |  |
>>2 -> 3: 2|  |
>>4 -> 7: 14   |  |
>>8 -> 15   : 3268 |* |
>>   16 -> 31   : 732  |  |
>>   32 -> 63   : 20042|* |
>>   64 -> 127  : 12154|**|
>>  128 -> 255  : 2215 |***   |
>>  256 -> 511  : 9|  |
>>  512 -> 1023 : 0|  |
>> 1024 -> 2047 : 1|  |
>
> This is pretty awesome.
>
> Given that this is tracing two tracepoints at once, I'd like to see a
> similar example where time is stored on the first tracepoint,
> retrieved on the second for a delta calculation, then presented with a
> similar histogram as seen above.

Very good point. The time related helpers are missing. In V5 I'm
thinking to add something like bpf_ktime_get_ns().
To associate begin and end events I think bpf_gettid() would be
needed, but that doesn't feel generic enough for helper function,
so I'm leaning toward 'bpf_get_current()' helper that will return
'current' task pointer. eBPF program can use this pointer for
correlation of events or can go exploring task fields with
bpf_fetch_() helpers...

Thank you very much for trying things out and for your feedback!
--
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 RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-15 Thread Alexei Starovoitov
On Thu, Aug 14, 2014 at 3:13 PM, Brendan Gregg
brendan.d.gr...@gmail.com wrote:
 On Wed, Aug 13, 2014 at 12:57 AM, Alexei Starovoitov a...@plumgrid.com 
 wrote:
 this example has two probes in C that use two different maps.

 1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint 
 and
 count number of packet drops at different locations

 2nd probe attaches to kprobe/sys_write and computes a histogram of different
 write sizes

 Usage:
 $ sudo ex2

 Should see:
 writing bpf-5 - /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
 writing bpf-8 - /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
 location 0x816efc67 count 1

 location 0x815d8030 count 1
 location 0x816efc67 count 3

 location 0x815d8030 count 4
 location 0x816efc67 count 9

syscall write() stats
  byte_size   : count distribution
1 - 1: 3141 |  |
2 - 3: 2|  |
4 - 7: 14   |  |
8 - 15   : 3268 |* |
   16 - 31   : 732  |  |
   32 - 63   : 20042|* |
   64 - 127  : 12154|**|
  128 - 255  : 2215 |***   |
  256 - 511  : 9|  |
  512 - 1023 : 0|  |
 1024 - 2047 : 1|  |

 This is pretty awesome.

 Given that this is tracing two tracepoints at once, I'd like to see a
 similar example where time is stored on the first tracepoint,
 retrieved on the second for a delta calculation, then presented with a
 similar histogram as seen above.

Very good point. The time related helpers are missing. In V5 I'm
thinking to add something like bpf_ktime_get_ns().
To associate begin and end events I think bpf_gettid() would be
needed, but that doesn't feel generic enough for helper function,
so I'm leaning toward 'bpf_get_current()' helper that will return
'current' task pointer. eBPF program can use this pointer for
correlation of events or can go exploring task fields with
bpf_fetch_() helpers...

Thank you very much for trying things out and for your feedback!
--
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 RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-14 Thread Brendan Gregg
On Wed, Aug 13, 2014 at 12:57 AM, Alexei Starovoitov  wrote:
> this example has two probes in C that use two different maps.
>
> 1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint and
> count number of packet drops at different locations
>
> 2nd probe attaches to kprobe/sys_write and computes a histogram of different
> write sizes
>
> Usage:
> $ sudo ex2
>
> Should see:
> writing bpf-5 -> /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
> writing bpf-8 -> /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
> location 0x816efc67 count 1
>
> location 0x815d8030 count 1
> location 0x816efc67 count 3
>
> location 0x815d8030 count 4
> location 0x816efc67 count 9
>
>syscall write() stats
>  byte_size   : count distribution
>1 -> 1: 3141 |  |
>2 -> 3: 2|  |
>4 -> 7: 14   |  |
>8 -> 15   : 3268 |* |
>   16 -> 31   : 732  |  |
>   32 -> 63   : 20042|* |
>   64 -> 127  : 12154|**|
>  128 -> 255  : 2215 |***   |
>  256 -> 511  : 9|  |
>  512 -> 1023 : 0|  |
> 1024 -> 2047 : 1|  |

This is pretty awesome.

Given that this is tracing two tracepoints at once, I'd like to see a
similar example where time is stored on the first tracepoint,
retrieved on the second for a delta calculation, then presented with a
similar histogram as seen above.

Brendan
--
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 RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-14 Thread Brendan Gregg
On Wed, Aug 13, 2014 at 12:57 AM, Alexei Starovoitov a...@plumgrid.com wrote:
 this example has two probes in C that use two different maps.

 1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint and
 count number of packet drops at different locations

 2nd probe attaches to kprobe/sys_write and computes a histogram of different
 write sizes

 Usage:
 $ sudo ex2

 Should see:
 writing bpf-5 - /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
 writing bpf-8 - /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
 location 0x816efc67 count 1

 location 0x815d8030 count 1
 location 0x816efc67 count 3

 location 0x815d8030 count 4
 location 0x816efc67 count 9

syscall write() stats
  byte_size   : count distribution
1 - 1: 3141 |  |
2 - 3: 2|  |
4 - 7: 14   |  |
8 - 15   : 3268 |* |
   16 - 31   : 732  |  |
   32 - 63   : 20042|* |
   64 - 127  : 12154|**|
  128 - 255  : 2215 |***   |
  256 - 511  : 9|  |
  512 - 1023 : 0|  |
 1024 - 2047 : 1|  |

This is pretty awesome.

Given that this is tracing two tracepoints at once, I'd like to see a
similar example where time is stored on the first tracepoint,
retrieved on the second for a delta calculation, then presented with a
similar histogram as seen above.

Brendan
--
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 RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-13 Thread Alexei Starovoitov
this example has two probes in C that use two different maps.

1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint and
count number of packet drops at different locations

2nd probe attaches to kprobe/sys_write and computes a histogram of different
write sizes

Usage:
$ sudo ex2

Should see:
writing bpf-5 -> /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
writing bpf-8 -> /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
location 0x816efc67 count 1

location 0x815d8030 count 1
location 0x816efc67 count 3

location 0x815d8030 count 4
location 0x816efc67 count 9

   syscall write() stats
 byte_size   : count distribution
   1 -> 1: 3141 |  |
   2 -> 3: 2|  |
   4 -> 7: 14   |  |
   8 -> 15   : 3268 |* |
  16 -> 31   : 732  |  |
  32 -> 63   : 20042|* |
  64 -> 127  : 12154|**|
 128 -> 255  : 2215 |***   |
 256 -> 511  : 9|  |
 512 -> 1023 : 0|  |
1024 -> 2047 : 1|  |

Ctrl-C at any time. Kernel will auto cleanup maps and programs

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/Makefile   |6 ++--
 samples/bpf/ex2_kern.c |   73 +
 samples/bpf/ex2_user.c |   94 
 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 samples/bpf/ex2_kern.c
 create mode 100644 samples/bpf/ex2_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index c97f408fcd6d..b865a5df5c60 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -2,19 +2,21 @@
 obj- := dummy.o
 
 # List of programs to build
-hostprogs-y := sock_example dropmon ex1
+hostprogs-y := sock_example dropmon ex1 ex2
 
 sock_example-objs := sock_example.o libbpf.o
 dropmon-objs := dropmon.o libbpf.o
 ex1-objs := bpf_load.o libbpf.o ex1_user.o
+ex2-objs := bpf_load.o libbpf.o ex2_user.o
 
 # Tell kbuild to always build the programs
-always := $(hostprogs-y) ex1_kern.o
+always := $(hostprogs-y) ex1_kern.o ex2_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
 HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable
 HOSTLOADLIBES_ex1 += -lelf
+HOSTLOADLIBES_ex2 += -lelf
 
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
 
diff --git a/samples/bpf/ex2_kern.c b/samples/bpf/ex2_kern.c
new file mode 100644
index ..2daa50b27ce5
--- /dev/null
+++ b/samples/bpf/ex2_kern.c
@@ -0,0 +1,73 @@
+#include 
+#include 
+#include 
+#include 
+#include "bpf_helpers.h"
+
+struct bpf_map_def SEC("maps") my_map = {
+   .type = BPF_MAP_TYPE_HASH,
+   .key_size = sizeof(long),
+   .value_size = sizeof(long),
+   .max_entries = 1024,
+};
+
+SEC("events/skb/kfree_skb")
+int bpf_prog2(struct bpf_context *ctx)
+{
+   long loc = ctx->arg2;
+   long init_val = 1;
+   void *value;
+
+   value = bpf_map_lookup_elem(_map, );
+   if (value)
+   (*(long *) value) += 1;
+   else
+   bpf_map_update_elem(_map, , _val);
+   return 0;
+}
+
+static unsigned int log2(unsigned int v)
+{
+   unsigned int r;
+   unsigned int shift;
+
+   r = (v > 0x) << 4; v >>= r;
+   shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
+   shift = (v > 0xF) << 2; v >>= shift; r |= shift;
+   shift = (v > 0x3) << 1; v >>= shift; r |= shift;
+   r |= (v >> 1);
+   return r;
+}
+
+static unsigned int log2l(unsigned long v)
+{
+   unsigned int hi = v >> 32;
+   if (hi)
+   return log2(hi) + 32;
+   else
+   return log2(v);
+}
+
+struct bpf_map_def SEC("maps") my_hist_map = {
+   .type = BPF_MAP_TYPE_HASH,
+   .key_size = sizeof(u32),
+   .value_size = sizeof(long),
+   .max_entries = 64,
+};
+
+SEC("events/kprobes/sys_write")
+int bpf_prog3(struct bpf_context *ctx)
+{
+   long write_size = ctx->arg3;
+   long init_val = 1;
+   void *value;
+   u32 index = log2l(write_size);
+
+   value = bpf_map_lookup_elem(_hist_map, );
+   if (value)
+   __sync_fetch_and_add((long *)value, 1);
+   else
+   bpf_map_update_elem(_hist_map, , _val);
+   return 0;
+}
+char license[] SEC("license") = "GPL";
diff --git a/samples/bpf/ex2_user.c b/samples/bpf/ex2_user.c
new file mode 100644
index ..fd5ce21ae60a
--- /dev/null
+++ b/samples/bpf/ex2_user.c
@@ -0,0 +1,94 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 

[PATCH RFC v4 net-next 25/26] samples: bpf: counting eBPF example in C

2014-08-13 Thread Alexei Starovoitov
this example has two probes in C that use two different maps.

1st probe is the similar to dropmon.c. It attaches to kfree_skb tracepoint and
count number of packet drops at different locations

2nd probe attaches to kprobe/sys_write and computes a histogram of different
write sizes

Usage:
$ sudo ex2

Should see:
writing bpf-5 - /sys/kernel/debug/tracing/events/skb/kfree_skb/filter
writing bpf-8 - /sys/kernel/debug/tracing/events/kprobes/sys_write/filter
location 0x816efc67 count 1

location 0x815d8030 count 1
location 0x816efc67 count 3

location 0x815d8030 count 4
location 0x816efc67 count 9

   syscall write() stats
 byte_size   : count distribution
   1 - 1: 3141 |  |
   2 - 3: 2|  |
   4 - 7: 14   |  |
   8 - 15   : 3268 |* |
  16 - 31   : 732  |  |
  32 - 63   : 20042|* |
  64 - 127  : 12154|**|
 128 - 255  : 2215 |***   |
 256 - 511  : 9|  |
 512 - 1023 : 0|  |
1024 - 2047 : 1|  |

Ctrl-C at any time. Kernel will auto cleanup maps and programs

Signed-off-by: Alexei Starovoitov a...@plumgrid.com
---
 samples/bpf/Makefile   |6 ++--
 samples/bpf/ex2_kern.c |   73 +
 samples/bpf/ex2_user.c |   94 
 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 samples/bpf/ex2_kern.c
 create mode 100644 samples/bpf/ex2_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index c97f408fcd6d..b865a5df5c60 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -2,19 +2,21 @@
 obj- := dummy.o
 
 # List of programs to build
-hostprogs-y := sock_example dropmon ex1
+hostprogs-y := sock_example dropmon ex1 ex2
 
 sock_example-objs := sock_example.o libbpf.o
 dropmon-objs := dropmon.o libbpf.o
 ex1-objs := bpf_load.o libbpf.o ex1_user.o
+ex2-objs := bpf_load.o libbpf.o ex2_user.o
 
 # Tell kbuild to always build the programs
-always := $(hostprogs-y) ex1_kern.o
+always := $(hostprogs-y) ex1_kern.o ex2_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
 HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable
 HOSTLOADLIBES_ex1 += -lelf
+HOSTLOADLIBES_ex2 += -lelf
 
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
 
diff --git a/samples/bpf/ex2_kern.c b/samples/bpf/ex2_kern.c
new file mode 100644
index ..2daa50b27ce5
--- /dev/null
+++ b/samples/bpf/ex2_kern.c
@@ -0,0 +1,73 @@
+#include linux/skbuff.h
+#include linux/netdevice.h
+#include uapi/linux/bpf.h
+#include trace/bpf_trace.h
+#include bpf_helpers.h
+
+struct bpf_map_def SEC(maps) my_map = {
+   .type = BPF_MAP_TYPE_HASH,
+   .key_size = sizeof(long),
+   .value_size = sizeof(long),
+   .max_entries = 1024,
+};
+
+SEC(events/skb/kfree_skb)
+int bpf_prog2(struct bpf_context *ctx)
+{
+   long loc = ctx-arg2;
+   long init_val = 1;
+   void *value;
+
+   value = bpf_map_lookup_elem(my_map, loc);
+   if (value)
+   (*(long *) value) += 1;
+   else
+   bpf_map_update_elem(my_map, loc, init_val);
+   return 0;
+}
+
+static unsigned int log2(unsigned int v)
+{
+   unsigned int r;
+   unsigned int shift;
+
+   r = (v  0x)  4; v = r;
+   shift = (v  0xFF)  3; v = shift; r |= shift;
+   shift = (v  0xF)  2; v = shift; r |= shift;
+   shift = (v  0x3)  1; v = shift; r |= shift;
+   r |= (v  1);
+   return r;
+}
+
+static unsigned int log2l(unsigned long v)
+{
+   unsigned int hi = v  32;
+   if (hi)
+   return log2(hi) + 32;
+   else
+   return log2(v);
+}
+
+struct bpf_map_def SEC(maps) my_hist_map = {
+   .type = BPF_MAP_TYPE_HASH,
+   .key_size = sizeof(u32),
+   .value_size = sizeof(long),
+   .max_entries = 64,
+};
+
+SEC(events/kprobes/sys_write)
+int bpf_prog3(struct bpf_context *ctx)
+{
+   long write_size = ctx-arg3;
+   long init_val = 1;
+   void *value;
+   u32 index = log2l(write_size);
+
+   value = bpf_map_lookup_elem(my_hist_map, index);
+   if (value)
+   __sync_fetch_and_add((long *)value, 1);
+   else
+   bpf_map_update_elem(my_hist_map, index, init_val);
+   return 0;
+}
+char license[] SEC(license) = GPL;
diff --git a/samples/bpf/ex2_user.c b/samples/bpf/ex2_user.c
new file mode 100644
index ..fd5ce21ae60a
--- /dev/null
+++ b/samples/bpf/ex2_user.c
@@ -0,0 +1,94 @@
+#include