fix: deadlock in virgl_resource_create_blob, remove Box::leak
BUG 1: virgl_resource_create_blob held device lock while calling self.gem_create() which internally tries to lock device again. Rust std::sync::Mutex is not reentrant — guaranteed deadlock. Fix: release device lock before calling gem_create, using a scoped block for the has_resource_blob feature check. BUG 2: Box::leak in atomic_commit error paths converted dynamically-formatted strings to &'static str at the cost of a memory leak per error. Replaced with static &str literals.
This commit is contained in:
@@ -902,12 +902,14 @@ impl GpuDriver for VirtioDriver {
|
|||||||
fn virgl_resource_create_blob(
|
fn virgl_resource_create_blob(
|
||||||
&self, blob_mem: u32, blob_flags: u32, blob_id: u64, size: u64,
|
&self, blob_mem: u32, blob_flags: u32, blob_id: u64, size: u64,
|
||||||
) -> Result<(GemHandle, u32)> {
|
) -> Result<(GemHandle, u32)> {
|
||||||
let mut device = self
|
{
|
||||||
.device
|
let device = self
|
||||||
.lock()
|
.device
|
||||||
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
.lock()
|
||||||
if !device.has_resource_blob {
|
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
||||||
return Err(DriverError::Unsupported("virgl blob resource create"));
|
if !device.has_resource_blob {
|
||||||
|
return Err(DriverError::Unsupported("virgl blob resource create"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let gem_handle = self.gem_create(size, 0, 0)?;
|
let gem_handle = self.gem_create(size, 0, 0)?;
|
||||||
let resource = self
|
let resource = self
|
||||||
@@ -916,6 +918,10 @@ impl GpuDriver for VirtioDriver {
|
|||||||
.map_err(|_| DriverError::Initialization("VirtIO resource state poisoned".into()))?
|
.map_err(|_| DriverError::Initialization("VirtIO resource state poisoned".into()))?
|
||||||
.find_by_handle(gem_handle)
|
.find_by_handle(gem_handle)
|
||||||
.ok_or(DriverError::NotFound(format!("resource for GEM handle {}", gem_handle)))?;
|
.ok_or(DriverError::NotFound(format!("resource for GEM handle {}", gem_handle)))?;
|
||||||
|
let mut device = self
|
||||||
|
.device
|
||||||
|
.lock()
|
||||||
|
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
||||||
device.resource_create_blob(resource.resource_id, blob_mem, blob_flags, blob_id, size)?;
|
device.resource_create_blob(resource.resource_id, blob_mem, blob_flags, blob_id, size)?;
|
||||||
Ok((gem_handle, resource.resource_id))
|
Ok((gem_handle, resource.resource_id))
|
||||||
}
|
}
|
||||||
@@ -1016,14 +1022,14 @@ impl GpuDriver for VirtioDriver {
|
|||||||
return Err(DriverError::NotFound(format!("CRTC {}", crtc_id)));
|
return Err(DriverError::NotFound(format!("CRTC {}", crtc_id)));
|
||||||
}
|
}
|
||||||
AtomicCheckResult::InvalidMode { crtc_id, reason } => {
|
AtomicCheckResult::InvalidMode { crtc_id, reason } => {
|
||||||
return Err(DriverError::InvalidArgument(Box::leak(
|
return Err(DriverError::InvalidArgument(
|
||||||
format!("CRTC {} invalid mode: {}", crtc_id, reason).into_boxed_str(),
|
"atomic mode validation failed",
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
AtomicCheckResult::ClockTooHigh { crtc_id, .. } => {
|
AtomicCheckResult::ClockTooHigh { crtc_id, .. } => {
|
||||||
return Err(DriverError::InvalidArgument(Box::leak(
|
return Err(DriverError::InvalidArgument(
|
||||||
format!("CRTC {} pixel clock exceeds hardware limit", crtc_id).into_boxed_str(),
|
"atomic pixel clock exceeds hardware limit",
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
AtomicCheckResult::ConnectorDisconnected { connector_id } => {
|
AtomicCheckResult::ConnectorDisconnected { connector_id } => {
|
||||||
return Err(DriverError::Initialization(format!(
|
return Err(DriverError::Initialization(format!(
|
||||||
|
|||||||
Reference in New Issue
Block a user