diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-07-18 14:47:10 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-07-18 21:31:32 -0400 |
commit | 7710b639953b791610f0022a7d52d9801c93b969 (patch) | |
tree | ad1e4822ad3b1b067ee2806142613caec0ed1e60 /kernel | |
parent | 8f768993394a8c0d3801033c11fd86ce8c88dcac (diff) |
tracing: Simplify the iteration logic in f_start/f_next
f_next() looks overcomplicated, and it is not strictly correct
even if this doesn't matter.
Say, FORMAT_FIELD_SEPERATOR should not return NULL (means EOF)
if trace_get_fields() returns an empty list, we should simply
advance to FORMAT_PRINTFMT as we do when we find the end of list.
1. Change f_next() to return "struct list_head *" rather than
"ftrace_event_field *", and change f_show() to do list_entry().
This simplifies the code a bit, only f_show() needs to know
about ftrace_event_field, and f_next() can play with ->prev
directly
2. Change f_next() to not play with ->prev / return inside the
switch() statement. It can simply set node = head/common_head,
the prev-or-advance-to-the-next-magic below does all work.
While at it. f_start() looks overcomplicated too. I don't think
*pos == 0 makes sense as a separate case, just change this code
to do "while" instead of "do/while".
The patch also moves f_start() down, close to f_stop(). This is
purely cosmetic, just to make the locking added by the next patch
more clear/visible.
Link: http://lkml.kernel.org/r/20130718184710.GA4783@redhat.com
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace_events.c | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 7a75cb22eab7..76defd91f9b4 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -826,59 +826,33 @@ enum { | |||
826 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) | 826 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) |
827 | { | 827 | { |
828 | struct ftrace_event_call *call = m->private; | 828 | struct ftrace_event_call *call = m->private; |
829 | struct ftrace_event_field *field; | ||
830 | struct list_head *common_head = &ftrace_common_fields; | 829 | struct list_head *common_head = &ftrace_common_fields; |
831 | struct list_head *head = trace_get_fields(call); | 830 | struct list_head *head = trace_get_fields(call); |
831 | struct list_head *node = v; | ||
832 | 832 | ||
833 | (*pos)++; | 833 | (*pos)++; |
834 | 834 | ||
835 | switch ((unsigned long)v) { | 835 | switch ((unsigned long)v) { |
836 | case FORMAT_HEADER: | 836 | case FORMAT_HEADER: |
837 | if (unlikely(list_empty(common_head))) | 837 | node = common_head; |
838 | return NULL; | 838 | break; |
839 | |||
840 | field = list_entry(common_head->prev, | ||
841 | struct ftrace_event_field, link); | ||
842 | return field; | ||
843 | 839 | ||
844 | case FORMAT_FIELD_SEPERATOR: | 840 | case FORMAT_FIELD_SEPERATOR: |
845 | if (unlikely(list_empty(head))) | 841 | node = head; |
846 | return NULL; | 842 | break; |
847 | |||
848 | field = list_entry(head->prev, struct ftrace_event_field, link); | ||
849 | return field; | ||
850 | 843 | ||
851 | case FORMAT_PRINTFMT: | 844 | case FORMAT_PRINTFMT: |
852 | /* all done */ | 845 | /* all done */ |
853 | return NULL; | 846 | return NULL; |
854 | } | 847 | } |
855 | 848 | ||
856 | field = v; | 849 | node = node->prev; |
857 | if (field->link.prev == common_head) | 850 | if (node == common_head) |
858 | return (void *)FORMAT_FIELD_SEPERATOR; | 851 | return (void *)FORMAT_FIELD_SEPERATOR; |
859 | else if (field->link.prev == head) | 852 | else if (node == head) |
860 | return (void *)FORMAT_PRINTFMT; | 853 | return (void *)FORMAT_PRINTFMT; |
861 | 854 | else | |
862 | field = list_entry(field->link.prev, struct ftrace_event_field, link); | 855 | return node; |
863 | |||
864 | return field; | ||
865 | } | ||
866 | |||
867 | static void *f_start(struct seq_file *m, loff_t *pos) | ||
868 | { | ||
869 | loff_t l = 0; | ||
870 | void *p; | ||
871 | |||
872 | /* Start by showing the header */ | ||
873 | if (!*pos) | ||
874 | return (void *)FORMAT_HEADER; | ||
875 | |||
876 | p = (void *)FORMAT_HEADER; | ||
877 | do { | ||
878 | p = f_next(m, p, &l); | ||
879 | } while (p && l < *pos); | ||
880 | |||
881 | return p; | ||
882 | } | 856 | } |
883 | 857 | ||
884 | static int f_show(struct seq_file *m, void *v) | 858 | static int f_show(struct seq_file *m, void *v) |
@@ -904,8 +878,7 @@ static int f_show(struct seq_file *m, void *v) | |||
904 | return 0; | 878 | return 0; |
905 | } | 879 | } |
906 | 880 | ||
907 | field = v; | 881 | field = list_entry(v, struct ftrace_event_field, link); |
908 | |||
909 | /* | 882 | /* |
910 | * Smartly shows the array type(except dynamic array). | 883 | * Smartly shows the array type(except dynamic array). |
911 | * Normal: | 884 | * Normal: |
@@ -932,6 +905,17 @@ static int f_show(struct seq_file *m, void *v) | |||
932 | return 0; | 905 | return 0; |
933 | } | 906 | } |
934 | 907 | ||
908 | static void *f_start(struct seq_file *m, loff_t *pos) | ||
909 | { | ||
910 | void *p = (void *)FORMAT_HEADER; | ||
911 | loff_t l = 0; | ||
912 | |||
913 | while (l < *pos && p) | ||
914 | p = f_next(m, p, &l); | ||
915 | |||
916 | return p; | ||
917 | } | ||
918 | |||
935 | static void f_stop(struct seq_file *m, void *p) | 919 | static void f_stop(struct seq_file *m, void *p) |
936 | { | 920 | { |
937 | } | 921 | } |