core_sched.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * A simple wrapper around refcount. An allocated sched_core_cookie's
  4. * address is used to compute the cookie of the task.
  5. */
  6. struct sched_core_cookie {
  7. refcount_t refcnt;
  8. };
  9. static unsigned long sched_core_alloc_cookie(void)
  10. {
  11. struct sched_core_cookie *ck = kmalloc(sizeof(*ck), GFP_KERNEL);
  12. if (!ck)
  13. return 0;
  14. refcount_set(&ck->refcnt, 1);
  15. sched_core_get();
  16. return (unsigned long)ck;
  17. }
  18. static void sched_core_put_cookie(unsigned long cookie)
  19. {
  20. struct sched_core_cookie *ptr = (void *)cookie;
  21. if (ptr && refcount_dec_and_test(&ptr->refcnt)) {
  22. kfree(ptr);
  23. sched_core_put();
  24. }
  25. }
  26. static unsigned long sched_core_get_cookie(unsigned long cookie)
  27. {
  28. struct sched_core_cookie *ptr = (void *)cookie;
  29. if (ptr)
  30. refcount_inc(&ptr->refcnt);
  31. return cookie;
  32. }
  33. /*
  34. * sched_core_update_cookie - replace the cookie on a task
  35. * @p: the task to update
  36. * @cookie: the new cookie
  37. *
  38. * Effectively exchange the task cookie; caller is responsible for lifetimes on
  39. * both ends.
  40. *
  41. * Returns: the old cookie
  42. */
  43. static unsigned long sched_core_update_cookie(struct task_struct *p,
  44. unsigned long cookie)
  45. {
  46. unsigned long old_cookie;
  47. struct rq_flags rf;
  48. struct rq *rq;
  49. rq = task_rq_lock(p, &rf);
  50. /*
  51. * Since creating a cookie implies sched_core_get(), and we cannot set
  52. * a cookie until after we've created it, similarly, we cannot destroy
  53. * a cookie until after we've removed it, we must have core scheduling
  54. * enabled here.
  55. */
  56. SCHED_WARN_ON((p->core_cookie || cookie) && !sched_core_enabled(rq));
  57. if (sched_core_enqueued(p))
  58. sched_core_dequeue(rq, p, DEQUEUE_SAVE);
  59. old_cookie = p->core_cookie;
  60. p->core_cookie = cookie;
  61. /*
  62. * Consider the cases: !prev_cookie and !cookie.
  63. */
  64. if (cookie && task_on_rq_queued(p))
  65. sched_core_enqueue(rq, p);
  66. /*
  67. * If task is currently running, it may not be compatible anymore after
  68. * the cookie change, so enter the scheduler on its CPU to schedule it
  69. * away.
  70. *
  71. * Note that it is possible that as a result of this cookie change, the
  72. * core has now entered/left forced idle state. Defer accounting to the
  73. * next scheduling edge, rather than always forcing a reschedule here.
  74. */
  75. if (task_on_cpu(rq, p))
  76. resched_curr(rq);
  77. task_rq_unlock(rq, p, &rf);
  78. return old_cookie;
  79. }
  80. static unsigned long sched_core_clone_cookie(struct task_struct *p)
  81. {
  82. unsigned long cookie, flags;
  83. raw_spin_lock_irqsave(&p->pi_lock, flags);
  84. cookie = sched_core_get_cookie(p->core_cookie);
  85. raw_spin_unlock_irqrestore(&p->pi_lock, flags);
  86. return cookie;
  87. }
  88. void sched_core_fork(struct task_struct *p)
  89. {
  90. RB_CLEAR_NODE(&p->core_node);
  91. p->core_cookie = sched_core_clone_cookie(current);
  92. }
  93. void sched_core_free(struct task_struct *p)
  94. {
  95. sched_core_put_cookie(p->core_cookie);
  96. }
  97. static void __sched_core_set(struct task_struct *p, unsigned long cookie)
  98. {
  99. cookie = sched_core_get_cookie(cookie);
  100. cookie = sched_core_update_cookie(p, cookie);
  101. sched_core_put_cookie(cookie);
  102. }
  103. /* Called from prctl interface: PR_SCHED_CORE */
  104. int sched_core_share_pid(unsigned int cmd, pid_t pid, enum pid_type type,
  105. unsigned long uaddr)
  106. {
  107. unsigned long cookie = 0, id = 0;
  108. struct task_struct *task, *p;
  109. struct pid *grp;
  110. int err = 0;
  111. if (!static_branch_likely(&sched_smt_present))
  112. return -ENODEV;
  113. BUILD_BUG_ON(PR_SCHED_CORE_SCOPE_THREAD != PIDTYPE_PID);
  114. BUILD_BUG_ON(PR_SCHED_CORE_SCOPE_THREAD_GROUP != PIDTYPE_TGID);
  115. BUILD_BUG_ON(PR_SCHED_CORE_SCOPE_PROCESS_GROUP != PIDTYPE_PGID);
  116. if (type > PIDTYPE_PGID || cmd >= PR_SCHED_CORE_MAX || pid < 0 ||
  117. (cmd != PR_SCHED_CORE_GET && uaddr))
  118. return -EINVAL;
  119. rcu_read_lock();
  120. if (pid == 0) {
  121. task = current;
  122. } else {
  123. task = find_task_by_vpid(pid);
  124. if (!task) {
  125. rcu_read_unlock();
  126. return -ESRCH;
  127. }
  128. }
  129. get_task_struct(task);
  130. rcu_read_unlock();
  131. /*
  132. * Check if this process has the right to modify the specified
  133. * process. Use the regular "ptrace_may_access()" checks.
  134. */
  135. if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
  136. err = -EPERM;
  137. goto out;
  138. }
  139. switch (cmd) {
  140. case PR_SCHED_CORE_GET:
  141. if (type != PIDTYPE_PID || uaddr & 7) {
  142. err = -EINVAL;
  143. goto out;
  144. }
  145. cookie = sched_core_clone_cookie(task);
  146. if (cookie) {
  147. /* XXX improve ? */
  148. ptr_to_hashval((void *)cookie, &id);
  149. }
  150. err = put_user(id, (u64 __user *)uaddr);
  151. goto out;
  152. case PR_SCHED_CORE_CREATE:
  153. cookie = sched_core_alloc_cookie();
  154. if (!cookie) {
  155. err = -ENOMEM;
  156. goto out;
  157. }
  158. break;
  159. case PR_SCHED_CORE_SHARE_TO:
  160. cookie = sched_core_clone_cookie(current);
  161. break;
  162. case PR_SCHED_CORE_SHARE_FROM:
  163. if (type != PIDTYPE_PID) {
  164. err = -EINVAL;
  165. goto out;
  166. }
  167. cookie = sched_core_clone_cookie(task);
  168. __sched_core_set(current, cookie);
  169. goto out;
  170. default:
  171. err = -EINVAL;
  172. goto out;
  173. }
  174. if (type == PIDTYPE_PID) {
  175. __sched_core_set(task, cookie);
  176. goto out;
  177. }
  178. read_lock(&tasklist_lock);
  179. grp = task_pid_type(task, type);
  180. do_each_pid_thread(grp, type, p) {
  181. if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) {
  182. err = -EPERM;
  183. goto out_tasklist;
  184. }
  185. } while_each_pid_thread(grp, type, p);
  186. do_each_pid_thread(grp, type, p) {
  187. __sched_core_set(p, cookie);
  188. } while_each_pid_thread(grp, type, p);
  189. out_tasklist:
  190. read_unlock(&tasklist_lock);
  191. out:
  192. sched_core_put_cookie(cookie);
  193. put_task_struct(task);
  194. return err;
  195. }
  196. #ifdef CONFIG_SCHEDSTATS
  197. /* REQUIRES: rq->core's clock recently updated. */
  198. void __sched_core_account_forceidle(struct rq *rq)
  199. {
  200. const struct cpumask *smt_mask = cpu_smt_mask(cpu_of(rq));
  201. u64 delta, now = rq_clock(rq->core);
  202. struct rq *rq_i;
  203. struct task_struct *p;
  204. int i;
  205. lockdep_assert_rq_held(rq);
  206. WARN_ON_ONCE(!rq->core->core_forceidle_count);
  207. if (rq->core->core_forceidle_start == 0)
  208. return;
  209. delta = now - rq->core->core_forceidle_start;
  210. if (unlikely((s64)delta <= 0))
  211. return;
  212. rq->core->core_forceidle_start = now;
  213. if (WARN_ON_ONCE(!rq->core->core_forceidle_occupation)) {
  214. /* can't be forced idle without a running task */
  215. } else if (rq->core->core_forceidle_count > 1 ||
  216. rq->core->core_forceidle_occupation > 1) {
  217. /*
  218. * For larger SMT configurations, we need to scale the charged
  219. * forced idle amount since there can be more than one forced
  220. * idle sibling and more than one running cookied task.
  221. */
  222. delta *= rq->core->core_forceidle_count;
  223. delta = div_u64(delta, rq->core->core_forceidle_occupation);
  224. }
  225. for_each_cpu(i, smt_mask) {
  226. rq_i = cpu_rq(i);
  227. p = rq_i->core_pick ?: rq_i->curr;
  228. if (p == rq_i->idle)
  229. continue;
  230. /*
  231. * Note: this will account forceidle to the current CPU, even
  232. * if it comes from our SMT sibling.
  233. */
  234. __account_forceidle_time(p, delta);
  235. }
  236. }
  237. void __sched_core_tick(struct rq *rq)
  238. {
  239. if (!rq->core->core_forceidle_count)
  240. return;
  241. if (rq != rq->core)
  242. update_rq_clock(rq->core);
  243. __sched_core_account_forceidle(rq);
  244. }
  245. #endif /* CONFIG_SCHEDSTATS */