Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
// SPDX-License-Identifier: GPL-2.0

#ifndef _LINUX_KERNEL_TRACE_H
#define _LINUX_KERNEL_TRACE_H

#include <linux/fs.h>
#include <linux/atomic.h>
#include <linux/sched.h>
#include <linux/clocksource.h>
#include <linux/ring_buffer.h>
#include <linux/mmiotrace.h>
#include <linux/tracepoint.h>
#include <linux/ftrace.h>
#include <linux/trace.h>
#include <linux/hw_breakpoint.h>
#include <linux/trace_seq.h>
#include <linux/trace_events.h>
#include <linux/compiler.h>
#include <linux/glob.h>
#include <linux/irq_work.h>
#include <linux/workqueue.h>
#include <linux/ctype.h>
#include <linux/once_lite.h>

#include "pid_list.h"

#ifdef CONFIG_FTRACE_SYSCALLS
#include <asm/unistd.h>		/* For NR_SYSCALLS	     */
#include <asm/syscall.h>	/* some archs define it here */
#endif

#define TRACE_MODE_WRITE	0640
#define TRACE_MODE_READ		0440

enum trace_type {
	__TRACE_FIRST_TYPE = 0,

	TRACE_FN,
	TRACE_CTX,
	TRACE_WAKE,
	TRACE_STACK,
	TRACE_PRINT,
	TRACE_BPRINT,
	TRACE_MMIO_RW,
	TRACE_MMIO_MAP,
	TRACE_BRANCH,
	TRACE_GRAPH_RET,
	TRACE_GRAPH_ENT,
	TRACE_USER_STACK,
	TRACE_BLK,
	TRACE_BPUTS,
	TRACE_HWLAT,
	TRACE_OSNOISE,
	TRACE_TIMERLAT,
	TRACE_RAW_DATA,
	TRACE_FUNC_REPEATS,

	__TRACE_LAST_TYPE,
};


#undef __field
#define __field(type, item)		type	item;

#undef __field_fn
#define __field_fn(type, item)		type	item;

#undef __field_struct
#define __field_struct(type, item)	__field(type, item)

#undef __field_desc
#define __field_desc(type, container, item)

#undef __field_packed
#define __field_packed(type, container, item)

#undef __array
#define __array(type, item, size)	type	item[size];

#undef __array_desc
#define __array_desc(type, container, item, size)

#undef __dynamic_array
#define __dynamic_array(type, item)	type	item[];

#undef __rel_dynamic_array
#define __rel_dynamic_array(type, item)	type	item[];

#undef F_STRUCT
#define F_STRUCT(args...)		args

#undef FTRACE_ENTRY
#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
	struct struct_name {						\
		struct trace_entry	ent;				\
		tstruct							\
	}

#undef FTRACE_ENTRY_DUP
#define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk)

#undef FTRACE_ENTRY_REG
#define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print,	regfn)	\
	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))

#undef FTRACE_ENTRY_PACKED
#define FTRACE_ENTRY_PACKED(name, struct_name, id, tstruct, print)	\
	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print)) __packed

#include "trace_entries.h"

/* Use this for memory failure errors */
#define MEM_FAIL(condition, fmt, ...)					\
	DO_ONCE_LITE_IF(condition, pr_err, "ERROR: " fmt, ##__VA_ARGS__)

#define FAULT_STRING "(fault)"

#define HIST_STACKTRACE_DEPTH	16
#define HIST_STACKTRACE_SIZE	(HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
#define HIST_STACKTRACE_SKIP	5

/*
 * syscalls are special, and need special handling, this is why
 * they are not included in trace_entries.h
 */
struct syscall_trace_enter {
	struct trace_entry	ent;
	int			nr;
	unsigned long		args[];
};

struct syscall_trace_exit {
	struct trace_entry	ent;
	int			nr;
	long			ret;
};

struct kprobe_trace_entry_head {
	struct trace_entry	ent;
	unsigned long		ip;
};

struct eprobe_trace_entry_head {
	struct trace_entry	ent;
};

struct kretprobe_trace_entry_head {
	struct trace_entry	ent;
	unsigned long		func;
	unsigned long		ret_ip;
};

#define TRACE_BUF_SIZE		1024

struct trace_array;

/*
 * The CPU trace array - it consists of thousands of trace entries
 * plus some other descriptor data: (for example which task started
 * the trace, etc.)
 */
struct trace_array_cpu {
	atomic_t		disabled;
	void			*buffer_page;	/* ring buffer spare */

	unsigned long		entries;
	unsigned long		saved_latency;
	unsigned long		critical_start;
	unsigned long		critical_end;
	unsigned long		critical_sequence;
	unsigned long		nice;
	unsigned long		policy;
	unsigned long		rt_priority;
	unsigned long		skipped_entries;
	u64			preempt_timestamp;
	pid_t			pid;
	kuid_t			uid;
	char			comm[TASK_COMM_LEN];

#ifdef CONFIG_FUNCTION_TRACER
	int			ftrace_ignore_pid;
#endif
	bool			ignore_pid;
};

struct tracer;
struct trace_option_dentry;

struct array_buffer {
	struct trace_array		*tr;
	struct trace_buffer		*buffer;
	struct trace_array_cpu __percpu	*data;
	u64				time_start;
	int				cpu;
};

#define TRACE_FLAGS_MAX_SIZE		32

struct trace_options {
	struct tracer			*tracer;
	struct trace_option_dentry	*topts;
};

struct trace_pid_list *trace_pid_list_alloc(void);
void trace_pid_list_free(struct trace_pid_list *pid_list);
bool trace_pid_list_is_set(struct trace_pid_list *pid_list, unsigned int pid);
int trace_pid_list_set(struct trace_pid_list *pid_list, unsigned int pid);
int trace_pid_list_clear(struct trace_pid_list *pid_list, unsigned int pid);
int trace_pid_list_first(struct trace_pid_list *pid_list, unsigned int *pid);
int trace_pid_list_next(struct trace_pid_list *pid_list, unsigned int pid,
			unsigned int *next);

enum {
	TRACE_PIDS		= BIT(0),
	TRACE_NO_PIDS		= BIT(1),
};

static inline bool pid_type_enabled(int type, struct trace_pid_list *pid_list,
				    struct trace_pid_list *no_pid_list)
{
	/* Return true if the pid list in type has pids */
	return ((type & TRACE_PIDS) && pid_list) ||
		((type & TRACE_NO_PIDS) && no_pid_list);
}

static inline bool still_need_pid_events(int type, struct trace_pid_list *pid_list,
					 struct trace_pid_list *no_pid_list)
{
	/*
	 * Turning off what is in @type, return true if the "other"
	 * pid list, still has pids in it.
	 */
	return (!(type & TRACE_PIDS) && pid_list) ||
		(!(type & TRACE_NO_PIDS) && no_pid_list);
}

typedef bool (*cond_update_fn_t)(struct trace_array *tr, void *cond_data);

/**
 * struct cond_snapshot - conditional snapshot data and callback
 *
 * The cond_snapshot structure encapsulates a callback function and
 * data associated with the snapshot for a given tracing instance.
 *
 * When a snapshot is taken conditionally, by invoking
 * tracing_snapshot_cond(tr, cond_data), the cond_data passed in is
 * passed in turn to the cond_snapshot.update() function.  That data
 * can be compared by the update() implementation with the cond_data
 * contained within the struct cond_snapshot instance associated with
 * the trace_array.  Because the tr->max_lock is held throughout the
 * update() call, the update() function can directly retrieve the
 * cond_snapshot and cond_data associated with the per-instance
 * snapshot associated with the trace_array.
 *
 * The cond_snapshot.update() implementation can save data to be
 * associated with the snapshot if it decides to, and returns 'true'
 * in that case, or it returns 'false' if the conditional snapshot
 * shouldn't be taken.
 *
 * The cond_snapshot instance is created and associated with the
 * user-defined cond_data by tracing_cond_snapshot_enable().
 * Likewise, the cond_snapshot instance is destroyed and is no longer
 * associated with the trace instance by
 * tracing_cond_snapshot_disable().
 *
 * The method below is required.
 *
 * @update: When a conditional snapshot is invoked, the update()
 *	callback function is invoked with the tr->max_lock held.  The
 *	update() implementation signals whether or not to actually
 *	take the snapshot, by returning 'true' if so, 'false' if no
 *	snapshot should be taken.  Because the max_lock is held for
 *	the duration of update(), the implementation is safe to
 *	directly retrieved and save any implementation data it needs
 *	to in association with the snapshot.
 */
struct cond_snapshot {
	void				*cond_data;
	cond_update_fn_t		update;
};

/*
 * struct trace_func_repeats - used to keep track of the consecutive
 * (on the same CPU) calls of a single function.
 */
struct trace_func_repeats {
	unsigned long	ip;
	unsigned long	parent_ip;
	unsigned long	count;
	u64		ts_last_call;
};

/*
 * The trace array - an array of per-CPU trace arrays. This is the
 * highest level data structure that individual tracers deal with.
 * They have on/off state as well:
 */
struct trace_array {
	struct list_head	list;
	char			*name;
	struct array_buffer	array_buffer;
#ifdef CONFIG_TRACER_MAX_TRACE
	/*
	 * The max_buffer is used to snapshot the trace when a maximum
	 * latency is reached, or when the user initiates a snapshot.
	 * Some tracers will use this to store a maximum trace while
	 * it continues examining live traces.
	 *
	 * The buffers for the max_buffer are set up the same as the array_buffer
	 * When a snapshot is taken, the buffer of the max_buffer is swapped
	 * with the buffer of the array_buffer and the buffers are reset for
	 * the array_buffer so the tracing can continue.
	 */
	struct array_buffer	max_buffer;
	bool			allocated_snapshot;
#endif
#ifdef CONFIG_TRACER_MAX_TRACE
	unsigned long		max_latency;
#ifdef CONFIG_FSNOTIFY
	struct dentry		*d_max_latency;
	struct work_struct	fsnotify_work;
	struct irq_work		fsnotify_irqwork;
#endif
#endif
	struct trace_pid_list	__rcu *filtered_pids;
	struct trace_pid_list	__rcu *filtered_no_pids;
	/*
	 * max_lock is used to protect the swapping of buffers
	 * when taking a max snapshot. The buffers themselves are
	 * protected by per_cpu spinlocks. But the action of the swap
	 * needs its own lock.
	 *
	 * This is defined as a arch_spinlock_t in order to help
	 * with performance when lockdep debugging is enabled.
	 *
	 * It is also used in other places outside the update_max_tr
	 * so it needs to be defined outside of the
	 * CONFIG_TRACER_MAX_TRACE.
	 */
	arch_spinlock_t		max_lock;
	int			buffer_disabled;
#ifdef CONFIG_FTRACE_SYSCALLS
	int			sys_refcount_enter;
	int			sys_refcount_exit;
	struct trace_event_file __rcu *enter_syscall_files[NR_syscalls];
	struct trace_event_file __rcu *exit_syscall_files[NR_syscalls];
#endif
	int			stop_count;
	int			clock_id;
	int			nr_topts;
	bool			clear_trace;
	int			buffer_percent;
	unsigned int		n_err_log_entries;
	struct tracer		*current_trace;
	unsigned int		trace_flags;
	unsigned char		trace_flags_index[TRACE_FLAGS_MAX_SIZE];
	unsigned int		flags;
	raw_spinlock_t		start_lock;
	struct list_head	err_log;
	struct dentry		*dir;
	struct dentry		*options;
	struct dentry		*percpu_dir;
	struct dentry		*event_dir;
	struct trace_options	*topts;
	struct list_head	systems;
	struct list_head	events;
	struct trace_event_file *trace_marker_file;
	cpumask_var_t		tracing_cpumask; /* only trace on set CPUs */
	int			ref;
	int			trace_ref;
#ifdef CONFIG_FUNCTION_TRACER
	struct ftrace_ops	*ops;
	struct trace_pid_list	__rcu *function_pids;
	struct trace_pid_list	__rcu *function_no_pids;
#ifdef CONFIG_DYNAMIC_FTRACE
	/* All of these are protected by the ftrace_lock */
	struct list_head	func_probes;
	struct list_head	mod_trace;
	struct list_head	mod_notrace;
#endif
	/* function tracing enabled */
	int			function_enabled;
#endif
	int			no_filter_buffering_ref;
	struct list_head	hist_vars;
#ifdef CONFIG_TRACER_SNAPSHOT
	struct cond_snapshot	*cond_snapshot;
#endif
	struct trace_func_repeats	__percpu *last_func_repeats;
};

enum {
	TRACE_ARRAY_FL_GLOBAL	= (1 << 0)
};

extern struct list_head ftrace_trace_arrays;

extern struct mutex trace_types_lock;

extern int trace_array_get(struct trace_array *tr);
extern int tracing_check_open_get_tr(struct trace_array *tr);
extern struct trace_array *trace_array_find(const char *instance);
extern struct trace_array *trace_array_find_get(const char *instance);

extern u64 tracing_event_time_stamp(struct trace_buffer *buffer, struct ring_buffer_event *rbe);
extern int tracing_set_filter_buffering(struct trace_array *tr, bool set);
extern int tracing_set_clock(struct trace_array *tr, const char *clockstr);

extern bool trace_clock_in_ns(struct trace_array *tr);

/*
 * The global tracer (top) should be the first trace array added,
 * but we check the flag anyway.
 */
static inline struct trace_array *top_trace_array(void)
{
	struct trace_array *tr;

	if (list_empty(&ftrace_trace_arrays))
		return NULL;

	tr = list_entry(ftrace_trace_arrays.prev,
			typeof(*tr), list);
	WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL));
	return tr;
}

#define FTRACE_CMP_TYPE(var, type) \
	__builtin_types_compatible_p(typeof(var), type *)

#undef IF_ASSIGN
#define IF_ASSIGN(var, entry, etype, id)			\
	if (FTRACE_CMP_TYPE(var, etype)) {			\
		var = (typeof(var))(entry);			\
		WARN_ON(id != 0 && (entry)->type != id);	\
		break;						\
	}

/* Will cause compile errors if type is not found. */
extern void __ftrace_bad_type(void);

/*
 * The trace_assign_type is a verifier that the entry type is
 * the same as the type being assigned. To add new types simply
 * add a line with the following format:
 *
 * IF_ASSIGN(var, ent, type, id);
 *
 *  Where "type" is the trace type that includes the trace_entry
 *  as the "ent" item. And "id" is the trace identifier that is
 *  used in the trace_type enum.
 *
 *  If the type can have more than one id, then use zero.
 */
#define trace_assign_type(var, ent)					\
	do {								\
		IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN);	\
		IF_ASSIGN(var, ent, struct ctx_switch_entry, 0);	\
		IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK);	\
		IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
		IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);	\
		IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT);	\
		IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS);	\
		IF_ASSIGN(var, ent, struct hwlat_entry, TRACE_HWLAT);	\
		IF_ASSIGN(var, ent, struct osnoise_entry, TRACE_OSNOISE);\
		IF_ASSIGN(var, ent, struct timerlat_entry, TRACE_TIMERLAT);\
		IF_ASSIGN(var, ent, struct raw_data_entry, TRACE_RAW_DATA);\
		IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,		\
			  TRACE_MMIO_RW);				\
		IF_ASSIGN(var, ent, struct trace_mmiotrace_map,		\
			  TRACE_MMIO_MAP);				\
		IF_ASSIGN(var, ent, struct trace_branch, TRACE_BRANCH); \
		IF_ASSIGN(var, ent, struct ftrace_graph_ent_entry,	\
			  TRACE_GRAPH_ENT);		\
		IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,	\
			  TRACE_GRAPH_RET);		\
		IF_ASSIGN(var, ent, struct func_repeats_entry,		\
			  TRACE_FUNC_REPEATS);				\
		__ftrace_bad_type();					\
	} while (0)

/*
 * An option specific to a tracer. This is a boolean value.
 * The bit is the bit index that sets its value on the
 * flags value in struct tracer_flags.
 */
struct tracer_opt {
	const char	*name; /* Will appear on the trace_options file */
	u32		bit; /* Mask assigned in val field in tracer_flags */
};

/*
 * The set of specific options for a tracer. Your tracer
 * have to set the initial value of the flags val.
 */
struct tracer_flags {
	u32			val;
	struct tracer_opt	*opts;
	struct tracer		*trace;
};

/* Makes more easy to define a tracer opt */
#define TRACER_OPT(s, b)	.name = #s, .bit = b


struct trace_option_dentry {
	struct tracer_opt		*opt;
	struct tracer_flags		*flags;
	struct trace_array		*tr;
	struct dentry			*entry;
};

/**
 * struct tracer - a specific tracer and its callbacks to interact with tracefs
 * @name: the name chosen to select it on the available_tracers file
 * @init: called when one switches to this tracer (echo name > current_tracer)
 * @reset: called when one switches to another tracer
 * @start: called when tracing is unpaused (echo 1 > tracing_on)
 * @stop: called when tracing is paused (echo 0 > tracing_on)
 * @update_thresh: called when tracing_thresh is updated
 * @open: called when the trace file is opened
 * @pipe_open: called when the trace_pipe file is opened
 * @close: called when the trace file is released
 * @pipe_close: called when the trace_pipe file is released
 * @read: override the default read callback on trace_pipe
 * @splice_read: override the default splice_read callback on trace_pipe
 * @selftest: selftest to run on boot (see trace_selftest.c)
 * @print_headers: override the first lines that describe your columns
 * @print_line: callback that prints a trace
 * @set_flag: signals one of your private flags changed (trace_options file)
 * @flags: your private flags
 */
struct tracer {
	const char		*name;
	int			(*init)(struct trace_array *tr);
	void			(*reset)(struct trace_array *tr);
	void			(*start)(struct trace_array *tr);
	void			(*stop)(struct trace_array *tr);
	int			(*update_thresh)(struct trace_array *tr);
	void			(*open)(struct trace_iterator *iter);
	void			(*pipe_open)(struct trace_iterator *iter);
	void			(*close)(struct trace_iterator *iter);
	void			(*pipe_close)(struct trace_iterator *iter);
	ssize_t			(*read)(struct trace_iterator *iter,
					struct file *filp, char __user *ubuf,
					size_t cnt, loff_t *ppos);
	ssize_t			(*splice_read)(struct trace_iterator *iter,
					       struct file *filp,
					       loff_t *ppos,
					       struct pipe_inode_info *pipe,
					       size_t len,
					       unsigned int flags);
#ifdef CONFIG_FTRACE_STARTUP_TEST
	int			(*selftest)(struct tracer *trace,
					    struct trace_array *tr);
#endif
	void			(*print_header)(struct seq_file *m);
	enum print_line_t	(*print_line)(struct trace_iterator *iter);
	/* If you handled the flag setting, return 0 */
	int			(*set_flag)(struct trace_array *tr,
					    u32 old_flags, u32 bit, int set);
	/* Return 0 if OK with change, else return non-zero */
	int			(*flag_changed)(struct trace_array *tr,
						u32 mask, int set);
	struct tracer		*next;
	struct tracer_flags	*flags;
	int			enabled;
	bool			print_max;
	bool			allow_instances;
#ifdef CONFIG_TRACER_MAX_TRACE
	bool			use_max_tr;
#endif
	/* True if tracer cannot be enabled in kernel param */
	bool			noboot;
};

static inline struct ring_buffer_iter *
trace_buffer_iter(struct trace_iterator *iter, int cpu)
{
	return iter->buffer_iter ? iter->buffer_iter[cpu] : NULL;
}

int tracer_init(struct tracer *t, struct trace_array *tr);
int tracing_is_enabled(void);
void tracing_reset_online_cpus(struct array_buffer *buf);
void tracing_reset_current(int cpu);
void tracing_reset_all_online_cpus(void);
void tracing_reset_all_online_cpus_unlocked(void);
int tracing_open_generic(struct inode *inode, struct file *filp);
int tracing_open_generic_tr(struct inode *inode, struct file *filp);
bool tracing_is_disabled(void);
bool tracer_tracing_is_on(struct trace_array *tr);
void tracer_tracing_on(struct trace_array *tr);
void tracer_tracing_off(struct trace_array *tr);
struct dentry *trace_create_file(const char *name,
				 umode_t mode,
				 struct dentry *parent,
				 void *data,
				 const struct file_operations *fops);

int tracing_init_dentry(void);

struct ring_buffer_event;

struct ring_buffer_event *
trace_buffer_lock_reserve(struct trace_buffer *buffer,
			  int type,
			  unsigned long len,
			  unsigned int trace_ctx);

struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
						struct trace_array_cpu *data);

struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
					  int *ent_cpu, u64 *ent_ts);

void trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer,
					struct ring_buffer_event *event);

bool trace_is_tracepoint_string(const char *str);
const char *trace_event_format(struct trace_iterator *iter, const char *fmt);
void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
			 va_list ap);

int trace_empty(struct trace_iterator *iter);

void *trace_find_next_entry_inc(struct trace_iterator *iter);

void trace_init_global_iter(struct trace_iterator *iter);

void tracing_iter_reset(struct trace_iterator *iter, int cpu);

unsigned long trace_total_entries_cpu(struct trace_array *tr, int cpu);
unsigned long trace_total_entries(struct trace_array *tr);

void trace_function(struct trace_array *tr,
		    unsigned long ip,
		    unsigned long parent_ip,
		    unsigned int trace_ctx);
void trace_graph_function(struct trace_array *tr,
		    unsigned long ip,
		    unsigned long parent_ip,
		    unsigned int trace_ctx);
void trace_latency_header(struct seq_file *m);
void trace_default_header(struct seq_file *m);
void print_trace_header(struct seq_file *m, struct trace_iterator *iter);

void trace_graph_return(struct ftrace_graph_ret *trace);
int trace_graph_entry(struct ftrace_graph_ent *trace);
void set_graph_array(struct trace_array *tr);

void tracing_start_cmdline_record(void);
void tracing_stop_cmdline_record(void);
void tracing_start_tgid_record(void);
void tracing_stop_tgid_record(void);

int register_tracer(struct tracer *type);
int is_tracing_stopped(void);

loff_t tracing_lseek(struct file *file, loff_t offset, int whence);

extern cpumask_var_t __read_mostly tracing_buffer_mask;

#define for_each_tracing_cpu(cpu)	\
	for_each_cpu(cpu, tracing_buffer_mask)

extern unsigned long nsecs_to_usecs(unsigned long nsecs);

extern unsigned long tracing_thresh;

/* PID filtering */

extern int pid_max;

bool trace_find_filtered_pid(struct trace_pid_list *filtered_pids,
			     pid_t search_pid);
bool trace_ignore_this_task(struct trace_pid_list *filtered_pids,
			    struct trace_pid_list *filtered_no_pids,
			    struct task_struct *task);
void trace_filter_add_remove_task(struct trace_pid_list *pid_list,
				  struct task_struct *self,
				  struct task_struct *task);
void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos);
void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos);
int trace_pid_show(struct seq_file *m, void *v);
void trace_free_pid_list(struct trace_pid_list *pid_list);
int trace_pid_write(struct trace_pid_list *filtered_pids,
		    struct trace_pid_list **new_pid_list,
		    const char __user *ubuf, size_t cnt);

#ifdef CONFIG_TRACER_MAX_TRACE
void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
		   void *cond_data);
void update_max_tr_single(struct trace_array *tr,
			  struct task_struct *tsk, int cpu);

#ifdef CONFIG_FSNOTIFY
#define LATENCY_FS_NOTIFY
#endif
#endif /* CONFIG_TRACER_MAX_TRACE */

#ifdef LATENCY_FS_NOTIFY
void latency_fsnotify(struct trace_array *tr);
#else
static inline void latency_fsnotify(struct trace_array *tr) { }
#endif

#ifdef CONFIG_STACKTRACE
void __trace_stack(struct trace_array *tr, unsigned int trace_ctx, int skip);
#else
static inline void __trace_stack(struct trace_array *tr, unsigned int trace_ctx,
				 int skip)
{
}
#endif /* CONFIG_STACKTRACE */

void trace_last_func_repeats(struct trace_array *tr,
			     struct trace_func_repeats *last_info,
			     unsigned int trace_ctx);

extern u64 ftrace_now(int cpu);

extern void trace_find_cmdline(int pid, char comm[]);
extern int trace_find_tgid(int pid);
extern void trace_event_follow_fork(struct trace_array *tr, bool enable);

#ifdef CONFIG_DYNAMIC_FTRACE
extern unsigned long ftrace_update_tot_cnt;
extern unsigned long ftrace_number_of_pages;
extern unsigned long ftrace_number_of_groups;
void ftrace_init_trace_array(struct trace_array *tr);
#else
static inline void ftrace_init_trace_array(struct trace_array *tr) { }
#endif
#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
extern int DYN_FTRACE_TEST_NAME(void);
#define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2
extern int DYN_FTRACE_TEST_NAME2(void);

extern bool ring_buffer_expanded;
extern bool tracing_selftest_disabled;

#ifdef CONFIG_FTRACE_STARTUP_TEST
extern void __init disable_tracing_selftest(const char *reason);

extern int trace_selftest_startup_function(struct tracer *trace,
					   struct trace_array *tr);
extern int trace_selftest_startup_function_graph(struct tracer *trace,
						 struct trace_array *tr);
extern int trace_selftest_startup_irqsoff(struct tracer *trace,
					  struct trace_array *tr);
extern int trace_selftest_startup_preemptoff(struct tracer *trace,
					     struct trace_array *tr);
extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace,
						 struct trace_array *tr);
extern int trace_selftest_startup_wakeup(struct tracer *trace,
					 struct trace_array *tr);
extern int trace_selftest_startup_nop(struct tracer *trace,
					 struct trace_array *tr);
extern int trace_selftest_startup_branch(struct tracer *trace,
					 struct trace_array *tr);
/*
 * Tracer data references selftest functions that only occur
 * on boot up. These can be __init functions. Thus, when selftests
 * are enabled, then the tracers need to reference __init functions.
 */
#define __tracer_data		__refdata
#else
static inline void __init disable_tracing_selftest(const char *reason)
{
}
/* Tracers are seldom changed. Optimize when selftests are disabled. */
#define __tracer_data		__read_mostly
#endif /* CONFIG_FTRACE_STARTUP_TEST */

extern void *head_page(struct trace_array_cpu *data);
extern unsigned long long ns2usecs(u64 nsec);
extern int
trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
extern int
trace_vprintk(unsigned long ip, const char *fmt, va_list args);
extern int
trace_array_vprintk(struct trace_array *tr,
		    unsigned long ip, const char *fmt, va_list args);
int trace_array_printk_buf(struct trace_buffer *buffer,
			   unsigned long ip, const char *fmt, ...);
void trace_printk_seq(struct trace_seq *s);
enum print_line_t print_trace_line(struct trace_iterator *iter);

extern char trace_find_mark(unsigned long long duration);

struct ftrace_hash;

struct ftrace_mod_load {
	struct list_head	list;
	char			*func;
	char			*module;
	int			 enable;
};

enum {
	FTRACE_HASH_FL_MOD	= (1 << 0),
};

struct ftrace_hash {
	unsigned long		size_bits;
	struct hlist_head	*buckets;
	unsigned long		count;
	unsigned long		flags;
	struct rcu_head		rcu;
};

struct ftrace_func_entry *
ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip);

static __always_inline bool ftrace_hash_empty(struct ftrace_hash *hash)
{
	return !hash || !(hash->count || (hash->flags & FTRACE_HASH_FL_MOD));
}

/* Standard output formatting function used for function return traces */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER

/* Flag options */
#define TRACE_GRAPH_PRINT_OVERRUN       0x1
#define TRACE_GRAPH_PRINT_CPU           0x2
#define TRACE_GRAPH_PRINT_OVERHEAD      0x4
#define TRACE_GRAPH_PRINT_PROC          0x8
#define TRACE_GRAPH_PRINT_DURATION      0x10
#define TRACE_GRAPH_PRINT_ABS_TIME      0x20
#define TRACE_GRAPH_PRINT_REL_TIME      0x40
#define TRACE_GRAPH_PRINT_IRQS          0x80
#define TRACE_GRAPH_PRINT_TAIL          0x100
#define TRACE_GRAPH_SLEEP_TIME          0x200
#define TRACE_GRAPH_GRAPH_TIME          0x400
#define TRACE_GRAPH_PRINT_FILL_SHIFT	28
#define TRACE_GRAPH_PRINT_FILL_MASK	(0x3 << TRACE_GRAPH_PRINT_FILL_SHIFT)

extern void ftrace_graph_sleep_time_control(bool enable);

#ifdef CONFIG_FUNCTION_PROFILER
extern void ftrace_graph_graph_time_control(bool enable);
#else
static inline void ftrace_graph_graph_time_control(bool enable) { }
#endif

extern enum print_line_t
print_graph_function_flags(struct trace_iterator *iter, u32 flags);
extern void print_graph_headers_flags(struct seq_file *s, u32 flags);
extern void
trace_print_graph_duration(unsigned long long duration, struct trace_seq *s);
extern void graph_trace_open(struct trace_iterator *iter);
extern void graph_trace_close(struct trace_iterator *iter);
extern int __trace_graph_entry(struct trace_array *tr,
			       struct ftrace_graph_ent *trace,
			       unsigned int trace_ctx);
extern void __trace_graph_return(struct trace_array *tr,
				 struct ftrace_graph_ret *trace,
				 unsigned int trace_ctx);

#ifdef CONFIG_DYNAMIC_FTRACE
extern struct ftrace_hash __rcu *ftrace_graph_hash;
extern struct ftrace_hash __rcu *ftrace_graph_notrace_hash;

static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
{
	unsigned long addr = trace->func;
	int ret = 0;
	struct ftrace_hash *hash;

	preempt_disable_notrace();

	/*
	 * Have to open code "rcu_dereference_sched()" because the
	 * function graph tracer can be called when RCU is not
	 * "watching".
	 * Protected with schedule_on_each_cpu(ftrace_sync)
	 */
	hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());

	if (ftrace_hash_empty(hash)) {
		ret = 1;
		goto out;
	}

	if (ftrace_lookup_ip(hash, addr)) {

		/*
		 * This needs to be cleared on the return functions
		 * when the depth is zero.
		 */
		trace_recursion_set(TRACE_GRAPH_BIT);
		trace_recursion_set_depth(trace->depth);

		/*
		 * If no irqs are to be traced, but a set_graph_function
		 * is set, and called by an interrupt handler, we still
		 * want to trace it.
		 */
		if (in_hardirq())
			trace_recursion_set(TRACE_IRQ_BIT);
		else
			trace_recursion_clear(TRACE_IRQ_BIT);
		ret = 1;
	}

out:
	preempt_enable_notrace();
	return ret;
}

static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
{
	if (trace_recursion_test(TRACE_GRAPH_BIT) &&
	    trace->depth == trace_recursion_depth())
		trace_recursion_clear(TRACE_GRAPH_BIT);
}

static inline int ftrace_graph_notrace_addr(unsigned long addr)
{
	int ret = 0;
	struct ftrace_hash *notrace_hash;

	preempt_disable_notrace();

	/*
	 * Have to open code "rcu_dereference_sched()" because the
	 * function graph tracer can be called when RCU is not
	 * "watching".
	 * Protected with schedule_on_each_cpu(ftrace_sync)
	 */
	notrace_hash = rcu_dereference_protected(ftrace_graph_notrace_hash,
						 !preemptible());

	if (ftrace_lookup_ip(notrace_hash, addr))
		ret = 1;

	preempt_enable_notrace();
	return ret;
}
#else
static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
{
	return 1;
}

static inline int ftrace_graph_notrace_addr(unsigned long addr)
{
	return 0;
}
static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
{ }
#endif /* CONFIG_DYNAMIC_FTRACE */

extern unsigned int fgraph_max_depth;

static inline bool ftrace_graph_ignore_func(struct ftrace_graph_ent *trace)
{
	/* trace it when it is-nested-in or is a function enabled. */
	return !(trace_recursion_test(TRACE_GRAPH_BIT) ||
		 ftrace_graph_addr(trace)) ||
		(trace->depth < 0) ||
		(fgraph_max_depth && trace->depth >= fgraph_max_depth);
}

#else /* CONFIG_FUNCTION_GRAPH_TRACER */
static inline enum print_line_t
print_graph_function_flags(struct trace_iterator *iter, u32 flags)
{
	return TRACE_TYPE_UNHANDLED;
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

extern struct list_head ftrace_pids;

#ifdef CONFIG_FUNCTION_TRACER

#define FTRACE_PID_IGNORE	-1
#define FTRACE_PID_TRACE	-2

struct ftrace_func_command {
	struct list_head	list;
	char			*name;
	int			(*func)(struct trace_array *tr,
					struct ftrace_hash *hash,
					char *func, char *cmd,
					char *params, int enable);
};
extern bool ftrace_filter_param __initdata;
static inline int ftrace_trace_task(struct trace_array *tr)
{
	return this_cpu_read(tr->array_buffer.data->ftrace_ignore_pid) !=
		FTRACE_PID_IGNORE;
}
extern int ftrace_is_dead(void);
int ftrace_create_function_files(struct trace_array *tr,
				 struct dentry *parent);
void ftrace_destroy_function_files(struct trace_array *tr);
int ftrace_allocate_ftrace_ops(struct trace_array *tr);
void ftrace_free_ftrace_ops(struct trace_array *tr);
void ftrace_init_global_array_ops(struct trace_array *tr);
void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func);
void ftrace_reset_array_ops(struct trace_array *tr);
void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d_tracer);
void ftrace_init_tracefs_toplevel(struct trace_array *tr,
				  struct dentry *d_tracer);
void ftrace_clear_pids(struct trace_array *tr);
int init_function_trace(void);
void ftrace_pid_follow_fork(struct trace_array *tr, bool enable);
#else
static inline int ftrace_trace_task(struct trace_array *tr)
{
	return 1;
}
static inline int ftrace_is_dead(void) { return 0; }
static inline int
ftrace_create_function_files(struct trace_array *tr,
			     struct dentry *parent)
{
	return 0;
}
static inline int ftrace_allocate_ftrace_ops(struct trace_array *tr)
{
	return 0;
}
static inline void ftrace_free_ftrace_ops(struct trace_array *tr) { }
static inline void ftrace_destroy_function_files(struct trace_array *tr) { }
static inline __init void
ftrace_init_global_array_ops(struct trace_array *tr) { }
static inline void ftrace_reset_array_ops(struct trace_array *tr) { }
static inline void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d) { }
static inline void ftrace_init_tracefs_toplevel(struct trace_array *tr, struct dentry *d) { }
static inline void ftrace_clear_pids(struct trace_array *tr) { }
static inline int init_function_trace(void) { return 0; }
static inline void ftrace_pid_follow_fork(struct trace_array *tr, bool enable) { }
/* ftace_func_t type is not defined, use macro instead of static inline */
#define ftrace_init_array_ops(tr, func) do { } while (0)
#endif /* CONFIG_FUNCTION_TRACER */

#if defined(CONFIG_FUNCTION_TRACER) && defined(CONFIG_DYNAMIC_FTRACE)

struct ftrace_probe_ops {
	void			(*func)(unsigned long ip,
					unsigned long parent_ip,
					struct trace_array *tr,
					struct ftrace_probe_ops *ops,
					void *data);
	int			(*init)(struct ftrace_probe_ops *ops,
					struct trace_array *tr,
					unsigned long ip, void *init_data,
					void **data);
	void			(*free)(struct ftrace_probe_ops *ops,
					struct trace_array *tr,
					unsigned long ip, void *data);
	int			(*print)(struct seq_file *m,
					 unsigned long ip,
					 struct ftrace_probe_ops *ops,
					 void *data);
};

struct ftrace_func_mapper;
typedef int (*ftrace_mapper_func)(void *data);

struct ftrace_func_mapper *allocate_ftrace_func_mapper(void);
void **ftrace_func_mapper_find_ip(struct ftrace_func_mapper *mapper,
					   unsigned long ip);
int ftrace_func_mapper_add_ip(struct ftrace_func_mapper *mapper,
			       unsigned long ip, void *data);
void *ftrace_func_mapper_remove_ip(struct ftrace_func_mapper *mapper,
				   unsigned long ip);
void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper,
			     ftrace_mapper_func free_func);

extern int
register_ftrace_function_probe(char *glob, struct trace_array *tr,
			       struct ftrace_probe_ops *ops, void *data);
extern int
unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
				      struct ftrace_probe_ops *ops);
extern void clear_ftrace_function_probes(struct trace_array *tr);

int register_ftrace_command(struct ftrace_func_command *cmd);
int unregister_ftrace_command(struct ftrace_func_command *cmd);

void ftrace_create_filter_files(struct ftrace_ops *ops,
				struct dentry *parent);
void ftrace_destroy_filter_files(struct ftrace_ops *ops);

extern int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf,
			     int len, int reset);
extern int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf,
			      int len, int reset);
#else
struct ftrace_func_command;

static inline __init int register_ftrace_command(struct ftrace_func_command *cmd)
{
	return -EINVAL;
}
static inline __init int unregister_ftrace_command(char *cmd_name)
{
	return -EINVAL;
}
static inline void clear_ftrace_function_probes(struct trace_array *tr)
{
}

/*
 * The ops parameter passed in is usually undefined.
 * This must be a macro.
 */
#define ftrace_create_filter_files(ops, parent) do { } while (0)
#define ftrace_destroy_filter_files(ops) do { } while (0)
#endif /* CONFIG_FUNCTION_TRACER && CONFIG_DYNAMIC_FTRACE */

bool ftrace_event_is_function(struct trace_event_call *call);

/*
 * struct trace_parser - servers for reading the user input separated by spaces
 * @cont: set if the input is not complete - no final space char was found
 * @buffer: holds the parsed user input
 * @idx: user input length
 * @size: buffer size
 */
struct trace_parser {
	bool		cont;
	char		*buffer;
	unsigned	idx;
	unsigned	size;
};

static inline bool trace_parser_loaded(struct trace_parser *parser)
{
	return (parser->idx != 0);
}

static inline bool trace_parser_cont(struct trace_parser *parser)
{
	return parser->cont;
}

static inline void trace_parser_clear(struct trace_parser *parser)
{
	parser->cont = false;
	parser->idx = 0;
}

extern int trace_parser_get_init(struct trace_parser *parser, int size);
extern void trace_parser_put(struct trace_parser *parser);
extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
	size_t cnt, loff_t *ppos);

/*
 * Only create function graph options if function graph is configured.
 */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
# define FGRAPH_FLAGS						\
		C(DISPLAY_GRAPH,	"display-graph"),
#else
# define FGRAPH_FLAGS
#endif

#ifdef CONFIG_BRANCH_TRACER
# define BRANCH_FLAGS					\
		C(BRANCH,		"branch"),
#else
# define BRANCH_FLAGS
#endif

#ifdef CONFIG_FUNCTION_TRACER
# define FUNCTION_FLAGS						\
		C(FUNCTION,		"function-trace"),	\
		C(FUNC_FORK,		"function-fork"),
# define FUNCTION_DEFAULT_FLAGS		TRACE_ITER_FUNCTION
#else
# define FUNCTION_FLAGS
# define FUNCTION_DEFAULT_FLAGS		0UL
# define TRACE_ITER_FUNC_FORK		0UL
#endif

#ifdef CONFIG_STACKTRACE
# define STACK_FLAGS				\
		C(STACKTRACE,		"stacktrace"),
#else
# define STACK_FLAGS
#endif

/*
 * trace_iterator_flags is an enumeration that defines bit
 * positions into trace_flags that controls the output.
 *
 * NOTE: These bits must match the trace_options array in
 *       trace.c (this macro guarantees it).
 */
#define TRACE_FLAGS						\
		C(PRINT_PARENT,		"print-parent"),	\
		C(SYM_OFFSET,		"sym-offset"),		\
		C(SYM_ADDR,		"sym-addr"),		\
		C(VERBOSE,		"verbose"),		\
		C(RAW,			"raw"),			\
		C(HEX,			"hex"),			\
		C(BIN,			"bin"),			\
		C(BLOCK,		"block"),		\
		C(PRINTK,		"trace_printk"),	\
		C(ANNOTATE,		"annotate"),		\
		C(USERSTACKTRACE,	"userstacktrace"),	\
		C(SYM_USEROBJ,		"sym-userobj"),		\
		C(PRINTK_MSGONLY,	"printk-msg-only"),	\
		C(CONTEXT_INFO,		"context-info"),   /* Print pid/cpu/time */ \
		C(LATENCY_FMT,		"latency-format"),	\
		C(RECORD_CMD,		"record-cmd"),		\
		C(RECORD_TGID,		"record-tgid"),		\
		C(OVERWRITE,		"overwrite"),		\
		C(STOP_ON_FREE,		"disable_on_free"),	\
		C(IRQ_INFO,		"irq-info"),		\
		C(MARKERS,		"markers"),		\
		C(EVENT_FORK,		"event-fork"),		\
		C(PAUSE_ON_TRACE,	"pause-on-trace"),	\
		C(HASH_PTR,		"hash-ptr"),	/* Print hashed pointer */ \
		FUNCTION_FLAGS					\
		FGRAPH_FLAGS					\
		STACK_FLAGS					\
		BRANCH_FLAGS

/*
 * By defining C, we can make TRACE_FLAGS a list of bit names
 * that will define the bits for the flag masks.
 */
#undef C
#define C(a, b) TRACE_ITER_##a##_BIT

enum trace_iterator_bits {
	TRACE_FLAGS
	/* Make sure we don't go more than we have bits for */
	TRACE_ITER_LAST_BIT
};

/*
 * By redefining C, we can make TRACE_FLAGS a list of masks that
 * use the bits as defined above.
 */
#undef C
#define C(a, b) TRACE_ITER_##a = (1 << TRACE_ITER_##a##_BIT)

enum trace_iterator_flags { TRACE_FLAGS };

/*
 * TRACE_ITER_SYM_MASK masks the options in trace_flags that
 * control the output of kernel symbols.
 */
#define TRACE_ITER_SYM_MASK \
	(TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR)

extern struct tracer nop_trace;

#ifdef CONFIG_BRANCH_TRACER
extern int enable_branch_tracing(struct trace_array *tr);
extern void disable_branch_tracing(void);
static inline int trace_branch_enable(struct trace_array *tr)
{
	if (tr->trace_flags & TRACE_ITER_BRANCH)
		return enable_branch_tracing(tr);
	return 0;
}
static inline void trace_branch_disable(void)
{
	/* due to races, always disable */
	disable_branch_tracing();
}
#else
static inline int trace_branch_enable(struct trace_array *tr)
{
	return 0;
}
static inline void trace_branch_disable(void)
{
}
#endif /* CONFIG_BRANCH_TRACER */

/* set ring buffers to default size if not already done so */
int tracing_update_buffers(void);

struct ftrace_event_field {
	struct list_head	link;
	const char		*name;
	const char		*type;
	int			filter_type;
	int			offset;
	int			size;
	int			is_signed;
	int			len;
};

struct prog_entry;

struct event_filter {
	struct prog_entry __rcu	*prog;
	char			*filter_string;
};

struct event_subsystem {
	struct list_head	list;
	const char		*name;
	struct event_filter	*filter;
	int			ref_count;
};

struct trace_subsystem_dir {
	struct list_head		list;
	struct event_subsystem		*subsystem;
	struct trace_array		*tr;
	struct dentry			*entry;
	int				ref_count;
	int				nr_events;
};

extern int call_filter_check_discard(struct trace_event_call *call, void *rec,
				     struct trace_buffer *buffer,
				     struct ring_buffer_event *event);

void trace_buffer_unlock_commit_regs(struct trace_array *tr,
				     struct trace_buffer *buffer,
				     struct ring_buffer_event *event,
				     unsigned int trcace_ctx,
				     struct pt_regs *regs);

static inline void trace_buffer_unlock_commit(struct trace_array *tr,
					      struct trace_buffer *buffer,
					      struct ring_buffer_event *event,
					      unsigned int trace_ctx)
{
	trace_buffer_unlock_commit_regs(tr, buffer, event, trace_ctx, NULL);
}

DECLARE_PER_CPU(struct ring_buffer_event *, trace_buffered_event);
DECLARE_PER_CPU(int, trace_buffered_event_cnt);
void trace_buffered_event_disable(void);
void trace_buffered_event_enable(void);

static inline void
__trace_event_discard_commit(struct trace_buffer *buffer,
			     struct ring_buffer_event *event)
{
	if (this_cpu_read(trace_buffered_event) == event) {
		/* Simply release the temp buffer and enable preemption */
		this_cpu_dec(trace_buffered_event_cnt);
		preempt_enable_notrace();
		return;
	}
	/* ring_buffer_discard_commit() enables preemption */
	ring_buffer_discard_commit(buffer, event);
}

/*
 * Helper function for event_trigger_unlock_commit{_regs}().
 * If there are event triggers attached to this event that requires
 * filtering against its fields, then they will be called as the
 * entry already holds the field information of the current event.
 *
 * It also checks if the event should be discarded or not.
 * It is to be discarded if the event is soft disabled and the
 * event was only recorded to process triggers, or if the event
 * filter is active and this event did not match the filters.
 *
 * Returns true if the event is discarded, false otherwise.
 */
static inline bool
__event_trigger_test_discard(struct trace_event_file *file,
			     struct trace_buffer *buffer,
			     struct ring_buffer_event *event,
			     void *entry,
			     enum event_trigger_type *tt)
{
	unsigned long eflags = file->flags;

	if (eflags & EVENT_FILE_FL_TRIGGER_COND)
		*tt = event_triggers_call(file, buffer, entry, event);

	if (likely(!(file->flags & (EVENT_FILE_FL_SOFT_DISABLED |
				    EVENT_FILE_FL_FILTERED |
				    EVENT_FILE_FL_PID_FILTER))))
		return false;

	if (file->flags & EVENT_FILE_FL_SOFT_DISABLED)
		goto discard;

	if (file->flags & EVENT_FILE_FL_FILTERED &&
	    !filter_match_preds(file->filter, entry))
		goto discard;

	if ((file->flags & EVENT_FILE_FL_PID_FILTER) &&
	    trace_event_ignore_this_pid(file))
		goto discard;

	return false;
 discard:
	__trace_event_discard_commit(buffer, event);
	return true;
}

/**
 * event_trigger_unlock_commit - handle triggers and finish event commit
 * @file: The file pointer associated with the event
 * @buffer: The ring buffer that the event is being written to
 * @event: The event meta data in the ring buffer
 * @entry: The event itself
 * @trace_ctx: The tracing context flags.
 *
 * This is a helper function to handle triggers that require data
 * from the event itself. It also tests the event against filters and
 * if the event is soft disabled and should be discarded.
 */
static inline void
event_trigger_unlock_commit(struct trace_event_file *file,
			    struct trace_buffer *buffer,
			    struct ring_buffer_event *event,
			    void *entry, unsigned int trace_ctx)
{
	enum event_trigger_type tt = ETT_NONE;

	if (!__event_trigger_test_discard(file, buffer, event, entry, &tt))
		trace_buffer_unlock_commit(file->tr, buffer, event, trace_ctx);

	if (tt)
		event_triggers_post_call(file, tt);
}

#define FILTER_PRED_INVALID	((unsigned short)-1)
#define FILTER_PRED_IS_RIGHT	(1 << 15)
#define FILTER_PRED_FOLD	(1 << 15)

/*
 * The max preds is the size of unsigned short with
 * two flags at the MSBs. One bit is used for both the IS_RIGHT
 * and FOLD flags. The other is reserved.
 *
 * 2^14 preds is way more than enough.
 */
#define MAX_FILTER_PRED		16384

struct filter_pred;
struct regex;

typedef int (*regex_match_func)(char *str, struct regex *r, int len);

enum regex_type {
	MATCH_FULL = 0,
	MATCH_FRONT_ONLY,
	MATCH_MIDDLE_ONLY,
	MATCH_END_ONLY,
	MATCH_GLOB,
	MATCH_INDEX,
};

struct regex {
	char			pattern[MAX_FILTER_STR_VAL];
	int			len;
	int			field_len;
	regex_match_func	match;
};

static inline bool is_string_field(struct ftrace_event_field *field)
{
	return field->filter_type == FILTER_DYN_STRING ||
	       field->filter_type == FILTER_RDYN_STRING ||
	       field->filter_type == FILTER_STATIC_STRING ||
	       field->filter_type == FILTER_PTR_STRING ||
	       field->filter_type == FILTER_COMM;
}

static inline bool is_function_field(struct ftrace_event_field *field)
{
	return field->filter_type == FILTER_TRACE_FN;
}

extern enum regex_type
filter_parse_regex(char *buff, int len, char **search, int *not);
extern void print_event_filter(struct trace_event_file *file,
			       struct trace_seq *s);
extern int apply_event_filter(struct trace_event_file *file,
			      char *filter_string);
extern int apply_subsystem_event_filter(struct trace_subsystem_dir *dir,
					char *filter_string);
extern void print_subsystem_event_filter(struct event_subsystem *system,
					 struct trace_seq *s);
extern int filter_assign_type(const char *type);
extern int create_event_filter(struct trace_array *tr,
			       struct trace_event_call *call,
			       char *filter_str, bool set_str,
			       struct event_filter **filterp);
extern void free_event_filter(struct event_filter *filter);

struct ftrace_event_field *
trace_find_event_field(struct trace_event_call *call, char *name);

extern void trace_event_enable_cmd_record(bool enable);
extern void trace_event_enable_tgid_record(bool enable);

extern int event_trace_init(void);
extern int init_events(void);
extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
extern int event_trace_del_tracer(struct trace_array *tr);
extern void __trace_early_add_events(struct trace_array *tr);

extern struct trace_event_file *__find_event_file(struct trace_array *tr,
						  const char *system,
						  const char *event);
extern struct trace_event_file *find_event_file(struct trace_array *tr,
						const char *system,
						const char *event);

static inline void *event_file_data(struct file *filp)
{
	return READ_ONCE(file_inode(filp)->i_private);
}

extern struct mutex event_mutex;
extern struct list_head ftrace_events;

extern const struct file_operations event_trigger_fops;
extern const struct file_operations event_hist_fops;
extern const struct file_operations event_hist_debug_fops;
extern const struct file_operations event_inject_fops;

#ifdef CONFIG_HIST_TRIGGERS
extern int register_trigger_hist_cmd(void);
extern int register_trigger_hist_enable_disable_cmds(void);
#else
static inline int register_trigger_hist_cmd(void) { return 0; }
static inline int register_trigger_hist_enable_disable_cmds(void) { return 0; }
#endif

extern int register_trigger_cmds(void);
extern void clear_event_triggers(struct trace_array *tr);

enum {
	EVENT_TRIGGER_FL_PROBE		= BIT(0),
};

struct event_trigger_data {
	unsigned long			count;
	int				ref;
	int				flags;
	struct event_trigger_ops	*ops;
	struct event_command		*cmd_ops;
	struct event_filter __rcu	*filter;
	char				*filter_str;
	void				*private_data;
	bool				paused;
	bool				paused_tmp;
	struct list_head		list;
	char				*name;
	struct list_head		named_list;
	struct event_trigger_data	*named_data;
};

/* Avoid typos */
#define ENABLE_EVENT_STR	"enable_event"
#define DISABLE_EVENT_STR	"disable_event"
#define ENABLE_HIST_STR		"enable_hist"
#define DISABLE_HIST_STR	"disable_hist"

struct enable_trigger_data {
	struct trace_event_file		*file;
	bool				enable;
	bool				hist;
};

extern int event_enable_trigger_print(struct seq_file *m,
				      struct event_trigger_data *data);
extern void event_enable_trigger_free(struct event_trigger_data *data);
extern int event_enable_trigger_parse(struct event_command *cmd_ops,
				      struct trace_event_file *file,
				      char *glob, char *cmd,
				      char *param_and_filter);
extern int event_enable_register_trigger(char *glob,
					 struct event_trigger_data *data,
					 struct trace_event_file *file);
extern void event_enable_unregister_trigger(char *glob,
					    struct event_trigger_data *test,
					    struct trace_event_file *file);
extern void trigger_data_free(struct event_trigger_data *data);
extern int event_trigger_init(struct event_trigger_data *data);
extern int trace_event_trigger_enable_disable(struct trace_event_file *file,
					      int trigger_enable);
extern void update_cond_flag(struct trace_event_file *file);
extern int set_trigger_filter(char *filter_str,
			      struct event_trigger_data *trigger_data,
			      struct trace_event_file *file);
extern struct event_trigger_data *find_named_trigger(const char *name);
extern bool is_named_trigger(struct event_trigger_data *test);
extern int save_named_trigger(const char *name,
			      struct event_trigger_data *data);
extern void del_named_trigger(struct event_trigger_data *data);
extern void pause_named_trigger(struct event_trigger_data *data);
extern void unpause_named_trigger(struct event_trigger_data *data);
extern void set_named_trigger_data(struct event_trigger_data *data,
				   struct event_trigger_data *named_data);
extern struct event_trigger_data *
get_named_trigger_data(struct event_trigger_data *data);
extern int register_event_command(struct event_command *cmd);
extern int unregister_event_command(struct event_command *cmd);
extern int register_trigger_hist_enable_disable_cmds(void);
extern bool event_trigger_check_remove(const char *glob);
extern bool event_trigger_empty_param(const char *param);
extern int event_trigger_separate_filter(char *param_and_filter, char **param,
					 char **filter, bool param_required);
extern struct event_trigger_data *
event_trigger_alloc(struct event_command *cmd_ops,
		    char *cmd,
		    char *param,
		    void *private_data);
extern int event_trigger_parse_num(char *trigger,
				   struct event_trigger_data *trigger_data);
extern int event_trigger_set_filter(struct event_command *cmd_ops,
				    struct trace_event_file *file,
				    char *param,
				    struct event_trigger_data *trigger_data);
extern void event_trigger_reset_filter(struct event_command *cmd_ops,
				       struct event_trigger_data *trigger_data);
extern int event_trigger_register(struct event_command *cmd_ops,
				  struct trace_event_file *file,
				  char *glob,
				  struct event_trigger_data *trigger_data);
extern void event_trigger_unregister(struct event_command *cmd_ops,
				     struct trace_event_file *file,
				     char *glob,
				     struct event_trigger_data *trigger_data);

/**
 * struct event_trigger_ops - callbacks for trace event triggers
 *
 * The methods in this structure provide per-event trigger hooks for
 * various trigger operations.
 *
 * The @init and @free methods are used during trigger setup and
 * teardown, typically called from an event_command's @parse()
 * function implementation.
 *
 * The @print method is used to print the trigger spec.
 *
 * The @trigger method is the function that actually implements the
 * trigger and is called in the context of the triggering event
 * whenever that event occurs.
 *
 * All the methods below, except for @init() and @free(), must be
 * implemented.
 *
 * @trigger: The trigger 'probe' function called when the triggering
 *	event occurs.  The data passed into this callback is the data
 *	that was supplied to the event_command @reg() function that
 *	registered the trigger (see struct event_command) along with
 *	the trace record, rec.
 *
 * @init: An optional initialization function called for the trigger
 *	when the trigger is registered (via the event_command reg()
 *	function).  This can be used to perform per-trigger
 *	initialization such as incrementing a per-trigger reference
 *	count, for instance.  This is usually implemented by the
 *	generic utility function @event_trigger_init() (see
 *	trace_event_triggers.c).
 *
 * @free: An optional de-initialization function called for the
 *	trigger when the trigger is unregistered (via the
 *	event_command @reg() function).  This can be used to perform
 *	per-trigger de-initialization such as decrementing a
 *	per-trigger reference count and freeing corresponding trigger
 *	data, for instance.  This is usually implemented by the
 *	generic utility function @event_trigger_free() (see
 *	trace_event_triggers.c).
 *
 * @print: The callback function invoked to have the trigger print
 *	itself.  This is usually implemented by a wrapper function
 *	that calls the generic utility function @event_trigger_print()
 *	(see trace_event_triggers.c).
 */
struct event_trigger_ops {
	void			(*trigger)(struct event_trigger_data *data,
					   struct trace_buffer *buffer,
					   void *rec,
					   struct ring_buffer_event *rbe);
	int			(*init)(struct event_trigger_data *data);
	void			(*free)(struct event_trigger_data *data);
	int			(*print)(struct seq_file *m,
					 struct event_trigger_data *data);
};

/**
 * struct event_command - callbacks and data members for event commands
 *
 * Event commands are invoked by users by writing the command name
 * into the 'trigger' file associated with a trace event.  The
 * parameters associated with a specific invocation of an event
 * command are used to create an event trigger instance, which is
 * added to the list of trigger instances associated with that trace
 * event.  When the event is hit, the set of triggers associated with
 * that event is invoked.
 *
 * The data members in this structure provide per-event command data
 * for various event commands.
 *
 * All the data members below, except for @post_trigger, must be set
 * for each event command.
 *
 * @name: The unique name that identifies the event command.  This is
 *	the name used when setting triggers via trigger files.
 *
 * @trigger_type: A unique id that identifies the event command
 *	'type'.  This value has two purposes, the first to ensure that
 *	only one trigger of the same type can be set at a given time
 *	for a particular event e.g. it doesn't make sense to have both
 *	a traceon and traceoff trigger attached to a single event at
 *	the same time, so traceon and traceoff have the same type
 *	though they have different names.  The @trigger_type value is
 *	also used as a bit value for deferring the actual trigger
 *	action until after the current event is finished.  Some
 *	commands need to do this if they themselves log to the trace
 *	buffer (see the @post_trigger() member below).  @trigger_type
 *	values are defined by adding new values to the trigger_type
 *	enum in include/linux/trace_events.h.
 *
 * @flags: See the enum event_command_flags below.
 *
 * All the methods below, except for @set_filter() and @unreg_all(),
 * must be implemented.
 *
 * @parse: The callback function responsible for parsing and
 *	registering the trigger written to the 'trigger' file by the
 *	user.  It allocates the trigger instance and registers it with
 *	the appropriate trace event.  It makes use of the other
 *	event_command callback functions to orchestrate this, and is
 *	usually implemented by the generic utility function
 *	@event_trigger_callback() (see trace_event_triggers.c).
 *
 * @reg: Adds the trigger to the list of triggers associated with the
 *	event, and enables the event trigger itself, after
 *	initializing it (via the event_trigger_ops @init() function).
 *	This is also where commands can use the @trigger_type value to
 *	make the decision as to whether or not multiple instances of
 *	the trigger should be allowed.  This is usually implemented by
 *	the generic utility function @register_trigger() (see
 *	trace_event_triggers.c).
 *
 * @unreg: Removes the trigger from the list of triggers associated
 *	with the event, and disables the event trigger itself, after
 *	initializing it (via the event_trigger_ops @free() function).
 *	This is usually implemented by the generic utility function
 *	@unregister_trigger() (see trace_event_triggers.c).
 *
 * @unreg_all: An optional function called to remove all the triggers
 *	from the list of triggers associated with the event.  Called
 *	when a trigger file is opened in truncate mode.
 *
 * @set_filter: An optional function called to parse and set a filter
 *	for the trigger.  If no @set_filter() method is set for the
 *	event command, filters set by the user for the command will be
 *	ignored.  This is usually implemented by the generic utility
 *	function @set_trigger_filter() (see trace_event_triggers.c).
 *
 * @get_trigger_ops: The callback function invoked to retrieve the
 *	event_trigger_ops implementation associated with the command.
 *	This callback function allows a single event_command to
 *	support multiple trigger implementations via different sets of
 *	event_trigger_ops, depending on the value of the @param
 *	string.
 */
struct event_command {
	struct list_head	list;
	char			*name;
	enum event_trigger_type	trigger_type;
	int			flags;
	int			(*parse)(struct event_command *cmd_ops,
					 struct trace_event_file *file,
					 char *glob, char *cmd,
					 char *param_and_filter);
	int			(*reg)(char *glob,
				       struct event_trigger_data *data,
				       struct trace_event_file *file);
	void			(*unreg)(char *glob,
					 struct event_trigger_data *data,
					 struct trace_event_file *file);
	void			(*unreg_all)(struct trace_event_file *file);
	int			(*set_filter)(char *filter_str,
					      struct event_trigger_data *data,
					      struct trace_event_file *file);
	struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
};

/**
 * enum event_command_flags - flags for struct event_command
 *
 * @POST_TRIGGER: A flag that says whether or not this command needs
 *	to have its action delayed until after the current event has
 *	been closed.  Some triggers need to avoid being invoked while
 *	an event is currently in the process of being logged, since
 *	the trigger may itself log data into the trace buffer.  Thus
 *	we make sure the current event is committed before invoking
 *	those triggers.  To do that, the trigger invocation is split
 *	in two - the first part checks the filter using the current
 *	trace record; if a command has the @post_trigger flag set, it
 *	sets a bit for itself in the return value, otherwise it
 *	directly invokes the trigger.  Once all commands have been
 *	either invoked or set their return flag, the current record is
 *	either committed or discarded.  At that point, if any commands
 *	have deferred their triggers, those commands are finally
 *	invoked following the close of the current event.  In other
 *	words, if the event_trigger_ops @func() probe implementation
 *	itself logs to the trace buffer, this flag should be set,
 *	otherwise it can be left unspecified.
 *
 * @NEEDS_REC: A flag that says whether or not this command needs
 *	access to the trace record in order to perform its function,
 *	regardless of whether or not it has a filter associated with
 *	it (filters make a trigger require access to the trace record
 *	but are not always present).
 */
enum event_command_flags {
	EVENT_CMD_FL_POST_TRIGGER	= 1,
	EVENT_CMD_FL_NEEDS_REC		= 2,
};

static inline bool event_command_post_trigger(struct event_command *cmd_ops)
{
	return cmd_ops->flags & EVENT_CMD_FL_POST_TRIGGER;
}

static inline bool event_command_needs_rec(struct event_command *cmd_ops)
{
	return cmd_ops->flags & EVENT_CMD_FL_NEEDS_REC;
}

extern int trace_event_enable_disable(struct trace_event_file *file,
				      int enable, int soft_disable);
extern int tracing_alloc_snapshot(void);
extern void tracing_snapshot_cond(struct trace_array *tr, void *cond_data);
extern int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data, cond_update_fn_t update);

extern int tracing_snapshot_cond_disable(struct trace_array *tr);
extern void *tracing_cond_snapshot_data(struct trace_array *tr);

extern const char *__start___trace_bprintk_fmt[];
extern const char *__stop___trace_bprintk_fmt[];

extern const char *__start___tracepoint_str[];
extern const char *__stop___tracepoint_str[];

void trace_printk_control(bool enabled);
void trace_printk_start_comm(void);
int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);

/* Used from boot time tracer */
extern int trace_set_options(struct trace_array *tr, char *option);
extern int tracing_set_tracer(struct trace_array *tr, const char *buf);
extern ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
					  unsigned long size, int cpu_id);
extern int tracing_set_cpumask(struct trace_array *tr,
				cpumask_var_t tracing_cpumask_new);


#define MAX_EVENT_NAME_LEN	64

extern ssize_t trace_parse_run_command(struct file *file,
		const char __user *buffer, size_t count, loff_t *ppos,
		int (*createfn)(const char *));

extern unsigned int err_pos(char *cmd, const char *str);
extern void tracing_log_err(struct trace_array *tr,
			    const char *loc, const char *cmd,
			    const char **errs, u8 type, u16 pos);

/*
 * Normal trace_printk() and friends allocates special buffers
 * to do the manipulation, as well as saves the print formats
 * into sections to display. But the trace infrastructure wants
 * to use these without the added overhead at the price of being
 * a bit slower (used mainly for warnings, where we don't care
 * about performance). The internal_trace_puts() is for such
 * a purpose.
 */
#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))

#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, id, tstruct, print)	\
	extern struct trace_event_call					\
	__aligned(4) event_##call;
#undef FTRACE_ENTRY_DUP
#define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print)	\
	FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
#undef FTRACE_ENTRY_PACKED
#define FTRACE_ENTRY_PACKED(call, struct_name, id, tstruct, print) \
	FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))

#include "trace_entries.h"

#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER)
int perf_ftrace_event_register(struct trace_event_call *call,
			       enum trace_reg type, void *data);
#else
#define perf_ftrace_event_register NULL
#endif

#ifdef CONFIG_FTRACE_SYSCALLS
void init_ftrace_syscalls(void);
const char *get_syscall_name(int syscall);
#else
static inline void init_ftrace_syscalls(void) { }
static inline const char *get_syscall_name(int syscall)
{
	return NULL;
}
#endif

#ifdef CONFIG_EVENT_TRACING
void trace_event_init(void);
void trace_event_eval_update(struct trace_eval_map **map, int len);
/* Used from boot time tracer */
extern int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
extern int trigger_process_regex(struct trace_event_file *file, char *buff);
#else
static inline void __init trace_event_init(void) { }
static inline void trace_event_eval_update(struct trace_eval_map **map, int len) { }
#endif

#ifdef CONFIG_TRACER_SNAPSHOT
void tracing_snapshot_instance(struct trace_array *tr);
int tracing_alloc_snapshot_instance(struct trace_array *tr);
#else
static inline void tracing_snapshot_instance(struct trace_array *tr) { }
static inline int tracing_alloc_snapshot_instance(struct trace_array *tr)
{
	return 0;
}
#endif

#ifdef CONFIG_PREEMPT_TRACER
void tracer_preempt_on(unsigned long a0, unsigned long a1);
void tracer_preempt_off(unsigned long a0, unsigned long a1);
#else
static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { }
static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { }
#endif
#ifdef CONFIG_IRQSOFF_TRACER
void tracer_hardirqs_on(unsigned long a0, unsigned long a1);
void tracer_hardirqs_off(unsigned long a0, unsigned long a1);
#else
static inline void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { }
static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { }
#endif

extern struct trace_iterator *tracepoint_print_iter;

/*
 * Reset the state of the trace_iterator so that it can read consumed data.
 * Normally, the trace_iterator is used for reading the data when it is not
 * consumed, and must retain state.
 */
static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
{
	memset_startat(iter, 0, seq);
	iter->pos = -1;
}

/* Check the name is good for event/group/fields */
static inline bool __is_good_name(const char *name, bool hash_ok)
{
	if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-'))
		return false;
	while (*++name != '\0') {
		if (!isalpha(*name) && !isdigit(*name) && *name != '_' &&
		    (!hash_ok || *name != '-'))
			return false;
	}
	return true;
}

/* Check the name is good for event/group/fields */
static inline bool is_good_name(const char *name)
{
	return __is_good_name(name, false);
}

/* Check the name is good for system */
static inline bool is_good_system_name(const char *name)
{
	return __is_good_name(name, true);
}

/* Convert certain expected symbols into '_' when generating event names */
static inline void sanitize_event_name(char *name)
{
	while (*name++ != '\0')
		if (*name == ':' || *name == '.')
			*name = '_';
}

/*
 * This is a generic way to read and write a u64 value from a file in tracefs.
 *
 * The value is stored on the variable pointed by *val. The value needs
 * to be at least *min and at most *max. The write is protected by an
 * existing *lock.
 */
struct trace_min_max_param {
	struct mutex	*lock;
	u64		*val;
	u64		*min;
	u64		*max;
};

#define U64_STR_SIZE		24	/* 20 digits max */

extern const struct file_operations trace_min_max_fops;

#ifdef CONFIG_RV
extern int rv_init_interface(void);
#else
static inline int rv_init_interface(void)
{
	return 0;
}
#endif

#endif /* _LINUX_KERNEL_TRACE_H */