[kgtp] r947 committed - Increase the speed of access to trace state variables.

  • From: kgtp@xxxxxxxxxxxxxx
  • To: kgtp@xxxxxxxxxxxxx
  • Date: Fri, 02 Mar 2012 13:51:29 +0000

Revision: 947
Author:   teawater
Date:     Fri Mar  2 05:50:56 2012
Log:      Increase the speed of access to trace state variables.

http://code.google.com/p/kgtp/source/detail?r=947

Modified:
 /trunk/UPDATE
 /trunk/gtp.c
 /trunk/gtp_for_review.patch

=======================================
--- /trunk/UPDATE       Wed Feb 29 04:28:19 2012
+++ /trunk/UPDATE       Fri Mar  2 05:50:56 2012
@@ -2,6 +2,8 @@

 * Fix bug with GDB RSP package sum check.

+* Increase the speed of access to trace state variables.
+
 *** 20120224

 * https://lkml.org/lkml/2012/2/26/127
=======================================
--- /trunk/gtp.c        Wed Feb 29 04:28:19 2012
+++ /trunk/gtp.c        Fri Mar  2 05:50:56 2012
@@ -249,6 +249,13 @@

 #define INT2CHAR(h)            ((h) > 9 ? (h) + 'a' - 10 : (h) + '0')

+#define OP_GETV_SPECIAL                0xfa
+#define OP_SETV_SPECIAL                0xfb
+#define OP_TRACEV_SPECIAL      0xfc
+#define OP_TRACE_PRINTK                0xfd
+#define OP_TRACE_QUICK_PRINTK  0xfe
+#define OP_TRACEV_PRINTK       0xff
+
 struct action_agent_exp {
        unsigned int    size;
        uint8_t         *buf;
@@ -2523,30 +2530,32 @@
        return ret;
 }

-uint64_t
-gtp_get_var(struct gtp_trace_s *gts, struct gtp_var *tve)
-{
-       switch (tve->num) {
+static uint64_t
+gtp_get_var_special(struct gtp_trace_s *gts, unsigned int num)
+{
+       uint64_t        ret;
+
+       switch (num) {
        case GTP_VAR_CURRENT_TASK_ID:
                if (gts->ri)
-                       return (uint64_t)(CORE_ADDR)gts->ri->task;
+                       ret = (uint64_t)(CORE_ADDR)gts->ri->task;
                else
-                       return (uint64_t)(CORE_ADDR)get_current();
+                       ret = (uint64_t)(CORE_ADDR)get_current();
                break;
        case GTP_VAR_CURRENT_TASK_PID_ID:
                if (gts->ri)
-                       return (uint64_t)(CORE_ADDR)gts->ri->task->pid;
+                       ret = (uint64_t)(CORE_ADDR)gts->ri->task->pid;
                else
-                       return (uint64_t)(CORE_ADDR)get_current()->pid;
+                       ret = (uint64_t)(CORE_ADDR)get_current()->pid;
                break;
        case GTP_VAR_CURRENT_THREAD_INFO_ID:
-               return (uint64_t)(CORE_ADDR)current_thread_info();
+               ret = (uint64_t)(CORE_ADDR)current_thread_info();
                break;
        case GTP_VAR_CLOCK_ID:
-               return (uint64_t)GTP_LOCAL_CLOCK;
+               ret = (uint64_t)GTP_LOCAL_CLOCK;
                break;
        case GTP_VAR_COOKED_CLOCK_ID:
-               return (uint64_t)(__get_cpu_var(local_clock_current)
+               ret = (uint64_t)(__get_cpu_var(local_clock_current)
                                        - __get_cpu_var(local_clock_offset));
                break;
 #ifdef CONFIG_X86
@@ -2554,50 +2563,134 @@
                {
                        unsigned long long a;
                        rdtscll(a);
-                       return (uint64_t)a;
+                       ret = (uint64_t)a;
                }
                break;
        case GTP_VAR_COOKED_RDTSC_ID:
-               return (uint64_t)(__get_cpu_var(rdtsc_current)
+               ret = (uint64_t)(__get_cpu_var(rdtsc_current)
                                        - __get_cpu_var(rdtsc_offset));
                break;
 #endif
        case GTP_VAR_CPU_ID:
-               return (uint64_t)(CORE_ADDR)smp_processor_id();
+               ret = (uint64_t)(CORE_ADDR)smp_processor_id();
                break;
        case GTP_VAR_CPU_NUMBER_ID:
-               return (uint64_t)gtp_cpu_number;
+               ret = (uint64_t)gtp_cpu_number;
                break;
        case GTP_VAR_PRINTK_TMP_ID:
-               return gts->printk_tmp;
+               ret = gts->printk_tmp;
                break;
        case GTP_VAR_DUMP_STACK_ID:
                printk(KERN_NULL "gtp %d %p:", (int)gts->tpe->num,
                       (void *)(CORE_ADDR)gts->tpe->addr);
                dump_stack();
-               return 0;
+               ret = 0;
                break;
        case GTP_VAR_XTIME_SEC_ID:
                if (gts->xtime.tv_sec == 0 && gts->xtime.tv_nsec == 0)
                        getnstimeofday(&gts->xtime);
-               return (uint64_t)gts->xtime.tv_sec;
+               ret = (uint64_t)gts->xtime.tv_sec;
                break;
        case GTP_VAR_XTIME_NSEC_ID:
                if (gts->xtime.tv_sec == 0 && gts->xtime.tv_nsec == 0)
                        getnstimeofday(&gts->xtime);
-               return (uint64_t)gts->xtime.tv_nsec;
+               ret = (uint64_t)gts->xtime.tv_nsec;
                break;
        case GTP_VAR_HARDIRQ_COUNT_ID:
-               return (uint64_t)hardirq_count();
+               ret = (uint64_t)hardirq_count();
                break;
        case GTP_VAR_SOFTIRQ_COUNT_ID:
-               return (uint64_t)softirq_count();
+               ret = (uint64_t)softirq_count();
                break;
        case GTP_VAR_IRQ_COUNT_ID:
-               return (uint64_t)irq_count();
+               ret = (uint64_t)irq_count();
                break;
+       default:
+               ret = 0;
+               break;
        }

+       return ret;
+}
+
+static void
+gtp_set_var_special(struct gtp_trace_s *gts, unsigned int num, ULONGEST val)
+{
+       switch (num) {
+       case GTP_VAR_PRINTK_TMP_ID:
+               gts->printk_tmp = val;
+               break;
+       case GTP_VAR_PRINTK_LEVEL_ID:
+               gts->printk_level = (unsigned int)val;
+               break;
+       case GTP_VAR_PRINTK_FORMAT_ID:
+               gts->printk_format = (unsigned int)val;
+               break;
+       case GTP_VAR_PC_PE_EN_ID:
+               gtp_pc_pe_en((int)val);
+               break;
+       }
+}
+
+static int
+gtp_collect_var_special(struct gtp_trace_s *gts, unsigned int num)
+{
+       struct gtp_frame_var            *fvar;
+       char                            *tmp;
+#ifdef GTP_FTRACE_RING_BUFFER
+       struct ring_buffer_event        *rbe;
+#endif
+
+       if (gts->next == NULL) {
+               if (gtp_action_head(gts))
+                       return -1;
+       }
+
+       if (GTP_VAR_AUTO_TRACEV(num))
+               return 0;
+
+#ifdef GTP_FTRACE_RING_BUFFER
+       GTP_FRAME_RINGBUFFER_ALLOC(GTP_FRAME_VAR_SIZE);
+#endif
+#if defined(GTP_FRAME_SIMPLE) || defined(GTP_RB)
+#ifdef GTP_RB
+       tmp = gtp_rb_alloc(gts->next, GTP_FRAME_VAR_SIZE, gts->id);
+#endif
+#ifdef GTP_FRAME_SIMPLE
+       tmp = gtp_frame_alloc(GTP_FRAME_VAR_SIZE);
+#endif
+       if (!tmp) {
+               gts->tpe->reason = gtp_stop_frame_full;
+               return -1;
+       }
+#ifdef GTP_FRAME_SIMPLE
+       *gts->next = tmp;
+#endif
+#endif
+
+       FID(tmp) = FID_VAR;
+       tmp += FID_SIZE;
+
+#ifdef GTP_FRAME_SIMPLE
+       gts->next = (char **)tmp;
+       *gts->next = NULL;
+       tmp += sizeof(char *);
+#endif
+
+       fvar = (struct gtp_frame_var *) tmp;
+       fvar->num = num;
+       fvar->val = gtp_get_var_special(gts, num);
+
+#ifdef GTP_FTRACE_RING_BUFFER
+       ring_buffer_unlock_commit(gtp_frame, rbe);
+#endif
+
+       return 0;
+}
+
+uint64_t
+gtp_get_var(struct gtp_trace_s *gts, struct gtp_var *tve)
+{
 #ifdef GTP_PERF_EVENTS
        if (tve->ptid == pe_tv_val || tve->ptid == pe_tv_enabled
            || tve->ptid == pe_tv_running) {
@@ -2702,42 +2795,20 @@
 #define gtp_action_x_setv_pe
 #endif

-#define gtp_action_x_setv                                              \
-       do {                                                            \
-               switch (arg) {                                          \
-               case GTP_VAR_PRINTK_TMP_ID:                             \
-                       gts->printk_tmp = top;                               \
-                       break;                                          \
-               case GTP_VAR_PRINTK_LEVEL_ID:                           \
-                       gts->printk_level = (unsigned int)top;               \
-                       break;                                          \
-               case GTP_VAR_PRINTK_FORMAT_ID:                          \
-                       gts->printk_format = (unsigned int)top;              \
-                       break;                                          \
-               case GTP_VAR_PC_PE_EN_ID:                               \
-                       gtp_pc_pe_en((int)top);                         \
-                       break;                                          \
-               default: {                                              \
-                               struct gtp_var  *tve;                   \
-                                                                       \
-                               tve = gtp_gtp_var_array_find(arg);      \
-                               if (!tve)                               \
-                                       goto code_error_out;            \
-                               gtp_action_x_setv_pe;                   \
-                               /* Not check the other special          \
-                                  trace state variables.               \
-                                  Because set in tve->val doesn't   \
-                                  affect anything.  */                 \
-                               tve->val = (uint64_t)top;            \
-                       }                                               \
-                       break;                                          \
-               }                                                       \
+#define gtp_action_x_setv                              \
+       do {                                            \
+               struct gtp_var  *tve;                   \
+                                                       \
+               tve = gtp_gtp_var_array_find(arg);      \
+               if (!tve)                               \
+                       goto code_error_out;            \
+               gtp_action_x_setv_pe;                   \
+               tve->val = (uint64_t)top;            \
        } while (0)

 #define gtp_action_x_tracev                                            \
        do {                                                            \
-               if (!gts->tpe->have_printk                                \
-                   || !GTP_VAR_AUTO_TRACEV(arg)) {                     \
+               if (!gts->tpe->have_printk) {                             \
                        struct gtp_var  *tve;                           \
                                                                        \
                        tve = gtp_gtp_var_array_find(arg);              \
@@ -2907,7 +2978,7 @@
                                top = stack[--sp];
                                break;
                        /* trace_printk */
-                       case 0xfd:
+                       case OP_TRACE_PRINTK:
                                if (gtp_action_printk(gts,
                                                      (ULONGEST)stack[--sp],
                                                      (size_t) top))
@@ -2925,7 +2996,7 @@
                                pc++;
                                break;
                        /* trace_quick_printk */
-                       case 0xfe:
+                       case OP_TRACE_QUICK_PRINTK:
                                if (gtp_action_printk(gts, (ULONGEST) top,
                                                      (size_t) ebuf[pc++]))
                                        goto out;
@@ -3087,20 +3158,39 @@
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_getv;
                                break;
+                       /* getv_sepecial */
+                       case OP_GETV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               stack[sp++] = top;
+                               top = gtp_get_var_special(gts, arg);
+                               break;
                        /* setv */
                        case 0x2d:
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_setv;
                                break;
+                       /* setv_sepecial */
+                       case OP_SETV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               gtp_set_var_special(gts, arg, top);
+                               break;
                        /* tracev */
                        case 0x2e:
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_tracev;
                                break;
+                       /* tracev_special */
+                       case OP_TRACEV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               gtp_collect_var_special(gts, arg);
+                               break;
                        /* tracev_printk */
-                       case 0xff:
+                       case OP_TRACEV_PRINTK:
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_tracev_printk;
@@ -3432,18 +3522,37 @@
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_getv;
                                break;
+                       /* getv_sepecial */
+                       case OP_GETV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               stack[sp++] = top;
+                               top = gtp_get_var_special(gts, arg);
+                               break;
                        /* setv */
                        case 0x2d:
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_setv;
                                break;
+                       /* setv_sepecial */
+                       case OP_SETV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               gtp_set_var_special(gts, arg, top);
+                               break;
                        /* tracev */
                        case 0x2e:
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];
                                gtp_action_x_tracev;
                                break;
+                       /* tracev_special */
+                       case OP_TRACEV_SPECIAL:
+                               arg = ebuf[pc++];
+                               arg = (arg << 8) + ebuf[pc++];
+                               gtp_collect_var_special(gts, arg);
+                               break;
                        /* printf */
                        case 0x31: {
                                        arg = ebuf[pc++];
@@ -4701,25 +4810,26 @@
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];

-                               if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
-                                       tpe->no_self_trace = 1;
-                                       ret = 1;
-                                       goto release_out;
-                               }
-
                                if (!GTP_VAR_IS_SPECIAL(arg)) {
                                        if (gtp_x_var_add(&vlist, arg, 1)) {
                                                ret = -ENOMEM;
                                                goto release_out;
                                        }
-                               }
-
-                               if (arg == GTP_VAR_COOKED_CLOCK_ID)
-                                       gtp_access_cooked_clock = 1;
+                               } else {
+                                       if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
+                                               tpe->no_self_trace = 1;
+                                               ret = 1;
+                                               goto release_out;
+                                       }
+
+                                       if (arg == GTP_VAR_COOKED_CLOCK_ID)
+                                               gtp_access_cooked_clock = 1;
 #ifdef CONFIG_X86
-                               else if (arg == GTP_VAR_COOKED_RDTSC_ID)
-                                       gtp_access_cooked_rdtsc = 1;
+                                       else if (arg == GTP_VAR_COOKED_RDTSC_ID)
+                                               gtp_access_cooked_rdtsc = 1;
 #endif
+                                       ebuf[pc - 3] = OP_GETV_SPECIAL;
+                               }
                        }
                        if (ae->type == 'X') {
                                sp++;
@@ -4737,26 +4847,28 @@
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];

-                               if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
-                                       tpe->no_self_trace = 1;
-                                       ret = 1;
-                                       goto release_out;
-                               } else if (arg == GTP_VAR_KRET_ID) {
-                                       /* XXX: still not set it
-                                          value to maxactive.  */
-                                       tpe->is_kretprobe = 1;
-                                       ret = 1;
-                                       goto release_out;
-                               }
-
-                               if (arg == GTP_VAR_PRINTK_LEVEL_ID)
-                                       tpe->have_printk = 1;
-
                                if (!GTP_VAR_IS_SPECIAL(arg)) {
                                        if (gtp_x_var_add(&vlist, arg, 2)) {
                                                ret = -ENOMEM;
                                                goto release_out;
                                        }
+                               } else {
+                                       if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
+                                               tpe->no_self_trace = 1;
+                                               ret = 1;
+                                               goto release_out;
+                                       } else if (arg == GTP_VAR_KRET_ID) {
+                                               /* XXX: still not set it
+                                               value to maxactive.  */
+                                               tpe->is_kretprobe = 1;
+                                               ret = 1;
+                                               goto release_out;
+                                       }
+
+                                       if (arg == GTP_VAR_PRINTK_LEVEL_ID)
+                                               tpe->have_printk = 1;
+
+                                       ebuf[pc - 3] = OP_SETV_SPECIAL;
                                }
                        }
                        break;
@@ -4773,25 +4885,25 @@
                                arg = ebuf[pc++];
                                arg = (arg << 8) + ebuf[pc++];

-                               if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
-                                       tpe->no_self_trace = 1;
-                                       ret = 1;
-                                       goto release_out;
-                               }
-
                                if (!GTP_VAR_IS_SPECIAL(arg)) {
                                        if (gtp_x_var_add(&vlist, arg, 4)) {
                                                ret = -ENOMEM;
                                                goto release_out;
                                        }
-                               }
-
-                               if (arg == GTP_VAR_COOKED_CLOCK_ID)
-                                       gtp_access_cooked_clock = 1;
+                               } else {
+                                       if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
+                                               tpe->no_self_trace = 1;
+                                               ret = 1;
+                                               goto release_out;
+                                       }
+                                       if (arg == GTP_VAR_COOKED_CLOCK_ID)
+                                               gtp_access_cooked_clock = 1;
 #ifdef CONFIG_X86
-                               else if (arg == GTP_VAR_COOKED_RDTSC_ID)
-                                       gtp_access_cooked_rdtsc = 1;
+                                       else if (arg == GTP_VAR_COOKED_RDTSC_ID)
+                                               gtp_access_cooked_rdtsc = 1;
 #endif
+                                       ebuf[pc - 3] = OP_TRACEV_SPECIAL;
+                               }
                        }
                        break;

@@ -4911,15 +5023,15 @@
                switch (ebuf[last_trace_pc]) {
                /* trace */
                case 0x0c:
-                       ebuf[last_trace_pc] = 0xfd;
+                       ebuf[last_trace_pc] = OP_TRACE_PRINTK;
                        break;
                /* trace_quick */
                case 0x0d:
-                       ebuf[last_trace_pc] = 0xfe;
+                       ebuf[last_trace_pc] = OP_TRACE_QUICK_PRINTK;
                        break;
                /* tracev */
                case 0x2e:
-                       ebuf[last_trace_pc] = 0xff;
+                       ebuf[last_trace_pc] = OP_TRACEV_PRINTK;
                        break;
                }
        }
=======================================
--- /trunk/gtp_for_review.patch Wed Feb 29 04:28:19 2012
+++ /trunk/gtp_for_review.patch Fri Mar  2 05:50:56 2012
@@ -8,12 +8,12 @@
  kernel/events/core.c             |   14
  lib/Kconfig.debug                |   10
  lib/Makefile                     |    4
- lib/gtp.c | 8608 +++++++++++++++++++++++++++++++++++++++ + lib/gtp.c | 8665 +++++++++++++++++++++++++++++++++++++++
  lib/gtp_rb.c                     |  495 ++
  scripts/gtp/add-ons/pe.py        |  729 +++
  scripts/gtp/getgtprsp.pl         |  137
  scripts/gtp/getmod.py            |  132
- 14 files changed, 11948 insertions(+), 2 deletions(-)
+ 14 files changed, 12005 insertions(+), 2 deletions(-)

 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
@@ -1952,7 +1952,7 @@
 +gtp.o: gtp_rb.c
 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,8608 @@
+@@ -0,0 +1,8665 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -2056,6 +2056,13 @@
 +
 +#define INT2CHAR(h)           ((h) > 9 ? (h) + 'a' - 10 : (h) + '0')
 +
++#define OP_GETV_SPECIAL               0xfa
++#define OP_SETV_SPECIAL               0xfb
++#define OP_TRACEV_SPECIAL     0xfc
++#define OP_TRACE_PRINTK               0xfd
++#define OP_TRACE_QUICK_PRINTK 0xfe
++#define OP_TRACEV_PRINTK      0xff
++
 +struct action_agent_exp {
 +      unsigned int    size;
 +      uint8_t         *buf;
@@ -4001,30 +4008,32 @@
 +      return ret;
 +}
 +
-+uint64_t
-+gtp_get_var(struct gtp_trace_s *gts, struct gtp_var *tve)
++static uint64_t
++gtp_get_var_special(struct gtp_trace_s *gts, unsigned int num)
 +{
-+      switch (tve->num) {
++      uint64_t        ret;
++
++      switch (num) {
 +      case GTP_VAR_CURRENT_TASK_ID:
 +              if (gts->ri)
-+                      return (uint64_t)(CORE_ADDR)gts->ri->task;
++                      ret = (uint64_t)(CORE_ADDR)gts->ri->task;
 +              else
-+                      return (uint64_t)(CORE_ADDR)get_current();
++                      ret = (uint64_t)(CORE_ADDR)get_current();
 +              break;
 +      case GTP_VAR_CURRENT_TASK_PID_ID:
 +              if (gts->ri)
-+                      return (uint64_t)(CORE_ADDR)gts->ri->task->pid;
++                      ret = (uint64_t)(CORE_ADDR)gts->ri->task->pid;
 +              else
-+                      return (uint64_t)(CORE_ADDR)get_current()->pid;
++                      ret = (uint64_t)(CORE_ADDR)get_current()->pid;
 +              break;
 +      case GTP_VAR_CURRENT_THREAD_INFO_ID:
-+              return (uint64_t)(CORE_ADDR)current_thread_info();
++              ret = (uint64_t)(CORE_ADDR)current_thread_info();
 +              break;
 +      case GTP_VAR_CLOCK_ID:
-+              return (uint64_t)GTP_LOCAL_CLOCK;
++              ret = (uint64_t)GTP_LOCAL_CLOCK;
 +              break;
 +      case GTP_VAR_COOKED_CLOCK_ID:
-+              return (uint64_t)(__get_cpu_var(local_clock_current)
++              ret = (uint64_t)(__get_cpu_var(local_clock_current)
 +                                      - __get_cpu_var(local_clock_offset));
 +              break;
 +#ifdef CONFIG_X86
@@ -4032,78 +4041,77 @@
 +              {
 +                      unsigned long long a;
 +                      rdtscll(a);
-+                      return (uint64_t)a;
++                      ret = (uint64_t)a;
 +              }
 +              break;
 +      case GTP_VAR_COOKED_RDTSC_ID:
-+              return (uint64_t)(__get_cpu_var(rdtsc_current)
++              ret = (uint64_t)(__get_cpu_var(rdtsc_current)
 +                                      - __get_cpu_var(rdtsc_offset));
 +              break;
 +#endif
 +      case GTP_VAR_CPU_ID:
-+              return (uint64_t)(CORE_ADDR)smp_processor_id();
++              ret = (uint64_t)(CORE_ADDR)smp_processor_id();
 +              break;
 +      case GTP_VAR_CPU_NUMBER_ID:
-+              return (uint64_t)gtp_cpu_number;
++              ret = (uint64_t)gtp_cpu_number;
 +              break;
 +      case GTP_VAR_PRINTK_TMP_ID:
-+              return gts->printk_tmp;
++              ret = gts->printk_tmp;
 +              break;
 +      case GTP_VAR_DUMP_STACK_ID:
 +              printk(KERN_NULL "gtp %d %p:", (int)gts->tpe->num,
 +                     (void *)(CORE_ADDR)gts->tpe->addr);
 +              dump_stack();
-+              return 0;
++              ret = 0;
 +              break;
 +      case GTP_VAR_XTIME_SEC_ID:
 +              if (gts->xtime.tv_sec == 0 && gts->xtime.tv_nsec == 0)
 +                      getnstimeofday(&gts->xtime);
-+              return (uint64_t)gts->xtime.tv_sec;
++              ret = (uint64_t)gts->xtime.tv_sec;
 +              break;
 +      case GTP_VAR_XTIME_NSEC_ID:
 +              if (gts->xtime.tv_sec == 0 && gts->xtime.tv_nsec == 0)
 +                      getnstimeofday(&gts->xtime);
-+              return (uint64_t)gts->xtime.tv_nsec;
++              ret = (uint64_t)gts->xtime.tv_nsec;
 +              break;
 +      case GTP_VAR_HARDIRQ_COUNT_ID:
-+              return (uint64_t)hardirq_count();
++              ret = (uint64_t)hardirq_count();
 +              break;
 +      case GTP_VAR_SOFTIRQ_COUNT_ID:
-+              return (uint64_t)softirq_count();
++              ret = (uint64_t)softirq_count();
 +              break;
 +      case GTP_VAR_IRQ_COUNT_ID:
-+              return (uint64_t)irq_count();
++              ret = (uint64_t)irq_count();
 +              break;
++      default:
++              ret = 0;
++              break;
 +      }
 +
-+#ifdef CONFIG_PERF_EVENTS
-+      if (tve->ptid == pe_tv_val || tve->ptid == pe_tv_enabled
-+          || tve->ptid == pe_tv_running) {
-+              tve->pts->val = perf_event_read_value(tve->pts->event,
-+                                                    &(tve->pts->enabled),
-+                                                    &(tve->pts->running));
-+              switch (tve->ptid) {
-+              case pe_tv_val:
-+                      return (uint64_t)(tve->pts->val);
-+                      break;
-+              case pe_tv_enabled:
-+                      return (uint64_t)(tve->pts->enabled);
-+                      break;
-+              case pe_tv_running:
-+                      return (uint64_t)(tve->pts->running);
-+                      break;
-+              default:
-+                      return 0;
-+                      break;
-+              }
-+      }
-+#endif
++      return ret;
++}
 +
-+      return tve->val;
++static void
++gtp_set_var_special(struct gtp_trace_s *gts, unsigned int num, ULONGEST val)
++{
++      switch (num) {
++      case GTP_VAR_PRINTK_TMP_ID:
++              gts->printk_tmp = val;
++              break;
++      case GTP_VAR_PRINTK_LEVEL_ID:
++              gts->printk_level = (unsigned int)val;
++              break;
++      case GTP_VAR_PRINTK_FORMAT_ID:
++              gts->printk_format = (unsigned int)val;
++              break;
++      case GTP_VAR_PC_PE_EN_ID:
++              gtp_pc_pe_en((int)val);
++              break;
++      }
 +}
 +
 +static int
-+gtp_collect_var(struct gtp_trace_s *gts, struct gtp_var *tve)
++gtp_collect_var_special(struct gtp_trace_s *gts, unsigned int num)
 +{
 +      struct gtp_frame_var            *fvar;
 +      char                            *tmp;
@@ -4115,6 +4123,9 @@
 +              if (gtp_action_head(gts))
 +                      return -1;
 +      }
++
++      if (GTP_VAR_AUTO_TRACEV(num))
++              return 0;
 +
 +#ifdef GTP_FTRACE_RING_BUFFER
 +      GTP_FRAME_RINGBUFFER_ALLOC(GTP_FRAME_VAR_SIZE);
@@ -4145,8 +4156,8 @@
 +#endif
 +
 +      fvar = (struct gtp_frame_var *) tmp;
-+      fvar->num = tve->num;
-+      fvar->val = gtp_get_var(gts, tve);
++      fvar->num = num;
++      fvar->val = gtp_get_var_special(gts, num);
 +
 +#ifdef GTP_FTRACE_RING_BUFFER
 +      ring_buffer_unlock_commit(gtp_frame, rbe);
@@ -4154,6 +4165,35 @@
 +
 +      return 0;
 +}
++
++uint64_t
++gtp_get_var(struct gtp_trace_s *gts, struct gtp_var *tve)
++{
++#ifdef GTP_PERF_EVENTS
++      if (tve->ptid == pe_tv_val || tve->ptid == pe_tv_enabled
++          || tve->ptid == pe_tv_running) {
++              tve->pts->val = perf_event_read_value(tve->pts->event,
++                                                    &(tve->pts->enabled),
++                                                    &(tve->pts->running));
++              switch (tve->ptid) {
++              case pe_tv_val:
++                      return (uint64_t)(tve->pts->val);
++                      break;
++              case pe_tv_enabled:
++                      return (uint64_t)(tve->pts->enabled);
++                      break;
++              case pe_tv_running:
++                      return (uint64_t)(tve->pts->running);
++                      break;
++              default:
++                      return 0;
++                      break;
++              }
++      }
++#endif
++
++      return tve->val;
++}
 +
 +#define gtp_action_x_getv                                             \
 +      do {                                                            \
@@ -4180,42 +4220,20 @@
 +#define gtp_action_x_setv_pe
 +#endif
 +
-+#define gtp_action_x_setv                                             \
-+      do {                                                            \
-+              switch (arg) {                                          \
-+              case GTP_VAR_PRINTK_TMP_ID:                             \
-+                      gts->printk_tmp = top;                               \
-+                      break;                                          \
-+              case GTP_VAR_PRINTK_LEVEL_ID:                           \
-+                      gts->printk_level = (unsigned int)top;               \
-+                      break;                                          \
-+              case GTP_VAR_PRINTK_FORMAT_ID:                          \
-+                      gts->printk_format = (unsigned int)top;              \
-+                      break;                                          \
-+              case GTP_VAR_PC_PE_EN_ID:                               \
-+                      gtp_pc_pe_en((int)top);                         \
-+                      break;                                          \
-+              default: {                                              \
-+                              struct gtp_var  *tve;                   \
-+                                                                      \
-+                              tve = gtp_gtp_var_array_find(arg);      \
-+                              if (!tve)                               \
-+                                      goto code_error_out;            \
-+                              gtp_action_x_setv_pe;                   \
-+                              /* Not check the other special          \
-+                                 trace state variables.               \
-+                                 Because set in tve->val doesn't   \
-+                                 affect anything.  */                 \
-+                              tve->val = (uint64_t)top;            \
-+                      }                                               \
-+                      break;                                          \
-+              }                                                       \
++#define gtp_action_x_setv                             \
++      do {                                            \
++              struct gtp_var  *tve;                   \
++                                                      \
++              tve = gtp_gtp_var_array_find(arg);      \
++              if (!tve)                               \
++                      goto code_error_out;            \
++              gtp_action_x_setv_pe;                   \
++              tve->val = (uint64_t)top;            \
 +      } while (0)
 +
 +#define gtp_action_x_tracev                                           \
 +      do {                                                            \
-+              if (!gts->tpe->have_printk                                \
-+                  || !GTP_VAR_AUTO_TRACEV(arg)) {                     \
++              if (!gts->tpe->have_printk) {                             \
 +                      struct gtp_var  *tve;                           \
 +                                                                      \
 +                      tve = gtp_gtp_var_array_find(arg);              \
@@ -4385,7 +4403,7 @@
 +                              top = stack[--sp];
 +                              break;
 +                      /* trace_printk */
-+                      case 0xfd:
++                      case OP_TRACE_PRINTK:
 +                              if (gtp_action_printk(gts,
 +                                                    (ULONGEST)stack[--sp],
 +                                                    (size_t) top))
@@ -4403,7 +4421,7 @@
 +                              pc++;
 +                              break;
 +                      /* trace_quick_printk */
-+                      case 0xfe:
++                      case OP_TRACE_QUICK_PRINTK:
 +                              if (gtp_action_printk(gts, (ULONGEST) top,
 +                                                    (size_t) ebuf[pc++]))
 +                                      goto out;
@@ -4565,20 +4583,39 @@
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_getv;
 +                              break;
++                      /* getv_sepecial */
++                      case OP_GETV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              stack[sp++] = top;
++                              top = gtp_get_var_special(gts, arg);
++                              break;
 +                      /* setv */
 +                      case 0x2d:
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_setv;
 +                              break;
++                      /* setv_sepecial */
++                      case OP_SETV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              gtp_set_var_special(gts, arg, top);
++                              break;
 +                      /* tracev */
 +                      case 0x2e:
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_tracev;
 +                              break;
++                      /* tracev_special */
++                      case OP_TRACEV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              gtp_collect_var_special(gts, arg);
++                              break;
 +                      /* tracev_printk */
-+                      case 0xff:
++                      case OP_TRACEV_PRINTK:
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_tracev_printk;
@@ -4910,18 +4947,37 @@
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_getv;
 +                              break;
++                      /* getv_sepecial */
++                      case OP_GETV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              stack[sp++] = top;
++                              top = gtp_get_var_special(gts, arg);
++                              break;
 +                      /* setv */
 +                      case 0x2d:
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_setv;
 +                              break;
++                      /* setv_sepecial */
++                      case OP_SETV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              gtp_set_var_special(gts, arg, top);
++                              break;
 +                      /* tracev */
 +                      case 0x2e:
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +                              gtp_action_x_tracev;
 +                              break;
++                      /* tracev_special */
++                      case OP_TRACEV_SPECIAL:
++                              arg = ebuf[pc++];
++                              arg = (arg << 8) + ebuf[pc++];
++                              gtp_collect_var_special(gts, arg);
++                              break;
 +                      /* printf */
 +                      case 0x31: {
 +                                      arg = ebuf[pc++];
@@ -6156,25 +6212,26 @@
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +
-+                              if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
-+                                      tpe->no_self_trace = 1;
-+                                      ret = 1;
-+                                      goto release_out;
-+                              }
-+
 +                              if (!GTP_VAR_IS_SPECIAL(arg)) {
 +                                      if (gtp_x_var_add(&vlist, arg, 1)) {
 +                                              ret = -ENOMEM;
 +                                              goto release_out;
 +                                      }
-+                              }
++                              } else {
++                                      if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
++                                              tpe->no_self_trace = 1;
++                                              ret = 1;
++                                              goto release_out;
++                                      }
 +
-+                              if (arg == GTP_VAR_COOKED_CLOCK_ID)
-+                                      gtp_access_cooked_clock = 1;
++                                      if (arg == GTP_VAR_COOKED_CLOCK_ID)
++                                              gtp_access_cooked_clock = 1;
 +#ifdef CONFIG_X86
-+                              else if (arg == GTP_VAR_COOKED_RDTSC_ID)
-+                                      gtp_access_cooked_rdtsc = 1;
++                                      else if (arg == GTP_VAR_COOKED_RDTSC_ID)
++                                              gtp_access_cooked_rdtsc = 1;
 +#endif
++                                      ebuf[pc - 3] = OP_GETV_SPECIAL;
++                              }
 +                      }
 +                      if (ae->type == 'X') {
 +                              sp++;
@@ -6229,25 +6286,25 @@
 +                              arg = ebuf[pc++];
 +                              arg = (arg << 8) + ebuf[pc++];
 +
-+                              if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
-+                                      tpe->no_self_trace = 1;
-+                                      ret = 1;
-+                                      goto release_out;
-+                              }
-+
 +                              if (!GTP_VAR_IS_SPECIAL(arg)) {
 +                                      if (gtp_x_var_add(&vlist, arg, 4)) {
 +                                              ret = -ENOMEM;
 +                                              goto release_out;
 +                                      }
-+                              }
-+
-+                              if (arg == GTP_VAR_COOKED_CLOCK_ID)
-+                                      gtp_access_cooked_clock = 1;
++                              } else {
++                                      if (arg == GTP_VAR_NO_SELF_TRACE_ID) {
++                                              tpe->no_self_trace = 1;
++                                              ret = 1;
++                                              goto release_out;
++                                      }
++                                      if (arg == GTP_VAR_COOKED_CLOCK_ID)
++                                              gtp_access_cooked_clock = 1;
 +#ifdef CONFIG_X86
-+                              else if (arg == GTP_VAR_COOKED_RDTSC_ID)
-+                                      gtp_access_cooked_rdtsc = 1;
++                                      else if (arg == GTP_VAR_COOKED_RDTSC_ID)
++                                              gtp_access_cooked_rdtsc = 1;
 +#endif
++                                      ebuf[pc - 3] = OP_TRACEV_SPECIAL;
++                              }
 +                      }
 +                      break;
 +
@@ -6367,15 +6424,15 @@
 +              switch (ebuf[last_trace_pc]) {
 +              /* trace */
 +              case 0x0c:
-+                      ebuf[last_trace_pc] = 0xfd;
++                      ebuf[last_trace_pc] = OP_TRACE_PRINTK;
 +                      break;
 +              /* trace_quick */
 +              case 0x0d:
-+                      ebuf[last_trace_pc] = 0xfe;
++                      ebuf[last_trace_pc] = OP_TRACE_QUICK_PRINTK;
 +                      break;
 +              /* tracev */
 +              case 0x2e:
-+                      ebuf[last_trace_pc] = 0xff;
++                      ebuf[last_trace_pc] = OP_TRACEV_PRINTK;
 +                      break;
 +              }
 +      }

Other related posts:

  • » [kgtp] r947 committed - Increase the speed of access to trace state variables. - kgtp