Permalink
Browse files

gdev: added "period" in /proc entry

gdev: extended gdev_time functions
gdev: added periodic credit replenishment
  • Loading branch information...
1 parent 56f5512 commit 657f7a2b213d78d0ede7eefd6364088ec5fbfa64 Shinpei Kato committed Jan 8, 2012
View
@@ -277,7 +277,7 @@ static int __gmemcpy_to_device
return -ENOENT;
#ifndef GDEV_SCHEDULER_DISABLED
- gdev_schedule_memcpy(se);
+ gdev_schedule_memory(se);
#endif
gdev_mem_lock(mem);
@@ -470,7 +470,7 @@ static int __gmemcpy_from_device
return -ENOENT;
#ifndef GDEV_SCHEDULER_DISABLED
- gdev_schedule_memcpy(se);
+ gdev_schedule_memory(se);
#endif
gdev_mem_lock(mem);
@@ -892,7 +892,7 @@ int glaunch(struct gdev_handle *h, struct gdev_kernel *kernel, uint32_t *id)
struct gdev_sched_entity *se = h->se;
#ifndef GDEV_SCHEDULER_DISABLED
- gdev_schedule_launch(se);
+ gdev_schedule_compute(se);
#endif
gdev_mem_lock_all(vas);
View
@@ -28,6 +28,7 @@
#include "gdev_api.h"
#include "gdev_device.h"
+#include "gdev_sched.h"
#include "gdev_system.h"
int gdev_count = 0; /* # of physical devices. */
@@ -44,16 +45,19 @@ void __gdev_init_device(struct gdev_device *gdev, int id)
gdev->dma_mem_size = 0;
gdev->dma_mem_used = 0;
gdev->chipset = 0;
- gdev->com_bw = 0;
- gdev->mem_bw = 0;
- gdev->mem_sh = 0;
+ gdev->com_bw = 100;
+ gdev->mem_bw = 100;
+ gdev->mem_sh = 100;
+ gdev->period = 0;
gdev->swap = NULL;
gdev->sched_com_thread = NULL;
gdev->sched_mem_thread = NULL;
gdev->se_com_current = NULL;
gdev->se_mem_current = NULL;
gdev->parent = NULL;
gdev->priv = NULL;
+ gdev_time_us(&gdev->credit_com, 0);
+ gdev_time_us(&gdev->credit_mem, 0);
gdev_list_init(&gdev->sched_com_list, NULL);
gdev_list_init(&gdev->sched_mem_list, NULL);
gdev_list_init(&gdev->vas_list, NULL);
@@ -68,9 +72,6 @@ void __gdev_init_device(struct gdev_device *gdev, int id)
int gdev_init_device(struct gdev_device *gdev, int id, void *priv)
{
__gdev_init_device(gdev, id);
- gdev->com_bw = 100; /* 100% */
- gdev->mem_bw = 100; /* 100% */
- gdev->mem_sh = 100; /* 100% */
gdev->priv = priv; /* this must be set before calls to gdev_query(). */
/* architecture-dependent chipset.
@@ -98,17 +99,15 @@ void gdev_exit_device(struct gdev_device *gdev)
}
/* initialize the virtual device information. */
-int gdev_init_virtual_device(struct gdev_device *gdev, int id, uint32_t com_bw, uint32_t mem_bw, uint32_t mem_sh, struct gdev_device *phys)
+int gdev_init_virtual_device(struct gdev_device *gdev, int id, struct gdev_device *phys)
{
__gdev_init_device(gdev, id);
- gdev->com_bw = com_bw;
- gdev->mem_bw = mem_bw;
- gdev->mem_sh = mem_sh;
+ gdev->period = GDEV_PERIOD_DEFAULT;
gdev->parent = phys;
gdev->priv = phys->priv;
gdev->compute = phys->compute;
- gdev->mem_size = phys->mem_size * mem_sh / 100;
- gdev->dma_mem_size = phys->dma_mem_size * mem_sh / 100;
+ gdev->mem_size = phys->mem_size;
+ gdev->dma_mem_size = phys->dma_mem_size;
gdev->chipset = phys->chipset;
/* create the swap memory object, if configured, for the virtual device. */
View
@@ -54,6 +54,9 @@ struct gdev_device {
uint32_t com_bw; /* available compute bandwidth */
uint32_t mem_bw; /* available memory bandwidth */
uint32_t mem_sh; /* available memory space share */
+ uint32_t period; /* minimum inter-arrival time (us) of replenishment. */
+ struct gdev_time credit_com; /* credit of compute execution */
+ struct gdev_time credit_mem; /* credit of memory transfer */
void *priv; /* private device object */
void *compute; /* private set of compute functions */
void *sched_com_thread; /* compute scheduler thread */
@@ -75,7 +78,7 @@ struct gdev_device {
int gdev_init_device(struct gdev_device *gdev, int id, void *priv);
void gdev_exit_device(struct gdev_device *gdev);
-int gdev_init_virtual_device(struct gdev_device *gdev, int id, uint32_t com_bw, uint32_t mem_bw, uint32_t mem_sh, struct gdev_device *parent);
+int gdev_init_virtual_device(struct gdev_device *gdev, int id, struct gdev_device *parent);
void gdev_exit_virtual_device(struct gdev_device*);
extern int gdev_count;
View
@@ -29,7 +29,7 @@
#include "gdev_api.h"
#include "gdev_device.h"
#include "gdev_list.h"
-#include "gdev_nvidia.h"
+#include "gdev_sched.h"
#include "gdev_time.h"
/* open a new Gdev object associated with the specified device. */
View
@@ -27,6 +27,7 @@
*/
#include "gdev_device.h"
+#include "gdev_sched.h"
#define GDEV_SHM_SEGMENT_COUNT 64 /* hardcoded */
static struct gdev_mem *gdev_shm_owners[GDEV_SHM_SEGMENT_COUNT] = {
View
@@ -30,6 +30,7 @@
#include "gdev_system.h"
struct gdev_sched_entity *sched_entity_ptr[GDEV_CONTEXT_MAX_COUNT];
+gdev_lock_t global_sched_lock;
/**
* initialize the scheduler for the device.
@@ -82,15 +83,26 @@ void gdev_sched_entity_destroy(struct gdev_sched_entity *se)
FREE(se);
}
+#include "gdev_vsched_credit.c"
+
+#define GDEV_VSCHED_POLICY_CREDIT
+#ifdef GDEV_VSCHED_POLICY_CREDIT
+struct gdev_vsched_policy *gdev_vsched = &gdev_vsched_credit;
+#endif
+
/**
- * schedule kernel-launch calls.
+ * schedule compute calls.
*/
-void gdev_schedule_launch(struct gdev_sched_entity *se)
+void gdev_schedule_compute(struct gdev_sched_entity *se)
{
struct gdev_device *gdev = se->gdev;
struct gdev_sched_entity *p, *tail = NULL;
-
+
resched:
+ /* algorithm-specific virtual device scheduler. */
+ gdev_vsched->schedule(gdev);
+
+ /* local compute scheduler. */
gdev_lock(&gdev->sched_com_lock);
if (gdev->se_com_current && gdev->se_com_current != se) {
/* insert the scheduling entity to the priority-ordered list. */
@@ -116,17 +128,22 @@ void gdev_schedule_launch(struct gdev_sched_entity *se)
goto resched;
}
else {
- gdev->se_com_current = se;
+ /* now, let's get offloaded to the device! */
+ if (se->launch_instances == 0) {
+ /* record the start time. */
+ gdev_time_stamp(&se->start);
+ }
se->launch_instances++;
+ gdev->se_com_current = se;
gdev_unlock(&gdev->sched_com_lock);
}
}
/**
- * schedule next contexts for kernel launch.
+ * schedule the next context of compute.
* invoked upon the completion of preceding contexts.
*/
-void gdev_schedule_launch_post(struct gdev_device *gdev)
+void gdev_schedule_compute_post(struct gdev_device *gdev)
{
struct gdev_sched_entity *se, *next;
@@ -135,6 +152,9 @@ void gdev_schedule_launch_post(struct gdev_device *gdev)
if (se) {
se->launch_instances--;
if (se->launch_instances == 0) {
+ /* record the end time. */
+ gdev_time_stamp(&se->end);
+ gdev_time_sub(&gdev->credit_com, &se->end, &se->start);
/* select the next context. */
next = gdev_list_container(gdev_list_head(&gdev->sched_com_list));
/* remove it from the waiting list. */
@@ -145,6 +165,7 @@ void gdev_schedule_launch_post(struct gdev_device *gdev)
gdev_unlock(&gdev->sched_com_lock);
/* wake up the next context! */
if (next) {
+ /* could be enforced when awakened. */
gdev_sched_wakeup(next->task);
}
}
@@ -158,17 +179,40 @@ void gdev_schedule_launch_post(struct gdev_device *gdev)
/**
* schedule memcpy-copy calls.
*/
-void gdev_schedule_memcpy(struct gdev_sched_entity *se)
+void gdev_schedule_memory(struct gdev_sched_entity *se)
{
- //gdev_schedule_launch(se);
+ //gdev_schedule_compute(se);
}
/**
- * schedule next contexts for memory copy.
+ * schedule the next context of memory copy.
* invoked upon the completion of preceding contexts.
*/
-void gdev_schedule_memcpy_post(struct gdev_device *gdev)
+void gdev_schedule_memory_post(struct gdev_device *gdev)
+{
+ //gdev_schedule_compute_post(gdev);
+}
+
+void gdev_replenish_credit_compute(struct gdev_device *gdev)
{
- //gdev_schedule_launch_post(gdev);
+ struct gdev_time credit, threshold;
+
+ gdev_time_us(&credit, gdev->period * gdev->com_bw / 100);
+ gdev_time_add(&gdev->credit_com, &gdev->credit_com, &credit);
+ /* when the credit exceeds the threshold, all credits taken away. */
+ gdev_time_us(&threshold, GDEV_CREDIT_INACTIVE_THRESHOLD);
+ if (gdev_time_g(&gdev->credit_com, &threshold))
+ gdev_time_us(&gdev->credit_com, 0);
}
+void gdev_replenish_credit_memory(struct gdev_device *gdev)
+{
+ struct gdev_time credit, threshold;
+
+ gdev_time_us(&credit, gdev->period * gdev->mem_bw / 100);
+ gdev_time_add(&gdev->credit_mem, &gdev->credit_mem, &credit);
+ /* when the credit exceeds the threshold, all credits taken away. */
+ gdev_time_us(&threshold, GDEV_CREDIT_INACTIVE_THRESHOLD);
+ if (gdev_time_g(&gdev->credit_mem, &threshold))
+ gdev_time_us(&gdev->credit_mem, 0);
+}
View
@@ -30,6 +30,20 @@
#define __GDEV_SCHED_H__
#include "gdev_device.h"
+#include "gdev_time.h"
+
+/**
+ * priority levels.
+ */
+#define GDEV_PRIO_MAX 40
+#define GDEV_PRIO_MIN 0
+#define GDEV_PRIO_DEFAULT 20
+
+/**
+ * virtual device period/threshold.
+ */
+#define GDEV_PERIOD_DEFAULT 30000 /* microseconds */
+#define GDEV_CREDIT_INACTIVE_THRESHOLD 300000 /* microseconds */
struct gdev_sched_entity {
struct gdev_device *gdev; /* associated Gdev (virtual) device */
@@ -39,24 +53,30 @@ struct gdev_sched_entity {
int rt_prio; /* real-time priority */
struct gdev_list list_entry_com; /* entry to compute scheduler list */
struct gdev_list list_entry_mem; /* entry to memory scheduler list */
+ struct gdev_time start; /* start time of kernel execution */
+ struct gdev_time end; /* end time of kernel execution */
int launch_instances;
int memcpy_instances;
};
+struct gdev_vsched_policy {
+ void (*schedule)(struct gdev_device *gdev);
+};
+
int gdev_init_scheduler(struct gdev_device *gdev);
void gdev_exit_scheduler(struct gdev_device *gdev);
struct gdev_sched_entity *gdev_sched_entity_create(struct gdev_device *gdev, gdev_ctx_t *ctx);
void gdev_sched_entity_destroy(struct gdev_sched_entity *se);
-void gdev_schedule_launch(struct gdev_sched_entity *se);
-void gdev_schedule_launch_post(struct gdev_device *gdev);
-void gdev_schedule_memcpy(struct gdev_sched_entity *se);
-void gdev_schedule_memcpy_post(struct gdev_device *gdev);
+void gdev_schedule_compute(struct gdev_sched_entity *se);
+void gdev_schedule_compute_post(struct gdev_device *gdev);
+void gdev_schedule_memory(struct gdev_sched_entity *se);
+void gdev_schedule_memory_post(struct gdev_device *gdev);
+void gdev_replenish_credit_compute(struct gdev_device *gdev);
+void gdev_replenish_credit_memory(struct gdev_device *gdev);
-/**
- * export the pointers to the scheduling entity.
- */
extern struct gdev_sched_entity *sched_entity_ptr[GDEV_CONTEXT_MAX_COUNT];
+extern gdev_lock_t global_sched_lock;
#endif
View
@@ -38,13 +38,6 @@
struct gdev_device; /* prototype declaration */
/**
- * priority levels.
- */
-#define GDEV_PRIO_MAX 40
-#define GDEV_PRIO_MIN 0
-#define GDEV_PRIO_DEFAULT 20
-
-/**
* OS and user-space private types.
*/
typedef struct gdev_lock gdev_lock_t;
Oops, something went wrong.

0 comments on commit 657f7a2

Please sign in to comment.