drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c- Extension
.c- Size
- 15153 bytes
- Lines
- 604
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
vmwgfx_vkms.hvmwgfx_bo.hvmwgfx_drv.hvmwgfx_kms.hvmw_surface_cache.hdrm/drm_crtc.hdrm/drm_debugfs_crc.hdrm/drm_print.hdrm/drm_vblank.hlinux/crc32.hlinux/delay.h
Detected Declarations
enum vmw_vkms_lock_statefunction Copyrightfunction compute_crcfunction crc_generate_workerfunction vmw_vkms_handle_vblank_timeoutfunction vmw_vkms_initfunction vmw_vkms_cleanupfunction vmw_vkms_get_vblank_timestampfunction vmw_vkms_enable_vblankfunction vmw_vkms_disable_vblankfunction vmw_vkms_crtc_initfunction vmw_vkms_crtc_cleanupfunction vmw_vkms_crtc_atomic_beginfunction vmw_vkms_crtc_atomic_flushfunction vmw_vkms_crtc_atomic_enablefunction vmw_vkms_crtc_atomic_disablefunction is_crc_supportedfunction crc_parse_sourcefunction vmw_vkms_get_crc_sourcesfunction vmw_vkms_verify_crc_sourcefunction vmw_vkms_set_crc_sourcefunction vmw_vkms_set_crc_surfacefunction vmw_vkms_lock_max_wait_nsfunction contextfunction vmw_vkms_modeset_lock_relaxedfunction vmw_vkms_vblank_trylockfunction vmw_vkms_unlock
Annotated Snippet
if (vmw_surface_sync(vmw, surf)) {
drm_warn(
crtc->dev,
"CRC worker wasn't able to sync the crc surface!\n");
return;
}
compute_crc(crtc, surf, &crc32);
vmw_surface_unreference(&surf);
}
spin_lock_irq(&du->vkms.crc_state_lock);
frame_start = du->vkms.frame_start;
frame_end = du->vkms.frame_end;
du->vkms.frame_start = 0;
du->vkms.frame_end = 0;
du->vkms.crc_pending = false;
spin_unlock_irq(&du->vkms.crc_state_lock);
/*
* The worker can fall behind the vblank hrtimer, make sure we catch up.
*/
while (frame_start <= frame_end)
drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32);
}
bool
vmw_vkms_handle_vblank_timeout(struct drm_crtc *crtc)
{
struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
struct vmw_private *vmw = vmw_priv(crtc->dev);
bool has_surface = false;
bool locked, ret;
locked = vmw_vkms_vblank_trylock(crtc);
ret = drm_crtc_handle_vblank(crtc);
WARN_ON(!ret);
if (!locked)
return true;
has_surface = du->vkms.surface != NULL;
vmw_vkms_unlock(crtc);
if (du->vkms.crc_enabled && has_surface) {
u64 frame = drm_crtc_accurate_vblank_count(crtc);
spin_lock(&du->vkms.crc_state_lock);
if (!du->vkms.crc_pending)
du->vkms.frame_start = frame;
else
drm_dbg_driver(crtc->dev,
"crc worker falling behind, frame_start: %llu, frame_end: %llu\n",
du->vkms.frame_start, frame);
du->vkms.frame_end = frame;
du->vkms.crc_pending = true;
spin_unlock(&du->vkms.crc_state_lock);
ret = queue_work(vmw->crc_workq, &du->vkms.crc_generator_work);
if (!ret)
drm_dbg_driver(crtc->dev, "Composer worker already queued\n");
}
return true;
}
void
vmw_vkms_init(struct vmw_private *vmw)
{
char buffer[64];
const size_t max_buf_len = sizeof(buffer) - 1;
size_t buf_len = max_buf_len;
int ret;
vmw->vkms_enabled = false;
ret = vmw_host_get_guestinfo(GUESTINFO_VBLANK, buffer, &buf_len);
if (ret || buf_len > max_buf_len)
return;
buffer[buf_len] = '\0';
ret = kstrtobool(buffer, &vmw->vkms_enabled);
if (!ret && vmw->vkms_enabled) {
ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS);
vmw->vkms_enabled = (ret == 0);
}
vmw->crc_workq = alloc_ordered_workqueue("vmwgfx_crc_generator", 0);
if (!vmw->crc_workq) {
drm_warn(&vmw->drm, "crc workqueue allocation failed. Disabling vkms.");
vmw->vkms_enabled = false;
}
Annotation
- Immediate include surface: `vmwgfx_vkms.h`, `vmwgfx_bo.h`, `vmwgfx_drv.h`, `vmwgfx_kms.h`, `vmw_surface_cache.h`, `drm/drm_crtc.h`, `drm/drm_debugfs_crc.h`, `drm/drm_print.h`.
- Detected declarations: `enum vmw_vkms_lock_state`, `function Copyright`, `function compute_crc`, `function crc_generate_worker`, `function vmw_vkms_handle_vblank_timeout`, `function vmw_vkms_init`, `function vmw_vkms_cleanup`, `function vmw_vkms_get_vblank_timestamp`, `function vmw_vkms_enable_vblank`, `function vmw_vkms_disable_vblank`.
- 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.