@@ -1473,6 +1473,28 @@ __trace_add_new_event(struct ftrace_event_call *call,
1473
1473
return event_create_dir (tr -> event_dir , file , id , enable , filter , format );
1474
1474
}
1475
1475
1476
+ /*
1477
+ * Just create a decriptor for early init. A descriptor is required
1478
+ * for enabling events at boot. We want to enable events before
1479
+ * the filesystem is initialized.
1480
+ */
1481
+ static __init int
1482
+ __trace_early_add_new_event (struct ftrace_event_call * call ,
1483
+ struct trace_array * tr )
1484
+ {
1485
+ struct ftrace_event_file * file ;
1486
+
1487
+ file = kzalloc (sizeof (* file ), GFP_KERNEL );
1488
+ if (!file )
1489
+ return - ENOMEM ;
1490
+
1491
+ file -> event_call = call ;
1492
+ file -> tr = tr ;
1493
+ list_add (& file -> list , & tr -> events );
1494
+
1495
+ return 0 ;
1496
+ }
1497
+
1476
1498
struct ftrace_module_file_ops ;
1477
1499
static void __add_event_to_tracers (struct ftrace_event_call * call ,
1478
1500
struct ftrace_module_file_ops * file_ops );
@@ -1709,6 +1731,56 @@ __trace_add_event_dirs(struct trace_array *tr)
1709
1731
}
1710
1732
}
1711
1733
1734
+ /*
1735
+ * The top level array has already had its ftrace_event_file
1736
+ * descriptors created in order to allow for early events to
1737
+ * be recorded. This function is called after the debugfs has been
1738
+ * initialized, and we now have to create the files associated
1739
+ * to the events.
1740
+ */
1741
+ static __init void
1742
+ __trace_early_add_event_dirs (struct trace_array * tr )
1743
+ {
1744
+ struct ftrace_event_file * file ;
1745
+ int ret ;
1746
+
1747
+
1748
+ list_for_each_entry (file , & tr -> events , list ) {
1749
+ ret = event_create_dir (tr -> event_dir , file ,
1750
+ & ftrace_event_id_fops ,
1751
+ & ftrace_enable_fops ,
1752
+ & ftrace_event_filter_fops ,
1753
+ & ftrace_event_format_fops );
1754
+ if (ret < 0 )
1755
+ pr_warning ("Could not create directory for event %s\n" ,
1756
+ file -> event_call -> name );
1757
+ }
1758
+ }
1759
+
1760
+ /*
1761
+ * For early boot up, the top trace array requires to have
1762
+ * a list of events that can be enabled. This must be done before
1763
+ * the filesystem is set up in order to allow events to be traced
1764
+ * early.
1765
+ */
1766
+ static __init void
1767
+ __trace_early_add_events (struct trace_array * tr )
1768
+ {
1769
+ struct ftrace_event_call * call ;
1770
+ int ret ;
1771
+
1772
+ list_for_each_entry (call , & ftrace_events , list ) {
1773
+ /* Early boot up should not have any modules loaded */
1774
+ if (WARN_ON_ONCE (call -> mod ))
1775
+ continue ;
1776
+
1777
+ ret = __trace_early_add_new_event (call , tr );
1778
+ if (ret < 0 )
1779
+ pr_warning ("Could not create early event %s\n" ,
1780
+ call -> name );
1781
+ }
1782
+ }
1783
+
1712
1784
/* Remove the event directory structure for a trace directory. */
1713
1785
static void
1714
1786
__trace_remove_event_dirs (struct trace_array * tr )
@@ -1763,25 +1835,23 @@ static __init int setup_trace_event(char *str)
1763
1835
}
1764
1836
__setup ("trace_event=" , setup_trace_event );
1765
1837
1766
- int event_trace_add_tracer (struct dentry * parent , struct trace_array * tr )
1838
+ /* Expects to have event_mutex held when called */
1839
+ static int
1840
+ create_event_toplevel_files (struct dentry * parent , struct trace_array * tr )
1767
1841
{
1768
1842
struct dentry * d_events ;
1769
1843
struct dentry * entry ;
1770
1844
1771
- mutex_lock (& event_mutex );
1772
-
1773
1845
entry = debugfs_create_file ("set_event" , 0644 , parent ,
1774
1846
tr , & ftrace_set_event_fops );
1775
1847
if (!entry ) {
1776
1848
pr_warning ("Could not create debugfs 'set_event' entry\n" );
1777
- mutex_unlock (& event_mutex );
1778
1849
return - ENOMEM ;
1779
1850
}
1780
1851
1781
1852
d_events = debugfs_create_dir ("events" , parent );
1782
1853
if (!d_events ) {
1783
1854
pr_warning ("Could not create debugfs 'events' directory\n" );
1784
- mutex_unlock (& event_mutex );
1785
1855
return - ENOMEM ;
1786
1856
}
1787
1857
@@ -1798,13 +1868,64 @@ int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr)
1798
1868
tr , & ftrace_tr_enable_fops );
1799
1869
1800
1870
tr -> event_dir = d_events ;
1871
+
1872
+ return 0 ;
1873
+ }
1874
+
1875
+ /**
1876
+ * event_trace_add_tracer - add a instance of a trace_array to events
1877
+ * @parent: The parent dentry to place the files/directories for events in
1878
+ * @tr: The trace array associated with these events
1879
+ *
1880
+ * When a new instance is created, it needs to set up its events
1881
+ * directory, as well as other files associated with events. It also
1882
+ * creates the event hierachry in the @parent/events directory.
1883
+ *
1884
+ * Returns 0 on success.
1885
+ */
1886
+ int event_trace_add_tracer (struct dentry * parent , struct trace_array * tr )
1887
+ {
1888
+ int ret ;
1889
+
1890
+ mutex_lock (& event_mutex );
1891
+
1892
+ ret = create_event_toplevel_files (parent , tr );
1893
+ if (ret )
1894
+ goto out_unlock ;
1895
+
1801
1896
down_write (& trace_event_mutex );
1802
1897
__trace_add_event_dirs (tr );
1803
1898
up_write (& trace_event_mutex );
1804
1899
1900
+ out_unlock :
1805
1901
mutex_unlock (& event_mutex );
1806
1902
1807
- return 0 ;
1903
+ return ret ;
1904
+ }
1905
+
1906
+ /*
1907
+ * The top trace array already had its file descriptors created.
1908
+ * Now the files themselves need to be created.
1909
+ */
1910
+ static __init int
1911
+ early_event_add_tracer (struct dentry * parent , struct trace_array * tr )
1912
+ {
1913
+ int ret ;
1914
+
1915
+ mutex_lock (& event_mutex );
1916
+
1917
+ ret = create_event_toplevel_files (parent , tr );
1918
+ if (ret )
1919
+ goto out_unlock ;
1920
+
1921
+ down_write (& trace_event_mutex );
1922
+ __trace_early_add_event_dirs (tr );
1923
+ up_write (& trace_event_mutex );
1924
+
1925
+ out_unlock :
1926
+ mutex_unlock (& event_mutex );
1927
+
1928
+ return ret ;
1808
1929
}
1809
1930
1810
1931
int event_trace_del_tracer (struct trace_array * tr )
@@ -1842,6 +1963,14 @@ static __init int event_trace_enable(void)
1842
1963
list_add (& call -> list , & ftrace_events );
1843
1964
}
1844
1965
1966
+ /*
1967
+ * We need the top trace array to have a working set of trace
1968
+ * points at early init, before the debug files and directories
1969
+ * are created. Create the file entries now, and attach them
1970
+ * to the actual file dentries later.
1971
+ */
1972
+ __trace_early_add_events (tr );
1973
+
1845
1974
while (true) {
1846
1975
token = strsep (& buf , "," );
1847
1976
@@ -1882,7 +2011,7 @@ static __init int event_trace_init(void)
1882
2011
if (trace_define_common_fields ())
1883
2012
pr_warning ("tracing: Failed to allocate common fields" );
1884
2013
1885
- ret = event_trace_add_tracer (d_tracer , tr );
2014
+ ret = early_event_add_tracer (d_tracer , tr );
1886
2015
if (ret )
1887
2016
return ret ;
1888
2017
0 commit comments