aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace_events.c95
1 files changed, 88 insertions, 7 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index b92081588088..be4d3a437c17 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -770,7 +770,11 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
770} 770}
771 771
772static int 772static int
773event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) 773event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
774 const struct file_operations *id,
775 const struct file_operations *enable,
776 const struct file_operations *filter,
777 const struct file_operations *format)
774{ 778{
775 struct dentry *entry; 779 struct dentry *entry;
776 int ret; 780 int ret;
@@ -800,11 +804,11 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
800 804
801 if (call->regfunc) 805 if (call->regfunc)
802 entry = trace_create_file("enable", 0644, call->dir, call, 806 entry = trace_create_file("enable", 0644, call->dir, call,
803 &ftrace_enable_fops); 807 enable);
804 808
805 if (call->id) 809 if (call->id)
806 entry = trace_create_file("id", 0444, call->dir, call, 810 entry = trace_create_file("id", 0444, call->dir, call,
807 &ftrace_event_id_fops); 811 id);
808 812
809 if (call->define_fields) { 813 if (call->define_fields) {
810 ret = call->define_fields(); 814 ret = call->define_fields();
@@ -814,7 +818,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
814 return ret; 818 return ret;
815 } 819 }
816 entry = trace_create_file("filter", 0644, call->dir, call, 820 entry = trace_create_file("filter", 0644, call->dir, call,
817 &ftrace_event_filter_fops); 821 filter);
818 } 822 }
819 823
820 /* A trace may not want to export its format */ 824 /* A trace may not want to export its format */
@@ -822,7 +826,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
822 return 0; 826 return 0;
823 827
824 entry = trace_create_file("format", 0444, call->dir, call, 828 entry = trace_create_file("format", 0444, call->dir, call,
825 &ftrace_event_format_fops); 829 format);
826 830
827 return 0; 831 return 0;
828} 832}
@@ -833,8 +837,60 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
833 event++) 837 event++)
834 838
835#ifdef CONFIG_MODULES 839#ifdef CONFIG_MODULES
840
841static LIST_HEAD(ftrace_module_file_list);
842
843/*
844 * Modules must own their file_operations to keep up with
845 * reference counting.
846 */
847struct ftrace_module_file_ops {
848 struct list_head list;
849 struct module *mod;
850 struct file_operations id;
851 struct file_operations enable;
852 struct file_operations format;
853 struct file_operations filter;
854};
855
856static struct ftrace_module_file_ops *
857trace_create_file_ops(struct module *mod)
858{
859 struct ftrace_module_file_ops *file_ops;
860
861 /*
862 * This is a bit of a PITA. To allow for correct reference
863 * counting, modules must "own" their file_operations.
864 * To do this, we allocate the file operations that will be
865 * used in the event directory.
866 */
867
868 file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL);
869 if (!file_ops)
870 return NULL;
871
872 file_ops->mod = mod;
873
874 file_ops->id = ftrace_event_id_fops;
875 file_ops->id.owner = mod;
876
877 file_ops->enable = ftrace_enable_fops;
878 file_ops->enable.owner = mod;
879
880 file_ops->filter = ftrace_event_filter_fops;
881 file_ops->filter.owner = mod;
882
883 file_ops->format = ftrace_event_format_fops;
884 file_ops->format.owner = mod;
885
886 list_add(&file_ops->list, &ftrace_module_file_list);
887
888 return file_ops;
889}
890
836static void trace_module_add_events(struct module *mod) 891static void trace_module_add_events(struct module *mod)
837{ 892{
893 struct ftrace_module_file_ops *file_ops = NULL;
838 struct ftrace_event_call *call, *start, *end; 894 struct ftrace_event_call *call, *start, *end;
839 struct dentry *d_events; 895 struct dentry *d_events;
840 896
@@ -852,14 +908,27 @@ static void trace_module_add_events(struct module *mod)
852 /* The linker may leave blanks */ 908 /* The linker may leave blanks */
853 if (!call->name) 909 if (!call->name)
854 continue; 910 continue;
911
912 /*
913 * This module has events, create file ops for this module
914 * if not already done.
915 */
916 if (!file_ops) {
917 file_ops = trace_create_file_ops(mod);
918 if (!file_ops)
919 return;
920 }
855 call->mod = mod; 921 call->mod = mod;
856 list_add(&call->list, &ftrace_events); 922 list_add(&call->list, &ftrace_events);
857 event_create_dir(call, d_events); 923 event_create_dir(call, d_events,
924 &file_ops->id, &file_ops->enable,
925 &file_ops->filter, &file_ops->format);
858 } 926 }
859} 927}
860 928
861static void trace_module_remove_events(struct module *mod) 929static void trace_module_remove_events(struct module *mod)
862{ 930{
931 struct ftrace_module_file_ops *file_ops;
863 struct ftrace_event_call *call, *p; 932 struct ftrace_event_call *call, *p;
864 933
865 list_for_each_entry_safe(call, p, &ftrace_events, list) { 934 list_for_each_entry_safe(call, p, &ftrace_events, list) {
@@ -874,6 +943,16 @@ static void trace_module_remove_events(struct module *mod)
874 list_del(&call->list); 943 list_del(&call->list);
875 } 944 }
876 } 945 }
946
947 /* Now free the file_operations */
948 list_for_each_entry(file_ops, &ftrace_module_file_list, list) {
949 if (file_ops->mod == mod)
950 break;
951 }
952 if (&file_ops->list != &ftrace_module_file_list) {
953 list_del(&file_ops->list);
954 kfree(file_ops);
955 }
877} 956}
878 957
879static int trace_module_notify(struct notifier_block *self, 958static int trace_module_notify(struct notifier_block *self,
@@ -954,7 +1033,9 @@ static __init int event_trace_init(void)
954 if (!call->name) 1033 if (!call->name)
955 continue; 1034 continue;
956 list_add(&call->list, &ftrace_events); 1035 list_add(&call->list, &ftrace_events);
957 event_create_dir(call, d_events); 1036 event_create_dir(call, d_events, &ftrace_event_id_fops,
1037 &ftrace_enable_fops, &ftrace_event_filter_fops,
1038 &ftrace_event_format_fops);
958 } 1039 }
959 1040
960 ret = register_module_notifier(&trace_module_nb); 1041 ret = register_module_notifier(&trace_module_nb);