From 6bb6957dab9e5fab126cd1666467a98c1008d9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20L=C3=BCtke=20Dreimann?= Date: Wed, 25 Jan 2023 17:12:16 +0100 Subject: [PATCH] updated scheduling data structures --- .../src/gpgpu/gpgpu_genode.cc | 1 - repos/dde_uos-intel-gpgpu/src/gpgpu/main.cc | 7 +- repos/dde_uos-intel-gpgpu/src/gpgpu/target.mk | 4 +- repos/dde_uos-intel-gpgpu/src/virt/rpc.cc | 8 +- .../dde_uos-intel-gpgpu/src/virt/scheduler.h | 23 +++- .../dde_uos-intel-gpgpu/src/virt/strategie.h | 7 ++ .../src/virt/strategies/cfs.cc | 110 +++++++++++------- .../src/virt/strategies/cfs.h | 33 ++++-- .../src/virt/strategies/cfs_entry.h | 17 +++ .../src/virt/strategies/config.h | 6 + .../src/virt/strategies/rr.cc | 10 +- .../src/virt/strategies/rr.h | 11 +- repos/dde_uos-intel-gpgpu/src/virt/vgpu.h | 15 ++- 13 files changed, 179 insertions(+), 73 deletions(-) create mode 100644 repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs_entry.h create mode 100644 repos/dde_uos-intel-gpgpu/src/virt/strategies/config.h diff --git a/repos/dde_uos-intel-gpgpu/src/gpgpu/gpgpu_genode.cc b/repos/dde_uos-intel-gpgpu/src/gpgpu/gpgpu_genode.cc index 3b0ec70090..71a0100772 100644 --- a/repos/dde_uos-intel-gpgpu/src/gpgpu/gpgpu_genode.cc +++ b/repos/dde_uos-intel-gpgpu/src/gpgpu/gpgpu_genode.cc @@ -4,7 +4,6 @@ #include "../uos-intel-gpgpu/driver/gpgpu_driver.h" #include "../virt/scheduler.h" -#include "../virt/strategies/rr.h" extern gpgpu_virt::GPGPUScheduler* _global_sched; namespace gpgpu diff --git a/repos/dde_uos-intel-gpgpu/src/gpgpu/main.cc b/repos/dde_uos-intel-gpgpu/src/gpgpu/main.cc index d3477d9f05..a4445ee978 100644 --- a/repos/dde_uos-intel-gpgpu/src/gpgpu/main.cc +++ b/repos/dde_uos-intel-gpgpu/src/gpgpu/main.cc @@ -2,7 +2,6 @@ #include "../virt/rpc.h" #include "../virt/scheduler.h" -#include "../virt/strategies/rr.h" #define GENODE // use genodes stdint header #include "../uos-intel-gpgpu/driver/gpgpu_driver.h" @@ -97,5 +96,11 @@ void Component::construct(Genode::Env& e) Genode::log("Register RPCs..."); static gpgpu_virt::Main main(e); +#ifdef SCHED_CFS + Genode::log("Scheduler is using CFS policy!"); +#else + Genode::log("Scheduler is using RR policy!"); +#endif // SCHED_CFS + Genode::log("This is the UOS Intel GPGPU End!"); } diff --git a/repos/dde_uos-intel-gpgpu/src/gpgpu/target.mk b/repos/dde_uos-intel-gpgpu/src/gpgpu/target.mk index 11d8619622..6fa08873ee 100644 --- a/repos/dde_uos-intel-gpgpu/src/gpgpu/target.mk +++ b/repos/dde_uos-intel-gpgpu/src/gpgpu/target.mk @@ -7,9 +7,9 @@ LIBS = base UOS_INTEL_GPGPU = uos-intel-gpgpu-link-cxx.o EXT_OBJECTS = $(BUILD_BASE_DIR)/bin/$(UOS_INTEL_GPGPU) -$(TARGET): $(UOS_INTEL_GPGPU) +$(TARGET): $(UOS_INTEL_GPGPU) $(SRC_CC) ../virt/strategies/config.h -$(UOS_INTEL_GPGPU): $(SRC_CC) +$(UOS_INTEL_GPGPU): $(MSG_BUILD) "Building uos-intel-gpgpu..." $(MAKE) -C $(REP_DIR)/src/uos-intel-gpgpu/ cp $(REP_DIR)/src/uos-intel-gpgpu/build/$(UOS_INTEL_GPGPU) $(BUILD_BASE_DIR)/bin/. diff --git a/repos/dde_uos-intel-gpgpu/src/virt/rpc.cc b/repos/dde_uos-intel-gpgpu/src/virt/rpc.cc index ec8684fe30..852bef3ece 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/rpc.cc +++ b/repos/dde_uos-intel-gpgpu/src/virt/rpc.cc @@ -10,7 +10,6 @@ #include "../gpgpu/gpgpu_genode.h" extern gpgpu::gpgpu_genode* _global_gpgpu_genode; #include "scheduler.h" -#include "strategies/rr.h" extern gpgpu_virt::GPGPUScheduler* _global_sched; // driver @@ -65,8 +64,15 @@ void Session_component::start_task(unsigned long kconf) // add kernel Kernel* kernel = new(_global_gpgpu_genode->getAlloc()) Kernel(kc); + const bool needsUpdate = vgpu.has_kernel() == false; vgpu.add_kernel(kernel); + // trigger vgpu update + if(needsUpdate) + { + _global_sched->update_vgpu(&vgpu); + } + // trigger sched if its idle if(_global_sched->is_idle()) { diff --git a/repos/dde_uos-intel-gpgpu/src/virt/scheduler.h b/repos/dde_uos-intel-gpgpu/src/virt/scheduler.h index c56e1776dc..2a2be72aac 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/scheduler.h +++ b/repos/dde_uos-intel-gpgpu/src/virt/scheduler.h @@ -1,10 +1,17 @@ #ifndef SCHEDULER_H #define SCHEDULER_H +#include "strategies/config.h" #include "vgpu.h" #include "kernel.h" -#include "strategies/rr.h" +#ifdef SCHED_CFS + #include "strategies/util/rbtree.h" + #include "strategies/cfs.h" +#else + #include "strategies/util/wf_queue.h" + #include "strategies/rr.h" +#endif // SCHED_CFS // genode instance #include "../gpgpu/gpgpu_genode.h" @@ -103,6 +110,16 @@ namespace gpgpu_virt { strat.removeVGPU(vgpu); } + /** + * @brief + * + * @param vgpu + */ + void update_vgpu(VGpu* vgpu) + { + strat.updateVGPU(vgpu); + } + /** * @brief * @@ -115,7 +132,11 @@ namespace gpgpu_virt { } }; +#ifdef SCHED_CFS + using GPGPUScheduler = Scheduler; +#else using GPGPUScheduler = Scheduler; +#endif // SCHED_CFS } #endif // SCHEDULER_H diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategie.h b/repos/dde_uos-intel-gpgpu/src/virt/strategie.h index 4633bc8b6a..510284652c 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/strategie.h +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategie.h @@ -28,6 +28,13 @@ namespace gpgpu_virt { */ virtual void removeVGPU(VGpu* vgpu) = 0; + /** + * @brief + * + * @param vgpu + */ + virtual void updateVGPU(VGpu* vgpu) = 0; + /** * @brief * diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.cc b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.cc index e02ff97425..48e595b692 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.cc +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.cc @@ -22,66 +22,88 @@ static unsigned long long int rdtsc() void CompletlyFair::addVGPU(VGpu* vgpu) { // create new entry - cfs_entry* ce = new (_global_gpgpu_genode->getAlloc()) cfs_entry(vgpu); + cfs_entry* ce = (cfs_entry*)vgpu; // find current min - cfs_entry* min = nullptr; - _run_list.head([&min](cfs_entry& ce){ - min = &ce; - }); - _run_list.for_each([&min](cfs_entry& ce){ - if(ce.runtime < min->runtime) - { - min = &ce; - } - }); + cfs_entry* min = rbt_ready.getMin_cached(); // add new entry with minimum runtime - ce->runtime = min->runtime; - _run_list.enqueue(*ce); + if(min != nullptr) + { + ce->runtime = min->runtime; + } + + // add vgpu to rbtree + if(vgpu->has_kernel()) + { + rbt_ready.insert(*ce); + } + else + { + rbt_idle.insert(*ce); + } + } void CompletlyFair::removeVGPU(VGpu* vgpu) { - _run_list.for_each([&vgpu, this](cfs_entry& ce){ - if(ce.vgpu == vgpu) - { - _run_list.remove(ce); - _global_gpgpu_genode->free(&ce); - } - }); + if((VGpu*)_curr == vgpu || vgpu->has_kernel() ) + { + rbt_ready.remove(*vgpu); + } + else + { + rbt_idle.remove(*vgpu); + } +} + +void CompletlyFair::updateVGPU(VGpu* vgpu) +{ + // dont touch a running vgpu! it will be updated in nextVGPU + if(vgpu == (VGpu*)_curr) + { + return; + } + + rbt_idle.remove(*vgpu); + rbt_ready.insert(*vgpu); } VGpu* CompletlyFair::nextVGPU() { // update cfs entry - _curr->runtime += (rdtsc() - _curr->ts) * -_curr->vgpu->getPriority(); - - // list empty? - if(_run_list.empty()) - return nullptr; - - cfs_entry* min = nullptr; - _run_list.head([&min](cfs_entry& ce){ - min = &ce; - }); - - _run_list.for_each([&min](cfs_entry& ce){ - if(ce.runtime < min->runtime && ce.vgpu->has_kernel()) - { - min = &ce; - } - }); - - if(min->vgpu->has_kernel()) // in case this is still the head + if(_curr != nullptr) { - _curr = min; - _curr->ts = rdtsc(); - return min->vgpu; + VGpu* curr = (VGpu*)_curr; + int prio = curr->getPriority(); + _curr->runtime += (rdtsc() - _curr->ts) * -prio; + + if(curr->has_kernel()) + { + rbt_ready.insert(*_curr); + } + else + { + rbt_idle.insert(*_curr); + } } - // no vgpu with kernel found - return nullptr; + VGpu* min = (VGpu*)rbt_ready.getMin_cached(); + + // tree empty? + if(min == nullptr) + { + _curr = nullptr; + return nullptr; + } + + // remove vgpu from ready tree + rbt_ready.remove(*min); + + // exec min + _curr = (cfs_entry*)min; + _curr->ts = rdtsc(); + return min; } } diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.h b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.h index 34accc1694..6c37ca39b8 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.h +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs.h @@ -1,24 +1,26 @@ #ifndef CFS_H #define CFS_H -#include +#include "cfs_entry.h" +#include "util/rbtree.h" #include "../strategie.h" namespace gpgpu_virt { class CompletlyFair : Strategie { - class cfs_entry : public Genode::Fifo::Element - { - public: - VGpu* vgpu; - unsigned long runtime; - unsigned long ts; - cfs_entry(VGpu* vg) : vgpu(vg), runtime(0), ts(0) {} - }; - private: - Genode::Fifo _run_list; // TODO: Red Black Tree + static int compareCFSentry(const cfs_entry& a, const cfs_entry& b) + { + return (int)((long)a.runtime - (long)b.runtime); + } + static int compareAddr(const cfs_entry& a, const cfs_entry& b) + { + return (int)(&a - &b); + } + + util::RBTree rbt_ready; + util::RBTree rbt_idle; cfs_entry* _curr; CompletlyFair(const CompletlyFair ©) = delete; @@ -27,7 +29,7 @@ namespace gpgpu_virt { CompletlyFair& operator=(CompletlyFair&&) = delete; public: - CompletlyFair() : _run_list(), _curr(nullptr) {}; + CompletlyFair() : rbt_ready(compareCFSentry), rbt_idle(compareAddr), _curr(nullptr) {}; /** * @brief @@ -43,6 +45,13 @@ namespace gpgpu_virt { */ void removeVGPU(VGpu* vgpu) override; + /** + * @brief + * + * @param vgpu + */ + void updateVGPU(VGpu* vgpu) override; + /** * @brief * diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs_entry.h b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs_entry.h new file mode 100644 index 0000000000..a17680b3a1 --- /dev/null +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/cfs_entry.h @@ -0,0 +1,17 @@ +#ifndef CFS_ENTRY_H +#define CFS_ENTRY_H + +#include "util/rbtree.h" + +namespace gpgpu_virt { + + class cfs_entry : public util::RBTree::RBNode + { + public: + unsigned long runtime; + unsigned long ts; + cfs_entry() : runtime(0), ts(0) {} + }; +} + +#endif // CFS_ENTRY_H diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/config.h b/repos/dde_uos-intel-gpgpu/src/virt/strategies/config.h new file mode 100644 index 0000000000..2cbed7619a --- /dev/null +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/config.h @@ -0,0 +1,6 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define SCHED_CFS + +#endif // CONFIG_H \ No newline at end of file diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.cc b/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.cc index c3905b1606..921ae6dd7a 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.cc +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.cc @@ -5,12 +5,12 @@ namespace gpgpu_virt void RoundRobin::addVGPU(VGpu* vgpu) { - _run_list.enqueue(*vgpu); + _run_list.enqueue((util::WFQueue::Chain*)vgpu); } void RoundRobin::removeVGPU(VGpu* vgpu) { - _run_list.remove(*vgpu); + _run_list.remove((util::WFQueue::Chain*)vgpu); } VGpu* RoundRobin::nextVGPU() @@ -24,12 +24,10 @@ VGpu* RoundRobin::nextVGPU() for(;;) { // get next vgpu - _run_list.dequeue([&next](VGpu& vgpu){ - next = &vgpu; - }); + next = (VGpu*)_run_list.dequeue(); // add vgpu back to end of list - _run_list.enqueue(*next); + _run_list.enqueue((util::WFQueue::Chain*)next); // check if it has kernel? if(next->has_kernel()) diff --git a/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.h b/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.h index a80ae0ecf2..6844a4dce3 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.h +++ b/repos/dde_uos-intel-gpgpu/src/virt/strategies/rr.h @@ -1,7 +1,7 @@ #ifndef RR_H #define RR_H -#include +#include "util/wf_queue.h" #include "../strategie.h" namespace gpgpu_virt { @@ -9,7 +9,7 @@ namespace gpgpu_virt { class RoundRobin : Strategie { private: - Genode::Fifo _run_list; + util::WFQueue _run_list; public: RoundRobin() : _run_list() {}; @@ -28,6 +28,13 @@ namespace gpgpu_virt { */ void removeVGPU(VGpu* vgpu) override; + /** + * @brief + * + * @param vgpu + */ + void updateVGPU(VGpu* vgpu) override { (void)vgpu; }; // not needed + /** * @brief * diff --git a/repos/dde_uos-intel-gpgpu/src/virt/vgpu.h b/repos/dde_uos-intel-gpgpu/src/virt/vgpu.h index 2ecdaa3311..16ab636f11 100644 --- a/repos/dde_uos-intel-gpgpu/src/virt/vgpu.h +++ b/repos/dde_uos-intel-gpgpu/src/virt/vgpu.h @@ -1,10 +1,15 @@ #ifndef VGPU_H #define VGPU_H -#include -#include "kernel.h" #include +#include "strategies/config.h" +#include "kernel.h" +#ifdef SCHED_CFS + #include "strategies/cfs_entry.h" +#else + #include "strategies/util/wf_queue.h" +#endif // SCHED_CFS // driver #define GENODE @@ -13,7 +18,11 @@ namespace gpgpu_virt { - class VGpu : public Genode::Fifo::Element +#ifdef SCHED_CFS + class VGpu : public cfs_entry +#else + class VGpu : public util::WFQueue::Chain +#endif // SCHED_CFS { private: // context of vgpu