brintos

brintos / linux-shallow public Read only

0
0
Text · 37.7 KiB · 5a00795 Raw
1495 lines · c
1/*2 * lib/dynamic_debug.c3 *4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their5 * source module.6 *7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>8 * By Greg Banks <gnb@melbourne.sgi.com>9 * Copyright (c) 2008 Silicon Graphics Inc.  All Rights Reserved.10 * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.11 * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>12 */13 14#define pr_fmt(fmt) "dyndbg: " fmt15 16#include <linux/kernel.h>17#include <linux/module.h>18#include <linux/moduleparam.h>19#include <linux/kallsyms.h>20#include <linux/types.h>21#include <linux/mutex.h>22#include <linux/proc_fs.h>23#include <linux/seq_file.h>24#include <linux/list.h>25#include <linux/sysctl.h>26#include <linux/ctype.h>27#include <linux/string.h>28#include <linux/parser.h>29#include <linux/string_helpers.h>30#include <linux/uaccess.h>31#include <linux/dynamic_debug.h>32#include <linux/debugfs.h>33#include <linux/slab.h>34#include <linux/jump_label.h>35#include <linux/hardirq.h>36#include <linux/sched.h>37#include <linux/device.h>38#include <linux/netdevice.h>39 40#include <rdma/ib_verbs.h>41 42extern struct _ddebug __start___dyndbg[];43extern struct _ddebug __stop___dyndbg[];44extern struct ddebug_class_map __start___dyndbg_classes[];45extern struct ddebug_class_map __stop___dyndbg_classes[];46 47struct ddebug_table {48	struct list_head link, maps;49	const char *mod_name;50	unsigned int num_ddebugs;51	struct _ddebug *ddebugs;52};53 54struct ddebug_query {55	const char *filename;56	const char *module;57	const char *function;58	const char *format;59	const char *class_string;60	unsigned int first_lineno, last_lineno;61};62 63struct ddebug_iter {64	struct ddebug_table *table;65	int idx;66};67 68struct flag_settings {69	unsigned int flags;70	unsigned int mask;71};72 73static DEFINE_MUTEX(ddebug_lock);74static LIST_HEAD(ddebug_tables);75static int verbose;76module_param(verbose, int, 0644);77MODULE_PARM_DESC(verbose, " dynamic_debug/control processing "78		 "( 0 = off (default), 1 = module add/rm, 2 = >control summary, 3 = parsing, 4 = per-site changes)");79 80/* Return the path relative to source root */81static inline const char *trim_prefix(const char *path)82{83	int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");84 85	if (strncmp(path, __FILE__, skip))86		skip = 0; /* prefix mismatch, don't skip */87 88	return path + skip;89}90 91static const struct { unsigned flag:8; char opt_char; } opt_array[] = {92	{ _DPRINTK_FLAGS_PRINT, 'p' },93	{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },94	{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },95	{ _DPRINTK_FLAGS_INCL_SOURCENAME, 's' },96	{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },97	{ _DPRINTK_FLAGS_INCL_TID, 't' },98	{ _DPRINTK_FLAGS_NONE, '_' },99};100 101struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };102 103/* format a string into buf[] which describes the _ddebug's flags */104static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)105{106	char *p = fb->buf;107	int i;108 109	for (i = 0; i < ARRAY_SIZE(opt_array); ++i)110		if (flags & opt_array[i].flag)111			*p++ = opt_array[i].opt_char;112	if (p == fb->buf)113		*p++ = '_';114	*p = '\0';115 116	return fb->buf;117}118 119#define vnpr_info(lvl, fmt, ...)				\120do {								\121	if (verbose >= lvl)					\122		pr_info(fmt, ##__VA_ARGS__);			\123} while (0)124 125#define vpr_info(fmt, ...)	vnpr_info(1, fmt, ##__VA_ARGS__)126#define v2pr_info(fmt, ...)	vnpr_info(2, fmt, ##__VA_ARGS__)127#define v3pr_info(fmt, ...)	vnpr_info(3, fmt, ##__VA_ARGS__)128#define v4pr_info(fmt, ...)	vnpr_info(4, fmt, ##__VA_ARGS__)129 130static void vpr_info_dq(const struct ddebug_query *query, const char *msg)131{132	/* trim any trailing newlines */133	int fmtlen = 0;134 135	if (query->format) {136		fmtlen = strlen(query->format);137		while (fmtlen && query->format[fmtlen - 1] == '\n')138			fmtlen--;139	}140 141	v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u class=%s\n",142		  msg,143		  query->function ?: "",144		  query->filename ?: "",145		  query->module ?: "",146		  fmtlen, query->format ?: "",147		  query->first_lineno, query->last_lineno, query->class_string);148}149 150static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,151							  const char *class_string, int *class_id)152{153	struct ddebug_class_map *map;154	int idx;155 156	list_for_each_entry(map, &dt->maps, link) {157		idx = match_string(map->class_names, map->length, class_string);158		if (idx >= 0) {159			*class_id = idx + map->base;160			return map;161		}162	}163	*class_id = -ENOENT;164	return NULL;165}166 167#define __outvar /* filled by callee */168/*169 * Search the tables for _ddebug's which match the given `query' and170 * apply the `flags' and `mask' to them.  Returns number of matching171 * callsites, normally the same as number of changes.  If verbose,172 * logs the changes.  Takes ddebug_lock.173 */174static int ddebug_change(const struct ddebug_query *query,175			 struct flag_settings *modifiers)176{177	int i;178	struct ddebug_table *dt;179	unsigned int newflags;180	unsigned int nfound = 0;181	struct flagsbuf fbuf, nbuf;182	struct ddebug_class_map *map = NULL;183	int __outvar valid_class;184 185	/* search for matching ddebugs */186	mutex_lock(&ddebug_lock);187	list_for_each_entry(dt, &ddebug_tables, link) {188 189		/* match against the module name */190		if (query->module &&191		    !match_wildcard(query->module, dt->mod_name))192			continue;193 194		if (query->class_string) {195			map = ddebug_find_valid_class(dt, query->class_string, &valid_class);196			if (!map)197				continue;198		} else {199			/* constrain query, do not touch class'd callsites */200			valid_class = _DPRINTK_CLASS_DFLT;201		}202 203		for (i = 0; i < dt->num_ddebugs; i++) {204			struct _ddebug *dp = &dt->ddebugs[i];205 206			/* match site against query-class */207			if (dp->class_id != valid_class)208				continue;209 210			/* match against the source filename */211			if (query->filename &&212			    !match_wildcard(query->filename, dp->filename) &&213			    !match_wildcard(query->filename,214					   kbasename(dp->filename)) &&215			    !match_wildcard(query->filename,216					   trim_prefix(dp->filename)))217				continue;218 219			/* match against the function */220			if (query->function &&221			    !match_wildcard(query->function, dp->function))222				continue;223 224			/* match against the format */225			if (query->format) {226				if (*query->format == '^') {227					char *p;228					/* anchored search. match must be at beginning */229					p = strstr(dp->format, query->format+1);230					if (p != dp->format)231						continue;232				} else if (!strstr(dp->format, query->format))233					continue;234			}235 236			/* match against the line number range */237			if (query->first_lineno &&238			    dp->lineno < query->first_lineno)239				continue;240			if (query->last_lineno &&241			    dp->lineno > query->last_lineno)242				continue;243 244			nfound++;245 246			newflags = (dp->flags & modifiers->mask) | modifiers->flags;247			if (newflags == dp->flags)248				continue;249#ifdef CONFIG_JUMP_LABEL250			if (dp->flags & _DPRINTK_FLAGS_PRINT) {251				if (!(newflags & _DPRINTK_FLAGS_PRINT))252					static_branch_disable(&dp->key.dd_key_true);253			} else if (newflags & _DPRINTK_FLAGS_PRINT) {254				static_branch_enable(&dp->key.dd_key_true);255			}256#endif257			v4pr_info("changed %s:%d [%s]%s %s => %s\n",258				  trim_prefix(dp->filename), dp->lineno,259				  dt->mod_name, dp->function,260				  ddebug_describe_flags(dp->flags, &fbuf),261				  ddebug_describe_flags(newflags, &nbuf));262			dp->flags = newflags;263		}264	}265	mutex_unlock(&ddebug_lock);266 267	if (!nfound && verbose)268		pr_info("no matches for query\n");269 270	return nfound;271}272 273/*274 * Split the buffer `buf' into space-separated words.275 * Handles simple " and ' quoting, i.e. without nested,276 * embedded or escaped \".  Return the number of words277 * or <0 on error.278 */279static int ddebug_tokenize(char *buf, char *words[], int maxwords)280{281	int nwords = 0;282 283	while (*buf) {284		char *end;285 286		/* Skip leading whitespace */287		buf = skip_spaces(buf);288		if (!*buf)289			break;	/* oh, it was trailing whitespace */290		if (*buf == '#')291			break;	/* token starts comment, skip rest of line */292 293		/* find `end' of word, whitespace separated or quoted */294		if (*buf == '"' || *buf == '\'') {295			int quote = *buf++;296			for (end = buf; *end && *end != quote; end++)297				;298			if (!*end) {299				pr_err("unclosed quote: %s\n", buf);300				return -EINVAL;	/* unclosed quote */301			}302		} else {303			for (end = buf; *end && !isspace(*end); end++)304				;305			if (end == buf) {306				pr_err("parse err after word:%d=%s\n", nwords,307				       nwords ? words[nwords - 1] : "<none>");308				return -EINVAL;309			}310		}311 312		/* `buf' is start of word, `end' is one past its end */313		if (nwords == maxwords) {314			pr_err("too many words, legal max <=%d\n", maxwords);315			return -EINVAL;	/* ran out of words[] before bytes */316		}317		if (*end)318			*end++ = '\0';	/* terminate the word */319		words[nwords++] = buf;320		buf = end;321	}322 323	if (verbose >= 3) {324		int i;325		pr_info("split into words:");326		for (i = 0; i < nwords; i++)327			pr_cont(" \"%s\"", words[i]);328		pr_cont("\n");329	}330 331	return nwords;332}333 334/*335 * Parse a single line number.  Note that the empty string ""336 * is treated as a special case and converted to zero, which337 * is later treated as a "don't care" value.338 */339static inline int parse_lineno(const char *str, unsigned int *val)340{341	BUG_ON(str == NULL);342	if (*str == '\0') {343		*val = 0;344		return 0;345	}346	if (kstrtouint(str, 10, val) < 0) {347		pr_err("bad line-number: %s\n", str);348		return -EINVAL;349	}350	return 0;351}352 353static int parse_linerange(struct ddebug_query *query, const char *first)354{355	char *last = strchr(first, '-');356 357	if (query->first_lineno || query->last_lineno) {358		pr_err("match-spec: line used 2x\n");359		return -EINVAL;360	}361	if (last)362		*last++ = '\0';363	if (parse_lineno(first, &query->first_lineno) < 0)364		return -EINVAL;365	if (last) {366		/* range <first>-<last> */367		if (parse_lineno(last, &query->last_lineno) < 0)368			return -EINVAL;369 370		/* special case for last lineno not specified */371		if (query->last_lineno == 0)372			query->last_lineno = UINT_MAX;373 374		if (query->last_lineno < query->first_lineno) {375			pr_err("last-line:%d < 1st-line:%d\n",376			       query->last_lineno,377			       query->first_lineno);378			return -EINVAL;379		}380	} else {381		query->last_lineno = query->first_lineno;382	}383	v3pr_info("parsed line %d-%d\n", query->first_lineno,384		 query->last_lineno);385	return 0;386}387 388static int check_set(const char **dest, char *src, char *name)389{390	int rc = 0;391 392	if (*dest) {393		rc = -EINVAL;394		pr_err("match-spec:%s val:%s overridden by %s\n",395		       name, *dest, src);396	}397	*dest = src;398	return rc;399}400 401/*402 * Parse words[] as a ddebug query specification, which is a series403 * of (keyword, value) pairs chosen from these possibilities:404 *405 * func <function-name>406 * file <full-pathname>407 * file <base-filename>408 * module <module-name>409 * format <escaped-string-to-find-in-format>410 * line <lineno>411 * line <first-lineno>-<last-lineno> // where either may be empty412 *413 * Only 1 of each type is allowed.414 * Returns 0 on success, <0 on error.415 */416static int ddebug_parse_query(char *words[], int nwords,417			struct ddebug_query *query, const char *modname)418{419	unsigned int i;420	int rc = 0;421	char *fline;422 423	/* check we have an even number of words */424	if (nwords % 2 != 0) {425		pr_err("expecting pairs of match-spec <value>\n");426		return -EINVAL;427	}428 429	for (i = 0; i < nwords; i += 2) {430		char *keyword = words[i];431		char *arg = words[i+1];432 433		if (!strcmp(keyword, "func")) {434			rc = check_set(&query->function, arg, "func");435		} else if (!strcmp(keyword, "file")) {436			if (check_set(&query->filename, arg, "file"))437				return -EINVAL;438 439			/* tail :$info is function or line-range */440			fline = strchr(query->filename, ':');441			if (!fline)442				continue;443			*fline++ = '\0';444			if (isalpha(*fline) || *fline == '*' || *fline == '?') {445				/* take as function name */446				if (check_set(&query->function, fline, "func"))447					return -EINVAL;448			} else {449				if (parse_linerange(query, fline))450					return -EINVAL;451			}452		} else if (!strcmp(keyword, "module")) {453			rc = check_set(&query->module, arg, "module");454		} else if (!strcmp(keyword, "format")) {455			string_unescape_inplace(arg, UNESCAPE_SPACE |456							    UNESCAPE_OCTAL |457							    UNESCAPE_SPECIAL);458			rc = check_set(&query->format, arg, "format");459		} else if (!strcmp(keyword, "line")) {460			if (parse_linerange(query, arg))461				return -EINVAL;462		} else if (!strcmp(keyword, "class")) {463			rc = check_set(&query->class_string, arg, "class");464		} else {465			pr_err("unknown keyword \"%s\"\n", keyword);466			return -EINVAL;467		}468		if (rc)469			return rc;470	}471	if (!query->module && modname)472		/*473		 * support $modname.dyndbg=<multiple queries>, when474		 * not given in the query itself475		 */476		query->module = modname;477 478	vpr_info_dq(query, "parsed");479	return 0;480}481 482/*483 * Parse `str' as a flags specification, format [-+=][p]+.484 * Sets up *maskp and *flagsp to be used when changing the485 * flags fields of matched _ddebug's.  Returns 0 on success486 * or <0 on error.487 */488static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)489{490	int op, i;491 492	switch (*str) {493	case '+':494	case '-':495	case '=':496		op = *str++;497		break;498	default:499		pr_err("bad flag-op %c, at start of %s\n", *str, str);500		return -EINVAL;501	}502	v3pr_info("op='%c'\n", op);503 504	for (; *str ; ++str) {505		for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {506			if (*str == opt_array[i].opt_char) {507				modifiers->flags |= opt_array[i].flag;508				break;509			}510		}511		if (i < 0) {512			pr_err("unknown flag '%c'\n", *str);513			return -EINVAL;514		}515	}516	v3pr_info("flags=0x%x\n", modifiers->flags);517 518	/* calculate final flags, mask based upon op */519	switch (op) {520	case '=':521		/* modifiers->flags already set */522		modifiers->mask = 0;523		break;524	case '+':525		modifiers->mask = ~0U;526		break;527	case '-':528		modifiers->mask = ~modifiers->flags;529		modifiers->flags = 0;530		break;531	}532	v3pr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);533 534	return 0;535}536 537static int ddebug_exec_query(char *query_string, const char *modname)538{539	struct flag_settings modifiers = {};540	struct ddebug_query query = {};541#define MAXWORDS 9542	int nwords, nfound;543	char *words[MAXWORDS];544 545	nwords = ddebug_tokenize(query_string, words, MAXWORDS);546	if (nwords <= 0) {547		pr_err("tokenize failed\n");548		return -EINVAL;549	}550	/* check flags 1st (last arg) so query is pairs of spec,val */551	if (ddebug_parse_flags(words[nwords-1], &modifiers)) {552		pr_err("flags parse failed\n");553		return -EINVAL;554	}555	if (ddebug_parse_query(words, nwords-1, &query, modname)) {556		pr_err("query parse failed\n");557		return -EINVAL;558	}559	/* actually go and implement the change */560	nfound = ddebug_change(&query, &modifiers);561	vpr_info_dq(&query, nfound ? "applied" : "no-match");562 563	return nfound;564}565 566/* handle multiple queries in query string, continue on error, return567   last error or number of matching callsites.  Module name is either568   in param (for boot arg) or perhaps in query string.569*/570static int ddebug_exec_queries(char *query, const char *modname)571{572	char *split;573	int i, errs = 0, exitcode = 0, rc, nfound = 0;574 575	for (i = 0; query; query = split) {576		split = strpbrk(query, ";\n");577		if (split)578			*split++ = '\0';579 580		query = skip_spaces(query);581		if (!query || !*query || *query == '#')582			continue;583 584		vpr_info("query %d: \"%s\" mod:%s\n", i, query, modname ?: "*");585 586		rc = ddebug_exec_query(query, modname);587		if (rc < 0) {588			errs++;589			exitcode = rc;590		} else {591			nfound += rc;592		}593		i++;594	}595	if (i)596		v2pr_info("processed %d queries, with %d matches, %d errs\n",597			 i, nfound, errs);598 599	if (exitcode)600		return exitcode;601	return nfound;602}603 604/* apply a new bitmap to the sys-knob's current bit-state */605static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,606				     unsigned long *new_bits, unsigned long *old_bits)607{608#define QUERY_SIZE 128609	char query[QUERY_SIZE];610	const struct ddebug_class_map *map = dcp->map;611	int matches = 0;612	int bi, ct;613 614	v2pr_info("apply: 0x%lx to: 0x%lx\n", *new_bits, *old_bits);615 616	for (bi = 0; bi < map->length; bi++) {617		if (test_bit(bi, new_bits) == test_bit(bi, old_bits))618			continue;619 620		snprintf(query, QUERY_SIZE, "class %s %c%s", map->class_names[bi],621			 test_bit(bi, new_bits) ? '+' : '-', dcp->flags);622 623		ct = ddebug_exec_queries(query, NULL);624		matches += ct;625 626		v2pr_info("bit_%d: %d matches on class: %s -> 0x%lx\n", bi,627			  ct, map->class_names[bi], *new_bits);628	}629	return matches;630}631 632/* stub to later conditionally add "$module." prefix where not already done */633#define KP_NAME(kp)	kp->name634 635#define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)636 637/* accept comma-separated-list of [+-] classnames */638static int param_set_dyndbg_classnames(const char *instr, const struct kernel_param *kp)639{640	const struct ddebug_class_param *dcp = kp->arg;641	const struct ddebug_class_map *map = dcp->map;642	unsigned long curr_bits, old_bits;643	char *cl_str, *p, *tmp;644	int cls_id, totct = 0;645	bool wanted;646 647	cl_str = tmp = kstrdup_and_replace(instr, '\n', '\0', GFP_KERNEL);648	if (!tmp)649		return -ENOMEM;650 651	/* start with previously set state-bits, then modify */652	curr_bits = old_bits = *dcp->bits;653	vpr_info("\"%s\" > %s:0x%lx\n", cl_str, KP_NAME(kp), curr_bits);654 655	for (; cl_str; cl_str = p) {656		p = strchr(cl_str, ',');657		if (p)658			*p++ = '\0';659 660		if (*cl_str == '-') {661			wanted = false;662			cl_str++;663		} else {664			wanted = true;665			if (*cl_str == '+')666				cl_str++;667		}668		cls_id = match_string(map->class_names, map->length, cl_str);669		if (cls_id < 0) {670			pr_err("%s unknown to %s\n", cl_str, KP_NAME(kp));671			continue;672		}673 674		/* have one or more valid class_ids of one *_NAMES type */675		switch (map->map_type) {676		case DD_CLASS_TYPE_DISJOINT_NAMES:677			/* the +/- pertains to a single bit */678			if (test_bit(cls_id, &curr_bits) == wanted) {679				v3pr_info("no change on %s\n", cl_str);680				continue;681			}682			curr_bits ^= BIT(cls_id);683			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, dcp->bits);684			*dcp->bits = curr_bits;685			v2pr_info("%s: changed bit %d:%s\n", KP_NAME(kp), cls_id,686				  map->class_names[cls_id]);687			break;688		case DD_CLASS_TYPE_LEVEL_NAMES:689			/* cls_id = N in 0..max. wanted +/- determines N or N-1 */690			old_bits = CLASSMAP_BITMASK(*dcp->lvl);691			curr_bits = CLASSMAP_BITMASK(cls_id + (wanted ? 1 : 0 ));692 693			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, &old_bits);694			*dcp->lvl = (cls_id + (wanted ? 1 : 0));695			v2pr_info("%s: changed bit-%d: \"%s\" %lx->%lx\n", KP_NAME(kp), cls_id,696				  map->class_names[cls_id], old_bits, curr_bits);697			break;698		default:699			pr_err("illegal map-type value %d\n", map->map_type);700		}701	}702	kfree(tmp);703	vpr_info("total matches: %d\n", totct);704	return 0;705}706 707/**708 * param_set_dyndbg_classes - class FOO >control709 * @instr: string echo>d to sysfs, input depends on map_type710 * @kp:    kp->arg has state: bits/lvl, map, map_type711 *712 * Enable/disable prdbgs by their class, as given in the arguments to713 * DECLARE_DYNDBG_CLASSMAP.  For LEVEL map-types, enforce relative714 * levels by bitpos.715 *716 * Returns: 0 or <0 if error.717 */718int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)719{720	const struct ddebug_class_param *dcp = kp->arg;721	const struct ddebug_class_map *map = dcp->map;722	unsigned long inrep, new_bits, old_bits;723	int rc, totct = 0;724 725	switch (map->map_type) {726 727	case DD_CLASS_TYPE_DISJOINT_NAMES:728	case DD_CLASS_TYPE_LEVEL_NAMES:729		/* handle [+-]classnames list separately, we are done here */730		return param_set_dyndbg_classnames(instr, kp);731 732	case DD_CLASS_TYPE_DISJOINT_BITS:733	case DD_CLASS_TYPE_LEVEL_NUM:734		/* numeric input, accept and fall-thru */735		rc = kstrtoul(instr, 0, &inrep);736		if (rc) {737			pr_err("expecting numeric input: %s > %s\n", instr, KP_NAME(kp));738			return -EINVAL;739		}740		break;741	default:742		pr_err("%s: bad map type: %d\n", KP_NAME(kp), map->map_type);743		return -EINVAL;744	}745 746	/* only _BITS,_NUM (numeric) map-types get here */747	switch (map->map_type) {748	case DD_CLASS_TYPE_DISJOINT_BITS:749		/* expect bits. mask and warn if too many */750		if (inrep & ~CLASSMAP_BITMASK(map->length)) {751			pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, masking\n",752				KP_NAME(kp), inrep, CLASSMAP_BITMASK(map->length));753			inrep &= CLASSMAP_BITMASK(map->length);754		}755		v2pr_info("bits:%lx > %s\n", inrep, KP_NAME(kp));756		totct += ddebug_apply_class_bitmap(dcp, &inrep, dcp->bits);757		*dcp->bits = inrep;758		break;759	case DD_CLASS_TYPE_LEVEL_NUM:760		/* input is bitpos, of highest verbosity to be enabled */761		if (inrep > map->length) {762			pr_warn("%s: level:%ld exceeds max:%d, clamping\n",763				KP_NAME(kp), inrep, map->length);764			inrep = map->length;765		}766		old_bits = CLASSMAP_BITMASK(*dcp->lvl);767		new_bits = CLASSMAP_BITMASK(inrep);768		v2pr_info("lvl:%ld bits:0x%lx > %s\n", inrep, new_bits, KP_NAME(kp));769		totct += ddebug_apply_class_bitmap(dcp, &new_bits, &old_bits);770		*dcp->lvl = inrep;771		break;772	default:773		pr_warn("%s: bad map type: %d\n", KP_NAME(kp), map->map_type);774	}775	vpr_info("%s: total matches: %d\n", KP_NAME(kp), totct);776	return 0;777}778EXPORT_SYMBOL(param_set_dyndbg_classes);779 780/**781 * param_get_dyndbg_classes - classes reader782 * @buffer: string description of controlled bits -> classes783 * @kp:     kp->arg has state: bits, map784 *785 * Reads last written state, underlying prdbg state may have been786 * altered by direct >control.  Displays 0x for DISJOINT, 0-N for787 * LEVEL Returns: #chars written or <0 on error788 */789int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)790{791	const struct ddebug_class_param *dcp = kp->arg;792	const struct ddebug_class_map *map = dcp->map;793 794	switch (map->map_type) {795 796	case DD_CLASS_TYPE_DISJOINT_NAMES:797	case DD_CLASS_TYPE_DISJOINT_BITS:798		return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", *dcp->bits);799 800	case DD_CLASS_TYPE_LEVEL_NAMES:801	case DD_CLASS_TYPE_LEVEL_NUM:802		return scnprintf(buffer, PAGE_SIZE, "%d\n", *dcp->lvl);803	default:804		return -1;805	}806}807EXPORT_SYMBOL(param_get_dyndbg_classes);808 809const struct kernel_param_ops param_ops_dyndbg_classes = {810	.set = param_set_dyndbg_classes,811	.get = param_get_dyndbg_classes,812};813EXPORT_SYMBOL(param_ops_dyndbg_classes);814 815#define PREFIX_SIZE 128816 817static int remaining(int wrote)818{819	if (PREFIX_SIZE - wrote > 0)820		return PREFIX_SIZE - wrote;821	return 0;822}823 824static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)825{826	int pos_after_tid;827	int pos = 0;828 829	if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {830		if (in_interrupt())831			pos += snprintf(buf + pos, remaining(pos), "<intr> ");832		else833			pos += snprintf(buf + pos, remaining(pos), "[%d] ",834					task_pid_vnr(current));835	}836	pos_after_tid = pos;837	if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)838		pos += snprintf(buf + pos, remaining(pos), "%s:",839				desc->modname);840	if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)841		pos += snprintf(buf + pos, remaining(pos), "%s:",842				desc->function);843	if (desc->flags & _DPRINTK_FLAGS_INCL_SOURCENAME)844		pos += snprintf(buf + pos, remaining(pos), "%s:",845				trim_prefix(desc->filename));846	if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)847		pos += snprintf(buf + pos, remaining(pos), "%d:",848				desc->lineno);849	if (pos - pos_after_tid)850		pos += snprintf(buf + pos, remaining(pos), " ");851	if (pos >= PREFIX_SIZE)852		buf[PREFIX_SIZE - 1] = '\0';853 854	return buf;855}856 857static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)858{859	if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))860		return __dynamic_emit_prefix(desc, buf);861	return buf;862}863 864void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)865{866	va_list args;867	struct va_format vaf;868	char buf[PREFIX_SIZE] = "";869 870	BUG_ON(!descriptor);871	BUG_ON(!fmt);872 873	va_start(args, fmt);874 875	vaf.fmt = fmt;876	vaf.va = &args;877 878	printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);879 880	va_end(args);881}882EXPORT_SYMBOL(__dynamic_pr_debug);883 884void __dynamic_dev_dbg(struct _ddebug *descriptor,885		      const struct device *dev, const char *fmt, ...)886{887	struct va_format vaf;888	va_list args;889 890	BUG_ON(!descriptor);891	BUG_ON(!fmt);892 893	va_start(args, fmt);894 895	vaf.fmt = fmt;896	vaf.va = &args;897 898	if (!dev) {899		printk(KERN_DEBUG "(NULL device *): %pV", &vaf);900	} else {901		char buf[PREFIX_SIZE] = "";902 903		dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",904				dynamic_emit_prefix(descriptor, buf),905				dev_driver_string(dev), dev_name(dev),906				&vaf);907	}908 909	va_end(args);910}911EXPORT_SYMBOL(__dynamic_dev_dbg);912 913#ifdef CONFIG_NET914 915void __dynamic_netdev_dbg(struct _ddebug *descriptor,916			  const struct net_device *dev, const char *fmt, ...)917{918	struct va_format vaf;919	va_list args;920 921	BUG_ON(!descriptor);922	BUG_ON(!fmt);923 924	va_start(args, fmt);925 926	vaf.fmt = fmt;927	vaf.va = &args;928 929	if (dev && dev->dev.parent) {930		char buf[PREFIX_SIZE] = "";931 932		dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,933				"%s%s %s %s%s: %pV",934				dynamic_emit_prefix(descriptor, buf),935				dev_driver_string(dev->dev.parent),936				dev_name(dev->dev.parent),937				netdev_name(dev), netdev_reg_state(dev),938				&vaf);939	} else if (dev) {940		printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),941		       netdev_reg_state(dev), &vaf);942	} else {943		printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);944	}945 946	va_end(args);947}948EXPORT_SYMBOL(__dynamic_netdev_dbg);949 950#endif951 952#if IS_ENABLED(CONFIG_INFINIBAND)953 954void __dynamic_ibdev_dbg(struct _ddebug *descriptor,955			 const struct ib_device *ibdev, const char *fmt, ...)956{957	struct va_format vaf;958	va_list args;959 960	va_start(args, fmt);961 962	vaf.fmt = fmt;963	vaf.va = &args;964 965	if (ibdev && ibdev->dev.parent) {966		char buf[PREFIX_SIZE] = "";967 968		dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,969				"%s%s %s %s: %pV",970				dynamic_emit_prefix(descriptor, buf),971				dev_driver_string(ibdev->dev.parent),972				dev_name(ibdev->dev.parent),973				dev_name(&ibdev->dev),974				&vaf);975	} else if (ibdev) {976		printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);977	} else {978		printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);979	}980 981	va_end(args);982}983EXPORT_SYMBOL(__dynamic_ibdev_dbg);984 985#endif986 987/*988 * Install a noop handler to make dyndbg look like a normal kernel cli param.989 * This avoids warnings about dyndbg being an unknown cli param when supplied990 * by a user.991 */992static __init int dyndbg_setup(char *str)993{994	return 1;995}996 997__setup("dyndbg=", dyndbg_setup);998 999/*1000 * File_ops->write method for <debugfs>/dynamic_debug/control.  Gathers the1001 * command text from userspace, parses and executes it.1002 */1003#define USER_BUF_PAGE 40961004static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,1005				  size_t len, loff_t *offp)1006{1007	char *tmpbuf;1008	int ret;1009 1010	if (len == 0)1011		return 0;1012	if (len > USER_BUF_PAGE - 1) {1013		pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);1014		return -E2BIG;1015	}1016	tmpbuf = memdup_user_nul(ubuf, len);1017	if (IS_ERR(tmpbuf))1018		return PTR_ERR(tmpbuf);1019	v2pr_info("read %zu bytes from userspace\n", len);1020 1021	ret = ddebug_exec_queries(tmpbuf, NULL);1022	kfree(tmpbuf);1023	if (ret < 0)1024		return ret;1025 1026	*offp += len;1027	return len;1028}1029 1030/*1031 * Set the iterator to point to the first _ddebug object1032 * and return a pointer to that first object.  Returns1033 * NULL if there are no _ddebugs at all.1034 */1035static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)1036{1037	if (list_empty(&ddebug_tables)) {1038		iter->table = NULL;1039		return NULL;1040	}1041	iter->table = list_entry(ddebug_tables.next,1042				 struct ddebug_table, link);1043	iter->idx = iter->table->num_ddebugs;1044	return &iter->table->ddebugs[--iter->idx];1045}1046 1047/*1048 * Advance the iterator to point to the next _ddebug1049 * object from the one the iterator currently points at,1050 * and returns a pointer to the new _ddebug.  Returns1051 * NULL if the iterator has seen all the _ddebugs.1052 */1053static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)1054{1055	if (iter->table == NULL)1056		return NULL;1057	if (--iter->idx < 0) {1058		/* iterate to next table */1059		if (list_is_last(&iter->table->link, &ddebug_tables)) {1060			iter->table = NULL;1061			return NULL;1062		}1063		iter->table = list_entry(iter->table->link.next,1064					 struct ddebug_table, link);1065		iter->idx = iter->table->num_ddebugs;1066		--iter->idx;1067	}1068	return &iter->table->ddebugs[iter->idx];1069}1070 1071/*1072 * Seq_ops start method.  Called at the start of every1073 * read() call from userspace.  Takes the ddebug_lock and1074 * seeks the seq_file's iterator to the given position.1075 */1076static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)1077{1078	struct ddebug_iter *iter = m->private;1079	struct _ddebug *dp;1080	int n = *pos;1081 1082	mutex_lock(&ddebug_lock);1083 1084	if (!n)1085		return SEQ_START_TOKEN;1086	if (n < 0)1087		return NULL;1088	dp = ddebug_iter_first(iter);1089	while (dp != NULL && --n > 0)1090		dp = ddebug_iter_next(iter);1091	return dp;1092}1093 1094/*1095 * Seq_ops next method.  Called several times within a read()1096 * call from userspace, with ddebug_lock held.  Walks to the1097 * next _ddebug object with a special case for the header line.1098 */1099static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)1100{1101	struct ddebug_iter *iter = m->private;1102	struct _ddebug *dp;1103 1104	if (p == SEQ_START_TOKEN)1105		dp = ddebug_iter_first(iter);1106	else1107		dp = ddebug_iter_next(iter);1108	++*pos;1109	return dp;1110}1111 1112#define class_in_range(class_id, map)					\1113	(class_id >= map->base && class_id < map->base + map->length)1114 1115static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)1116{1117	struct ddebug_class_map *map;1118 1119	list_for_each_entry(map, &iter->table->maps, link)1120		if (class_in_range(dp->class_id, map))1121			return map->class_names[dp->class_id - map->base];1122 1123	return NULL;1124}1125 1126/*1127 * Seq_ops show method.  Called several times within a read()1128 * call from userspace, with ddebug_lock held.  Formats the1129 * current _ddebug as a single human-readable line, with a1130 * special case for the header line.1131 */1132static int ddebug_proc_show(struct seq_file *m, void *p)1133{1134	struct ddebug_iter *iter = m->private;1135	struct _ddebug *dp = p;1136	struct flagsbuf flags;1137	char const *class;1138 1139	if (p == SEQ_START_TOKEN) {1140		seq_puts(m,1141			 "# filename:lineno [module]function flags format\n");1142		return 0;1143	}1144 1145	seq_printf(m, "%s:%u [%s]%s =%s \"",1146		   trim_prefix(dp->filename), dp->lineno,1147		   iter->table->mod_name, dp->function,1148		   ddebug_describe_flags(dp->flags, &flags));1149	seq_escape_str(m, dp->format, ESCAPE_SPACE, "\t\r\n\"");1150	seq_putc(m, '"');1151 1152	if (dp->class_id != _DPRINTK_CLASS_DFLT) {1153		class = ddebug_class_name(iter, dp);1154		if (class)1155			seq_printf(m, " class:%s", class);1156		else1157			seq_printf(m, " class unknown, _id:%d", dp->class_id);1158	}1159	seq_putc(m, '\n');1160 1161	return 0;1162}1163 1164/*1165 * Seq_ops stop method.  Called at the end of each read()1166 * call from userspace.  Drops ddebug_lock.1167 */1168static void ddebug_proc_stop(struct seq_file *m, void *p)1169{1170	mutex_unlock(&ddebug_lock);1171}1172 1173static const struct seq_operations ddebug_proc_seqops = {1174	.start = ddebug_proc_start,1175	.next = ddebug_proc_next,1176	.show = ddebug_proc_show,1177	.stop = ddebug_proc_stop1178};1179 1180static int ddebug_proc_open(struct inode *inode, struct file *file)1181{1182	return seq_open_private(file, &ddebug_proc_seqops,1183				sizeof(struct ddebug_iter));1184}1185 1186static const struct file_operations ddebug_proc_fops = {1187	.owner = THIS_MODULE,1188	.open = ddebug_proc_open,1189	.read = seq_read,1190	.llseek = seq_lseek,1191	.release = seq_release_private,1192	.write = ddebug_proc_write1193};1194 1195static const struct proc_ops proc_fops = {1196	.proc_open = ddebug_proc_open,1197	.proc_read = seq_read,1198	.proc_lseek = seq_lseek,1199	.proc_release = seq_release_private,1200	.proc_write = ddebug_proc_write1201};1202 1203static void ddebug_attach_module_classes(struct ddebug_table *dt,1204					 struct ddebug_class_map *classes,1205					 int num_classes)1206{1207	struct ddebug_class_map *cm;1208	int i, j, ct = 0;1209 1210	for (cm = classes, i = 0; i < num_classes; i++, cm++) {1211 1212		if (!strcmp(cm->mod_name, dt->mod_name)) {1213 1214			v2pr_info("class[%d]: module:%s base:%d len:%d ty:%d\n", i,1215				  cm->mod_name, cm->base, cm->length, cm->map_type);1216 1217			for (j = 0; j < cm->length; j++)1218				v3pr_info(" %d: %d %s\n", j + cm->base, j,1219					  cm->class_names[j]);1220 1221			list_add(&cm->link, &dt->maps);1222			ct++;1223		}1224	}1225	if (ct)1226		vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);1227}1228 1229/*1230 * Allocate a new ddebug_table for the given module1231 * and add it to the global list.1232 */1233static int ddebug_add_module(struct _ddebug_info *di, const char *modname)1234{1235	struct ddebug_table *dt;1236 1237	v3pr_info("add-module: %s.%d sites\n", modname, di->num_descs);1238	if (!di->num_descs) {1239		v3pr_info(" skip %s\n", modname);1240		return 0;1241	}1242 1243	dt = kzalloc(sizeof(*dt), GFP_KERNEL);1244	if (dt == NULL) {1245		pr_err("error adding module: %s\n", modname);1246		return -ENOMEM;1247	}1248	/*1249	 * For built-in modules, name lives in .rodata and is1250	 * immortal. For loaded modules, name points at the name[]1251	 * member of struct module, which lives at least as long as1252	 * this struct ddebug_table.1253	 */1254	dt->mod_name = modname;1255	dt->ddebugs = di->descs;1256	dt->num_ddebugs = di->num_descs;1257 1258	INIT_LIST_HEAD(&dt->link);1259	INIT_LIST_HEAD(&dt->maps);1260 1261	if (di->classes && di->num_classes)1262		ddebug_attach_module_classes(dt, di->classes, di->num_classes);1263 1264	mutex_lock(&ddebug_lock);1265	list_add_tail(&dt->link, &ddebug_tables);1266	mutex_unlock(&ddebug_lock);1267 1268	vpr_info("%3u debug prints in module %s\n", di->num_descs, modname);1269	return 0;1270}1271 1272/* helper for ddebug_dyndbg_(boot|module)_param_cb */1273static int ddebug_dyndbg_param_cb(char *param, char *val,1274				const char *modname, int on_err)1275{1276	char *sep;1277 1278	sep = strchr(param, '.');1279	if (sep) {1280		/* needed only for ddebug_dyndbg_boot_param_cb */1281		*sep = '\0';1282		modname = param;1283		param = sep + 1;1284	}1285	if (strcmp(param, "dyndbg"))1286		return on_err; /* determined by caller */1287 1288	ddebug_exec_queries((val ? val : "+p"), modname);1289 1290	return 0; /* query failure shouldn't stop module load */1291}1292 1293/* handle both dyndbg and $module.dyndbg params at boot */1294static int ddebug_dyndbg_boot_param_cb(char *param, char *val,1295				const char *unused, void *arg)1296{1297	vpr_info("%s=\"%s\"\n", param, val);1298	return ddebug_dyndbg_param_cb(param, val, NULL, 0);1299}1300 1301/*1302 * modprobe foo finds foo.params in boot-args, strips "foo.", and1303 * passes them to load_module().  This callback gets unknown params,1304 * processes dyndbg params, rejects others.1305 */1306int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)1307{1308	vpr_info("module: %s %s=\"%s\"\n", module, param, val);1309	return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);1310}1311 1312static void ddebug_table_free(struct ddebug_table *dt)1313{1314	list_del_init(&dt->link);1315	kfree(dt);1316}1317 1318#ifdef CONFIG_MODULES1319 1320/*1321 * Called in response to a module being unloaded.  Removes1322 * any ddebug_table's which point at the module.1323 */1324static int ddebug_remove_module(const char *mod_name)1325{1326	struct ddebug_table *dt, *nextdt;1327	int ret = -ENOENT;1328 1329	mutex_lock(&ddebug_lock);1330	list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {1331		if (dt->mod_name == mod_name) {1332			ddebug_table_free(dt);1333			ret = 0;1334			break;1335		}1336	}1337	mutex_unlock(&ddebug_lock);1338	if (!ret)1339		v2pr_info("removed module \"%s\"\n", mod_name);1340	return ret;1341}1342 1343static int ddebug_module_notify(struct notifier_block *self, unsigned long val,1344				void *data)1345{1346	struct module *mod = data;1347	int ret = 0;1348 1349	switch (val) {1350	case MODULE_STATE_COMING:1351		ret = ddebug_add_module(&mod->dyndbg_info, mod->name);1352		if (ret)1353			WARN(1, "Failed to allocate memory: dyndbg may not work properly.\n");1354		break;1355	case MODULE_STATE_GOING:1356		ddebug_remove_module(mod->name);1357		break;1358	}1359 1360	return notifier_from_errno(ret);1361}1362 1363static struct notifier_block ddebug_module_nb = {1364	.notifier_call = ddebug_module_notify,1365	.priority = 0, /* dynamic debug depends on jump label */1366};1367 1368#endif /* CONFIG_MODULES */1369 1370static void ddebug_remove_all_tables(void)1371{1372	mutex_lock(&ddebug_lock);1373	while (!list_empty(&ddebug_tables)) {1374		struct ddebug_table *dt = list_entry(ddebug_tables.next,1375						      struct ddebug_table,1376						      link);1377		ddebug_table_free(dt);1378	}1379	mutex_unlock(&ddebug_lock);1380}1381 1382static __initdata int ddebug_init_success;1383 1384static int __init dynamic_debug_init_control(void)1385{1386	struct proc_dir_entry *procfs_dir;1387	struct dentry *debugfs_dir;1388 1389	if (!ddebug_init_success)1390		return -ENODEV;1391 1392	/* Create the control file in debugfs if it is enabled */1393	if (debugfs_initialized()) {1394		debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);1395		debugfs_create_file("control", 0644, debugfs_dir, NULL,1396				    &ddebug_proc_fops);1397	}1398 1399	/* Also create the control file in procfs */1400	procfs_dir = proc_mkdir("dynamic_debug", NULL);1401	if (procfs_dir)1402		proc_create("control", 0644, procfs_dir, &proc_fops);1403 1404	return 0;1405}1406 1407static int __init dynamic_debug_init(void)1408{1409	struct _ddebug *iter, *iter_mod_start;1410	int ret, i, mod_sites, mod_ct;1411	const char *modname;1412	char *cmdline;1413 1414	struct _ddebug_info di = {1415		.descs = __start___dyndbg,1416		.classes = __start___dyndbg_classes,1417		.num_descs = __stop___dyndbg - __start___dyndbg,1418		.num_classes = __stop___dyndbg_classes - __start___dyndbg_classes,1419	};1420 1421#ifdef CONFIG_MODULES1422	ret = register_module_notifier(&ddebug_module_nb);1423	if (ret) {1424		pr_warn("Failed to register dynamic debug module notifier\n");1425		return ret;1426	}1427#endif /* CONFIG_MODULES */1428 1429	if (&__start___dyndbg == &__stop___dyndbg) {1430		if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {1431			pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");1432			return 1;1433		}1434		pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");1435		ddebug_init_success = 1;1436		return 0;1437	}1438 1439	iter = iter_mod_start = __start___dyndbg;1440	modname = iter->modname;1441	i = mod_sites = mod_ct = 0;1442 1443	for (; iter < __stop___dyndbg; iter++, i++, mod_sites++) {1444 1445		if (strcmp(modname, iter->modname)) {1446			mod_ct++;1447			di.num_descs = mod_sites;1448			di.descs = iter_mod_start;1449			ret = ddebug_add_module(&di, modname);1450			if (ret)1451				goto out_err;1452 1453			mod_sites = 0;1454			modname = iter->modname;1455			iter_mod_start = iter;1456		}1457	}1458	di.num_descs = mod_sites;1459	di.descs = iter_mod_start;1460	ret = ddebug_add_module(&di, modname);1461	if (ret)1462		goto out_err;1463 1464	ddebug_init_success = 1;1465	vpr_info("%d prdebugs in %d modules, %d KiB in ddebug tables, %d kiB in __dyndbg section\n",1466		 i, mod_ct, (int)((mod_ct * sizeof(struct ddebug_table)) >> 10),1467		 (int)((i * sizeof(struct _ddebug)) >> 10));1468 1469	if (di.num_classes)1470		v2pr_info("  %d builtin ddebug class-maps\n", di.num_classes);1471 1472	/* now that ddebug tables are loaded, process all boot args1473	 * again to find and activate queries given in dyndbg params.1474	 * While this has already been done for known boot params, it1475	 * ignored the unknown ones (dyndbg in particular).  Reusing1476	 * parse_args avoids ad-hoc parsing.  This will also attempt1477	 * to activate queries for not-yet-loaded modules, which is1478	 * slightly noisy if verbose, but harmless.1479	 */1480	cmdline = kstrdup(saved_command_line, GFP_KERNEL);1481	parse_args("dyndbg params", cmdline, NULL,1482		   0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);1483	kfree(cmdline);1484	return 0;1485 1486out_err:1487	ddebug_remove_all_tables();1488	return 0;1489}1490/* Allow early initialization for boot messages via boot param */1491early_initcall(dynamic_debug_init);1492 1493/* Debugfs setup must be done later */1494fs_initcall(dynamic_debug_init_control);1495