lib/dynamic_debug.c

Source file repositories/reference/linux-study-clean/lib/dynamic_debug.c

File Facts

System
Linux kernel
Corpus path
lib/dynamic_debug.c
Extension
.c
Size
38650 bytes
Lines
1496
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations ddebug_proc_fops = {
	.owner = THIS_MODULE,
	.open = ddebug_proc_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release_private,
	.write = ddebug_proc_write
};

static const struct proc_ops proc_fops = {
	.proc_open = ddebug_proc_open,
	.proc_read = seq_read,
	.proc_lseek = seq_lseek,
	.proc_release = seq_release_private,
	.proc_write = ddebug_proc_write
};

static void ddebug_attach_module_classes(struct ddebug_table *dt,
					 struct ddebug_class_map *classes,
					 int num_classes)
{
	struct ddebug_class_map *cm;
	int i, j, ct = 0;

	for (cm = classes, i = 0; i < num_classes; i++, cm++) {

		if (!strcmp(cm->mod_name, dt->mod_name)) {

			v2pr_info("class[%d]: module:%s base:%d len:%d ty:%d\n", i,
				  cm->mod_name, cm->base, cm->length, cm->map_type);

			for (j = 0; j < cm->length; j++)
				v3pr_info(" %d: %d %s\n", j + cm->base, j,
					  cm->class_names[j]);

			list_add(&cm->link, &dt->maps);
			ct++;
		}
	}
	if (ct)
		vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);
}

/*
 * Allocate a new ddebug_table for the given module
 * and add it to the global list.
 */
static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
{
	struct ddebug_table *dt;

	v3pr_info("add-module: %s.%d sites\n", modname, di->num_descs);
	if (!di->num_descs) {
		v3pr_info(" skip %s\n", modname);
		return 0;
	}

	dt = kzalloc_obj(*dt);
	if (dt == NULL) {
		pr_err("error adding module: %s\n", modname);
		return -ENOMEM;
	}
	/*
	 * For built-in modules, name lives in .rodata and is
	 * immortal. For loaded modules, name points at the name[]
	 * member of struct module, which lives at least as long as
	 * this struct ddebug_table.
	 */
	dt->mod_name = modname;
	dt->ddebugs = di->descs;
	dt->num_ddebugs = di->num_descs;

	INIT_LIST_HEAD(&dt->link);
	INIT_LIST_HEAD(&dt->maps);

	if (di->classes && di->num_classes)
		ddebug_attach_module_classes(dt, di->classes, di->num_classes);

	mutex_lock(&ddebug_lock);
	list_add_tail(&dt->link, &ddebug_tables);
	mutex_unlock(&ddebug_lock);

	vpr_info("%3u debug prints in module %s\n", di->num_descs, modname);
	return 0;
}

/* helper for ddebug_dyndbg_(boot|module)_param_cb */
static int ddebug_dyndbg_param_cb(char *param, char *val,
				const char *modname, int on_err)
{

Annotation

Implementation Notes