1134 lines · 27.3 KB · C
RawDownload
 * Called in response to a module being unloaded.  Removes * any ddebug_table's which point at the module. */int ddebug_remove_module(const char *mod_name){	struct ddebug_table *dt, *nextdt;	int ret = -ENOENT; 	v2pr_info("removing module \"%s\"\n", mod_name); 	mutex_lock(&ddebug_lock);	list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {		if (dt->mod_name == mod_name) {			ddebug_table_free(dt);			ret = 0;			break;		}	}	mutex_unlock(&ddebug_lock);	return ret;} static void ddebug_remove_all_tables(void){	mutex_lock(&ddebug_lock);	while (!list_empty(&ddebug_tables)) {		struct ddebug_table *dt = list_entry(ddebug_tables.next,						      struct ddebug_table,						      link);		ddebug_table_free(dt);	}	mutex_unlock(&ddebug_lock);} static __initdata int ddebug_init_success; static int __init dynamic_debug_init_control(void){	struct proc_dir_entry *procfs_dir;	struct dentry *debugfs_dir; 	if (!ddebug_init_success)		return -ENODEV; 	/* Create the control file in debugfs if it is enabled */	if (debugfs_initialized()) {		debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);		debugfs_create_file("control", 0644, debugfs_dir, NULL,				    &ddebug_proc_fops);	} 	/* Also create the control file in procfs */	procfs_dir = proc_mkdir("dynamic_debug", NULL);	if (procfs_dir)		proc_create("control", 0644, procfs_dir, &proc_fops); 	return 0;} static int __init dynamic_debug_init(void){	struct _ddebug *iter, *iter_start;	const char *modname = NULL;	char *cmdline;	int ret = 0;	int n = 0, entries = 0, modct = 0; 	if (&__start___dyndbg == &__stop___dyndbg) {		if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {			pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");			return 1;		}		pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");		ddebug_init_success = 1;		return 0;	}	iter = __start___dyndbg;	modname = iter->modname;	iter_start = iter;	for (; iter < __stop___dyndbg; iter++) {		entries++;		if (strcmp(modname, iter->modname)) {			modct++;			ret = ddebug_add_module(iter_start, n, modname);			if (ret)				goto out_err;			n = 0;			modname = iter->modname;			iter_start = iter;		}		n++;	}	ret = ddebug_add_module(iter_start, n, modname);	if (ret)		goto out_err; 	ddebug_init_success = 1;	vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",		 modct, entries, (int)(modct * sizeof(struct ddebug_table)),		 (int)(entries * sizeof(struct _ddebug))); 	/* apply ddebug_query boot param, dont unload tables on err */	if (ddebug_setup_string[0] != '\0') {		pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");		ret = ddebug_exec_queries(ddebug_setup_string, NULL);		if (ret < 0)			pr_warn("Invalid ddebug boot param %s\n",				ddebug_setup_string);		else			pr_info("%d changes by ddebug_query\n", ret);	}	/* now that ddebug tables are loaded, process all boot args	 * again to find and activate queries given in dyndbg params.	 * While this has already been done for known boot params, it	 * ignored the unknown ones (dyndbg in particular).  Reusing	 * parse_args avoids ad-hoc parsing.  This will also attempt	 * to activate queries for not-yet-loaded modules, which is	 * slightly noisy if verbose, but harmless.	 */	cmdline = kstrdup(saved_command_line, GFP_KERNEL);	parse_args("dyndbg params", cmdline, NULL,		   0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);	kfree(cmdline);	return 0; out_err:	ddebug_remove_all_tables();	return 0;}/* Allow early initialization for boot messages via boot param */early_initcall(dynamic_debug_init); /* Debugfs setup must be done later */fs_initcall(dynamic_debug_init_control);

Lines 1001–1134 of 1134. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t