From: Roman Gushchin <[email protected]> This commit adds the following helper functions: acquire_core() - acquires per-core lock release_core() - releases per-core lock core_acquired() - checks if per-core lock is acquired core_is_rt_free() - checks if there are no rt tasks on specified core core_rt_free_thread() - finds free SMT thread on specified core find_rt_free_core() - finds free core starting with specified core
Signed-off-by: Roman Gushchin <[email protected]> --- kernel/sched/sched.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 7e26454..4603096 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1418,6 +1418,89 @@ static inline int next_core(int cpu) return smart_data(cpu).core_next; } +static inline int acquire_core(int cpu) +{ + return (0 == atomic_cmpxchg(&smart_data(cpu).core_locked, 0, 1)); +} + +static inline void release_core(int cpu) +{ + atomic_set(&smart_data(cpu).core_locked, 0); +} + +static inline int core_acquired(int cpu) +{ + return atomic_read(&smart_data(cpu).core_locked); +} + +static inline int core_is_rt_free(int core) +{ + struct rq *rq; + int cpu; + unsigned int nr_rt; + struct task_struct *task; + + for_each_cpu(cpu, topology_thread_cpumask(core)) { + rq = cpu_rq(cpu); + + if (rq->rt.rt_throttled) + return 0; + + nr_rt = rq->rt.rt_nr_running; + if (nr_rt) { + if (nr_rt > 1) + return 0; + + task = ACCESS_ONCE(rq->curr); + if (task->mm) + return 0; + } + } + + return 1; +} + +static inline int core_rt_free_thread(int core) +{ + struct rq *rq; + int cpu; + + for_each_cpu(cpu, topology_thread_cpumask(core)) { + rq = cpu_rq(cpu); + + if (rq->rt.rt_throttled) + continue; + + if (!rq->rt.rt_nr_running) + return cpu; + } + + return -1; +} + +static inline int find_rt_free_core(int start_cpu, struct task_struct *task) +{ + int core; + + /* Local cores */ + core = cpu_core_id(start_cpu); + do { + if (!core_acquired(core) && core_is_rt_free(core) && + cpumask_test_cpu(core, tsk_cpus_allowed(task))) + return core; + } while (core = next_core(core), core != cpu_core_id(start_cpu)); + + /* Remote cores */ + core = core_node_sibling(start_cpu); + do { + if (!core_acquired(core) && core_is_rt_free(core) && + cpumask_test_cpu(core, tsk_cpus_allowed(task))) + return core; + } while (core = next_core(core), core != core_node_sibling(start_cpu)); + + return -1; +} + void build_smart_topology(void); #else /* CONFIG_SMART */ @@ -1430,4 +1513,8 @@ static inline bool smart_enabled(void) return false; } +static inline void release_core(int cpu) +{ +} + #endif /* CONFIG_SMART */ -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

