drivers/misc/sgi-gru/grumain.c
Source file repositories/reference/linux-study-clean/drivers/misc/sgi-gru/grumain.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/sgi-gru/grumain.c- Extension
.c- Size
- 25880 bytes
- Lines
- 970
- Domain
- Driver Families
- Bucket
- drivers/misc
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/kernel.hlinux/slab.hlinux/mm.hlinux/spinlock.hlinux/sched.hlinux/device.hlinux/list.hlinux/err.hlinux/prefetch.hasm/uv/uv_hub.hgru.hgrutables.hgruhandles.h
Detected Declarations
function gru_cpu_fault_map_idfunction usefunction gru_reset_asid_limitfunction gru_assign_asidfunction reserve_resourcesfunction gru_reserve_cb_resourcesfunction gru_reserve_ds_resourcesfunction reserve_gru_resourcesfunction free_gru_resourcesfunction check_gru_resourcesfunction gru_load_mm_trackerfunction gru_unload_mm_trackerfunction gts_dropfunction gru_free_gru_contextfunction prefetch_datafunction gru_copy_handlefunction gru_prefetch_contextfunction for_each_cbr_in_allocation_mapfunction gru_load_context_datafunction for_each_cbr_in_allocation_mapfunction gru_unload_context_datafunction for_each_cbr_in_allocation_mapfunction gru_unload_contextfunction gru_load_contextfunction gru_update_cchfunction gru_retarget_intrfunction gru_check_chiplet_assignmentfunction gru_check_context_placementfunction is_gts_stealablefunction gts_stolenfunction gru_steal_contextfunction gru_assign_context_numberfunction gru_fault
Annotated Snippet
static struct device_driver gru_driver = {
.name = "gru"
};
static struct device gru_device = {
.init_name = "",
.driver = &gru_driver,
};
struct device *grudev = &gru_device;
/*
* Select a gru fault map to be used by the current cpu. Note that
* multiple cpus may be using the same map.
* ZZZ should be inline but did not work on emulator
*/
int gru_cpu_fault_map_id(void)
{
int cpu = smp_processor_id();
int id, core;
core = uv_cpu_core_number(cpu);
id = core + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
return id;
}
/*--------- ASID Management -------------------------------------------
*
* Initially, assign asids sequentially from MIN_ASID .. MAX_ASID.
* Once MAX is reached, flush the TLB & start over. However,
* some asids may still be in use. There won't be many (percentage wise) still
* in use. Search active contexts & determine the value of the first
* asid in use ("x"s below). Set "limit" to this value.
* This defines a block of assignable asids.
*
* When "limit" is reached, search forward from limit+1 and determine the
* next block of assignable asids.
*
* Repeat until MAX_ASID is reached, then start over again.
*
* Each time MAX_ASID is reached, increment the asid generation. Since
* the search for in-use asids only checks contexts with GRUs currently
* assigned, asids in some contexts will be missed. Prior to loading
* a context, the asid generation of the GTS asid is rechecked. If it
* doesn't match the current generation, a new asid will be assigned.
*
* 0---------------x------------x---------------------x----|
* ^-next ^-limit ^-MAX_ASID
*
* All asid manipulation & context loading/unloading is protected by the
* gs_lock.
*/
/* Hit the asid limit. Start over */
static int gru_wrap_asid(struct gru_state *gru)
{
gru_dbg(grudev, "gid %d\n", gru->gs_gid);
STAT(asid_wrap);
gru->gs_asid_gen++;
return MIN_ASID;
}
/* Find the next chunk of unused asids */
static int gru_reset_asid_limit(struct gru_state *gru, int asid)
{
int i, gid, inuse_asid, limit;
gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
STAT(asid_next);
limit = MAX_ASID;
if (asid >= limit)
asid = gru_wrap_asid(gru);
gru_flush_all_tlb(gru);
gid = gru->gs_gid;
again:
for (i = 0; i < GRU_NUM_CCH; i++) {
if (!gru->gs_gts[i] || is_kernel_context(gru->gs_gts[i]))
continue;
inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid;
gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms,
inuse_asid, i);
if (inuse_asid == asid) {
asid += ASID_INC;
if (asid >= limit) {
/*
* empty range: reset the range limit and
* start over
*/
limit = MAX_ASID;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/mm.h`, `linux/spinlock.h`, `linux/sched.h`, `linux/device.h`, `linux/list.h`, `linux/err.h`.
- Detected declarations: `function gru_cpu_fault_map_id`, `function use`, `function gru_reset_asid_limit`, `function gru_assign_asid`, `function reserve_resources`, `function gru_reserve_cb_resources`, `function gru_reserve_ds_resources`, `function reserve_gru_resources`, `function free_gru_resources`, `function check_gru_resources`.
- Atlas domain: Driver Families / drivers/misc.
- Implementation status: pattern implementation candidate.
- 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.