Basic structure for GPGPU service.

This commit is contained in:
Michael Müller
2022-07-18 12:37:37 +02:00
parent 024e774e46
commit b9c3f29740
8 changed files with 414 additions and 0 deletions

View 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);
}
};

View 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()) { }
};

View 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; }
};
}

View 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
}
};
}

View 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) {}
};

View 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);
};

View 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;
};

View 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; }
};
}