aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/litmus/ikglp_lock.h2
-rw-r--r--litmus/ikglp_lock.c65
2 files changed, 61 insertions, 6 deletions
diff --git a/include/litmus/ikglp_lock.h b/include/litmus/ikglp_lock.h
index 2558a382446c..dd4f14e4eaff 100644
--- a/include/litmus/ikglp_lock.h
+++ b/include/litmus/ikglp_lock.h
@@ -118,7 +118,7 @@ struct ikglp_queue_info
118struct ikglp_affinity_ops 118struct ikglp_affinity_ops
119{ 119{
120 struct fifo_queue* (*advise_enqueue)(struct ikglp_affinity* aff, struct task_struct* t); // select FIFO 120 struct fifo_queue* (*advise_enqueue)(struct ikglp_affinity* aff, struct task_struct* t); // select FIFO
121 ikglp_wait_state_t* (*advise_steal)(struct ikglp_affinity* aff); // select steal from FIFO 121 ikglp_wait_state_t* (*advise_steal)(struct ikglp_affinity* aff, struct fifo_queue* dst); // select steal from FIFO
122 ikglp_donee_heap_node_t* (*advise_donee_selection)(struct ikglp_affinity* aff, struct task_struct* t); // select a donee 122 ikglp_donee_heap_node_t* (*advise_donee_selection)(struct ikglp_affinity* aff, struct task_struct* t); // select a donee
123 ikglp_wait_state_t* (*advise_doner_to_fq)(struct ikglp_affinity* aff, struct fifo_queue* dst); // select a donor to move to PQ 123 ikglp_wait_state_t* (*advise_doner_to_fq)(struct ikglp_affinity* aff, struct fifo_queue* dst); // select a donor to move to PQ
124 124
diff --git a/litmus/ikglp_lock.c b/litmus/ikglp_lock.c
index 9ae71422d813..1ce6572eddcb 100644
--- a/litmus/ikglp_lock.c
+++ b/litmus/ikglp_lock.c
@@ -1281,7 +1281,7 @@ int ikglp_unlock(struct litmus_lock* l)
1281 1281
1282#ifdef CONFIG_LITMUS_AFFINITY_LOCKING 1282#ifdef CONFIG_LITMUS_AFFINITY_LOCKING
1283 fq_wait = (sem->aff_obs) ? 1283 fq_wait = (sem->aff_obs) ?
1284 sem->aff_obs->ops->advise_steal(sem->aff_obs) : 1284 sem->aff_obs->ops->advise_steal(sem->aff_obs, fq) :
1285 ikglp_find_hp_waiter_to_steal(sem); 1285 ikglp_find_hp_waiter_to_steal(sem);
1286#else 1286#else
1287 fq_wait = ikglp_find_hp_waiter_to_steal(sem); 1287 fq_wait = ikglp_find_hp_waiter_to_steal(sem);
@@ -1932,7 +1932,8 @@ struct fifo_queue* gpu_ikglp_advise_enqueue(struct ikglp_affinity* aff, struct t
1932 //return(sem->shortest_fifo_queue); 1932 //return(sem->shortest_fifo_queue);
1933} 1933}
1934 1934
1935ikglp_wait_state_t* gpu_ikglp_advise_steal(struct ikglp_affinity* aff) 1935ikglp_wait_state_t* gpu_ikglp_advise_steal(struct ikglp_affinity* aff,
1936 struct fifo_queue* dst)
1936{ 1937{
1937 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); 1938 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock);
1938 1939
@@ -2127,11 +2128,64 @@ out:
2127 return(donee_node); 2128 return(donee_node);
2128} 2129}
2129 2130
2131
2132
2133static void __find_closest_donor(int target_gpu,
2134 struct binheap_node* donor_node,
2135 ikglp_wait_state_t** cur_closest,
2136 int* cur_dist)
2137{
2138 ikglp_wait_state_t *this_donor =
2139 binheap_entry(donor_node, ikglp_wait_state_t, node);
2140
2141 int this_dist =
2142 gpu_migration_distance(target_gpu, tsk_rt(this_donor->task)->last_gpu);
2143
2144 if(this_dist < *cur_dist) {
2145 // take this donor
2146 *cur_dist = this_dist;
2147 *cur_closest = this_donor;
2148 }
2149 else if(this_dist == *cur_dist) {
2150 // priority tie-break. Even though this is a pre-order traversal,
2151 // this is a heap, not a binary tree, so we still need to do a priority
2152 // comparision.
2153 if(!(*cur_closest) ||
2154 litmus->compare(this_donor->task, (*cur_closest)->task)) {
2155 *cur_dist = this_dist;
2156 *cur_closest = this_donor;
2157 }
2158 }
2159
2160 if(donor_node->left) __find_closest_donor(target_gpu, donor_node->left, cur_closest, cur_dist);
2161 if(donor_node->right) __find_closest_donor(target_gpu, donor_node->right, cur_closest, cur_dist);
2162}
2163
2130ikglp_wait_state_t* gpu_ikglp_advise_doner_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq) 2164ikglp_wait_state_t* gpu_ikglp_advise_doner_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq)
2131{ 2165{
2132 // TODO: MAKE THIS SMARTER 2166 // Huristic strategy: Find donor with the closest affinity to fq.
2167 // Tie-break on priority.
2168
2169 // We need to iterate over all the donors to do this. Unfortunatly,
2170 // our donors are organized in a heap. We'll visit each node with a
2171 // recurisve call. This is realitively safe since there are only sem->m
2172 // donors, at most. We won't recurse too deeply to have to worry about
2173 // our stack. (even with 128 CPUs, our nest depth is at most 7 deep).
2174
2133 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); 2175 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock);
2134 ikglp_wait_state_t* donor = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); 2176 ikglp_wait_state_t *donor = NULL;
2177 int distance = MIG_NONE;
2178 int gpu = replica_to_gpu(aff, ikglp_get_idx(sem, fq));
2179 ikglp_wait_state_t* default_donor = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node);
2180
2181 __find_closest_donor(gpu, sem->donors.root, &donor, &distance);
2182
2183 TRACE_CUR("Selected %s/%d as donor (distance = %d) "
2184 "(non-aff wanted %s/%d)\n",
2185 donor->task->comm, donor->task->pid,
2186 distance,
2187 default_donor->task->comm, default_donor->task->pid);
2188
2135 return(donor); 2189 return(donor);
2136} 2190}
2137 2191
@@ -2331,7 +2385,8 @@ struct fifo_queue* simple_gpu_ikglp_advise_enqueue(struct ikglp_affinity* aff, s
2331 return to_enqueue; 2385 return to_enqueue;
2332} 2386}
2333 2387
2334ikglp_wait_state_t* simple_gpu_ikglp_advise_steal(struct ikglp_affinity* aff) 2388ikglp_wait_state_t* simple_gpu_ikglp_advise_steal(struct ikglp_affinity* aff,
2389 struct fifo_queue* dst)
2335{ 2390{
2336 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); 2391 struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock);
2337 // TRACE_CUR("Simple GPU ikglp advise_steal invoked\n"); 2392 // TRACE_CUR("Simple GPU ikglp advise_steal invoked\n");