Skip to content
Browse files

gdev: added a priority-based scheduler

test: added CUDA loop repeated test
  • Loading branch information...
1 parent 246ecef commit 5e75425a897a7221d6fadcba46b14acb96ba43dc Shinpei Kato committed
View
12 common/gdev_api.c
@@ -268,6 +268,7 @@ static int __gmemcpy_to_device
gdev_ctx_t *ctx = h->ctx;
gdev_mem_t *mem = gdev_mem_lookup(vas, dst_addr, GDEV_MEM_DEVICE);
gdev_mem_t **dma_mem = h->dma_mem;
+ struct gdev_sched_entity *se = h->se;
uint32_t ch_size = h->chunk_size;
int p_count = h->pipeline_count;
int ret;
@@ -275,6 +276,10 @@ static int __gmemcpy_to_device
if (!mem)
return -ENOENT;
+#ifndef GDEV_SCHEDULER_DISABLED
+ gdev_schedule_memcpy(se);
+#endif
+
gdev_mem_lock(mem);
gdev_shm_evict_conflict(ctx, mem); /* evict conflicting data. */
ret = __gmemcpy_to_device_locked(ctx, dst_addr, src_buf, size, async,
@@ -456,6 +461,7 @@ static int __gmemcpy_from_device
gdev_ctx_t *ctx = h->ctx;
gdev_mem_t *mem = gdev_mem_lookup(vas, src_addr, GDEV_MEM_DEVICE);
gdev_mem_t **dma_mem = h->dma_mem;
+ struct gdev_sched_entity *se = h->se;
uint32_t ch_size = h->chunk_size;
int p_count = h->pipeline_count;
int ret;
@@ -463,6 +469,10 @@ static int __gmemcpy_from_device
if (!mem)
return -ENOENT;
+#ifndef GDEV_SCHEDULER_DISABLED
+ gdev_schedule_memcpy(se);
+#endif
+
gdev_mem_lock(mem);
gdev_shm_retrieve_swap(ctx, mem); /* retrieve data swapped. */
ret = __gmemcpy_from_device_locked(ctx, dst_buf, src_addr, size, async,
@@ -881,7 +891,9 @@ int glaunch(struct gdev_handle *h, struct gdev_kernel *kernel, uint32_t *id)
gdev_ctx_t *ctx = h->ctx;
struct gdev_sched_entity *se = h->se;
+#ifndef GDEV_SCHEDULER_DISABLED
gdev_schedule_launch(se);
+#endif
gdev_mem_lock_all(vas);
gdev_shm_retrieve_swap_all(ctx, vas); /* get all data swapped back! */
View
58 common/gdev_device.c
@@ -35,25 +35,43 @@ int gdev_vcount = 0; /* # of virtual devices. */
struct gdev_device *gdevs = NULL; /* physical devices */
struct gdev_device *gdev_vds = NULL; /* virtual devices */
-/* initialize the physical device information. */
-int gdev_init_device(struct gdev_device *gdev, int minor, void *priv)
+void __gdev_init_device(struct gdev_device *gdev, int id)
{
- gdev->id = minor;
+ gdev->id = id;
gdev->users = 0;
gdev->mem_size = 0;
gdev->mem_used = 0;
gdev->dma_mem_size = 0;
gdev->dma_mem_used = 0;
- gdev->proc_util = 100; /* 100% */
- gdev->mem_util = 100; /* 100% */
+ gdev->chipset = 0;
+ gdev->com_bw = 0;
+ gdev->mem_bw = 0;
+ gdev->mem_sh = 0;
gdev->swap = NULL;
- gdev->sched_thread = 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 = priv; /* this must be set before calls to gdev_query(). */
- gdev_list_init(&gdev->vas_list, NULL); /* VAS list. */
- gdev_list_init(&gdev->shm_list, NULL); /* shared memory list. */
+ gdev->priv = NULL;
+ gdev_list_init(&gdev->sched_com_list, NULL);
+ gdev_list_init(&gdev->sched_mem_list, NULL);
+ gdev_list_init(&gdev->vas_list, NULL);
+ gdev_list_init(&gdev->shm_list, NULL);
+ gdev_lock_init(&gdev->sched_com_lock);
+ gdev_lock_init(&gdev->sched_mem_lock);
gdev_lock_init(&gdev->vas_lock);
gdev_mutex_init(&gdev->shm_mutex);
+}
+
+/* initialize the physical device information. */
+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.
this call must be prior to the following. */
@@ -80,26 +98,18 @@ 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 proc_util, uint32_t mem_util,
- struct gdev_device *phys)
+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)
{
- gdev->id = id;
- gdev->users = 0;
- gdev->proc_util = proc_util;
- gdev->mem_util = mem_util;
- gdev->swap = NULL;
- gdev->sched_thread = NULL;
+ __gdev_init_device(gdev, id);
+ gdev->com_bw = com_bw;
+ gdev->mem_bw = mem_bw;
+ gdev->mem_sh = mem_sh;
gdev->parent = phys;
gdev->priv = phys->priv;
gdev->compute = phys->compute;
- gdev->mem_size = phys->mem_size * mem_util / 100;
- gdev->dma_mem_size = phys->dma_mem_size * mem_util / 100;
+ gdev->mem_size = phys->mem_size * mem_sh / 100;
+ gdev->dma_mem_size = phys->dma_mem_size * mem_sh / 100;
gdev->chipset = phys->chipset;
- gdev_list_init(&gdev->vas_list, NULL); /* VAS list. */
- gdev_list_init(&gdev->shm_list, NULL); /* shared memory list. */
- gdev_lock_init(&gdev->vas_lock);
- gdev_mutex_init(&gdev->shm_mutex);
/* create the swap memory object, if configured, for the virtual device. */
if (GDEV_SWAP_MEM_SIZE > 0) {
View
27 common/gdev_device.h
@@ -34,6 +34,13 @@
#include "gdev_system.h"
/**
+ * generic subchannel definitions
+ */
+#define GDEV_SUBCH_LAUNCH 1
+#define GDEV_SUBCH_MEMCPY 2
+#define GDEV_SUBCH_MEMCPY_ASYNC 3
+
+/**
* Gdev device struct:
*/
struct gdev_device {
@@ -44,23 +51,31 @@ struct gdev_device {
uint64_t mem_used;
uint64_t dma_mem_size;
uint64_t dma_mem_used;
- uint32_t proc_util; /* available processor utilization */
- uint32_t mem_util; /* available memory utilization */
+ uint32_t com_bw; /* available compute bandwidth */
+ uint32_t mem_bw; /* available memory bandwidth */
+ uint32_t mem_sh; /* available memory space share */
void *priv; /* private device object */
void *compute; /* private set of compute functions */
- void *sched_thread; /* scheduler thread */
+ void *sched_com_thread; /* compute scheduler thread */
+ void *sched_mem_thread; /* memory scheduler thread */
+ struct gdev_sched_entity *se_com_current; /* compute scheduling entity */
+ struct gdev_sched_entity *se_mem_current; /* memory scheduling entity */
struct gdev_device *parent; /* only for virtual devices */
+ struct gdev_list sched_com_list; /* wait list for compute scheduling */
+ struct gdev_list sched_mem_list; /* wait list for memory scheduling */
struct gdev_list vas_list; /* list of VASes allocated to this device */
- struct gdev_list shm_list; /* list of VASes allocated to this device */
+ struct gdev_list shm_list; /* list of shm users allocated to this device */
+ gdev_lock_t sched_com_lock;
+ gdev_lock_t sched_mem_lock;
gdev_lock_t vas_lock;
gdev_mutex_t shm_mutex;
gdev_mem_t *swap; /* reserved swap memory space */
};
-int gdev_init_device(struct gdev_device *gdev, int minor, void *priv);
+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 proc_util, uint32_t mem_util, struct gdev_device *parent);
+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);
void gdev_exit_virtual_device(struct gdev_device*);
extern int gdev_count;
View
44 common/gdev_list.h
@@ -47,8 +47,7 @@ static inline void gdev_list_init(struct gdev_list *entry, void *container)
entry->container = container;
}
-static inline void gdev_list_add
-(struct gdev_list *entry, struct gdev_list *head)
+static inline void gdev_list_add(struct gdev_list *entry, struct gdev_list *head)
{
struct gdev_list *next = head->next;
@@ -59,6 +58,28 @@ static inline void gdev_list_add
head->next = entry;
}
+static inline void gdev_list_add_next(struct gdev_list *entry, struct gdev_list *pos)
+{
+ struct gdev_list *next = pos->next;
+
+ entry->next = next;
+ if (next)
+ next->prev = entry;
+ entry->prev = pos;
+ pos->next = entry;
+}
+
+static inline void gdev_list_add_prev(struct gdev_list *entry, struct gdev_list *pos)
+{
+ struct gdev_list *prev = pos->prev;
+
+ entry->prev = prev;
+ if (prev)
+ prev->next = entry;
+ entry->next = pos;
+ pos->prev = entry;
+}
+
static inline void gdev_list_del(struct gdev_list *entry)
{
struct gdev_list *next = entry->next;
@@ -88,24 +109,9 @@ static inline void *gdev_list_container(struct gdev_list *entry)
return entry ? entry->container : NULL;
}
-#define gdev_list_for_each(p, list, entry) \
+#define gdev_list_for_each(p, list, entry_name) \
for (p = gdev_list_container(gdev_list_head(list)); \
p != NULL; \
- p = gdev_list_container((p)->entry.next))
-
-#define gdev_list_add_ordered(entry, head, member) \
- do { \
- struct gdev_list *p, *tail = head; \
- (entry)->next = (entry)->prev = NULL; \
- gdev_list_for_each(p, head) { \
- if ((entry)->member <= p->member) { \
- gdev_list_add(entry, p); \
- break; \
- } \
- tail = p; \
- } \
- if (gdev_list_empty(entry)) \
- gdev_list_add(entry, tail); \
- } while (0)
+ p = gdev_list_container((p)->entry_name.next))
#endif
View
8 common/gdev_nvidia.h
@@ -35,10 +35,10 @@
#include "gdev_system.h"
#include "gdev_time.h"
-#define GDEV_SUBCH_COMPUTE 1
-#define GDEV_SUBCH_M2MF 2
-#define GDEV_SUBCH_PCOPY0 3
-#define GDEV_SUBCH_PCOPY1 4
+#define GDEV_SUBCH_COMPUTE GDEV_SUBCH_LAUNCH
+#define GDEV_SUBCH_M2MF GDEV_SUBCH_MEMCPY
+#define GDEV_SUBCH_PCOPY0 GDEV_SUBCH_MEMCPY_ASYNC
+#define GDEV_SUBCH_PCOPY1 (GDEV_SUBCH_MEMCPY_ASYNC + 1)
#define GDEV_FENCE_BUF_SIZE 0x10000 /* 64KB */
#define GDEV_FENCE_QUERY_SIZE 0x10 /* aligned with nvc0's query */
View
78 common/gdev_sched.c
@@ -63,7 +63,12 @@ struct gdev_sched_entity *gdev_sched_entity_create(struct gdev_device *gdev, gde
se->gdev = gdev;
se->task = gdev_sched_get_current_task();
se->ctx = ctx;
+ se->prio = gdev_sched_get_static_prio(se->task);
se->rt_prio = GDEV_PRIO_DEFAULT;
+ se->launch_instances = 0;
+ se->memcpy_instances = 0;
+ gdev_list_init(&se->list_entry_com, (void*)se);
+ gdev_list_init(&se->list_entry_mem, (void*)se);
sched_entity_ptr[gdev_ctx_get_cid(ctx)] = se;
return se;
@@ -83,8 +88,73 @@ void gdev_sched_entity_destroy(struct gdev_sched_entity *se)
void gdev_schedule_launch(struct gdev_sched_entity *se)
{
struct gdev_device *gdev = se->gdev;
- //struct gdev_sched_entity *se_current = gdev->
+ struct gdev_sched_entity *p, *tail = NULL;
+resched:
+ 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. */
+ gdev_list_for_each (p, &gdev->sched_com_list, list_entry_com) {
+ if (se->prio > p->prio) {
+ gdev_list_add_prev(&se->list_entry_com, &p->list_entry_com);
+ break;
+ }
+ tail = p;
+ }
+ if (gdev_list_empty(&se->list_entry_com)) {
+ if (tail)
+ gdev_list_add_next(&se->list_entry_com, &tail->list_entry_com);
+ else
+ gdev_list_add(&se->list_entry_com, &gdev->sched_com_list);
+ }
+ gdev_unlock(&gdev->sched_com_lock);
+
+ /* now the corresponding task will be suspended until some other tasks
+ will awaken it upon completions of their compute launches. */
+ gdev_sched_sleep();
+
+ goto resched;
+ }
+ else {
+ gdev->se_com_current = se;
+ se->launch_instances++;
+ gdev_unlock(&gdev->sched_com_lock);
+
+ printk("ctx %d excute\n", se->ctx->cid);
+ }
+}
+
+/**
+ * schedule next contexts for kernel launch.
+ * invoked upon the completion of preceding contexts.
+ */
+void gdev_schedule_launch_post(struct gdev_device *gdev)
+{
+ struct gdev_sched_entity *se, *next;
+
+ gdev_lock(&gdev->sched_com_lock);
+ se = gdev->se_com_current;
+ if (se) {
+ se->launch_instances--;
+ if (se->launch_instances == 0) {
+ /* select the next context. */
+ next = gdev_list_container(gdev_list_head(&gdev->sched_com_list));
+ /* remove it from the waiting list. */
+ if (next)
+ gdev_list_del(&next->list_entry_com);
+ /* now this is going to be the current context. */
+ gdev->se_com_current = next;
+ gdev_unlock(&gdev->sched_com_lock);
+ /* wake up the next context! */
+ if (next) {
+ gdev_sched_wakeup(next->task);
+ }
+ }
+ else
+ gdev_unlock(&gdev->sched_com_lock);
+ }
+ else
+ gdev_unlock(&gdev->sched_com_lock);
}
/**
@@ -92,13 +162,15 @@ void gdev_schedule_launch(struct gdev_sched_entity *se)
*/
void gdev_schedule_memcpy(struct gdev_sched_entity *se)
{
+ //gdev_schedule_launch(se);
}
/**
- * schedule next contexts.
+ * schedule next contexts for memory copy.
* invoked upon the completion of preceding contexts.
*/
-void gdev_schedule_invoked(int subc, uint32_t data)
+void gdev_schedule_memcpy_post(struct gdev_device *gdev)
{
+ //gdev_schedule_launch_post(gdev);
}
View
16 common/gdev_sched.h
@@ -32,10 +32,15 @@
#include "gdev_device.h"
struct gdev_sched_entity {
- struct gdev_device *gdev; /* associated Gdev (virtual) device. */
- void *task; /* private task structure. */
- gdev_ctx_t *ctx;
- int rt_prio; /* real-time priority. */
+ struct gdev_device *gdev; /* associated Gdev (virtual) device */
+ void *task; /* private task structure */
+ gdev_ctx_t *ctx; /* holder context */
+ int prio; /* general priority */
+ 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 */
+ int launch_instances;
+ int memcpy_instances;
};
int gdev_init_scheduler(struct gdev_device *gdev);
@@ -45,8 +50,9 @@ struct gdev_sched_entity *gdev_sched_entity_create(struct gdev_device *gdev, gde
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_invoked(int subc, uint32_t data);
+void gdev_schedule_memcpy_post(struct gdev_device *gdev);
/**
* export the pointers to the scheduling entity.
View
3 common/gdev_system.h
@@ -56,6 +56,9 @@ typedef struct gdev_mutex gdev_mutex_t;
int gdev_sched_create_scheduler(struct gdev_device *gdev);
void gdev_sched_destroy_scheduler(struct gdev_device *gdev);
void *gdev_sched_get_current_task(void);
+int gdev_sched_get_static_prio(void *task);
+void gdev_sched_sleep(void);
+void gdev_sched_wakeup(void *task);
void gdev_lock_init(gdev_lock_t *p);
void gdev_lock(gdev_lock_t *p);
void gdev_unlock(gdev_lock_t *p);
View
113 driver/gdev/gdev_drv.c
@@ -64,23 +64,53 @@ static void __gdev_notify_handler(int subc, uint32_t data)
if (cid < GDEV_CONTEXT_MAX_COUNT) {
se = sched_entity_ptr[cid];
gdev = se->gdev;
- wake_up_process(gdev->sched_thread);
+ switch (subc) {
+ case GDEV_SUBCH_LAUNCH:
+ wake_up_process(gdev->sched_com_thread);
+ break;
+ case GDEV_SUBCH_MEMCPY:
+ case GDEV_SUBCH_MEMCPY_ASYNC:
+ wake_up_process(gdev->sched_mem_thread);
+ break;
+ default:
+ GDEV_PRINT("Unknown subchannel %d\n", subc);
+ }
}
+ else
+ GDEV_PRINT("Unknown context %d\n", cid);
}
-static int __gdev_sched_thread(void *__data)
+static int __gdev_sched_com_thread(void *__data)
{
struct gdev_device *gdev = (struct gdev_device*)__data;
- GDEV_PRINT("Gdev #%d scheduler running\n", gdev->id);
- gdev->sched_thread = current;
+ GDEV_PRINT("Gdev#%d compute scheduler running\n", gdev->id);
+ gdev->sched_com_thread = current;
while (!kthread_should_stop()) {
- GDEV_PRINT("Scheduler invoked\n");
- /* push data into the list here! */
- /*gdev_schedule_invoked();*/
set_current_state(TASK_UNINTERRUPTIBLE);
schedule();
+#ifndef GDEV_SCHEDULER_DISABLED
+ gdev_schedule_launch_post(gdev);
+#endif
+ }
+
+ return 0;
+}
+
+static int __gdev_sched_mem_thread(void *__data)
+{
+ struct gdev_device *gdev = (struct gdev_device*)__data;
+
+ GDEV_PRINT("Gdev#%d memory scheduler running\n", gdev->id);
+ gdev->sched_mem_thread = current;
+
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule();
+#ifndef GDEV_SCHEDULER_DISABLED
+ gdev_schedule_memcpy_post(gdev);
+#endif
}
return 0;
@@ -89,16 +119,23 @@ static int __gdev_sched_thread(void *__data)
int gdev_sched_create_scheduler(struct gdev_device *gdev)
{
struct sched_param sp = { .sched_priority = MAX_RT_PRIO - 1 };
- struct task_struct *p;
+ struct task_struct *com_thread, *mem_thread;
char name[64];
/* create scheduler threads. */
- sprintf(name, "gsched%d", gdev->id);
- p = kthread_create(__gdev_sched_thread, (void*)gdev, name);
- if (p) {
- sched_setscheduler(p, SCHED_FIFO, &sp);
- wake_up_process(p);
- gdev->sched_thread = p;
+ sprintf(name, "gcom%d", gdev->id);
+ com_thread = kthread_create(__gdev_sched_com_thread, (void*)gdev, name);
+ if (com_thread) {
+ sched_setscheduler(com_thread, SCHED_FIFO, &sp);
+ wake_up_process(com_thread);
+ gdev->sched_com_thread = com_thread;
+ }
+ sprintf(name, "gmem%d", gdev->id);
+ mem_thread = kthread_create(__gdev_sched_mem_thread, (void*)gdev, name);
+ if (mem_thread) {
+ sched_setscheduler(mem_thread, SCHED_FIFO, &sp);
+ wake_up_process(mem_thread);
+ gdev->sched_mem_thread = mem_thread;
}
return 0;
@@ -106,8 +143,10 @@ int gdev_sched_create_scheduler(struct gdev_device *gdev)
void gdev_sched_destroy_scheduler(struct gdev_device *gdev)
{
- if (gdev->sched_thread)
- kthread_stop(gdev->sched_thread);
+ if (gdev->sched_com_thread)
+ kthread_stop(gdev->sched_com_thread);
+ if (gdev->sched_mem_thread)
+ kthread_stop(gdev->sched_mem_thread);
}
void *gdev_sched_get_current_task(void)
@@ -115,6 +154,24 @@ void *gdev_sched_get_current_task(void)
return (void*)current;
}
+int gdev_sched_get_static_prio(void *task)
+{
+ struct task_struct *p = (struct task_struct *)task;
+ return p->static_prio;
+}
+
+void gdev_sched_sleep(void)
+{
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule();
+}
+
+void gdev_sched_wakeup(void *task)
+{
+ if (!wake_up_process(task))
+ GDEV_PRINT("Failed to wake up process\n");
+}
+
void gdev_lock_init(struct gdev_lock *p)
{
spin_lock_init(&p->lock);
@@ -170,22 +227,22 @@ void gdev_mutex_unlock(struct gdev_mutex *p)
*/
int gdev_minor_init(struct drm_device *drm)
{
- int minor = drm->primary->index;
+ int id = drm->primary->index;
- if (minor >= gdev_count) {
- GDEV_PRINT("Could not find device %d\n", minor);
+ if (id >= gdev_count) {
+ GDEV_PRINT("Could not find device %d\n", id);
return -EINVAL;
}
/* initialize the physical device. */
- gdev_init_device(&gdevs[minor], minor, drm);
+ gdev_init_device(&gdevs[id], id, drm);
/* initialize the virtual device.
when Gdev first loaded, one-to-one map physical and virtual device. */
- gdev_init_virtual_device(&gdev_vds[minor], minor, 100, 100, &gdevs[minor]);
+ gdev_init_virtual_device(&gdev_vds[id], id, 100, 100, 100, &gdevs[id]);
/* initialize the scheduler for the virtual device. */
- gdev_init_scheduler(&gdev_vds[minor]);
+ gdev_init_scheduler(&gdev_vds[id]);
return 0;
}
@@ -195,21 +252,21 @@ int gdev_minor_init(struct drm_device *drm)
*/
int gdev_minor_exit(struct drm_device *drm)
{
- int minor = drm->primary->index;
+ int id = drm->primary->index;
int i;
- if (gdevs[minor].users) {
- GDEV_PRINT("Device %d has %d users\n", minor, gdevs[minor].users);
+ if (gdevs[id].users) {
+ GDEV_PRINT("Device %d has %d users\n", id, gdevs[id].users);
}
- if (minor < gdev_count) {
+ if (id < gdev_count) {
for (i = 0; i < gdev_vcount; i++) {
- if (gdev_vds[i].parent == &gdevs[minor]) {
+ if (gdev_vds[i].parent == &gdevs[id]) {
gdev_exit_scheduler(&gdev_vds[i]);
gdev_exit_virtual_device(&gdev_vds[i]);
}
}
- gdev_exit_device(&gdevs[minor]);
+ gdev_exit_device(&gdevs[id]);
}
return 0;
View
85 driver/gdev/gdev_proc.c
@@ -37,8 +37,9 @@ static struct proc_dir_entry *proc_dev_count;
static struct proc_dir_entry *proc_virt_dev_count;
static struct gdev_proc_vd {
struct proc_dir_entry *dir;
- struct proc_dir_entry *processor;
- struct proc_dir_entry *memory;
+ struct proc_dir_entry *com_bw;
+ struct proc_dir_entry *mem_bw;
+ struct proc_dir_entry *mem_sh;
} *proc_vd;
static struct semaphore proc_sem;
@@ -66,9 +67,8 @@ static int gdev_proc_write(char *kbuf, const char *buf, int count)
return count;
}
-/* show virutal and physical device counts. */
-static int device_count_read
-(char *page, char **start, off_t off, int count, int *eof, void *data)
+/* integer count read. */
+static int gdev_proc_count_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
char kbuf[64];
uint32_t dev_count = *((uint32_t*)data);
@@ -78,9 +78,8 @@ static int device_count_read
return gdev_proc_read(kbuf, page, count, eof);
}
-/* show virutal device processor/memory utilization. */
-static int vd_util_read
-(char *page, char **start, off_t off, int count, int *eof, void *data)
+/* integer utilization [0,100] read. */
+static int gdev_proc_util_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
char kbuf[64];
uint32_t util = *((uint32_t*)data);
@@ -90,9 +89,8 @@ static int vd_util_read
return gdev_proc_read(kbuf, page, count, eof);
}
-/* set virutal device processor/memory utilization. */
-static int vd_util_write
-(struct file *filp, const char __user *buf, unsigned long count, void *data)
+/* integer utilization [0,100] write. */
+static int gdev_proc_util_write(struct file *filp, const char __user *buf, unsigned long count, void *data)
{
char kbuf[64];
uint32_t *ptr = (uint32_t*)data;
@@ -102,7 +100,7 @@ static int vd_util_write
count = gdev_proc_write(kbuf, buf, count);
sscanf(kbuf, "%u", ptr);
if (*ptr > 100) {
- GDEV_PRINT("Invalid virtual device utilization %u\n", *ptr);
+ GDEV_PRINT("Invalid virtual device bandwidth/share %u\n", *ptr);
*ptr = old;
}
@@ -114,16 +112,16 @@ static int vd_util_write
struct gdev_device *phys = virt->parent;
if (!phys)
continue;
- if (virt->mem_size != phys->mem_size * virt->mem_util / 100) {
- virt->mem_size = phys->mem_size * virt->mem_util / 100;
+ if (virt->mem_size != phys->mem_size * virt->mem_sh / 100) {
+ virt->mem_size = phys->mem_size * virt->mem_sh / 100;
if (virt->swap) {
- uint32_t swap_size = GDEV_SWAP_MEM_SIZE * virt->mem_util / 100;
+ uint32_t swap_size = GDEV_SWAP_MEM_SIZE * virt->mem_sh / 100;
gdev_swap_destroy(virt);
gdev_swap_create(virt, swap_size);
}
}
- if (virt->dma_mem_size != phys->dma_mem_size * virt->mem_util / 100) {
- virt->dma_mem_size = phys->dma_mem_size * virt->mem_util / 100;
+ if (virt->dma_mem_size != phys->dma_mem_size * virt->mem_sh / 100) {
+ virt->dma_mem_size = phys->dma_mem_size * virt->mem_sh / 100;
}
}
@@ -148,7 +146,7 @@ int gdev_proc_create(void)
GDEV_PRINT("Failed to create /proc/gdev/%s\n", name);
goto fail_proc_dev_count;
}
- proc_dev_count->read_proc = device_count_read;
+ proc_dev_count->read_proc = gdev_proc_count_read;
proc_dev_count->write_proc = NULL;
proc_dev_count->data = (void*)&gdev_count;
@@ -159,7 +157,7 @@ int gdev_proc_create(void)
GDEV_PRINT("Failed to create /proc/gdev/%s\n", name);
goto fail_proc_virt_dev_count;
}
- proc_virt_dev_count->read_proc = device_count_read;
+ proc_virt_dev_count->read_proc = gdev_proc_count_read;
proc_virt_dev_count->write_proc = NULL;
proc_virt_dev_count->data = (void*)&gdev_vcount;
@@ -177,25 +175,35 @@ int gdev_proc_create(void)
goto fail_proc_vd;
}
- sprintf(name, "processor");
- proc_vd[i].processor = create_proc_entry(name, 0644, proc_vd[i].dir);
- if (!proc_vd[i].processor) {
+ sprintf(name, "compute_bandwidth");
+ proc_vd[i].com_bw = create_proc_entry(name, 0644, proc_vd[i].dir);
+ if (!proc_vd[i].com_bw) {
GDEV_PRINT("Failed to create /proc/gdev/vd%d/%s\n", i, name);
goto fail_proc_vd;
}
- proc_vd[i].processor->read_proc = vd_util_read;
- proc_vd[i].processor->write_proc = vd_util_write;
- proc_vd[i].processor->data = (void*)&gdev_vds[i].proc_util;
+ proc_vd[i].com_bw->read_proc = gdev_proc_util_read;
+ proc_vd[i].com_bw->write_proc = gdev_proc_util_write;
+ proc_vd[i].com_bw->data = (void*)&gdev_vds[i].com_bw;
- sprintf(name, "memory");
- proc_vd[i].memory = create_proc_entry(name, 0644, proc_vd[i].dir);
- if (!proc_vd[i].memory) {
+ sprintf(name, "memory_bandwidth");
+ proc_vd[i].mem_bw = create_proc_entry(name, 0644, proc_vd[i].dir);
+ if (!proc_vd[i].mem_bw) {
GDEV_PRINT("Failed to create /proc/gdev/vd%d/%s\n", i, name);
goto fail_proc_vd;
}
- proc_vd[i].memory->read_proc = vd_util_read;
- proc_vd[i].memory->write_proc = vd_util_write;
- proc_vd[i].memory->data = (void*)&gdev_vds[i].mem_util;
+ proc_vd[i].mem_bw->read_proc = gdev_proc_util_read;
+ proc_vd[i].mem_bw->write_proc = gdev_proc_util_write;
+ proc_vd[i].mem_bw->data = (void*)&gdev_vds[i].mem_bw;
+
+ sprintf(name, "memory_share");
+ proc_vd[i].mem_sh = create_proc_entry(name, 0644, proc_vd[i].dir);
+ if (!proc_vd[i].mem_sh) {
+ GDEV_PRINT("Failed to create /proc/gdev/vd%d/%s\n", i, name);
+ goto fail_proc_vd;
+ }
+ proc_vd[i].mem_sh->read_proc = gdev_proc_util_read;
+ proc_vd[i].mem_sh->write_proc = gdev_proc_util_write;
+ proc_vd[i].mem_sh->data = (void*)&gdev_vds[i].mem_sh;
}
sema_init(&proc_sem, 1);
@@ -208,10 +216,12 @@ int gdev_proc_create(void)
sprintf(name, "gdev/vd%d", i);
remove_proc_entry(name, gdev_proc);
}
- if (proc_vd[i].processor)
- remove_proc_entry("processor", proc_vd[i].dir);
- if (proc_vd[i].memory)
- remove_proc_entry("memory", proc_vd[i].memory);
+ if (proc_vd[i].com_bw)
+ remove_proc_entry("compute_bandwidth", proc_vd[i].dir);
+ if (proc_vd[i].mem_bw)
+ remove_proc_entry("memory_bandwidth", proc_vd[i].dir);
+ if (proc_vd[i].mem_sh)
+ remove_proc_entry("memory_share", proc_vd[i].dir);
}
kfree(proc_vd);
fail_alloc_proc_vd:
@@ -232,8 +242,9 @@ int gdev_proc_delete(void)
for (i = 0; i < gdev_vcount; i++) {
sprintf(name, "gdev/vd%d", i);
remove_proc_entry(name, gdev_proc);
- remove_proc_entry("processor", proc_vd[i].dir);
- remove_proc_entry("memory", proc_vd[i].memory);
+ remove_proc_entry("processor_bandwidth", proc_vd[i].dir);
+ remove_proc_entry("memory_bandwidth", proc_vd[i].dir);
+ remove_proc_entry("memory_share", proc_vd[i].dir);
}
kfree(proc_vd);
View
2 driver/gdev/install.sh
@@ -38,5 +38,5 @@ if [ ! -d $gdevetc ]; then
mkdir $gdevetc
fi
cp -f Module.symvers $gdevetc/Module.symvers.gdev
-cp -f {gdev_api.h,gdev_nvidia_def.h,gdev_list.h,gdev_time.h} $gdevinc
+cp -f gdev_api.h gdev_nvidia_def.h gdev_list.h gdev_time.h $gdevinc
View
6 runtime/kernel/Makefile
@@ -4,7 +4,7 @@ CC = gcc
TARGET = libgdev
CFLAGS = -O3 -Wall
GDEVDIR = /usr/local/gdev
-HEADERS = gdev_api.h,gdev_nvidia_def.h,gdev_list.h,gdev_time.h
+HEADERS = gdev_api.h gdev_nvidia_def.h gdev_list.h gdev_time.h
#OBJS = $(patsubst %.c,%.o,$(wildcard ./*.c))
OBJS = gdev_lib.o
@@ -23,11 +23,11 @@ install:
cp -f ./$(TARGET).so.1.0.0 $(GDEVDIR)/lib64/
ln -sf $(GDEVDIR)/lib64/$(TARGET).so.1.0.0 $(GDEVDIR)/lib64/$(TARGET).so.1
ln -sf $(GDEVDIR)/lib64/$(TARGET).so.1 $(GDEVDIR)/lib64/$(TARGET).so
- cp -f ./{$(HEADERS)} $(GDEVDIR)/include
+ cp -f $(HEADERS) $(GDEVDIR)/include
uninstall:
rm -f $(GDEVDIR)/lib64/$(TARGET).*
- rm -f $(GDEVDIR)/include/{$(HEADERS)}
+ rm -f $(GDEVDIR)/include/gdev*.h
clean:
rm -f $(TARGET).so.* $(OBJS) $(ZOMBIE)
View
6 runtime/user/gdev/Makefile
@@ -4,7 +4,7 @@ CC = gcc
TARGET = libgdev
CFLAGS = -O2 -Wall
GDEVDIR = /usr/local/gdev
-HEADERS = gdev_api.h,gdev_nvidia_def.h,gdev_list.h,gdev_time.h
+HEADERS = gdev_api.h gdev_nvidia_def.h gdev_list.h gdev_time.h
OBJS = pscnv_gdev.o libpscnv.o libpscnv_ib.o \
gdev_lib.o \
@@ -26,11 +26,11 @@ install:
cp -f ./$(TARGET).so.1.0.0 $(GDEVDIR)/lib64/
ln -sf $(GDEVDIR)/lib64/$(TARGET).so.1.0.0 $(GDEVDIR)/lib64/$(TARGET).so.1
ln -sf $(GDEVDIR)/lib64/$(TARGET).so.1 $(GDEVDIR)/lib64/$(TARGET).so
- cp -f ./{$(HEADERS)} $(GDEVDIR)/include
+ cp -f $(HEADERS) $(GDEVDIR)/include
uninstall:
rm -f $(GDEVDIR)/lib64/$(TARGET).*
- rm -f $(GDEVDIR)/include/{$(HEADERS)}
+ rm -f $(GDEVDIR)/include/gdev*.h
clean:
rm -f $(TARGET).so.* $(OBJS) $(ZOMBIE)
View
13 runtime/user/gdev/gdev_lib.c
@@ -39,6 +39,19 @@ void *gdev_sched_get_current_task(void)
return NULL;
}
+int gdev_sched_get_static_prio(void *task)
+{
+ return 0;
+}
+
+void gdev_sched_sleep(void)
+{
+}
+
+void gdev_sched_wakeup(void *task)
+{
+}
+
void gdev_lock_init(struct gdev_lock *p)
{
}
View
167 test/cuda/common/loop_repeated.c
@@ -0,0 +1,167 @@
+#include <cuda.h>
+#ifdef __KERNEL__ /* just for measurement */
+#include <linux/vmalloc.h>
+#include <linux/time.h>
+#define printf printk
+#define malloc vmalloc
+#define free vfree
+#define gettimeofday(x, y) do_gettimeofday(x)
+#else /* just for measurement */
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+/* tvsub: ret = x - y. */
+static inline void tvsub(struct timeval *x,
+ struct timeval *y,
+ struct timeval *ret)
+{
+ ret->tv_sec = x->tv_sec - y->tv_sec;
+ ret->tv_usec = x->tv_usec - y->tv_usec;
+ if (ret->tv_usec < 0) {
+ ret->tv_sec--;
+ ret->tv_usec += 1000000;
+ }
+}
+
+int cuda_test_loop(unsigned int n, int count, char *path)
+{
+ int i, j, idx;
+ CUresult res;
+ CUdevice dev;
+ CUcontext ctx;
+ CUfunction function;
+ CUmodule module;
+ CUdeviceptr d_data;
+ unsigned int *data = (unsigned int *) malloc (n * sizeof(unsigned int));
+ int block_x, block_y, grid_x, grid_y;
+ char fname[256];
+ struct timeval tv;
+
+ block_x = 1;
+ block_y = 1;
+ grid_x = 1;
+ grid_y = 1;
+
+ res = cuInit(0);
+ if (res != CUDA_SUCCESS) {
+ printf("cuInit failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ res = cuDeviceGet(&dev, 0);
+ if (res != CUDA_SUCCESS) {
+ printf("cuDeviceGet failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ res = cuCtxCreate(&ctx, 0, dev);
+ if (res != CUDA_SUCCESS) {
+ printf("cuCtxCreate failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ sprintf(fname, "%s/loop_gpu.cubin", path);
+ res = cuModuleLoad(&module, fname);
+ if (res != CUDA_SUCCESS) {
+ printf("cuModuleLoad() failed\n");
+ return -1;
+ }
+ res = cuModuleGetFunction(&function, module, "_Z4loopPjjj");
+ if (res != CUDA_SUCCESS) {
+ printf("cuModuleGetFunction() failed\n");
+ return -1;
+ }
+ res = cuFuncSetSharedSize(function, 0);
+ if (res != CUDA_SUCCESS) {
+ printf("cuFuncSetSharedSize() failed\n");
+ return -1;
+ }
+ res = cuFuncSetBlockShape(function, block_x, block_y, 1);
+ if (res != CUDA_SUCCESS) {
+ printf("cuFuncSetBlockShape() failed\n");
+ return -1;
+ }
+
+ res = cuMemAlloc(&d_data, n * sizeof(unsigned int));
+ if (res != CUDA_SUCCESS) {
+ printf("cuMemAlloc failed\n");
+ return -1;
+ }
+
+ res = cuMemcpyHtoD(d_data, data, n * sizeof(unsigned int));
+ if (res != CUDA_SUCCESS) {
+ printf("cuMemcpyHtoD failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ /* set kernel parameters */
+ res = cuParamSeti(function, 0, d_data);
+ if (res != CUDA_SUCCESS) {
+ printf("cuParamSeti failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+ res = cuParamSeti(function, 4, d_data >> 32);
+ if (res != CUDA_SUCCESS) {
+ printf("cuParamSeti failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+ res = cuParamSeti(function, 8, n * sizeof(unsigned int));
+ if (res != CUDA_SUCCESS) {
+ printf("cuParamSeti failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+ res = cuParamSeti(function, 12, n);
+ if (res != CUDA_SUCCESS) {
+ printf("cuParamSeti failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+ res = cuParamSetSize(function, 16);
+ if (res != CUDA_SUCCESS) {
+ printf("cuParamSetSize failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+repeat:
+ usleep(50);
+ res = cuLaunchGrid(function, grid_x, grid_y);
+ if (res != CUDA_SUCCESS) {
+ printf("cuLaunchGrid failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+ cuCtxSynchronize();
+ gettimeofday(&tv, NULL);
+ printf("%lu:%lu\n", tv.tv_sec, tv.tv_usec);
+ count--;
+ if (count)
+ goto repeat;
+
+ res = cuMemcpyDtoH(data, d_data, n * sizeof(unsigned int));
+ if (res != CUDA_SUCCESS) {
+ printf("cuMemcpyDtoH failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ res = cuMemFree(d_data);
+ if (res != CUDA_SUCCESS) {
+ printf("cuMemFree failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ res = cuModuleUnload(module);
+ if (res != CUDA_SUCCESS) {
+ printf("cuModuleUnload failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ res = cuCtxDestroy(ctx);
+ if (res != CUDA_SUCCESS) {
+ printf("cuCtxDestroy failed: res = %lu\n", (unsigned long)res);
+ return -1;
+ }
+
+ free(data);
+
+ return 0;
+}
View
13 test/cuda/common/shm.c
@@ -23,12 +23,6 @@ int copy_to_shm(unsigned int *in, unsigned int size)
CUdeviceptr data_addr;
int shmid;
- res = cuInit(0);
- if (res != CUDA_SUCCESS) {
- printf("cuInit failed: res = %u\n", res);
- return -1;
- }
-
res = cuDeviceGet(&dev, 0);
if (res != CUDA_SUCCESS) {
printf("cuDeviceGet failed: res = %u\n", res);
@@ -82,12 +76,6 @@ int copy_from_shm(unsigned int *out, unsigned int size)
CUdeviceptr data_addr;
int shmid;
- res = cuInit(0);
- if (res != CUDA_SUCCESS) {
- printf("cuInit failed: res = %u\n", res);
- return -1;
- }
-
res = cuDeviceGet(&dev, 0);
if (res != CUDA_SUCCESS) {
printf("cuDeviceGet failed: res = %u\n", res);
@@ -112,7 +100,6 @@ int copy_from_shm(unsigned int *out, unsigned int size)
return -1;
}
- printf("data_addr = %llx\n", data_addr);
res = cuMemcpyDtoH(out, data_addr, size);
if (res != CUDA_SUCCESS) {
printf("cuMemcpyDtoH failed: res = %u\n", res);
View
13 test/cuda/user/loop_repeated/Makefile
@@ -0,0 +1,13 @@
+# Makefile
+TARGET = user_test
+CC = gcc
+NVCC = nvcc -arch sm_20 -cubin
+LIBS = -lcuda -lgdev
+CFLAGS = -L /usr/local/gdev/lib64 -I /usr/local/gdev/include
+
+all:
+ $(NVCC) -o loop_gpu.cubin loop_gpu.cu
+ gcc -o $(TARGET) $(CFLAGS) $(LIBS) main.c loop_repeated.c
+
+clean:
+ rm -f $(TARGET) *.cubin ./*~
View
13 test/cuda/user/loop_repeated/Makefile.nvidia
@@ -0,0 +1,13 @@
+# Makefile
+TARGET = user_test
+CC = gcc
+NVCC = nvcc -arch sm_20 -cubin
+LIBS = -lcuda
+CFLAGS = -I /usr/local/cuda/include
+
+all:
+ $(NVCC) -o loop_gpu.cubin loop_gpu.cu
+ gcc -o $(TARGET) $(CFLAGS) $(LIBS) main.c loop_repeated.c
+
+clean:
+ rm -f $(TARGET) *.cubin ./*~
View
1 test/cuda/user/loop_repeated/loop_gpu.cu
View
1 test/cuda/user/loop_repeated/loop_repeated.c
View
21 test/cuda/user/loop_repeated/main.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int cuda_test_loop(unsigned int n, int count, char *path);
+
+int main(int argc, char *argv[])
+{
+ unsigned int n = 3;
+ int count = 10;
+
+ if (argc > 1)
+ n = atoi(argv[1]);
+ if (argc > 2)
+ count = atoi(argv[2]);
+
+ if (cuda_test_loop(n, count, ".") < 0)
+ printf("Test failed\n");
+ else
+ printf("Test passed\n");
+
+ return 0;
+}

0 comments on commit 5e75425

Please sign in to comment.
Something went wrong with that request. Please try again.