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 | |
| 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>
| -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 | } |
