kernel/trace/trace_events_filter.c

Source file repositories/reference/linux-study-clean/kernel/trace/trace_events_filter.c

File Facts

System
Linux kernel
Corpus path
kernel/trace/trace_events_filter.c
Extension
.c
Size
72257 bytes
Lines
2925
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct filter_pred {
	struct regex		*regex;
	struct cpumask          *mask;
	unsigned short		*ops;
	struct ftrace_event_field *field;
	u64			val;
	u64			val2;
	enum filter_pred_fn	fn_num;
	int			offset;
	int			not;
	int			op;
};

/*
 * pred functions are OP_LE, OP_LT, OP_GE, OP_GT, and OP_BAND
 * pred_funcs_##type below must match the order of them above.
 */
#define PRED_FUNC_START			OP_LE
#define PRED_FUNC_MAX			(OP_BAND - PRED_FUNC_START)

#define ERRORS								\
	C(NONE,			"No error"),				\
	C(INVALID_OP,		"Invalid operator"),			\
	C(TOO_MANY_OPEN,	"Too many '('"),			\
	C(TOO_MANY_CLOSE,	"Too few '('"),				\
	C(MISSING_QUOTE,	"Missing matching quote"),		\
	C(MISSING_BRACE_OPEN,   "Missing '{'"),				\
	C(MISSING_BRACE_CLOSE,  "Missing '}'"),				\
	C(OPERAND_TOO_LONG,	"Operand too long"),			\
	C(EXPECT_STRING,	"Expecting string field"),		\
	C(EXPECT_DIGIT,		"Expecting numeric field"),		\
	C(ILLEGAL_FIELD_OP,	"Illegal operation for field type"),	\
	C(FIELD_NOT_FOUND,	"Field not found"),			\
	C(ILLEGAL_INTVAL,	"Illegal integer value"),		\
	C(BAD_SUBSYS_FILTER,	"Couldn't find or set field in one of a subsystem's events"), \
	C(TOO_MANY_PREDS,	"Too many terms in predicate expression"), \
	C(INVALID_FILTER,	"Meaningless filter expression"),	\
	C(INVALID_CPULIST,	"Invalid cpulist"),	\
	C(IP_FIELD_ONLY,	"Only 'ip' field is supported for function trace"), \
	C(INVALID_VALUE,	"Invalid value (did you forget quotes)?"), \
	C(NO_FUNCTION,		"Function not found"),			\
	C(ERRNO,		"Error"),				\
	C(NO_FILTER,		"No filter found")

#undef C
#define C(a, b)		FILT_ERR_##a

enum { ERRORS };

#undef C
#define C(a, b)		b

static const char *err_text[] = { ERRORS };

/* Called after a '!' character but "!=" and "!~" are not "not"s */
static bool is_not(const char *str)
{
	switch (str[1]) {
	case '=':
	case '~':
		return false;
	}
	return true;
}

/**
 * struct prog_entry - a single entry in the filter program
 * @target:	     Index to jump to on a branch (actually one minus the index)
 * @when_to_branch:  The value of the result of the predicate to do a branch
 * @pred:	     The predicate to execute.
 */
struct prog_entry {
	int			target;
	int			when_to_branch;
	struct filter_pred	*pred;
};

/**
 * update_preds - assign a program entry a label target
 * @prog: The program array
 * @N: The index of the current entry in @prog
 * @invert: What to assign a program entry for its branch condition
 *
 * The program entry at @N has a target that points to the index of a program
 * entry that can have its target and when_to_branch fields updated.
 * Update the current program entry denoted by index @N target field to be
 * that of the updated entry. This will denote the entry to update if
 * we are processing an "||" after an "&&".
 */
static void update_preds(struct prog_entry *prog, int N, int invert)

Annotation

Implementation Notes