gpu/intel: handle double insertion in PPGTT

As the PPGTT is populated by the client, the client has to account for
guard pages and so forth.

Issue  
This commit is contained in:
Josef Söntgen 2017-09-05 14:03:36 +02:00 committed by Christian Helmuth
parent 7dc997c8e6
commit 4b653fbac1
3 changed files with 20 additions and 13 deletions
repos/os
include/gpu_session
src/drivers/gpu/intel

@ -30,7 +30,8 @@ struct Gpu::Connection : Genode::Connection<Session>, Session_client
Genode::Capability<Gpu::Session> _session(Genode::Parent &parent,
char const *label, Genode::size_t quota)
{
return session(parent, "ram_quota=%ld, label=\"%s\"", quota, label);
return session(parent, "ram_quota=%ld, cap_quota=%ld, label=\"%s\"",
quota, CAP_QUOTA, label);
}
/**

@ -65,6 +65,7 @@ struct Gpu::Session : public Genode::Session
struct Out_of_ram : Genode::Exception { };
struct Out_of_caps : Genode::Exception { };
struct Invalid_state : Genode::Exception { };
struct Mapping_buffer_failed : Genode::Exception { };
enum { REQUIRED_QUOTA = 1024 * 1024, CAP_QUOTA = 8, };
@ -124,6 +125,8 @@ struct Gpu::Session : public Genode::Session
* \param ds dataspace capability for buffer
* \param aperture if true create CPU accessible mapping through
* GGTT window, otherwise create PPGTT mapping
*
* \throw Mapping_buffer_failed
*/
virtual Genode::Dataspace_capability map_buffer(Genode::Dataspace_capability ds,
bool aperture) = 0;
@ -140,6 +143,9 @@ struct Gpu::Session : public Genode::Session
*
* \param ds dataspace capability for buffer
* \param va virtual address
*
* \throw Mapping_buffer_failed
* \throw Out_of_ram
*/
virtual bool map_buffer_ppgtt(Genode::Dataspace_capability ds,
Gpu::addr_t va) = 0;
@ -174,12 +180,12 @@ struct Gpu::Session : public Genode::Session
Genode::size_t);
GENODE_RPC(Rpc_free_buffer, void, free_buffer, Genode::Dataspace_capability);
GENODE_RPC_THROW(Rpc_map_buffer, Genode::Dataspace_capability, map_buffer,
GENODE_TYPE_LIST(Out_of_ram),
GENODE_TYPE_LIST(Mapping_buffer_failed, Out_of_ram),
Genode::Dataspace_capability, bool);
GENODE_RPC(Rpc_unmap_buffer, void, unmap_buffer,
Genode::Dataspace_capability);
GENODE_RPC_THROW(Rpc_map_buffer_ppgtt, bool, map_buffer_ppgtt,
GENODE_TYPE_LIST(Out_of_ram),
GENODE_TYPE_LIST(Mapping_buffer_failed, Out_of_ram),
Genode::Dataspace_capability, Gpu::addr_t);
GENODE_RPC(Rpc_unmap_buffer_ppgtt, void, unmap_buffer_ppgtt,
Genode::Dataspace_capability, Gpu::addr_t);

@ -796,8 +796,8 @@ struct Igd::Device
} catch (Igd::Ppgtt_allocator::Out_of_memory) {
throw Igd::Device::Out_of_ram();
} catch (...) {
Genode::log(__func__, ": unknown exception");
throw;
/* Double_insertion and the like */
throw Igd::Device::Could_not_map_buffer();
}
}
@ -1560,21 +1560,21 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
buffer.ppgtt_va_valid = true;
result = OK;
} catch (Igd::Device::Could_not_map_buffer) {
/* FIXME do not result in Out_of_ram */
Genode::error("could not map buffer object into PPGTT");
Genode::error("could not map buffer object (", Genode::Hex(va), ") into PPGTT");
result = MAP_FAILED;
return;
}
/* will throw below */
catch (Igd::Device::Out_of_ram) { return; }
catch (Igd::Device::Out_of_ram) {
result = ALLOC_FAILED;
return;
}
};
_buffer_registry.for_each(lookup_and_map);
switch (result) {
case ALLOC_FAILED:
throw Gpu::Session::Out_of_ram();
case OK:
return true;
case ALLOC_FAILED: throw Gpu::Session::Out_of_ram();
case MAP_FAILED: throw Gpu::Session::Mapping_buffer_failed();
case OK: return true;
default:
return false;
}