Skip to content

Commit 10e6928

Browse files
committed
drm/asahi: Implement GEM objects sharing a single DMA resv
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 6d841dd commit 10e6928

3 files changed

Lines changed: 27 additions & 25 deletions

File tree

drivers/gpu/drm/asahi/file.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,21 +399,21 @@ impl File {
399399
return Err(EINVAL);
400400
}
401401

402-
let vm_id = if data.flags & uapi::ASAHI_GEM_VM_PRIVATE != 0 {
402+
let resv_obj = if data.flags & uapi::ASAHI_GEM_VM_PRIVATE != 0 {
403403
Some(
404404
file.inner()
405405
.vms()
406406
.get(data.vm_id.try_into()?)
407407
.ok_or(ENOENT)?
408408
.borrow()
409409
.vm
410-
.id(),
410+
.get_resv_obj(),
411411
)
412412
} else {
413413
None
414414
};
415415

416-
let bo = gem::new_object(device, data.size.try_into()?, data.flags, vm_id)?;
416+
let bo = gem::new_object(device, data.size.try_into()?, data.flags, resv_obj.as_ref())?;
417417

418418
let handle = bo.gem.create_handle(file)?;
419419
data.handle = handle;

drivers/gpu/drm/asahi/gem.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ pub(crate) struct DriverObject {
3030
kernel: bool,
3131
/// Object creation flags.
3232
flags: u32,
33-
/// VM ID for VM-private objects.
34-
vm_id: Option<u64>,
3533
/// ID for debug
3634
id: u64,
3735
}
@@ -82,12 +80,10 @@ impl ObjectRef {
8280
prot: u32,
8381
guard: bool,
8482
) -> Result<crate::mmu::KernelMapping> {
85-
let vm_id = vm.id();
86-
87-
if self.gem.vm_id.is_some() && self.gem.vm_id != Some(vm_id) {
83+
// Only used for kernel objects now
84+
if !self.gem.kernel {
8885
return Err(EINVAL);
8986
}
90-
9187
vm.map_in_range(self.gem.size(), &self.gem, alignment, range, prot, guard)
9288
}
9389

@@ -101,9 +97,7 @@ impl ObjectRef {
10197
prot: u32,
10298
guard: bool,
10399
) -> Result<crate::mmu::KernelMapping> {
104-
let vm_id = vm.id();
105-
106-
if self.gem.vm_id.is_some() && self.gem.vm_id != Some(vm_id) {
100+
if self.gem.flags & uapi::ASAHI_GEM_VM_PRIVATE != 0 && vm.is_extobj(&self.gem) {
107101
return Err(EINVAL);
108102
}
109103

@@ -128,21 +122,23 @@ pub(crate) fn new_object(
128122
dev: &AsahiDevice,
129123
size: usize,
130124
flags: u32,
131-
vm_id: Option<u64>,
125+
parent_object: Option<&gem::ObjectRef<Object>>,
132126
) -> Result<ObjectRef> {
127+
if (flags & uapi::ASAHI_GEM_VM_PRIVATE != 0) != parent_object.is_some() {
128+
return Err(EINVAL);
129+
}
130+
133131
let mut gem = shmem::Object::<DriverObject>::new(dev, align(size, mmu::UAT_PGSZ))?;
134132
gem.kernel = false;
135133
gem.flags = flags;
136-
gem.vm_id = vm_id;
137134

138-
gem.set_exportable(vm_id.is_none());
135+
gem.set_exportable(parent_object.is_none());
139136
gem.set_wc(flags & uapi::ASAHI_GEM_WRITEBACK == 0);
137+
if let Some(parent) = parent_object {
138+
gem.share_dma_resv(&**parent)?;
139+
}
140140

141-
mod_pr_debug!(
142-
"DriverObject new user object: vm_id={:?} id={}\n",
143-
vm_id,
144-
gem.id
145-
);
141+
mod_pr_debug!("DriverObject new user object: id={}\n", gem.id);
146142
Ok(ObjectRef::new(gem.into_ref()))
147143
}
148144

@@ -161,14 +157,13 @@ impl gem::BaseDriverObject<Object> for DriverObject {
161157
try_pin_init!(DriverObject {
162158
kernel: false,
163159
flags: 0,
164-
vm_id: None,
165160
id,
166161
})
167162
}
168163

169164
/// Callback to drop all mappings for a GEM object owned by a given `File`
170165
fn close(obj: &Object, file: &DrmFile) {
171-
mod_pr_debug!("DriverObject::close vm_id={:?} id={}\n", obj.vm_id, obj.id);
166+
mod_pr_debug!("DriverObject::close id={}\n", obj.id);
172167
if file::File::unbind_gem_object(file, obj).is_err() {
173168
pr_err!("DriverObject::close: Failed to unbind GEM object\n");
174169
}

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ impl VmInner {
522522
pub(crate) struct Vm {
523523
id: u64,
524524
inner: ARef<gpuvm::GpuVm<VmInner>>,
525+
dummy_obj: drm::gem::ObjectRef<gem::Object>,
525526
binding: Arc<Mutex<VmBinding>>,
526527
}
527528
no_debug!(Vm);
@@ -1041,6 +1042,7 @@ impl Vm {
10411042
let binding_clone = binding.clone();
10421043
Ok(Vm {
10431044
id,
1045+
dummy_obj: dummy_obj.gem.clone(),
10441046
inner: gpuvm::GpuVm::new(
10451047
c_str!("Asahi::GpuVm"),
10461048
dev,
@@ -1287,9 +1289,14 @@ impl Vm {
12871289
Ok(())
12881290
}
12891291

1290-
/// Returns the unique ID of this Vm
1291-
pub(crate) fn id(&self) -> u64 {
1292-
self.id
1292+
/// Returns the dummy GEM object used to hold the shared DMA reservation locks
1293+
pub(crate) fn get_resv_obj(&self) -> drm::gem::ObjectRef<gem::Object> {
1294+
self.dummy_obj.clone()
1295+
}
1296+
1297+
/// Check whether an object is external to this GpuVm
1298+
pub(crate) fn is_extobj(&self, gem: &gem::Object) -> bool {
1299+
self.inner.is_extobj(gem)
12931300
}
12941301
}
12951302

0 commit comments

Comments
 (0)