fs/resctrl/pseudo_lock.c
Source file repositories/reference/linux-study-clean/fs/resctrl/pseudo_lock.c
File Facts
- System
- Linux kernel
- Corpus path
fs/resctrl/pseudo_lock.c- Extension
.c- Size
- 29786 bytes
- Lines
- 1100
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cacheinfo.hlinux/cpu.hlinux/cpumask.hlinux/debugfs.hlinux/kthread.hlinux/mman.hlinux/pm_qos.hlinux/resctrl.hlinux/slab.hlinux/uaccess.hinternal.h
Detected Declarations
struct pseudo_lock_pm_reqfunction pseudo_lock_minor_getfunction pseudo_lock_minor_releasefunction list_for_each_entryfunction pseudo_lock_cstates_relaxfunction list_for_each_entry_safefunction pseudo_lock_cstates_constrainfunction for_each_cpufunction pseudo_lock_region_clearfunction pseudo_lock_region_initfunction pseudo_lock_initfunction pseudo_lock_region_allocfunction pseudo_lock_freefunction rdtgroup_monitor_in_progressfunction rdtgroup_locksetup_user_restorefunction rdtgroup_locksetup_user_restrictfunction rdtgroup_locksetup_enterfunction supportfunction rdtgroup_locksetup_exitfunction rdtgroup_cbm_overlaps_pseudo_lockedfunction rdtgroup_pseudo_locked_in_hierarchyfunction list_for_each_entryfunction pseudo_lock_measure_cyclesfunction pseudo_lock_measure_triggerfunction rdtgroup_pseudo_lock_createfunction rdtgroup_pseudo_lock_createfunction pseudo_lock_dev_openfunction pseudo_lock_dev_releasefunction pseudo_lock_dev_mremapfunction pseudo_lock_dev_mmap_preparefunction rdt_pseudo_lock_initfunction rdt_pseudo_lock_release
Annotated Snippet
static const struct file_operations pseudo_measure_fops = {
.write = pseudo_lock_measure_trigger,
.open = simple_open,
.llseek = default_llseek,
};
/**
* rdtgroup_pseudo_lock_create - Create a pseudo-locked region
* @rdtgrp: resource group to which pseudo-lock region belongs
*
* Called when a resource group in the pseudo-locksetup mode receives a
* valid schemata that should be pseudo-locked. Since the resource group is
* in pseudo-locksetup mode the &struct pseudo_lock_region has already been
* allocated and initialized with the essential information. If a failure
* occurs the resource group remains in the pseudo-locksetup mode with the
* &struct pseudo_lock_region associated with it, but cleared from all
* information and ready for the user to re-attempt pseudo-locking by
* writing the schemata again.
*
* Return: 0 if the pseudo-locked region was successfully pseudo-locked, <0
* on failure. Descriptive error will be written to last_cmd_status buffer.
*/
int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp)
{
struct pseudo_lock_region *plr = rdtgrp->plr;
struct task_struct *thread;
unsigned int new_minor;
struct device *dev;
char *kn_name __free(kfree) = NULL;
int ret;
ret = pseudo_lock_region_alloc(plr);
if (ret < 0)
return ret;
ret = pseudo_lock_cstates_constrain(plr);
if (ret < 0) {
ret = -EINVAL;
goto out_region;
}
kn_name = kstrdup(rdt_kn_name(rdtgrp->kn), GFP_KERNEL);
if (!kn_name) {
ret = -ENOMEM;
goto out_cstates;
}
plr->thread_done = 0;
thread = kthread_run_on_cpu(resctrl_arch_pseudo_lock_fn, plr,
plr->cpu, "pseudo_lock/%u");
if (IS_ERR(thread)) {
ret = PTR_ERR(thread);
rdt_last_cmd_printf("Locking thread returned error %d\n", ret);
goto out_cstates;
}
ret = wait_event_interruptible(plr->lock_thread_wq,
plr->thread_done == 1);
if (ret < 0) {
/*
* If the thread does not get on the CPU for whatever
* reason and the process which sets up the region is
* interrupted then this will leave the thread in runnable
* state and once it gets on the CPU it will dereference
* the cleared, but not freed, plr struct resulting in an
* empty pseudo-locking loop.
*/
rdt_last_cmd_puts("Locking thread interrupted\n");
goto out_cstates;
}
ret = pseudo_lock_minor_get(&new_minor);
if (ret < 0) {
rdt_last_cmd_puts("Unable to obtain a new minor number\n");
goto out_cstates;
}
/*
* Unlock access but do not release the reference. The
* pseudo-locked region will still be here on return.
*
* The mutex has to be released temporarily to avoid a potential
* deadlock with the mm->mmap_lock which is obtained in the
* device_create() and debugfs_create_dir() callpath below as well as
* before the mmap() callback is called.
*/
mutex_unlock(&rdtgroup_mutex);
if (!IS_ERR_OR_NULL(debugfs_resctrl)) {
plr->debugfs_dir = debugfs_create_dir(kn_name, debugfs_resctrl);
Annotation
- Immediate include surface: `linux/cacheinfo.h`, `linux/cpu.h`, `linux/cpumask.h`, `linux/debugfs.h`, `linux/kthread.h`, `linux/mman.h`, `linux/pm_qos.h`, `linux/resctrl.h`.
- Detected declarations: `struct pseudo_lock_pm_req`, `function pseudo_lock_minor_get`, `function pseudo_lock_minor_release`, `function list_for_each_entry`, `function pseudo_lock_cstates_relax`, `function list_for_each_entry_safe`, `function pseudo_lock_cstates_constrain`, `function for_each_cpu`, `function pseudo_lock_region_clear`, `function pseudo_lock_region_init`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.