Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

gdev: updated virtual device support

util: added gdev utilization monitor (gmonitor)
  • Loading branch information...
commit 7a89238f20ec8ebdc2d4819cf680d77ad44ddf34 1 parent 010bd64
Shinpei Kato authored
View
4 common/gdev_api.c
@@ -617,7 +617,7 @@ struct gdev_handle *gopen(int minor)
h->gdev = gdev;
h->dev_id = minor;
- GDEV_PRINT("Opened gdev%d\n", minor);
+ GDEV_DPRINT("Opened gdev%d\n", minor);
return h;
@@ -659,7 +659,7 @@ int gclose(struct gdev_handle *h)
gdev_vas_free(h->vas);
gdev_dev_close(h->gdev);
- GDEV_PRINT("Closed gdev%d\n", h->dev_id);
+ GDEV_DPRINT("Closed gdev%d\n", h->dev_id);
FREE(h);
View
4 common/gdev_device.c
@@ -47,8 +47,12 @@ void __gdev_init_device(struct gdev_device *gdev, int id)
gdev->chipset = 0;
gdev->com_bw = 100;
gdev->mem_bw = 100;
+ gdev->com_bw_used = 0;
+ gdev->mem_bw_used = 0;
gdev->mem_sh = 100;
gdev->period = 0;
+ gdev->com_time = 0;
+ gdev->mem_time = 0;
gdev->swap = NULL;
gdev->sched_com_thread = NULL;
gdev->sched_mem_thread = NULL;
View
4 common/gdev_device.h
@@ -55,6 +55,10 @@ struct gdev_device {
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. */
+ uint32_t com_bw_used; /* used compute bandwidth */
+ uint32_t mem_bw_used; /* used memory bandwidth */
+ uint32_t com_time; /* cumulative computation time. */
+ uint32_t mem_time; /* cumulative memory transfer time. */
struct gdev_time credit_com; /* credit of compute execution */
struct gdev_time credit_mem; /* credit of memory transfer */
void *priv; /* private device object */
View
2  common/gdev_nvidia_shm.c
@@ -29,7 +29,7 @@
#include "gdev_device.h"
#include "gdev_sched.h"
-#define GDEV_SHM_SEGMENT_COUNT 64 /* hardcoded */
+#define GDEV_SHM_SEGMENT_COUNT 128 /* hardcoded */
static struct gdev_mem *gdev_shm_owners[GDEV_SHM_SEGMENT_COUNT] = {
[0 ... GDEV_SHM_SEGMENT_COUNT - 1] = NULL
};
View
7 common/gdev_sched.c
@@ -195,7 +195,7 @@ void gdev_schedule_compute(struct gdev_sched_entity *se)
void gdev_select_next_compute(struct gdev_device *gdev)
{
struct gdev_sched_entity *se, *next;
- struct gdev_time now;
+ struct gdev_time now, exec;
gdev_lock(&gdev->sched_com_lock);
se = gdev->se_com_current;
@@ -207,6 +207,8 @@ void gdev_select_next_compute(struct gdev_device *gdev)
/* record the end time (update on multiple launches too). */
gdev_time_stamp(&now);
+ /* account for the execution time. */
+ gdev_time_sub(&exec, &now, &se->last_tick_com);
se->launch_instances--;
if (se->launch_instances == 0) {
@@ -226,6 +228,9 @@ void gdev_select_next_compute(struct gdev_device *gdev)
/* could be enforced when awakened. */
gdev_sched_wakeup(next->task);
}
+
+ /* accumulate the computation time on the device. */
+ gdev->com_time += gdev_time_to_us(&exec);
}
else
gdev_unlock(&gdev->sched_com_lock);
View
1  common/gdev_sched.h
@@ -44,6 +44,7 @@
*/
#define GDEV_PERIOD_DEFAULT 30000 /* microseconds */
#define GDEV_CREDIT_INACTIVE_THRESHOLD GDEV_PERIOD_DEFAULT
+#define GDEV_UPDATE_INTERVAL (GDEV_PERIOD_DEFAULT * 30)
struct gdev_sched_entity {
struct gdev_device *gdev; /* associated Gdev (virtual) device */
View
18 common/gdev_time.h
@@ -93,6 +93,24 @@ static inline void gdev_time_us(struct gdev_time *ret, unsigned long us)
ret->neg = 0;
}
+/* transform from struct gdev_time to seconds. */
+static inline unsigned long gdev_time_to_sec(struct gdev_time *p)
+{
+ return (p->sec * USEC_1SEC + p->usec) / USEC_1SEC;
+}
+
+/* transform from struct gdev_time to milliseconds. */
+static inline unsigned long gdev_time_to_ms(struct gdev_time *p)
+{
+ return (p->sec * USEC_1SEC + p->usec) / USEC_1MSEC;
+}
+
+/* transform from struct gdev_time to microseconds. */
+static inline unsigned long gdev_time_to_us(struct gdev_time *p)
+{
+ return (p->sec * USEC_1SEC + p->usec);
+}
+
/* clear the timeval values. */
static inline void gdev_time_clear(struct gdev_time *t)
{
View
21 driver/gdev/gdev_drv.c
@@ -126,18 +126,27 @@ static int __gdev_credit_com_thread(void *__data)
{
struct gdev_device *gdev = (struct gdev_device*)__data;
struct timer_list timer;
+ unsigned long elapsed = 0;
GDEV_PRINT("Gdev#%d compute reserve running\n", gdev->id);
setup_timer_on_stack(&timer, __gdev_credit_handler, (unsigned long)current);
while (!kthread_should_stop()) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule();
#ifndef GDEV_SCHEDULER_DISABLED
gdev_replenish_credit_compute(gdev);
mod_timer(&timer, jiffies + usecs_to_jiffies(gdev->period));
#endif
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule();
+ elapsed += gdev->period;
+ if (elapsed >= GDEV_UPDATE_INTERVAL) {
+ gdev->com_bw_used = gdev->com_time * 100 / GDEV_UPDATE_INTERVAL;
+ if (gdev->com_bw_used > 100)
+ gdev->com_bw_used = 100;
+ gdev->com_time = 0;
+ elapsed = 0;
+ }
}
local_irq_enable();
@@ -160,12 +169,12 @@ static int __gdev_credit_mem_thread(void *__data)
setup_timer_on_stack(&timer, __gdev_credit_handler, (unsigned long)current);
while (!kthread_should_stop()) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule();
#ifndef GDEV_SCHEDULER_DISABLED
gdev_replenish_credit_memory(gdev);
mod_timer(&timer, jiffies + usecs_to_jiffies(gdev->period));
#endif
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule();
}
local_irq_enable();
@@ -318,8 +327,10 @@ int gdev_minor_init(struct drm_device *drm)
when Gdev first loaded, one-to-one map physical and virtual device. */
gdev_init_virtual_device(&gdev_vds[id], id, &gdevs[id]);
+#ifndef GDEV_SCHEDULER_DISABLED
/* initialize the local scheduler for the virtual device. */
gdev_init_scheduler(&gdev_vds[id]);
+#endif
return 0;
}
@@ -339,7 +350,9 @@ int gdev_minor_exit(struct drm_device *drm)
if (id < gdev_count) {
for (i = 0; i < gdev_vcount; i++) {
if (gdev_vds[i].parent == &gdevs[id]) {
+#ifndef GDEV_SCHEDULER_DISABLED
gdev_exit_scheduler(&gdev_vds[i]);
+#endif
gdev_exit_virtual_device(&gdev_vds[i]);
}
}
View
28 driver/gdev/gdev_proc.c
@@ -41,6 +41,8 @@ static struct gdev_proc_vd {
struct proc_dir_entry *mem_bw;
struct proc_dir_entry *mem_sh;
struct proc_dir_entry *period;
+ struct proc_dir_entry *com_bw_used;
+ struct proc_dir_entry *mem_bw_used;
} *proc_vd;
static struct semaphore proc_sem;
@@ -227,6 +229,26 @@ int gdev_proc_create(void)
proc_vd[i].period->read_proc = gdev_proc_val_read;
proc_vd[i].period->write_proc = gdev_proc_val_write;
proc_vd[i].period->data = (void*)&gdev_vds[i].period;
+
+ sprintf(name, "compute_bandwidth_used");
+ proc_vd[i].com_bw_used = create_proc_entry(name, 0644, proc_vd[i].dir);
+ if (!proc_vd[i].com_bw_used) {
+ GDEV_PRINT("Failed to create /proc/gdev/vd%d/%s\n", i, name);
+ goto fail_proc_vd;
+ }
+ proc_vd[i].com_bw_used->read_proc = gdev_proc_util_read;
+ proc_vd[i].com_bw_used->write_proc = NULL;
+ proc_vd[i].com_bw_used->data = (void*)&gdev_vds[i].com_bw_used;
+
+ sprintf(name, "memory_bandwidth_used");
+ proc_vd[i].mem_bw_used = create_proc_entry(name, 0644, proc_vd[i].dir);
+ if (!proc_vd[i].mem_bw_used) {
+ GDEV_PRINT("Failed to create /proc/gdev/vd%d/%s\n", i, name);
+ goto fail_proc_vd;
+ }
+ proc_vd[i].mem_bw_used->read_proc = gdev_proc_util_read;
+ proc_vd[i].mem_bw_used->write_proc = NULL;
+ proc_vd[i].mem_bw_used->data = (void*)&gdev_vds[i].mem_bw_used;
}
sema_init(&proc_sem, 1);
@@ -247,6 +269,10 @@ int gdev_proc_create(void)
remove_proc_entry("memory_share", proc_vd[i].dir);
if (proc_vd[i].period)
remove_proc_entry("period", proc_vd[i].dir);
+ if (proc_vd[i].com_bw_used)
+ remove_proc_entry("compute_bandwidth_used", proc_vd[i].dir);
+ if (proc_vd[i].mem_bw_used)
+ remove_proc_entry("memory_bandwidth_used", proc_vd[i].dir);
}
kfree(proc_vd);
fail_alloc_proc_vd:
@@ -271,6 +297,8 @@ int gdev_proc_delete(void)
remove_proc_entry("memory_bandwidth", proc_vd[i].dir);
remove_proc_entry("memory_share", proc_vd[i].dir);
remove_proc_entry("period", proc_vd[i].dir);
+ remove_proc_entry("processor_bandwidth_used", proc_vd[i].dir);
+ remove_proc_entry("memory_bandwidth_used", proc_vd[i].dir);
}
kfree(proc_vd);
View
7 driver/pscnv/pscnv_gdev.c
@@ -411,8 +411,7 @@ struct gdev_mem *gdev_raw_mem_share(struct gdev_vas *vas, struct gdev_mem *mem,
if (!(new = kzalloc(sizeof(*new), GFP_KERNEL)))
goto fail_mem;
- if (pscnv_vspace_map(vs, bo, GDEV_VAS_USER_START, GDEV_VAS_USER_END, 0,
- &mm))
+ if (pscnv_vspace_map(vs, bo, GDEV_VAS_USER_START, GDEV_VAS_USER_END, 0,&mm))
goto fail_map;
/* address, size, and map. */
@@ -430,8 +429,8 @@ struct gdev_mem *gdev_raw_mem_share(struct gdev_vas *vas, struct gdev_mem *mem,
/* private data. */
new->bo = (void *) bo;
- GDEV_PRINT("Shared memory of 0x%llx bytes at 0x%llx.\n",
- *size, *addr);
+ GDEV_DPRINT("Shared memory of 0x%llx bytes at 0x%llx.\n",
+ *size, *addr);
return new;
View
2  test/cuda/common/loop_repeated.c
@@ -124,7 +124,7 @@ int cuda_test_loop(unsigned int n, int count, char *path)
}
repeat:
- usleep(100);
+ usleep(10);
res = cuLaunchGrid(function, grid_x, grid_y);
if (res != CUDA_SUCCESS) {
printf("cuLaunchGrid failed: res = %lu\n", (unsigned long)res);
View
4 util/Makefile
@@ -0,0 +1,4 @@
+all:
+ gcc -o gmonitor gmonitor.c
+clean:
+ rm -f gmonitor
View
71 util/gmonitor.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ int id = -1;
+ char fname[256], s[8];
+ FILE *fp;
+ int i, n;
+
+ if (argc > 1)
+ id = atoi(argv[1]);
+
+ if (id != -1) {
+ for (;;) {
+ sprintf(fname, "/proc/gdev/vd%d/compute_bandwidth_used", id);
+ if (!(fp = fopen(fname, "r")))
+ return -1;
+ fgets(s, 8, fp);
+ printf("Compute %s %\n", s);
+ fclose(fp);
+
+ sprintf(fname, "/proc/gdev/vd%d/memory_bandwidth_used", id);
+ if (!(fp = fopen(fname, "r")))
+ return -1;
+ fgets(s, 8, fp);
+ printf("Memory %s %\n", s);
+ fclose(fp);
+
+ sleep(1);
+ }
+ }
+ else {
+ if (!(fp = fopen("/proc/gdev/virtual_device_count", "r")))
+ return -1;
+ fgets(s, 8, fp);
+ n = atoi(s);
+ fclose(fp);
+ printf(" ");
+ for (i = 0; i < n; i++) {
+ printf("gdev%d ", i);
+ }
+ printf("\n");
+ for (;;) {
+ printf("Compute ");
+ for (i = 0; i < n; i++) {
+ sprintf(fname, "/proc/gdev/vd%d/compute_bandwidth_used", i);
+ if (!(fp = fopen(fname, "r")))
+ return -1;
+ fgets(s, 8, fp);
+ printf(" %s ", s);
+ fclose(fp);
+ }
+ printf("%\n");
+
+ printf("Memory ");
+ for (i = 0; i < n; i++) {
+ sprintf(fname, "/proc/gdev/vd%d/memory_bandwidth_used", i);
+ if (!(fp = fopen(fname, "r")))
+ return -1;
+ fgets(s, 8, fp);
+ printf(" %s ", s);
+ fclose(fp);
+ }
+ printf("%\n");
+
+ sleep(1);
+ }
+ }
+
+ return 0;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.