Re: [PATCH v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Jovi Zhangwei
On Mon, Mar 31, 2014 at 1:19 AM, Andi Kleen  wrote:
>> See test/benchmark/cmp_table.sh, that script compare
>
> Is that a realistic tracing scenario?
>
Yes, it's quite common to use string key in dynamic tracing tool,
for example, See samples/userspace/glibc_func_hist.kp

var s = {}

trace probe:/lib64/libc.so.6:* {
s[probename] += 1
}

trace_end {
print_hist(s)
}


Result:

Tracing... Hit Ctrl-C to end.
^C
 value - Distribution - count
  _IO_sputbackc |@@108344
 __GI__IO_sputbackc |@@107768
 _IO_default_xsputn |  46639
__GI__IO_default_xsputn |  46624
   free |  36871
__libc_free |  36841
  cfree |  36841
 __free |  36811
__cfree |  36811
   __GI___libc_free |  36804
strtoull_l_internal |  28670
__GI_strtoul_l_internal |  28670
   __GI_strtoull_l_internal |  28518
 strtoul_l_internal |  28518
  strchrnul |  27763
__strchrnul |  27741
   _IO_putc |  27589
  __GI__IO_putc |  27589
   putc |  27589
... |

Above script output histogram of glibc function call, you will know
which function will be called frequently, a very useful script.

'probename' return probe name string, then insert table as key.
The magic of above script is there have no string copy and string hash
in probe context, because probename string is interned.


>> table operation between ktap with stap, the result is very
>> inspiring, ktap table operation overhead is quite lower than
>> stap, especially when use constant string key.
>
> Ok fair enough.
>
>>
>> But I agree with you partly, because in some cases we don't
>> want/need to interning all string, for example:
>> trace xxx:yyy {
>> var str = cast("char *", arg1)
>> print(str)
>> }
>>
>> In above case, arg1 is a long kernel string, and no table insert,
>> so definitely no need to interned, so we need to add
>> KTAP_TRAWSTR to represent these values.
>
> Please don't make it more complicated. If there's a good rationale
> for interning it' ok to use always.
>
> It would be better to find ways to simplify things.
>
Definitely, the reason I implement ktap based on lua is the simplicity
and efficiency of lua.

The whole bytecode design and value type is very simple, it could
build a complete safe sandbox for kernel scripting, and easy to
extend to fulfill our need(like multi-key table, aggregation)

Thanks.

Jovi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Andi Kleen
> See test/benchmark/cmp_table.sh, that script compare

Is that a realistic tracing scenario?

> table operation between ktap with stap, the result is very
> inspiring, ktap table operation overhead is quite lower than
> stap, especially when use constant string key.

Ok fair enough.

> 
> But I agree with you partly, because in some cases we don't
> want/need to interning all string, for example:
> trace xxx:yyy {
> var str = cast("char *", arg1)
> print(str)
> }
> 
> In above case, arg1 is a long kernel string, and no table insert,
> so definitely no need to interned, so we need to add
> KTAP_TRAWSTR to represent these values.

Please don't make it more complicated. If there's a good rationale
for interning it' ok to use always.

It would be better to find ways to simplify things.

-Andi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Jovi Zhangwei
On Sun, Mar 30, 2014 at 11:50 AM, Andi Kleen  wrote:
>
> It's not clear to me why a kernel script language needs
> all that complicated string interning code.
>
> What kind of scripts would create as many strings that
> it would be worth it?
>
> I think it would be better to replace it with a really
> simple non interning dynamic string type.
>
Basically I think string interning is very useful in ktap, and
the implementation is not complicated(kp_str_new function
is very simple).

String interning will make string comparison and table index
extremely fast, just pointer equality, no strcmp. table index
is heavily used in these dynamic tracing tool ktap/stap/dtrace.

String interning make there don't need to copy whole string
each time when use string key in associative array(table)
(stap/dtrace need copy it), and don't need to compute
string hash every time when use string table key.
(Things became more easily if need to support multi-key
table, ktap don't need to pre-allocate string in table)

See test/benchmark/cmp_table.sh, that script compare
table operation between ktap with stap, the result is very
inspiring, ktap table operation overhead is quite lower than
stap, especially when use constant string key.

But I agree with you partly, because in some cases we don't
want/need to interning all string, for example:
trace xxx:yyy {
var str = cast("char *", arg1)
print(str)
}

In above case, arg1 is a long kernel string, and no table insert,
so definitely no need to interned, so we need to add
KTAP_TRAWSTR to represent these values.

The simplicity design of ktap make it very flexible to support
different kind of value type. :)

Thanks.

Jovi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Jovi Zhangwei
On Sun, Mar 30, 2014 at 11:50 AM, Andi Kleen a...@firstfloor.org wrote:

 It's not clear to me why a kernel script language needs
 all that complicated string interning code.

 What kind of scripts would create as many strings that
 it would be worth it?

 I think it would be better to replace it with a really
 simple non interning dynamic string type.

Basically I think string interning is very useful in ktap, and
the implementation is not complicated(kp_str_new function
is very simple).

String interning will make string comparison and table index
extremely fast, just pointer equality, no strcmp. table index
is heavily used in these dynamic tracing tool ktap/stap/dtrace.

String interning make there don't need to copy whole string
each time when use string key in associative array(table)
(stap/dtrace need copy it), and don't need to compute
string hash every time when use string table key.
(Things became more easily if need to support multi-key
table, ktap don't need to pre-allocate string in table)

See test/benchmark/cmp_table.sh, that script compare
table operation between ktap with stap, the result is very
inspiring, ktap table operation overhead is quite lower than
stap, especially when use constant string key.

But I agree with you partly, because in some cases we don't
want/need to interning all string, for example:
trace xxx:yyy {
var str = cast(char *, arg1)
print(str)
}

In above case, arg1 is a long kernel string, and no table insert,
so definitely no need to interned, so we need to add
KTAP_TRAWSTR to represent these values.

The simplicity design of ktap make it very flexible to support
different kind of value type. :)

Thanks.

Jovi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Andi Kleen
 See test/benchmark/cmp_table.sh, that script compare

Is that a realistic tracing scenario?

 table operation between ktap with stap, the result is very
 inspiring, ktap table operation overhead is quite lower than
 stap, especially when use constant string key.

Ok fair enough.

 
 But I agree with you partly, because in some cases we don't
 want/need to interning all string, for example:
 trace xxx:yyy {
 var str = cast(char *, arg1)
 print(str)
 }
 
 In above case, arg1 is a long kernel string, and no table insert,
 so definitely no need to interned, so we need to add
 KTAP_TRAWSTR to represent these values.

Please don't make it more complicated. If there's a good rationale
for interning it' ok to use always.

It would be better to find ways to simplify things.

-Andi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-30 Thread Jovi Zhangwei
On Mon, Mar 31, 2014 at 1:19 AM, Andi Kleen a...@firstfloor.org wrote:
 See test/benchmark/cmp_table.sh, that script compare

 Is that a realistic tracing scenario?

Yes, it's quite common to use string key in dynamic tracing tool,
for example, See samples/userspace/glibc_func_hist.kp

var s = {}

trace probe:/lib64/libc.so.6:* {
s[probename] += 1
}

trace_end {
print_hist(s)
}


Result:

Tracing... Hit Ctrl-C to end.
^C
 value - Distribution - count
  _IO_sputbackc |@@108344
 __GI__IO_sputbackc |@@107768
 _IO_default_xsputn |  46639
__GI__IO_default_xsputn |  46624
   free |  36871
__libc_free |  36841
  cfree |  36841
 __free |  36811
__cfree |  36811
   __GI___libc_free |  36804
strtoull_l_internal |  28670
__GI_strtoul_l_internal |  28670
   __GI_strtoull_l_internal |  28518
 strtoul_l_internal |  28518
  strchrnul |  27763
__strchrnul |  27741
   _IO_putc |  27589
  __GI__IO_putc |  27589
   putc |  27589
... |

Above script output histogram of glibc function call, you will know
which function will be called frequently, a very useful script.

'probename' return probe name string, then insert table as key.
The magic of above script is there have no string copy and string hash
in probe context, because probename string is interned.


 table operation between ktap with stap, the result is very
 inspiring, ktap table operation overhead is quite lower than
 stap, especially when use constant string key.

 Ok fair enough.


 But I agree with you partly, because in some cases we don't
 want/need to interning all string, for example:
 trace xxx:yyy {
 var str = cast(char *, arg1)
 print(str)
 }

 In above case, arg1 is a long kernel string, and no table insert,
 so definitely no need to interned, so we need to add
 KTAP_TRAWSTR to represent these values.

 Please don't make it more complicated. If there's a good rationale
 for interning it' ok to use always.

 It would be better to find ways to simplify things.

Definitely, the reason I implement ktap based on lua is the simplicity
and efficiency of lua.

The whole bytecode design and value type is very simple, it could
build a complete safe sandbox for kernel scripting, and easy to
extend to fulfill our need(like multi-key table, aggregation)

Thanks.

Jovi
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-29 Thread Andi Kleen

It's not clear to me why a kernel script language needs
all that complicated string interning code.

What kind of scripts would create as many strings that
it would be worth it?

I think it would be better to replace it with a really
simple non interning dynamic string type.

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only.
--
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 v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-29 Thread Jovi Zhangwei
Exposed functions:

1). kp_str_new:
Return a interned string, failure if out of memory
or exceed max string number(default ).
It allocate memory from mempool, not kmalloc, because we
don't want dynamic allocate string in probe context.

2). kp_str_resize:
Initizate interned hash table g->strhash.

3). kp_str_fmt:
Return a format string, called from 'printf' built-in function.

4). kp_mempool_init/kp_mempool_destroy/kp_mempool_alloc
mempool is only service for string allocation currently.

All string in ktap is interned, it means ktap keeps
a single copy for any string. Whenever a new string appears, ktap
checks whether it already has a copy of that string and, if so,
reuses that copy. Internalization makes operations like string
comparison and table indexing very fast, but it slows down string creation.

Signed-off-by: Jovi Zhangwei 
---
 kernel/trace/ktap/kp_mempool.c |  94 +++
 kernel/trace/ktap/kp_mempool.h |   8 +
 kernel/trace/ktap/kp_str.c | 360 +
 kernel/trace/ktap/kp_str.h |  13 ++
 4 files changed, 475 insertions(+)
 create mode 100644 kernel/trace/ktap/kp_mempool.c
 create mode 100644 kernel/trace/ktap/kp_mempool.h
 create mode 100644 kernel/trace/ktap/kp_str.c
 create mode 100644 kernel/trace/ktap/kp_str.h

diff --git a/kernel/trace/ktap/kp_mempool.c b/kernel/trace/ktap/kp_mempool.c
new file mode 100644
index 000..37fb8e4
--- /dev/null
+++ b/kernel/trace/ktap/kp_mempool.c
@@ -0,0 +1,94 @@
+/*
+ * kp_mempool.c - ktap memory pool, service for string allocation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei .
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include 
+#include "kp_obj.h"
+#include "kp_str.h"
+
+#include 
+#include 
+#include "ktap.h"
+
+
+/*
+ * allocate memory from mempool, the allocated memory will be free
+ * util ktap exit.
+ * TODO: lock-free allocation
+ */
+void *kp_mempool_alloc(ktap_state_t *ks, int size)
+{
+   ktap_global_state_t *g = G(ks);
+   void *mempool = g->mempool;
+   void *freepos = g->mp_freepos;
+   void *addr;
+   unsigned long flags;
+
+   local_irq_save(flags);
+   arch_spin_lock(>mp_lock);
+
+   if (unlikely((unsigned long)((char *)freepos + size)) >
+(unsigned long)((char *)mempool + g->mp_size)) {
+   addr = NULL;
+   goto out;
+   }
+
+   addr = freepos;
+   g->mp_freepos = (char *)freepos + size;
+ out:
+
+   arch_spin_unlock(>mp_lock);
+   local_irq_restore(flags);
+   return addr;
+}
+
+/*
+ * destroy mempool.
+ */
+void kp_mempool_destroy(ktap_state_t *ks)
+{
+   ktap_global_state_t *g = G(ks);
+
+   if (!g->mempool)
+   return;
+
+   vfree(g->mempool);
+   g->mempool = NULL;
+   g->mp_freepos = NULL;
+   g->mp_size = 0;
+}
+
+/*
+ * pre-allocate size Kbytes memory pool.
+ */
+int kp_mempool_init(ktap_state_t *ks, int size)
+{
+   ktap_global_state_t *g = G(ks);
+
+   g->mempool = vmalloc(size * 1024);
+   if (!g->mempool)
+   return -ENOMEM;
+
+   g->mp_freepos = g->mempool;
+   g->mp_size = size * 1024;
+   g->mp_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+   return 0;
+}
+
diff --git a/kernel/trace/ktap/kp_mempool.h b/kernel/trace/ktap/kp_mempool.h
new file mode 100644
index 000..3eabf5e
--- /dev/null
+++ b/kernel/trace/ktap/kp_mempool.h
@@ -0,0 +1,8 @@
+#ifndef __KTAP_MEMPOOL_H__
+#define __KTAP_MEMPOOL_H__
+
+void *kp_mempool_alloc(ktap_state_t *ks, int size);
+void kp_mempool_destroy(ktap_state_t *ks);
+int kp_mempool_init(ktap_state_t *ks, int size);
+
+#endif /* __KTAP_MEMPOOL_H__ */
diff --git a/kernel/trace/ktap/kp_str.c b/kernel/trace/ktap/kp_str.c
new file mode 100644
index 000..9d2e741
--- /dev/null
+++ b/kernel/trace/ktap/kp_str.c
@@ -0,0 +1,360 @@
+/*
+ * kp_str.c - ktap string data struction manipulation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei .
+ *
+ * Adapted from luajit and lua interpreter.
+ * Copyright (C) 2005-2014 Mike Pall.
+ * Copyright (C) 1994-2008 Lua.org, PUC-Rio.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public 

[PATCH v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-29 Thread Jovi Zhangwei
Exposed functions:

1). kp_str_new:
Return a interned string, failure if out of memory
or exceed max string number(default ).
It allocate memory from mempool, not kmalloc, because we
don't want dynamic allocate string in probe context.

2). kp_str_resize:
Initizate interned hash table g-strhash.

3). kp_str_fmt:
Return a format string, called from 'printf' built-in function.

4). kp_mempool_init/kp_mempool_destroy/kp_mempool_alloc
mempool is only service for string allocation currently.

All string in ktap is interned, it means ktap keeps
a single copy for any string. Whenever a new string appears, ktap
checks whether it already has a copy of that string and, if so,
reuses that copy. Internalization makes operations like string
comparison and table indexing very fast, but it slows down string creation.

Signed-off-by: Jovi Zhangwei jovi.zhang...@gmail.com
---
 kernel/trace/ktap/kp_mempool.c |  94 +++
 kernel/trace/ktap/kp_mempool.h |   8 +
 kernel/trace/ktap/kp_str.c | 360 +
 kernel/trace/ktap/kp_str.h |  13 ++
 4 files changed, 475 insertions(+)
 create mode 100644 kernel/trace/ktap/kp_mempool.c
 create mode 100644 kernel/trace/ktap/kp_mempool.h
 create mode 100644 kernel/trace/ktap/kp_str.c
 create mode 100644 kernel/trace/ktap/kp_str.h

diff --git a/kernel/trace/ktap/kp_mempool.c b/kernel/trace/ktap/kp_mempool.c
new file mode 100644
index 000..37fb8e4
--- /dev/null
+++ b/kernel/trace/ktap/kp_mempool.c
@@ -0,0 +1,94 @@
+/*
+ * kp_mempool.c - ktap memory pool, service for string allocation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei jovi.zhang...@gmail.com.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include uapi/ktap/ktap_types.h
+#include kp_obj.h
+#include kp_str.h
+
+#include linux/ctype.h
+#include linux/module.h
+#include ktap.h
+
+
+/*
+ * allocate memory from mempool, the allocated memory will be free
+ * util ktap exit.
+ * TODO: lock-free allocation
+ */
+void *kp_mempool_alloc(ktap_state_t *ks, int size)
+{
+   ktap_global_state_t *g = G(ks);
+   void *mempool = g-mempool;
+   void *freepos = g-mp_freepos;
+   void *addr;
+   unsigned long flags;
+
+   local_irq_save(flags);
+   arch_spin_lock(g-mp_lock);
+
+   if (unlikely((unsigned long)((char *)freepos + size)) 
+(unsigned long)((char *)mempool + g-mp_size)) {
+   addr = NULL;
+   goto out;
+   }
+
+   addr = freepos;
+   g-mp_freepos = (char *)freepos + size;
+ out:
+
+   arch_spin_unlock(g-mp_lock);
+   local_irq_restore(flags);
+   return addr;
+}
+
+/*
+ * destroy mempool.
+ */
+void kp_mempool_destroy(ktap_state_t *ks)
+{
+   ktap_global_state_t *g = G(ks);
+
+   if (!g-mempool)
+   return;
+
+   vfree(g-mempool);
+   g-mempool = NULL;
+   g-mp_freepos = NULL;
+   g-mp_size = 0;
+}
+
+/*
+ * pre-allocate size Kbytes memory pool.
+ */
+int kp_mempool_init(ktap_state_t *ks, int size)
+{
+   ktap_global_state_t *g = G(ks);
+
+   g-mempool = vmalloc(size * 1024);
+   if (!g-mempool)
+   return -ENOMEM;
+
+   g-mp_freepos = g-mempool;
+   g-mp_size = size * 1024;
+   g-mp_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+   return 0;
+}
+
diff --git a/kernel/trace/ktap/kp_mempool.h b/kernel/trace/ktap/kp_mempool.h
new file mode 100644
index 000..3eabf5e
--- /dev/null
+++ b/kernel/trace/ktap/kp_mempool.h
@@ -0,0 +1,8 @@
+#ifndef __KTAP_MEMPOOL_H__
+#define __KTAP_MEMPOOL_H__
+
+void *kp_mempool_alloc(ktap_state_t *ks, int size);
+void kp_mempool_destroy(ktap_state_t *ks);
+int kp_mempool_init(ktap_state_t *ks, int size);
+
+#endif /* __KTAP_MEMPOOL_H__ */
diff --git a/kernel/trace/ktap/kp_str.c b/kernel/trace/ktap/kp_str.c
new file mode 100644
index 000..9d2e741
--- /dev/null
+++ b/kernel/trace/ktap/kp_str.c
@@ -0,0 +1,360 @@
+/*
+ * kp_str.c - ktap string data struction manipulation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei jovi.zhang...@gmail.com.
+ *
+ * Adapted from luajit and lua interpreter.
+ * Copyright (C) 2005-2014 Mike Pall.
+ * Copyright (C) 1994-2008 Lua.org, PUC-Rio.
+ *
+ * ktap is free software; you can 

Re: [PATCH v2 10/29] ktap: add string handling code(kernel/trace/ktap/kp_[str|mempool].[c|h])

2014-03-29 Thread Andi Kleen

It's not clear to me why a kernel script language needs
all that complicated string interning code.

What kind of scripts would create as many strings that
it would be worth it?

I think it would be better to replace it with a really
simple non interning dynamic string type.

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only.
--
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/