aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-04-24 20:34:17 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2013-04-24 20:34:17 -0400
commite3935c7f68ce428e394eb53ea29ebef5509bcd7f (patch)
tree33e5cff0aae98c00ce777b18fbaed888171ad334
parent76b0d79069973bd58cda6028c65a9edaa6d2ea73 (diff)
integrated numa support and fixed p2p migration
-rw-r--r--Makefile14
-rw-r--r--gpu/gpuspin.cu53
-rw-r--r--src/migration.c59
3 files changed, 100 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index f50af0f..b91dec5 100644
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,11 @@ ARCH ?= ${host-arch}
14# LITMUS_KERNEL -- where to find the litmus kernel? 14# LITMUS_KERNEL -- where to find the litmus kernel?
15LITMUS_KERNEL ?= ../litmus-rt 15LITMUS_KERNEL ?= ../litmus-rt
16 16
17# NUMA Support. Comment out to disable. Requires libnuma dev files.
18#
19# Enabling this option will ensure all memory resides on NUMA nodes
20# that overlap clusters/partitions specified by a call to be_migrate*().
21NUMA_SUPPORT = dummyval
17 22
18# ############################################################################## 23# ##############################################################################
19# Internal configuration. 24# Internal configuration.
@@ -62,8 +67,17 @@ CUFLAGS = ${flags-api} ${flags-cu-debug} ${flags-cu-optim} ${flags-cu-nvcc} ${f
62CFLAGS = ${flags-debug} ${flags-misc} 67CFLAGS = ${flags-debug} ${flags-misc}
63LDFLAGS = ${flags-${ARCH}} 68LDFLAGS = ${flags-${ARCH}}
64 69
70ifdef NUMA_SUPPORT
71CFLAGS += -DLITMUS_NUMA_SUPPORT
72CPPFLAGS += -DLITMUS_NUMA_SUPPORT
73CUFLAGS += -DLITMUS_NUMA_SUPPORT
74endif
75
65# how to link against liblitmus 76# how to link against liblitmus
66liblitmus-flags = -L${LIBLITMUS} -llitmus 77liblitmus-flags = -L${LIBLITMUS} -llitmus
78ifdef NUMA_SUPPORT
79liblitmus-flags += -lnuma
80endif
67 81
68# how to link cuda 82# how to link cuda
69cuda-flags-i386 = -L/usr/local/cuda/lib 83cuda-flags-i386 = -L/usr/local/cuda/lib
diff --git a/gpu/gpuspin.cu b/gpu/gpuspin.cu
index b096c82..970d6f2 100644
--- a/gpu/gpuspin.cu
+++ b/gpu/gpuspin.cu
@@ -57,7 +57,7 @@ size_t CHUNK_SIZE = 0;
57 57
58int TOKEN_LOCK = -1; 58int TOKEN_LOCK = -1;
59 59
60bool USE_ENGINE_LOCKS = true; 60bool USE_ENGINE_LOCKS = false;
61bool USE_DYNAMIC_GROUP_LOCKS = false; 61bool USE_DYNAMIC_GROUP_LOCKS = false;
62int EE_LOCKS[NR_GPUS]; 62int EE_LOCKS[NR_GPUS];
63int CE_SEND_LOCKS[NR_GPUS]; 63int CE_SEND_LOCKS[NR_GPUS];
@@ -692,12 +692,13 @@ static void init_cuda(int num_gpu_users)
692 { 692 {
693 if (i != j) 693 if (i != j)
694 { 694 {
695 int other = GPU_PARTITION*GPU_PARTITION_SIZE + j;
695 int canAccess = 0; 696 int canAccess = 0;
696 cudaDeviceCanAccessPeer(&canAccess, i, j); 697 cudaDeviceCanAccessPeer(&canAccess, which, other);
697 if(canAccess) 698 if(canAccess)
698 { 699 {
699 cudaDeviceEnablePeerAccess(j, 0); 700 cudaDeviceEnablePeerAccess(other, 0);
700 p2pMigration[i][j] = true; 701 p2pMigration[which][other] = true;
701 } 702 }
702 } 703 }
703 } 704 }
@@ -1294,8 +1295,8 @@ enum eScheduler
1294 RT_LINUX 1295 RT_LINUX
1295}; 1296};
1296 1297
1297#define CPU_OPTIONS "p:z:c:wlveio:f:s:q:X:L:Q:d" 1298#define CPU_OPTIONS "p:z:c:wlveio:f:s:q:X:L:Q:d:"
1298#define GPU_OPTIONS "g:y:r:C:E:DG:xS:R:T:Z:aFm:b:MNIk:" 1299#define GPU_OPTIONS "g:y:r:C:E:DG:xS:R:T:Z:aFm:b:MNIk:V"
1299 1300
1300// concat the option strings 1301// concat the option strings
1301#define OPTSTR CPU_OPTIONS GPU_OPTIONS 1302#define OPTSTR CPU_OPTIONS GPU_OPTIONS
@@ -1372,6 +1373,9 @@ int main(int argc, char** argv)
1372 NUM_COPY_ENGINES = atoi(optarg); 1373 NUM_COPY_ENGINES = atoi(optarg);
1373 assert(NUM_COPY_ENGINES == 1 || NUM_COPY_ENGINES == 2); 1374 assert(NUM_COPY_ENGINES == 1 || NUM_COPY_ENGINES == 2);
1374 break; 1375 break;
1376 case 'V':
1377 RESERVED_MIGR_COPY_ENGINE = true;
1378 break;
1375 case 'E': 1379 case 'E':
1376 USE_ENGINE_LOCKS = true; 1380 USE_ENGINE_LOCKS = true;
1377 ENGINE_LOCK_TYPE = (eEngineLockTypes)atoi(optarg); 1381 ENGINE_LOCK_TYPE = (eEngineLockTypes)atoi(optarg);
@@ -1440,7 +1444,9 @@ int main(int argc, char** argv)
1440 want_signals = 1; 1444 want_signals = 1;
1441 break; 1445 break;
1442 case 'd': 1446 case 'd':
1443 drain = DRAIN_SOBLIV; 1447 drain = (budget_drain_policy_t)atoi(optarg);
1448 assert(drain >= DRAIN_SIMPLE && drain <= DRAIN_SOBLIV);
1449 assert(drain != DRAIN_SAWARE); // unsupported
1444 break; 1450 break;
1445 case 'l': 1451 case 'l':
1446 test_loop = 1; 1452 test_loop = 1;
@@ -1623,18 +1629,6 @@ int main(int argc, char** argv)
1623 activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal); 1629 activate_litmus_signals(SIG_BUDGET_MASK, longjmp_on_litmus_signal);
1624 } 1630 }
1625 1631
1626 if (scheduler == LITMUS)
1627 {
1628 ret = task_mode(LITMUS_RT_TASK);
1629 if (ret != 0)
1630 bail_out("could not become RT task");
1631 }
1632 else
1633 {
1634 trace_name();
1635 trace_param();
1636 }
1637
1638// if (protocol >= 0) { 1632// if (protocol >= 0) {
1639// /* open reference to semaphore */ 1633// /* open reference to semaphore */
1640// lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); 1634// lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster);
@@ -1654,12 +1648,20 @@ int main(int argc, char** argv)
1654 1648
1655 init_cuda(num_gpu_users); 1649 init_cuda(num_gpu_users);
1656 safetynet = true; 1650 safetynet = true;
1657
1658 if (ENABLE_RT_AUX_THREADS)
1659 if (enable_aux_rt_tasks(AUX_CURRENT | AUX_FUTURE) != 0)
1660 bail_out("enable_aux_rt_tasks() failed");
1661 } 1651 }
1662 1652
1653 if (scheduler == LITMUS)
1654 {
1655 ret = task_mode(LITMUS_RT_TASK);
1656 if (ret != 0)
1657 bail_out("could not become RT task");
1658 }
1659 else
1660 {
1661 trace_name();
1662 trace_param();
1663 }
1664
1663 if (wait) { 1665 if (wait) {
1664 ret = wait_for_ts_release2(&releaseTime); 1666 ret = wait_for_ts_release2(&releaseTime);
1665 if (ret != 0) 1667 if (ret != 0)
@@ -1674,6 +1676,11 @@ int main(int argc, char** argv)
1674 sleep_next_period_linux(); 1676 sleep_next_period_linux();
1675 } 1677 }
1676 1678
1679 if (scheduler == LITMUS && GPU_USING && ENABLE_RT_AUX_THREADS) {
1680 if (enable_aux_rt_tasks(AUX_CURRENT | AUX_FUTURE) != 0)
1681 bail_out("enable_aux_rt_tasks() failed");
1682 }
1683
1677 start = wctime(); 1684 start = wctime();
1678 1685
1679 if (scheduler == LITMUS) 1686 if (scheduler == LITMUS)
diff --git a/src/migration.c b/src/migration.c
index 152d81b..7ac320e 100644
--- a/src/migration.c
+++ b/src/migration.c
@@ -4,8 +4,13 @@
4#include <sched.h> /* for cpu sets */ 4#include <sched.h> /* for cpu sets */
5#include <unistd.h> 5#include <unistd.h>
6 6
7#ifdef LITMUS_NUMA_SUPPORT
8#include <numa.h>
9#endif
10
7#include "migration.h" 11#include "migration.h"
8 12
13
9extern ssize_t read_file(const char* fname, void* buf, size_t maxlen); 14extern ssize_t read_file(const char* fname, void* buf, size_t maxlen);
10 15
11int release_master() 16int release_master()
@@ -54,6 +59,50 @@ int cluster_to_first_cpu(int cluster, int cluster_sz)
54 return first_cpu; 59 return first_cpu;
55} 60}
56 61
62#ifdef LITMUS_NUMA_SUPPORT
63/* Restrict the task to the numa nodes in the cpu mask. */
64/* Call this before setting up CPU affinity masks since that mask may be
65 * a subset of the numa nodes. */
66static int setup_numa(pid_t tid, int sz, const cpu_set_t *cpus)
67{
68 int nr_nodes;
69 struct bitmask* new_nodes;
70 struct bitmask* old_nodes;
71 int i;
72 int ret = 0;
73
74 if (numa_available() != 0)
75 goto out;
76
77 nr_nodes = numa_max_node()+1;
78 new_nodes = numa_bitmask_alloc(nr_nodes);
79 old_nodes = numa_bitmask_alloc(nr_nodes);
80 /* map the cpu mask to a numa mask */
81 for (i = 0; i < sz; ++i) {
82 if(CPU_ISSET_S(i, sz, cpus)) {
83 numa_bitmask_setbit(new_nodes, numa_node_of_cpu(i));
84 }
85 }
86 /* compute the complement numa mask */
87 for (i = 0; i < nr_nodes; ++i) {
88 if (!numa_bitmask_isbitset(new_nodes, i)) {
89 numa_bitmask_setbit(old_nodes, i);
90 }
91 }
92
93 numa_set_strict(1);
94 numa_bind(new_nodes); /* sets CPU and memory policy */
95 ret = numa_migrate_pages(tid, old_nodes, new_nodes); /* move over prio alloc'ed pages */
96 numa_bitmask_free(new_nodes);
97 numa_bitmask_free(old_nodes);
98
99out:
100 return ret;
101}
102#else
103#define setup_numa(x, y, z) 0
104#endif
105
57int be_migrate_thread_to_cpu(pid_t tid, int target_cpu) 106int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
58{ 107{
59 cpu_set_t *cpu_set; 108 cpu_set_t *cpu_set;
@@ -82,7 +131,9 @@ int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
82 if (tid == 0) 131 if (tid == 0)
83 tid = gettid(); 132 tid = gettid();
84 133
85 ret = sched_setaffinity(tid, sz, cpu_set); 134 ret = (setup_numa(tid, sz, cpu_set) >= 0) ? 0 : -1;
135 if (!ret)
136 ret = sched_setaffinity(tid, sz, cpu_set);
86 137
87 CPU_FREE(cpu_set); 138 CPU_FREE(cpu_set);
88 139
@@ -114,7 +165,7 @@ int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
114 } 165 }
115 166
116 master = (ignore_rm) ? -1 : release_master(); 167 master = (ignore_rm) ? -1 : release_master();
117 num_cpus = num_online_cpus(); 168 num_cpus = num_online_cpus();
118 169
119 if (num_cpus == -1 || last_cpu >= num_cpus || first_cpu < 0) 170 if (num_cpus == -1 || last_cpu >= num_cpus || first_cpu < 0)
120 return -1; 171 return -1;
@@ -133,7 +184,9 @@ int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
133 if (tid == 0) 184 if (tid == 0)
134 tid = gettid(); 185 tid = gettid();
135 186
136 ret = sched_setaffinity(tid, sz, cpu_set); 187 ret = (setup_numa(tid, sz, cpu_set) >= 0) ? 0 : -1;
188 if (!ret)
189 ret = sched_setaffinity(tid, sz, cpu_set);
137 190
138 CPU_FREE(cpu_set); 191 CPU_FREE(cpu_set);
139 192