diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-23 19:11:32 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-23 19:11:32 -0400 |
commit | 6f436b63bc551bbd9f9ddcf4d8a960d7d847948e (patch) | |
tree | daf47a45c3dc51afcb532ac2105e7e83b2f56161 | |
parent | fa43d7a6bb9b0e748f23529424ac5eebd849d9d7 (diff) |
Tested/Fixed IKGLP heurs. OS WORK FINALLY DONE!
-rw-r--r-- | include/litmus/ikglp_lock.h | 2 | ||||
-rw-r--r-- | include/litmus/sched_plugin.h | 1 | ||||
-rw-r--r-- | litmus/fdso.c | 4 | ||||
-rw-r--r-- | litmus/ikglp_lock.c | 172 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 16 |
5 files changed, 132 insertions, 63 deletions
diff --git a/include/litmus/ikglp_lock.h b/include/litmus/ikglp_lock.h index dd4f14e4eaff..eb017d48410a 100644 --- a/include/litmus/ikglp_lock.h +++ b/include/litmus/ikglp_lock.h | |||
@@ -120,7 +120,7 @@ struct ikglp_affinity_ops | |||
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, struct fifo_queue* dst); // 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_donor_to_fq)(struct ikglp_affinity* aff, struct fifo_queue* dst); // select a donor to move to PQ |
124 | 124 | ||
125 | void (*notify_enqueue)(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t); // fifo enqueue | 125 | void (*notify_enqueue)(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t); // fifo enqueue |
126 | void (*notify_dequeue)(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t); // fifo dequeue | 126 | void (*notify_dequeue)(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t); // fifo dequeue |
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h index f0b464207e14..24a6858b4b0b 100644 --- a/include/litmus/sched_plugin.h +++ b/include/litmus/sched_plugin.h | |||
@@ -63,6 +63,7 @@ typedef void (*task_exit_t) (struct task_struct *); | |||
63 | typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type, | 63 | typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type, |
64 | void* __user config); | 64 | void* __user config); |
65 | 65 | ||
66 | struct affinity_observer; | ||
66 | typedef long (*allocate_affinity_observer_t) ( | 67 | typedef long (*allocate_affinity_observer_t) ( |
67 | struct affinity_observer **aff_obs, int type, | 68 | struct affinity_observer **aff_obs, int type, |
68 | void* __user config); | 69 | void* __user config); |
diff --git a/litmus/fdso.c b/litmus/fdso.c index 0fc74be7f5ee..18fc61b6414a 100644 --- a/litmus/fdso.c +++ b/litmus/fdso.c | |||
@@ -20,7 +20,9 @@ | |||
20 | 20 | ||
21 | extern struct fdso_ops generic_lock_ops; | 21 | extern struct fdso_ops generic_lock_ops; |
22 | 22 | ||
23 | #ifdef CONFIG_LITMUS_AFFINITY_LOCKING | ||
23 | extern struct fdso_ops generic_affinity_ops; | 24 | extern struct fdso_ops generic_affinity_ops; |
25 | #endif | ||
24 | 26 | ||
25 | static const struct fdso_ops* fdso_ops[] = { | 27 | static const struct fdso_ops* fdso_ops[] = { |
26 | &generic_lock_ops, /* FMLP_SEM */ | 28 | &generic_lock_ops, /* FMLP_SEM */ |
@@ -28,10 +30,12 @@ static const struct fdso_ops* fdso_ops[] = { | |||
28 | &generic_lock_ops, /* RSM_MUTEX */ | 30 | &generic_lock_ops, /* RSM_MUTEX */ |
29 | &generic_lock_ops, /* IKGLP_SEM */ | 31 | &generic_lock_ops, /* IKGLP_SEM */ |
30 | &generic_lock_ops, /* KFMLP_SEM */ | 32 | &generic_lock_ops, /* KFMLP_SEM */ |
33 | #ifdef CONFIG_LITMUS_AFFINITY_LOCKING | ||
31 | &generic_affinity_ops, /* IKGLP_SIMPLE_GPU_AFF_OBS */ | 34 | &generic_affinity_ops, /* IKGLP_SIMPLE_GPU_AFF_OBS */ |
32 | &generic_affinity_ops, /* IKGLP_GPU_AFF_OBS */ | 35 | &generic_affinity_ops, /* IKGLP_GPU_AFF_OBS */ |
33 | &generic_affinity_ops, /* KFMLP_SIMPLE_GPU_AFF_OBS */ | 36 | &generic_affinity_ops, /* KFMLP_SIMPLE_GPU_AFF_OBS */ |
34 | &generic_affinity_ops, /* KFMLP_GPU_AFF_OBS */ | 37 | &generic_affinity_ops, /* KFMLP_GPU_AFF_OBS */ |
38 | #endif | ||
35 | }; | 39 | }; |
36 | 40 | ||
37 | static int fdso_create(void** obj_ref, obj_type_t type, void* __user config) | 41 | static int fdso_create(void** obj_ref, obj_type_t type, void* __user config) |
diff --git a/litmus/ikglp_lock.c b/litmus/ikglp_lock.c index 1a5d674b26a5..b7e23029b849 100644 --- a/litmus/ikglp_lock.c +++ b/litmus/ikglp_lock.c | |||
@@ -660,7 +660,7 @@ static void __ikglp_enqueue_on_fq(struct ikglp_semaphore *sem, | |||
660 | ikglp_add_donees(sem, fq, t, donee_heap_node); | 660 | ikglp_add_donees(sem, fq, t, donee_heap_node); |
661 | } | 661 | } |
662 | 662 | ||
663 | if(likely(sem->shortest_fifo_queue == fq)) { | 663 | if(sem->shortest_fifo_queue == fq) { |
664 | sem->shortest_fifo_queue = ikglp_find_shortest(sem, fq); | 664 | sem->shortest_fifo_queue = ikglp_find_shortest(sem, fq); |
665 | } | 665 | } |
666 | 666 | ||
@@ -912,7 +912,7 @@ int ikglp_lock(struct litmus_lock* l) | |||
912 | 912 | ||
913 | if(fq->count == 0) { | 913 | if(fq->count == 0) { |
914 | // take available resource | 914 | // take available resource |
915 | //replica = ikglp_get_idx(sem, fq); | 915 | replica = ikglp_get_idx(sem, fq); |
916 | 916 | ||
917 | ikglp_get_immediate(t, fq, sem, flags); // unlocks sem->lock | 917 | ikglp_get_immediate(t, fq, sem, flags); // unlocks sem->lock |
918 | 918 | ||
@@ -964,7 +964,7 @@ int ikglp_lock(struct litmus_lock* l) | |||
964 | fq = ikglp_get_queue(sem, t); | 964 | fq = ikglp_get_queue(sem, t); |
965 | BUG_ON(!fq); | 965 | BUG_ON(!fq); |
966 | 966 | ||
967 | //replica = ikglp_get_idx(sem, fq); | 967 | replica = ikglp_get_idx(sem, fq); |
968 | } | 968 | } |
969 | 969 | ||
970 | TRACE_CUR("Acquired lock %d, queue %d\n", | 970 | TRACE_CUR("Acquired lock %d, queue %d\n", |
@@ -976,7 +976,7 @@ int ikglp_lock(struct litmus_lock* l) | |||
976 | } | 976 | } |
977 | #endif | 977 | #endif |
978 | 978 | ||
979 | return ikglp_get_idx(sem, fq); | 979 | return replica; |
980 | } | 980 | } |
981 | 981 | ||
982 | static void ikglp_move_donor_to_fq(struct ikglp_semaphore *sem, | 982 | static void ikglp_move_donor_to_fq(struct ikglp_semaphore *sem, |
@@ -1184,15 +1184,7 @@ int ikglp_unlock(struct litmus_lock* l) | |||
1184 | unsigned long flags = 0, real_flags; | 1184 | unsigned long flags = 0, real_flags; |
1185 | 1185 | ||
1186 | int err = 0; | 1186 | int err = 0; |
1187 | 1187 | ||
1188 | |||
1189 | fq = ikglp_get_queue(sem, t); // returns NULL if 't' is not owner. | ||
1190 | |||
1191 | if (!fq) { | ||
1192 | err = -EINVAL; | ||
1193 | goto out; | ||
1194 | } | ||
1195 | |||
1196 | #ifdef CONFIG_LITMUS_DGL_SUPPORT | 1188 | #ifdef CONFIG_LITMUS_DGL_SUPPORT |
1197 | dgl_lock = litmus->get_dgl_spinlock(t); | 1189 | dgl_lock = litmus->get_dgl_spinlock(t); |
1198 | #endif | 1190 | #endif |
@@ -1201,6 +1193,14 @@ int ikglp_unlock(struct litmus_lock* l) | |||
1201 | lock_global_irqsave(dgl_lock, flags); // TODO: Push this deeper | 1193 | lock_global_irqsave(dgl_lock, flags); // TODO: Push this deeper |
1202 | lock_fine_irqsave(&sem->lock, flags); | 1194 | lock_fine_irqsave(&sem->lock, flags); |
1203 | 1195 | ||
1196 | |||
1197 | fq = ikglp_get_queue(sem, t); // returns NULL if 't' is not owner. | ||
1198 | |||
1199 | if (!fq) { | ||
1200 | err = -EINVAL; | ||
1201 | goto out; | ||
1202 | } | ||
1203 | |||
1204 | TRACE_TASK(t, "Freeing replica %d.\n", ikglp_get_idx(sem, fq)); | 1204 | TRACE_TASK(t, "Freeing replica %d.\n", ikglp_get_idx(sem, fq)); |
1205 | 1205 | ||
1206 | 1206 | ||
@@ -1223,7 +1223,7 @@ int ikglp_unlock(struct litmus_lock* l) | |||
1223 | 1223 | ||
1224 | // Move the next request into the FQ and update heaps as needed. | 1224 | // Move the next request into the FQ and update heaps as needed. |
1225 | // We defer re-evaluation of priorities to later in the function. | 1225 | // We defer re-evaluation of priorities to later in the function. |
1226 | if(fq->donee_heap_node.donor_info) { // move my doner to FQ | 1226 | if(fq->donee_heap_node.donor_info) { // move my donor to FQ |
1227 | ikglp_wait_state_t *donor_info = fq->donee_heap_node.donor_info; | 1227 | ikglp_wait_state_t *donor_info = fq->donee_heap_node.donor_info; |
1228 | 1228 | ||
1229 | new_on_fq = donor_info->task; | 1229 | new_on_fq = donor_info->task; |
@@ -1240,7 +1240,7 @@ int ikglp_unlock(struct litmus_lock* l) | |||
1240 | // Select a donor | 1240 | // Select a donor |
1241 | #ifdef CONFIG_LITMUS_AFFINITY_LOCKING | 1241 | #ifdef CONFIG_LITMUS_AFFINITY_LOCKING |
1242 | other_donor_info = (sem->aff_obs) ? | 1242 | other_donor_info = (sem->aff_obs) ? |
1243 | sem->aff_obs->ops->advise_doner_to_fq(sem->aff_obs, fq) : | 1243 | sem->aff_obs->ops->advise_donor_to_fq(sem->aff_obs, fq) : |
1244 | binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); | 1244 | binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); |
1245 | #else | 1245 | #else |
1246 | other_donor_info = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); | 1246 | other_donor_info = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); |
@@ -1784,7 +1784,7 @@ static struct affinity_observer* ikglp_aff_obs_new(struct affinity_observer_ops* | |||
1784 | ikglp_aff->nr_simult = aff_args.nr_simult_users; | 1784 | ikglp_aff->nr_simult = aff_args.nr_simult_users; |
1785 | ikglp_aff->nr_rsrc = sem->nr_replicas / ikglp_aff->nr_simult; | 1785 | ikglp_aff->nr_rsrc = sem->nr_replicas / ikglp_aff->nr_simult; |
1786 | 1786 | ||
1787 | memset(ikglp_aff->nr_cur_users_on_rsrc, 0, sizeof(int)*(sem->nr_replicas / ikglp_aff->nr_rsrc)); | 1787 | memset(ikglp_aff->nr_cur_users_on_rsrc, 0, sizeof(int)*(ikglp_aff->nr_rsrc)); |
1788 | 1788 | ||
1789 | for(i = 0; i < sem->nr_replicas; ++i) { | 1789 | for(i = 0; i < sem->nr_replicas; ++i) { |
1790 | ikglp_aff->q_info[i].q = &sem->fifo_queues[i]; | 1790 | ikglp_aff->q_info[i].q = &sem->fifo_queues[i]; |
@@ -1882,37 +1882,42 @@ struct fifo_queue* gpu_ikglp_advise_enqueue(struct ikglp_affinity* aff, struct t | |||
1882 | min_len); | 1882 | min_len); |
1883 | 1883 | ||
1884 | for(i = 0; i < sem->nr_replicas; ++i) { | 1884 | for(i = 0; i < sem->nr_replicas; ++i) { |
1885 | if((&aff->q_info[i] != shortest) && | 1885 | if(&aff->q_info[i] != shortest) { |
1886 | (aff->q_info[i].q->count < sem->max_fifo_len)) { | 1886 | if(aff->q_info[i].q->count < sem->max_fifo_len) { |
1887 | 1887 | ||
1888 | lt_t est_len = | 1888 | lt_t est_len = |
1889 | aff->q_info[i].estimated_len + | 1889 | aff->q_info[i].estimated_len + |
1890 | get_gpu_estimate(t, gpu_migration_distance(tsk_rt(t)->last_gpu, | 1890 | get_gpu_estimate(t, |
1891 | gpu_migration_distance(tsk_rt(t)->last_gpu, | ||
1891 | replica_to_gpu(aff, i))); | 1892 | replica_to_gpu(aff, i))); |
1892 | 1893 | ||
1893 | // queue is smaller, or they're equal and the other has a smaller number | 1894 | // queue is smaller, or they're equal and the other has a smaller number |
1894 | // of total users. | 1895 | // of total users. |
1895 | // | 1896 | // |
1896 | // tie-break on the shortest number of simult users. this only kicks in | 1897 | // tie-break on the shortest number of simult users. this only kicks in |
1897 | // when there are more than 1 empty queues. | 1898 | // when there are more than 1 empty queues. |
1898 | if((est_len < min_len) || | 1899 | if((shortest->q->count >= sem->max_fifo_len) || /* 'shortest' is full and i-th queue is not */ |
1899 | ((est_len == min_len) && (*(aff->q_info[i].nr_cur_users) < min_nr_users))) { | 1900 | (est_len < min_len) || /* i-th queue has shortest length */ |
1900 | shortest = &aff->q_info[i]; | 1901 | ((est_len == min_len) && /* equal lengths, but one has fewer over-all users */ |
1901 | min_len = est_len; | 1902 | (*(aff->q_info[i].nr_cur_users) < min_nr_users))) { |
1902 | min_nr_users = *(aff->q_info[i].nr_cur_users); | 1903 | |
1903 | } | 1904 | shortest = &aff->q_info[i]; |
1905 | min_len = est_len; | ||
1906 | min_nr_users = *(aff->q_info[i].nr_cur_users); | ||
1907 | } | ||
1904 | 1908 | ||
1905 | TRACE_CUR("cs is %llu on queue %d (count = %d): est len = %llu\n", | 1909 | TRACE_CUR("cs is %llu on queue %d (count = %d): est len = %llu\n", |
1906 | get_gpu_estimate(t, | 1910 | get_gpu_estimate(t, |
1907 | gpu_migration_distance(tsk_rt(t)->last_gpu, | 1911 | gpu_migration_distance(tsk_rt(t)->last_gpu, |
1908 | replica_to_gpu(aff, i))), | 1912 | replica_to_gpu(aff, i))), |
1909 | ikglp_get_idx(sem, aff->q_info[i].q), | 1913 | ikglp_get_idx(sem, aff->q_info[i].q), |
1910 | aff->q_info[i].q->count, | 1914 | aff->q_info[i].q->count, |
1911 | est_len); | 1915 | est_len); |
1912 | } | 1916 | } |
1913 | else { | 1917 | else { |
1914 | TRACE_CUR("queue %d is too long. ineligible for enqueue.\n", | 1918 | TRACE_CUR("queue %d is too long. ineligible for enqueue.\n", |
1915 | ikglp_get_idx(sem, aff->q_info[i].q)); | 1919 | ikglp_get_idx(sem, aff->q_info[i].q)); |
1920 | } | ||
1916 | } | 1921 | } |
1917 | } | 1922 | } |
1918 | 1923 | ||
@@ -1959,8 +1964,16 @@ static ikglp_donee_heap_node_t* pick_donee(struct ikglp_affinity* aff, | |||
1959 | ikglp_donee_heap_node_t *donee_node; | 1964 | ikglp_donee_heap_node_t *donee_node; |
1960 | struct task_struct *mth_highest = ikglp_mth_highest(sem); | 1965 | struct task_struct *mth_highest = ikglp_mth_highest(sem); |
1961 | 1966 | ||
1967 | lt_t now = litmus_clock(); | ||
1968 | |||
1969 | // TRACE_CUR("fq %d: mth_highest: %s/%d, deadline = %d: (donor) = ??? ", | ||
1970 | // ikglp_get_idx(sem, fq), | ||
1971 | // mth_highest->comm, mth_highest->pid, | ||
1972 | // (int)get_deadline(mth_highest) - now); | ||
1973 | |||
1962 | if(fq->owner && | 1974 | if(fq->owner && |
1963 | fq->donee_heap_node.donor_info != NULL && | 1975 | fq->donee_heap_node.donor_info == NULL && |
1976 | mth_highest != fq->owner && | ||
1964 | litmus->__compare(mth_highest, BASE, fq->owner, BASE)) { | 1977 | litmus->__compare(mth_highest, BASE, fq->owner, BASE)) { |
1965 | donee = fq->owner; | 1978 | donee = fq->owner; |
1966 | donee_node = &(fq->donee_heap_node); | 1979 | donee_node = &(fq->donee_heap_node); |
@@ -1976,6 +1989,20 @@ static ikglp_donee_heap_node_t* pick_donee(struct ikglp_affinity* aff, | |||
1976 | else if(waitqueue_active(&fq->wait)) { | 1989 | else if(waitqueue_active(&fq->wait)) { |
1977 | struct list_head *pos; | 1990 | struct list_head *pos; |
1978 | 1991 | ||
1992 | |||
1993 | // TRACE_CUR("fq %d: owner: %s/%d, deadline = %d: (donor) = %s/%d " | ||
1994 | // "(mth_highest != fq->owner) = %d " | ||
1995 | // "(mth_highest > fq->owner) = %d\n", | ||
1996 | // ikglp_get_idx(sem, fq), | ||
1997 | // (fq->owner) ? fq->owner->comm : "nil", | ||
1998 | // (fq->owner) ? fq->owner->pid : -1, | ||
1999 | // (fq->owner) ? (int)get_deadline(fq->owner) - now : -999, | ||
2000 | // (fq->donee_heap_node.donor_info) ? fq->donee_heap_node.donor_info->task->comm : "nil", | ||
2001 | // (fq->donee_heap_node.donor_info) ? fq->donee_heap_node.donor_info->task->pid : -1, | ||
2002 | // (mth_highest != fq->owner), | ||
2003 | // (litmus->__compare(mth_highest, BASE, fq->owner, BASE))); | ||
2004 | |||
2005 | |||
1979 | *dist_from_head = 1; | 2006 | *dist_from_head = 1; |
1980 | 2007 | ||
1981 | // iterating from the start of the queue is nice since this means | 2008 | // iterating from the start of the queue is nice since this means |
@@ -1983,7 +2010,22 @@ static ikglp_donee_heap_node_t* pick_donee(struct ikglp_affinity* aff, | |||
1983 | list_for_each(pos, &fq->wait.task_list) { | 2010 | list_for_each(pos, &fq->wait.task_list) { |
1984 | wait_queue_t *fq_wait = list_entry(pos, wait_queue_t, task_list); | 2011 | wait_queue_t *fq_wait = list_entry(pos, wait_queue_t, task_list); |
1985 | ikglp_wait_state_t *wait = container_of(fq_wait, ikglp_wait_state_t, fq_node); | 2012 | ikglp_wait_state_t *wait = container_of(fq_wait, ikglp_wait_state_t, fq_node); |
2013 | |||
2014 | // TRACE_CUR("fq %d: waiter %d: %s/%d, deadline = %d (donor) = %s/%d " | ||
2015 | // "(mth_highest != wait->task) = %d " | ||
2016 | // "(mth_highest > wait->task) = %d\n", | ||
2017 | // ikglp_get_idx(sem, fq), | ||
2018 | // dist_from_head, | ||
2019 | // wait->task->comm, wait->task->pid, | ||
2020 | // (int)get_deadline(wait->task) - now, | ||
2021 | // (wait->donee_heap_node.donor_info) ? wait->donee_heap_node.donor_info->task->comm : "nil", | ||
2022 | // (wait->donee_heap_node.donor_info) ? wait->donee_heap_node.donor_info->task->pid : -1, | ||
2023 | // (mth_highest != wait->task), | ||
2024 | // (litmus->__compare(mth_highest, BASE, wait->task, BASE))); | ||
2025 | |||
2026 | |||
1986 | if(!has_donor(fq_wait) && | 2027 | if(!has_donor(fq_wait) && |
2028 | mth_highest != wait->task && | ||
1987 | litmus->__compare(mth_highest, BASE, wait->task, BASE)) { | 2029 | litmus->__compare(mth_highest, BASE, wait->task, BASE)) { |
1988 | donee = (struct task_struct*) fq_wait->private; | 2030 | donee = (struct task_struct*) fq_wait->private; |
1989 | donee_node = &wait->donee_heap_node; | 2031 | donee_node = &wait->donee_heap_node; |
@@ -1997,8 +2039,6 @@ static ikglp_donee_heap_node_t* pick_donee(struct ikglp_affinity* aff, | |||
1997 | } | 2039 | } |
1998 | ++(*dist_from_head); | 2040 | ++(*dist_from_head); |
1999 | } | 2041 | } |
2000 | |||
2001 | WARN_ON(1); | ||
2002 | } | 2042 | } |
2003 | 2043 | ||
2004 | donee = NULL; | 2044 | donee = NULL; |
@@ -2120,16 +2160,17 @@ ikglp_donee_heap_node_t* gpu_ikglp_advise_donee_selection( | |||
2120 | default_donee->donor_info = default_donee_donor_info; | 2160 | default_donee->donor_info = default_donee_donor_info; |
2121 | 2161 | ||
2122 | if(!donee_node) { | 2162 | if(!donee_node) { |
2163 | donee_node = default_donee; | ||
2164 | |||
2123 | TRACE_CUR("Could not find a donee. We have to steal one.\n"); | 2165 | TRACE_CUR("Could not find a donee. We have to steal one.\n"); |
2124 | WARN_ON(default_donee->donor_info == NULL); | 2166 | WARN_ON(default_donee->donor_info == NULL); |
2125 | |||
2126 | donee_node = default_donee; | ||
2127 | } | 2167 | } |
2128 | 2168 | ||
2129 | out: | 2169 | out: |
2130 | 2170 | ||
2131 | TRACE_CUR("Selected donee %s/%d from GPU %d for %s/%d with affinity for GPU %d\n", | 2171 | TRACE_CUR("Selected donee %s/%d on fq %d (GPU %d) for %s/%d with affinity for GPU %d\n", |
2132 | donee_node->task->comm, donee_node->task->pid, | 2172 | donee_node->task->comm, donee_node->task->pid, |
2173 | ikglp_get_idx(sem, donee_node->fq), | ||
2133 | replica_to_gpu(aff, ikglp_get_idx(sem, donee_node->fq)), | 2174 | replica_to_gpu(aff, ikglp_get_idx(sem, donee_node->fq)), |
2134 | donor->comm, donor->pid, tsk_rt(donor)->last_gpu); | 2175 | donor->comm, donor->pid, tsk_rt(donor)->last_gpu); |
2135 | 2176 | ||
@@ -2149,6 +2190,11 @@ static void __find_closest_donor(int target_gpu, | |||
2149 | int this_dist = | 2190 | int this_dist = |
2150 | gpu_migration_distance(target_gpu, tsk_rt(this_donor->task)->last_gpu); | 2191 | gpu_migration_distance(target_gpu, tsk_rt(this_donor->task)->last_gpu); |
2151 | 2192 | ||
2193 | // TRACE_CUR("%s/%d: dist from target = %d\n", | ||
2194 | // this_donor->task->comm, | ||
2195 | // this_donor->task->pid, | ||
2196 | // this_dist); | ||
2197 | |||
2152 | if(this_dist < *cur_dist) { | 2198 | if(this_dist < *cur_dist) { |
2153 | // take this donor | 2199 | // take this donor |
2154 | *cur_dist = this_dist; | 2200 | *cur_dist = this_dist; |
@@ -2169,7 +2215,7 @@ static void __find_closest_donor(int target_gpu, | |||
2169 | if(donor_node->right) __find_closest_donor(target_gpu, donor_node->right, cur_closest, cur_dist); | 2215 | if(donor_node->right) __find_closest_donor(target_gpu, donor_node->right, cur_closest, cur_dist); |
2170 | } | 2216 | } |
2171 | 2217 | ||
2172 | ikglp_wait_state_t* gpu_ikglp_advise_doner_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq) | 2218 | ikglp_wait_state_t* gpu_ikglp_advise_donor_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq) |
2173 | { | 2219 | { |
2174 | // Huristic strategy: Find donor with the closest affinity to fq. | 2220 | // Huristic strategy: Find donor with the closest affinity to fq. |
2175 | // Tie-break on priority. | 2221 | // Tie-break on priority. |
@@ -2188,11 +2234,14 @@ ikglp_wait_state_t* gpu_ikglp_advise_doner_to_fq(struct ikglp_affinity* aff, str | |||
2188 | 2234 | ||
2189 | __find_closest_donor(gpu, sem->donors.root, &donor, &distance); | 2235 | __find_closest_donor(gpu, sem->donors.root, &donor, &distance); |
2190 | 2236 | ||
2191 | TRACE_CUR("Selected %s/%d as donor (distance = %d) " | 2237 | TRACE_CUR("Selected donor %s/%d (distance = %d) to move to fq %d " |
2192 | "(non-aff wanted %s/%d)\n", | 2238 | "(non-aff wanted %s/%d). differs = %d\n", |
2193 | donor->task->comm, donor->task->pid, | 2239 | donor->task->comm, donor->task->pid, |
2194 | distance, | 2240 | distance, |
2195 | default_donor->task->comm, default_donor->task->pid); | 2241 | ikglp_get_idx(sem, fq), |
2242 | default_donor->task->comm, default_donor->task->pid, | ||
2243 | (donor->task != default_donor->task) | ||
2244 | ); | ||
2196 | 2245 | ||
2197 | return(donor); | 2246 | return(donor); |
2198 | } | 2247 | } |
@@ -2265,7 +2314,9 @@ void gpu_ikglp_notify_dequeue(struct ikglp_affinity* aff, struct fifo_queue* fq, | |||
2265 | // } | 2314 | // } |
2266 | } | 2315 | } |
2267 | 2316 | ||
2268 | void gpu_ikglp_notify_acquired(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t) | 2317 | void gpu_ikglp_notify_acquired(struct ikglp_affinity* aff, |
2318 | struct fifo_queue* fq, | ||
2319 | struct task_struct* t) | ||
2269 | { | 2320 | { |
2270 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); | 2321 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); |
2271 | int replica = ikglp_get_idx(sem, fq); | 2322 | int replica = ikglp_get_idx(sem, fq); |
@@ -2286,7 +2337,9 @@ void gpu_ikglp_notify_acquired(struct ikglp_affinity* aff, struct fifo_queue* fq | |||
2286 | start_gpu_tracker(t); | 2337 | start_gpu_tracker(t); |
2287 | } | 2338 | } |
2288 | 2339 | ||
2289 | void gpu_ikglp_notify_freed(struct ikglp_affinity* aff, struct fifo_queue* fq, struct task_struct* t) | 2340 | void gpu_ikglp_notify_freed(struct ikglp_affinity* aff, |
2341 | struct fifo_queue* fq, | ||
2342 | struct task_struct* t) | ||
2290 | { | 2343 | { |
2291 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); | 2344 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); |
2292 | int replica = ikglp_get_idx(sem, fq); | 2345 | int replica = ikglp_get_idx(sem, fq); |
@@ -2307,7 +2360,8 @@ void gpu_ikglp_notify_freed(struct ikglp_affinity* aff, struct fifo_queue* fq, s | |||
2307 | // update estimates | 2360 | // update estimates |
2308 | update_gpu_estimate(t, get_gpu_time(t)); | 2361 | update_gpu_estimate(t, get_gpu_time(t)); |
2309 | 2362 | ||
2310 | TRACE_CUR("%s/%d freed gpu %d. actual time was %llu. estimated was %llu. diff is %d\n", | 2363 | TRACE_CUR("%s/%d freed gpu %d. actual time was %llu. " |
2364 | "estimated was %llu. diff is %d\n", | ||
2311 | t->comm, t->pid, gpu, | 2365 | t->comm, t->pid, gpu, |
2312 | get_gpu_time(t), | 2366 | get_gpu_time(t), |
2313 | est_time, | 2367 | est_time, |
@@ -2319,7 +2373,7 @@ struct ikglp_affinity_ops gpu_ikglp_affinity = | |||
2319 | .advise_enqueue = gpu_ikglp_advise_enqueue, | 2373 | .advise_enqueue = gpu_ikglp_advise_enqueue, |
2320 | .advise_steal = gpu_ikglp_advise_steal, | 2374 | .advise_steal = gpu_ikglp_advise_steal, |
2321 | .advise_donee_selection = gpu_ikglp_advise_donee_selection, | 2375 | .advise_donee_selection = gpu_ikglp_advise_donee_selection, |
2322 | .advise_doner_to_fq = gpu_ikglp_advise_doner_to_fq, | 2376 | .advise_donor_to_fq = gpu_ikglp_advise_donor_to_fq, |
2323 | 2377 | ||
2324 | .notify_enqueue = gpu_ikglp_notify_enqueue, | 2378 | .notify_enqueue = gpu_ikglp_notify_enqueue, |
2325 | .notify_dequeue = gpu_ikglp_notify_dequeue, | 2379 | .notify_dequeue = gpu_ikglp_notify_dequeue, |
@@ -2408,7 +2462,7 @@ ikglp_donee_heap_node_t* simple_gpu_ikglp_advise_donee_selection(struct ikglp_af | |||
2408 | return(donee); | 2462 | return(donee); |
2409 | } | 2463 | } |
2410 | 2464 | ||
2411 | ikglp_wait_state_t* simple_gpu_ikglp_advise_doner_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq) | 2465 | ikglp_wait_state_t* simple_gpu_ikglp_advise_donor_to_fq(struct ikglp_affinity* aff, struct fifo_queue* fq) |
2412 | { | 2466 | { |
2413 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); | 2467 | struct ikglp_semaphore *sem = ikglp_from_lock(aff->obs.lock); |
2414 | ikglp_wait_state_t* donor = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); | 2468 | ikglp_wait_state_t* donor = binheap_top_entry(&sem->donors, ikglp_wait_state_t, node); |
@@ -2457,7 +2511,7 @@ struct ikglp_affinity_ops simple_gpu_ikglp_affinity = | |||
2457 | .advise_enqueue = simple_gpu_ikglp_advise_enqueue, | 2511 | .advise_enqueue = simple_gpu_ikglp_advise_enqueue, |
2458 | .advise_steal = simple_gpu_ikglp_advise_steal, | 2512 | .advise_steal = simple_gpu_ikglp_advise_steal, |
2459 | .advise_donee_selection = simple_gpu_ikglp_advise_donee_selection, | 2513 | .advise_donee_selection = simple_gpu_ikglp_advise_donee_selection, |
2460 | .advise_doner_to_fq = simple_gpu_ikglp_advise_doner_to_fq, | 2514 | .advise_donor_to_fq = simple_gpu_ikglp_advise_donor_to_fq, |
2461 | 2515 | ||
2462 | .notify_enqueue = simple_gpu_ikglp_notify_enqueue, | 2516 | .notify_enqueue = simple_gpu_ikglp_notify_enqueue, |
2463 | .notify_dequeue = simple_gpu_ikglp_notify_dequeue, | 2517 | .notify_dequeue = simple_gpu_ikglp_notify_dequeue, |
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 422ad0395099..f2c5f180e819 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -1703,6 +1703,13 @@ static struct affinity_observer_ops gsnedf_kfmlp_affinity_ops = { | |||
1703 | .deallocate = kfmlp_aff_obs_free, | 1703 | .deallocate = kfmlp_aff_obs_free, |
1704 | }; | 1704 | }; |
1705 | 1705 | ||
1706 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
1707 | static struct affinity_observer_ops gsnedf_ikglp_affinity_ops = { | ||
1708 | .close = ikglp_aff_obs_close, | ||
1709 | .deallocate = ikglp_aff_obs_free, | ||
1710 | }; | ||
1711 | #endif | ||
1712 | |||
1706 | static long gsnedf_allocate_affinity_observer( | 1713 | static long gsnedf_allocate_affinity_observer( |
1707 | struct affinity_observer **aff_obs, | 1714 | struct affinity_observer **aff_obs, |
1708 | int type, | 1715 | int type, |
@@ -1720,9 +1727,12 @@ static long gsnedf_allocate_affinity_observer( | |||
1720 | *aff_obs = kfmlp_gpu_aff_obs_new(&gsnedf_kfmlp_affinity_ops, args); | 1727 | *aff_obs = kfmlp_gpu_aff_obs_new(&gsnedf_kfmlp_affinity_ops, args); |
1721 | break; | 1728 | break; |
1722 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | 1729 | #ifdef CONFIG_LITMUS_NESTED_LOCKING |
1723 | // case IKGLP_GPU_AFF_OBS: | 1730 | case IKGLP_SIMPLE_GPU_AFF_OBS: |
1724 | // *aff_obs = gsnedf_new_ikglp_aff(arg); | 1731 | *aff_obs = ikglp_simple_gpu_aff_obs_new(&gsnedf_ikglp_affinity_ops, args); |
1725 | // break; | 1732 | break; |
1733 | case IKGLP_GPU_AFF_OBS: | ||
1734 | *aff_obs = ikglp_gpu_aff_obs_new(&gsnedf_ikglp_affinity_ops, args); | ||
1735 | break; | ||
1726 | #endif | 1736 | #endif |
1727 | default: | 1737 | default: |
1728 | err = -ENXIO; | 1738 | err = -ENXIO; |