mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 20:42:56 +01:00
Basic structure for GPGPU service.
This commit is contained in:
44
repos/mml/include/kiihdytin/gpgpu/client.h
Normal file
44
repos/mml/include/kiihdytin/gpgpu/client.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief CLient-side interface to a GPGPU session
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <base/rpc_client.h>
|
||||
#include <base/log.h>
|
||||
#include "session.h"
|
||||
#include "kernel.h"
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
struct Session_client;
|
||||
}
|
||||
|
||||
struct Kiihdytin::GPGPU::Session_client : Genode::Rpc_client<Kiihdytin::GPGPU::Session>
|
||||
{
|
||||
Session_client(Genode::Capability<Session> cap)
|
||||
: Genode::Rpc_client<Session>(cap) { }
|
||||
|
||||
void enqueue_kernel(Kernel &kernel) override {
|
||||
call<Rpc_enqueue_kernel>(kernel);
|
||||
}
|
||||
|
||||
void wait_for_kernel(Kernel &kernel) override {
|
||||
call<Rpc_wait_for_kernel>(kernel);
|
||||
}
|
||||
|
||||
void abort_kernel(Kernel &kernel) override {
|
||||
call<Rpc_abort_kernel>(kernel);
|
||||
}
|
||||
|
||||
void remove_kernel(Kernel &kernel) override {
|
||||
call<Rpc_remove_kernel>(kernel);
|
||||
}
|
||||
};
|
||||
30
repos/mml/include/kiihdytin/gpgpu/connection.h
Normal file
30
repos/mml/include/kiihdytin/gpgpu/connection.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Connection to GPGPU session
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include <base/connection.h>
|
||||
|
||||
namespace Kiihdytin::GPGPU { struct Connection; }
|
||||
|
||||
|
||||
struct Kiihdytin::GPGPU::Connection : Genode::Connection<Session>, Session_client
|
||||
{
|
||||
Connection(Genode::Env &env)
|
||||
:
|
||||
/* create session */
|
||||
Genode::Connection<Kiihdytin::GPGPU::Session>(env, session(env.parent(),
|
||||
"ram_quota=6K, cap_quota=4")), // TODO: determine correct ram and cap quota
|
||||
|
||||
/* initialize RPC interface */
|
||||
Session_client(cap()) { }
|
||||
};
|
||||
46
repos/mml/include/kiihdytin/gpgpu/kernel.h
Normal file
46
repos/mml/include/kiihdytin/gpgpu/kernel.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Definition of a GPGPU kernel, i.e. OpenCL-slang for an executable unit of code for an OpenCL device
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gpgpu_driver.h>
|
||||
#include <cstdint>
|
||||
#include <util/list.h>
|
||||
#include <driver/lib/chain.h>
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
|
||||
typedef uint8_t Kernel_image;
|
||||
/**
|
||||
* @class This class represents an OpenCL kernel
|
||||
*
|
||||
*/
|
||||
class Kernel : public Chain
|
||||
{
|
||||
private:
|
||||
struct kernel_config _configuration;
|
||||
Kernel_image *_image;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief get configuration for this kernel
|
||||
* @return reference to kernel configuration
|
||||
*/
|
||||
inline struct kernel_config &get_config() { return _configuration; }
|
||||
|
||||
/**
|
||||
* @brief get pointer to kernel image
|
||||
* @return pointer to kernel's binary image
|
||||
*/
|
||||
inline Kernel_image *get_image() { return _image; }
|
||||
};
|
||||
}
|
||||
92
repos/mml/include/kiihdytin/gpgpu/scheduler.h
Normal file
92
repos/mml/include/kiihdytin/gpgpu/scheduler.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* \brief Scheduler interface for the GPGPU, select which vGPU to choose next.
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <driver/lib/wf_queue.h>
|
||||
#include <driver/gpgpu_driver.h>
|
||||
#include <driver/ppgtt32.h>
|
||||
#include "vgpu.h"
|
||||
#include "kernel.h"
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
|
||||
class Scheduler
|
||||
{
|
||||
private:
|
||||
VGpu *_curr_vgpu;
|
||||
// GPGPU_Driver _driver; /* TODO: Use driver session */
|
||||
WFQueue _run_list;
|
||||
/* TODO: Define handler object for GPGPU driver session to receive interrupts. */
|
||||
|
||||
public:
|
||||
|
||||
Scheduler()
|
||||
{
|
||||
// TODO: Initialize GPU driver
|
||||
|
||||
// TODO: Register interrupt/event handler for the GPGPU driver session.
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select next vGPU from run list
|
||||
* @details At the moment, round-robin is the only implemented strategy.
|
||||
* TODO: Implement interface for strategies and strategies *
|
||||
*/
|
||||
void schedule_next() {
|
||||
VGpu *next;
|
||||
|
||||
if ((next = static_cast<VGpu*>(_run_list.dequeue()))) {
|
||||
this->dispatch(*next);
|
||||
_curr_vgpu = next;
|
||||
_run_list.enqueue(next);
|
||||
} else
|
||||
_curr_vgpu = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Switch to new vGPU's context
|
||||
*
|
||||
* @param vgpu - vGPU to switch to
|
||||
*/
|
||||
void dispatch(VGpu &vgpu) {
|
||||
// TODO: Implement context switch using GPGPU driver
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implmentation for the handling of events from the GPU
|
||||
* @details The handler is especially important for scheduling the next vGPU and for
|
||||
* executing kernels. It is the target for interrupts coming from the GPGPU driver, e.g. when
|
||||
* a kernel has finished its execution.
|
||||
*/
|
||||
void handle_gpu_event() {
|
||||
// TODO: Check for error conditions
|
||||
|
||||
// TODO: Handle finish of kernel
|
||||
|
||||
/* Switch to next vGPU in the run list */
|
||||
schedule_next();
|
||||
|
||||
/* If no vGPU to schedule, this means that we don't have any clients anymore.
|
||||
* Thus, there are also no kernels anymore to run. */
|
||||
if (_curr_vgpu == nullptr)
|
||||
return;
|
||||
|
||||
Kernel *next = _curr_vgpu->take_kernel();
|
||||
|
||||
if (!next) /* If there is no kernel for the vGPU left */
|
||||
schedule_next(); /* pick the next vGPU, maybe it has got some kernels for us. */
|
||||
|
||||
// TODO: execute kernel using GPGPU driver
|
||||
}
|
||||
};
|
||||
}
|
||||
44
repos/mml/include/kiihdytin/gpgpu/service.h
Normal file
44
repos/mml/include/kiihdytin/gpgpu/service.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Definition of the GPGPU service's root component
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <base/component.h>
|
||||
#include <root/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <util/list.h>
|
||||
#include "session_component.h"
|
||||
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
class Service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The GPGPU service provides multiplexed accesses to GPGPU functionality to its clients.
|
||||
*
|
||||
*/
|
||||
|
||||
class Kiihdytin::GPGPU::Session : public Genode::Root_component<Kiihdytin::GPGPU::Session_component>
|
||||
{
|
||||
private:
|
||||
Genode::List<Kiihdytin::GPGPU::Session_component> sessions;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char*) override {
|
||||
return new (md_alloc()) Session_component();
|
||||
}
|
||||
|
||||
public:
|
||||
Session(Genode::Entrypoint &ep, Genode::Allocator &alloc) : Genode::Root_component<Session_component>(ep, alloc) {}
|
||||
};
|
||||
54
repos/mml/include/kiihdytin/gpgpu/session.h
Normal file
54
repos/mml/include/kiihdytin/gpgpu/session.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* \brief Interface definition of a GPU session
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <session/session.h>
|
||||
#include <base/rpc.h>
|
||||
#include "vgpu.h"
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
class Session;
|
||||
}
|
||||
|
||||
class Kiihdytin::GPGPU::Session : Genode::Session
|
||||
{
|
||||
|
||||
private:
|
||||
VGpu &vgpu;
|
||||
|
||||
VGpu& create_vgpu();
|
||||
PPGTT32& create_ppgtt();
|
||||
|
||||
|
||||
public:
|
||||
static const char *service_name() { return "Kiihdytin::GPGPU"; }
|
||||
|
||||
enum { CAP_QUOTA = 2 }; // TODO: determine actual cap quota
|
||||
|
||||
Session() : vgpu(create_vgpu()) {}
|
||||
|
||||
/* Backend methods */
|
||||
virtual void enqueue_kernel(Kernel &kernel) = 0;
|
||||
virtual void wait_for_kernel(Kernel &kernel) = 0;
|
||||
virtual void abort_kernel(Kernel &kernel) = 0;
|
||||
virtual void remove_kernel(Kernel &kernel) = 0;
|
||||
|
||||
/* RPC interface */
|
||||
|
||||
GENODE_RPC(Rpc_enqueue_kernel, void, enqueue_kernel, Kernel&);
|
||||
GENODE_RPC(Rpc_wait_for_kernel, void, wait_for_kernel, Kernel &);
|
||||
GENODE_RPC(Rpc_abort_kernel, void, abort_kernel, Kernel &);
|
||||
GENODE_RPC(Rpc_remove_kernel, void, remove_kernel, Kernel &);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_enqueue_kernel, Rpc_remove_kernel, Rpc_wait_for_kernel, Rpc_abort_kernel);
|
||||
};
|
||||
31
repos/mml/include/kiihdytin/gpgpu/session_component.h
Normal file
31
repos/mml/include/kiihdytin/gpgpu/session_component.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* \brief RPC object for a GPGPU session
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include "session.h"
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
class Session_component;
|
||||
}
|
||||
|
||||
class Kiihdytin::GPGPU::Session_component : public Genode::Rpc_object<Kiihdytin::GPGPU::Session>
|
||||
{
|
||||
public:
|
||||
void enqueue_kernel(Kernel &kernel) override;
|
||||
void wait_for_kernel(Kernel &kernel) override;
|
||||
void abort_kernel(Kernel &kernel) override;
|
||||
void remove_kernel(Kernel &kernel) override;
|
||||
|
||||
};
|
||||
73
repos/mml/include/kiihdytin/gpgpu/vgpu.h
Normal file
73
repos/mml/include/kiihdytin/gpgpu/vgpu.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* \brief Representation of a "virtual" GPU, used as abstraction for the real thing.
|
||||
* \author Michael Müller
|
||||
* \date 2022-07-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU Affero General Public License version 3.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <driver/gpgpu_driver.h>
|
||||
#include "kernel.h"
|
||||
#include <driver/ppgtt32.h>
|
||||
#include <driver/lib/chain.h>
|
||||
#include <driver/lib/wf_queue.h>
|
||||
|
||||
namespace Kiihdytin::GPGPU {
|
||||
|
||||
class Context;
|
||||
|
||||
class VGpu : public Chain
|
||||
{
|
||||
private:
|
||||
// Context _context; TODO: implement context images
|
||||
PPGTT32 &_ppgtt;
|
||||
WFQueue _ready_list;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new VGpu object
|
||||
*
|
||||
* @param ppgtt - PPGTT mapping phyisical addresses from the client's rm space to gpu addresses
|
||||
*/
|
||||
VGpu(PPGTT32 &ppgtt) : _ppgtt(ppgtt) {}
|
||||
|
||||
/**
|
||||
* @brief Add a kernel to the vGPU's ready list
|
||||
*
|
||||
* @param kernel - the kernel object to enqueue
|
||||
*/
|
||||
void add_kernel(Kernel &kernel) {
|
||||
_ready_list.enqueue(&kernel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get saved GPU context for this VGPU
|
||||
*
|
||||
* @return GPU context image for this VGPU
|
||||
* TODO: implement saving the context of the GPU using the GPGPU driver
|
||||
*/
|
||||
Context get_context();
|
||||
|
||||
/**
|
||||
* @brief Dequeue a kernel from the ready list
|
||||
*
|
||||
* @return First kernel image in ready list
|
||||
*/
|
||||
Kernel *take_kernel() { return static_cast<Kernel*>(_ready_list.dequeue()); }
|
||||
|
||||
/**
|
||||
* @brief Get the ppgtt object
|
||||
*
|
||||
* @return PPGTT
|
||||
*/
|
||||
PPGTT32 &get_ppgtt() { return _ppgtt; }
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user