autogroup.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Auto-group scheduling implementation:
  4. */
  5. unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
  6. static struct autogroup autogroup_default;
  7. static atomic_t autogroup_seq_nr;
  8. #ifdef CONFIG_SYSCTL
  9. static struct ctl_table sched_autogroup_sysctls[] = {
  10. {
  11. .procname = "sched_autogroup_enabled",
  12. .data = &sysctl_sched_autogroup_enabled,
  13. .maxlen = sizeof(unsigned int),
  14. .mode = 0644,
  15. .proc_handler = proc_dointvec_minmax,
  16. .extra1 = SYSCTL_ZERO,
  17. .extra2 = SYSCTL_ONE,
  18. },
  19. };
  20. static void __init sched_autogroup_sysctl_init(void)
  21. {
  22. register_sysctl_init("kernel", sched_autogroup_sysctls);
  23. }
  24. #else
  25. #define sched_autogroup_sysctl_init() do { } while (0)
  26. #endif
  27. void __init autogroup_init(struct task_struct *init_task)
  28. {
  29. autogroup_default.tg = &root_task_group;
  30. kref_init(&autogroup_default.kref);
  31. init_rwsem(&autogroup_default.lock);
  32. init_task->signal->autogroup = &autogroup_default;
  33. sched_autogroup_sysctl_init();
  34. }
  35. void autogroup_free(struct task_group *tg)
  36. {
  37. kfree(tg->autogroup);
  38. }
  39. static inline void autogroup_destroy(struct kref *kref)
  40. {
  41. struct autogroup *ag = container_of(kref, struct autogroup, kref);
  42. #ifdef CONFIG_RT_GROUP_SCHED
  43. /* We've redirected RT tasks to the root task group... */
  44. ag->tg->rt_se = NULL;
  45. ag->tg->rt_rq = NULL;
  46. #endif
  47. sched_release_group(ag->tg);
  48. sched_destroy_group(ag->tg);
  49. }
  50. static inline void autogroup_kref_put(struct autogroup *ag)
  51. {
  52. kref_put(&ag->kref, autogroup_destroy);
  53. }
  54. static inline struct autogroup *autogroup_kref_get(struct autogroup *ag)
  55. {
  56. kref_get(&ag->kref);
  57. return ag;
  58. }
  59. static inline struct autogroup *autogroup_task_get(struct task_struct *p)
  60. {
  61. struct autogroup *ag;
  62. unsigned long flags;
  63. if (!lock_task_sighand(p, &flags))
  64. return autogroup_kref_get(&autogroup_default);
  65. ag = autogroup_kref_get(p->signal->autogroup);
  66. unlock_task_sighand(p, &flags);
  67. return ag;
  68. }
  69. static inline struct autogroup *autogroup_create(void)
  70. {
  71. struct autogroup *ag = kzalloc(sizeof(*ag), GFP_KERNEL);
  72. struct task_group *tg;
  73. if (!ag)
  74. goto out_fail;
  75. tg = sched_create_group(&root_task_group);
  76. if (IS_ERR(tg))
  77. goto out_free;
  78. kref_init(&ag->kref);
  79. init_rwsem(&ag->lock);
  80. ag->id = atomic_inc_return(&autogroup_seq_nr);
  81. ag->tg = tg;
  82. #ifdef CONFIG_RT_GROUP_SCHED
  83. /*
  84. * Autogroup RT tasks are redirected to the root task group
  85. * so we don't have to move tasks around upon policy change,
  86. * or flail around trying to allocate bandwidth on the fly.
  87. * A bandwidth exception in __sched_setscheduler() allows
  88. * the policy change to proceed.
  89. */
  90. free_rt_sched_group(tg);
  91. tg->rt_se = root_task_group.rt_se;
  92. tg->rt_rq = root_task_group.rt_rq;
  93. #endif
  94. tg->autogroup = ag;
  95. sched_online_group(tg, &root_task_group);
  96. return ag;
  97. out_free:
  98. kfree(ag);
  99. out_fail:
  100. if (printk_ratelimit()) {
  101. printk(KERN_WARNING "autogroup_create: %s failure.\n",
  102. ag ? "sched_create_group()" : "kzalloc()");
  103. }
  104. return autogroup_kref_get(&autogroup_default);
  105. }
  106. bool task_wants_autogroup(struct task_struct *p, struct task_group *tg)
  107. {
  108. if (tg != &root_task_group)
  109. return false;
  110. /*
  111. * If we race with autogroup_move_group() the caller can use the old
  112. * value of signal->autogroup but in this case sched_move_task() will
  113. * be called again before autogroup_kref_put().
  114. *
  115. * However, there is no way sched_autogroup_exit_task() could tell us
  116. * to avoid autogroup->tg, so we abuse PF_EXITING flag for this case.
  117. */
  118. if (p->flags & PF_EXITING)
  119. return false;
  120. return true;
  121. }
  122. void sched_autogroup_exit_task(struct task_struct *p)
  123. {
  124. /*
  125. * We are going to call exit_notify() and autogroup_move_group() can't
  126. * see this thread after that: we can no longer use signal->autogroup.
  127. * See the PF_EXITING check in task_wants_autogroup().
  128. */
  129. sched_move_task(p, true);
  130. }
  131. static void
  132. autogroup_move_group(struct task_struct *p, struct autogroup *ag)
  133. {
  134. struct autogroup *prev;
  135. struct task_struct *t;
  136. unsigned long flags;
  137. if (WARN_ON_ONCE(!lock_task_sighand(p, &flags)))
  138. return;
  139. prev = p->signal->autogroup;
  140. if (prev == ag) {
  141. unlock_task_sighand(p, &flags);
  142. return;
  143. }
  144. p->signal->autogroup = autogroup_kref_get(ag);
  145. /*
  146. * We can't avoid sched_move_task() after we changed signal->autogroup,
  147. * this process can already run with task_group() == prev->tg or we can
  148. * race with cgroup code which can read autogroup = prev under rq->lock.
  149. * In the latter case for_each_thread() can not miss a migrating thread,
  150. * cpu_cgroup_attach() must not be possible after cgroup_exit() and it
  151. * can't be removed from thread list, we hold ->siglock.
  152. *
  153. * If an exiting thread was already removed from thread list we rely on
  154. * sched_autogroup_exit_task().
  155. */
  156. for_each_thread(p, t)
  157. sched_move_task(t, true);
  158. unlock_task_sighand(p, &flags);
  159. autogroup_kref_put(prev);
  160. }
  161. /* Allocates GFP_KERNEL, cannot be called under any spinlock: */
  162. void sched_autogroup_create_attach(struct task_struct *p)
  163. {
  164. struct autogroup *ag = autogroup_create();
  165. autogroup_move_group(p, ag);
  166. /* Drop extra reference added by autogroup_create(): */
  167. autogroup_kref_put(ag);
  168. }
  169. EXPORT_SYMBOL(sched_autogroup_create_attach);
  170. /* Cannot be called under siglock. Currently has no users: */
  171. void sched_autogroup_detach(struct task_struct *p)
  172. {
  173. autogroup_move_group(p, &autogroup_default);
  174. }
  175. EXPORT_SYMBOL(sched_autogroup_detach);
  176. void sched_autogroup_fork(struct signal_struct *sig)
  177. {
  178. sig->autogroup = autogroup_task_get(current);
  179. }
  180. void sched_autogroup_exit(struct signal_struct *sig)
  181. {
  182. autogroup_kref_put(sig->autogroup);
  183. }
  184. static int __init setup_autogroup(char *str)
  185. {
  186. sysctl_sched_autogroup_enabled = 0;
  187. return 1;
  188. }
  189. __setup("noautogroup", setup_autogroup);
  190. #ifdef CONFIG_PROC_FS
  191. int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
  192. {
  193. static unsigned long next = INITIAL_JIFFIES;
  194. struct autogroup *ag;
  195. unsigned long shares;
  196. int err, idx;
  197. if (nice < MIN_NICE || nice > MAX_NICE)
  198. return -EINVAL;
  199. err = security_task_setnice(current, nice);
  200. if (err)
  201. return err;
  202. if (nice < 0 && !can_nice(current, nice))
  203. return -EPERM;
  204. /* This is a heavy operation, taking global locks.. */
  205. if (!capable(CAP_SYS_ADMIN) && time_before(jiffies, next))
  206. return -EAGAIN;
  207. next = HZ / 10 + jiffies;
  208. ag = autogroup_task_get(p);
  209. idx = array_index_nospec(nice + 20, 40);
  210. shares = scale_load(sched_prio_to_weight[idx]);
  211. down_write(&ag->lock);
  212. err = sched_group_set_shares(ag->tg, shares);
  213. if (!err)
  214. ag->nice = nice;
  215. up_write(&ag->lock);
  216. autogroup_kref_put(ag);
  217. return err;
  218. }
  219. void proc_sched_autogroup_show_task(struct task_struct *p, struct seq_file *m)
  220. {
  221. struct autogroup *ag = autogroup_task_get(p);
  222. if (!task_group_is_autogroup(ag->tg))
  223. goto out;
  224. down_read(&ag->lock);
  225. seq_printf(m, "/autogroup-%ld nice %d\n", ag->id, ag->nice);
  226. up_read(&ag->lock);
  227. out:
  228. autogroup_kref_put(ag);
  229. }
  230. #endif /* CONFIG_PROC_FS */
  231. int autogroup_path(struct task_group *tg, char *buf, int buflen)
  232. {
  233. if (!task_group_is_autogroup(tg))
  234. return 0;
  235. return snprintf(buf, buflen, "%s-%ld", "/autogroup", tg->autogroup->id);
  236. }