gpu/intel: remove vgpus from schedule before destruction

When a GPU session is destroyed, remove vgpu of session from scheduling
and as possible active vgpu. Otherwise, page faults might occur in case
already destroyed vgpu object is referenced during interrupt handling.

fixes #4881
This commit is contained in:
Sebastian Sumpf 2023-05-10 19:37:29 +02:00 committed by Christian Helmuth
parent e64f2eaff9
commit ae19ab0cff

View File

@ -974,9 +974,14 @@ struct Igd::Device
Vgpu *_unschedule_current_vgpu()
{
if (_active_vgpu == nullptr) return nullptr;
Vgpu *result = nullptr;
_vgpu_list.dequeue([&] (Vgpu &head) {
result = &head; });
_active_vgpu = nullptr;
return result;
}
@ -1382,11 +1387,19 @@ struct Igd::Device
*/
bool vgpu_active(Vgpu const &vgpu) const
{
bool result = false;
_vgpu_list.head([&] (Vgpu const &curr) {
result = (&vgpu == &curr);
});
return result;
return _active_vgpu == &vgpu;
}
/**
* Remove VGPU from scheduling list, if it is enqeued
*/
void vgpu_unschedule(Vgpu &vgpu)
{
if (vgpu_active(vgpu)) _active_vgpu = nullptr;
if (vgpu.enqueued())
_vgpu_list.remove(vgpu);
}
/*******************
@ -1542,7 +1555,6 @@ struct Igd::Device
if (user_complete) {
_unschedule_current_vgpu();
_active_vgpu = nullptr;
if (notify_gpu) {
if (!_notify_complete(notify_gpu)) {
@ -1874,6 +1886,11 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
return _device.vgpu_active(_vgpu);
}
void vgpu_unschedule()
{
return _device.vgpu_unschedule(_vgpu);
}
/***************************
** Gpu session interface **
***************************/
@ -2211,6 +2228,9 @@ class Gpu::Root : public Gpu::Root_component
Genode::warning("vGPU active, reset device and hope for the best");
_device->reset();
}
/* remove from scheduled list */
s->vgpu_unschedule();
Genode::destroy(md_alloc(), s);
}