drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c- Extension
.c- Size
- 6468 bytes
- Lines
- 211
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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
vmwgfx_drv.hdrm/ttm/ttm_placement.hlinux/idr.hlinux/spinlock.hlinux/kernel.h
Detected Declarations
struct vmwgfx_gmrid_manfunction vmw_gmrid_man_get_nodefunction vmw_gmrid_man_put_nodefunction vmw_gmrid_man_debugfunction vmw_gmrid_man_initfunction vmw_gmrid_man_fini
Annotated Snippet
struct vmwgfx_gmrid_man {
struct ttm_resource_manager manager;
spinlock_t lock;
struct ida gmr_ida;
uint32_t max_gmr_ids;
uint32_t max_gmr_pages;
uint32_t used_gmr_pages;
uint8_t type;
};
static struct vmwgfx_gmrid_man *to_gmrid_manager(struct ttm_resource_manager *man)
{
return container_of(man, struct vmwgfx_gmrid_man, manager);
}
static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res)
{
struct vmwgfx_gmrid_man *gman = to_gmrid_manager(man);
int id;
*res = kmalloc_obj(**res);
if (!*res)
return -ENOMEM;
ttm_resource_init(bo, place, *res);
id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
if (id < 0) {
ttm_resource_fini(man, *res);
kfree(*res);
return id;
}
spin_lock(&gman->lock);
if (gman->max_gmr_pages > 0) {
gman->used_gmr_pages += PFN_UP((*res)->size);
/*
* Because the graphics memory is a soft limit we can try to
* expand it instead of letting the userspace apps crash.
* We're just going to have a sane limit (half of RAM)
* on the number of MOB's that we create and will try to keep
* the system running until we reach that.
*/
if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages)) {
const unsigned long max_graphics_pages = totalram_pages() / 2;
uint32_t new_max_pages = 0;
DRM_WARN("vmwgfx: mob memory overflow. Consider increasing guest RAM and graphicsMemory.\n");
vmw_host_printf("vmwgfx, warning: mob memory overflow. Consider increasing guest RAM and graphicsMemory.\n");
if (gman->max_gmr_pages > (max_graphics_pages / 2)) {
DRM_WARN("vmwgfx: guest requires more than half of RAM for graphics.\n");
new_max_pages = max_graphics_pages;
} else
new_max_pages = gman->max_gmr_pages * 2;
if (new_max_pages > gman->max_gmr_pages && new_max_pages >= gman->used_gmr_pages) {
DRM_WARN("vmwgfx: increasing guest mob limits to %u KiB.\n",
((new_max_pages) << (PAGE_SHIFT - 10)));
gman->max_gmr_pages = new_max_pages;
} else {
char buf[256];
snprintf(buf, sizeof(buf),
"vmwgfx, error: guest graphics is out of memory (mob limit at: %u KiB).\n",
((gman->max_gmr_pages) << (PAGE_SHIFT - 10)));
vmw_host_printf(buf);
DRM_WARN("%s", buf);
goto nospace;
}
}
}
(*res)->start = id;
spin_unlock(&gman->lock);
return 0;
nospace:
gman->used_gmr_pages -= PFN_UP((*res)->size);
spin_unlock(&gman->lock);
ida_free(&gman->gmr_ida, id);
ttm_resource_fini(man, *res);
kfree(*res);
return -ENOSPC;
}
Annotation
- Immediate include surface: `vmwgfx_drv.h`, `drm/ttm/ttm_placement.h`, `linux/idr.h`, `linux/spinlock.h`, `linux/kernel.h`.
- Detected declarations: `struct vmwgfx_gmrid_man`, `function vmw_gmrid_man_get_node`, `function vmw_gmrid_man_put_node`, `function vmw_gmrid_man_debug`, `function vmw_gmrid_man_init`, `function vmw_gmrid_man_fini`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source 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.