Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:
"This fixes an ABI bug introduced this cycle, plus fixes a throttling
bug"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched/core: Fix uclamp ABI bug, clean up and robustify sched_read_attr() ABI logic and code
sched/fair: Don't assign runtime for throttled cfs_rq

+44 -39
+39 -39
kernel/sched/core.c
··· 5105 5105 return retval; 5106 5106 } 5107 5107 5108 - static int sched_read_attr(struct sched_attr __user *uattr, 5109 - struct sched_attr *attr, 5110 - unsigned int usize) 5108 + /* 5109 + * Copy the kernel size attribute structure (which might be larger 5110 + * than what user-space knows about) to user-space. 5111 + * 5112 + * Note that all cases are valid: user-space buffer can be larger or 5113 + * smaller than the kernel-space buffer. The usual case is that both 5114 + * have the same size. 5115 + */ 5116 + static int 5117 + sched_attr_copy_to_user(struct sched_attr __user *uattr, 5118 + struct sched_attr *kattr, 5119 + unsigned int usize) 5111 5120 { 5112 - int ret; 5121 + unsigned int ksize = sizeof(*kattr); 5113 5122 5114 5123 if (!access_ok(uattr, usize)) 5115 5124 return -EFAULT; 5116 5125 5117 5126 /* 5118 - * If we're handed a smaller struct than we know of, 5119 - * ensure all the unknown bits are 0 - i.e. old 5120 - * user-space does not get uncomplete information. 5127 + * sched_getattr() ABI forwards and backwards compatibility: 5128 + * 5129 + * If usize == ksize then we just copy everything to user-space and all is good. 5130 + * 5131 + * If usize < ksize then we only copy as much as user-space has space for, 5132 + * this keeps ABI compatibility as well. We skip the rest. 5133 + * 5134 + * If usize > ksize then user-space is using a newer version of the ABI, 5135 + * which part the kernel doesn't know about. Just ignore it - tooling can 5136 + * detect the kernel's knowledge of attributes from the attr->size value 5137 + * which is set to ksize in this case. 5121 5138 */ 5122 - if (usize < sizeof(*attr)) { 5123 - unsigned char *addr; 5124 - unsigned char *end; 5139 + kattr->size = min(usize, ksize); 5125 5140 5126 - addr = (void *)attr + usize; 5127 - end = (void *)attr + sizeof(*attr); 5128 - 5129 - for (; addr < end; addr++) { 5130 - if (*addr) 5131 - return -EFBIG; 5132 - } 5133 - 5134 - attr->size = usize; 5135 - } 5136 - 5137 - ret = copy_to_user(uattr, attr, attr->size); 5138 - if (ret) 5141 + if (copy_to_user(uattr, kattr, kattr->size)) 5139 5142 return -EFAULT; 5140 5143 5141 5144 return 0; ··· 5148 5145 * sys_sched_getattr - similar to sched_getparam, but with sched_attr 5149 5146 * @pid: the pid in question. 5150 5147 * @uattr: structure containing the extended parameters. 5151 - * @size: sizeof(attr) for fwd/bwd comp. 5148 + * @usize: sizeof(attr) that user-space knows about, for forwards and backwards compatibility. 5152 5149 * @flags: for future extension. 5153 5150 */ 5154 5151 SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, 5155 - unsigned int, size, unsigned int, flags) 5152 + unsigned int, usize, unsigned int, flags) 5156 5153 { 5157 - struct sched_attr attr = { 5158 - .size = sizeof(struct sched_attr), 5159 - }; 5154 + struct sched_attr kattr = { }; 5160 5155 struct task_struct *p; 5161 5156 int retval; 5162 5157 5163 - if (!uattr || pid < 0 || size > PAGE_SIZE || 5164 - size < SCHED_ATTR_SIZE_VER0 || flags) 5158 + if (!uattr || pid < 0 || usize > PAGE_SIZE || 5159 + usize < SCHED_ATTR_SIZE_VER0 || flags) 5165 5160 return -EINVAL; 5166 5161 5167 5162 rcu_read_lock(); ··· 5172 5171 if (retval) 5173 5172 goto out_unlock; 5174 5173 5175 - attr.sched_policy = p->policy; 5174 + kattr.sched_policy = p->policy; 5176 5175 if (p->sched_reset_on_fork) 5177 - attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; 5176 + kattr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; 5178 5177 if (task_has_dl_policy(p)) 5179 - __getparam_dl(p, &attr); 5178 + __getparam_dl(p, &kattr); 5180 5179 else if (task_has_rt_policy(p)) 5181 - attr.sched_priority = p->rt_priority; 5180 + kattr.sched_priority = p->rt_priority; 5182 5181 else 5183 - attr.sched_nice = task_nice(p); 5182 + kattr.sched_nice = task_nice(p); 5184 5183 5185 5184 #ifdef CONFIG_UCLAMP_TASK 5186 - attr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value; 5187 - attr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value; 5185 + kattr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value; 5186 + kattr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value; 5188 5187 #endif 5189 5188 5190 5189 rcu_read_unlock(); 5191 5190 5192 - retval = sched_read_attr(uattr, &attr, size); 5193 - return retval; 5191 + return sched_attr_copy_to_user(uattr, &kattr, usize); 5194 5192 5195 5193 out_unlock: 5196 5194 rcu_read_unlock();
+5
kernel/sched/fair.c
··· 4470 4470 if (likely(cfs_rq->runtime_remaining > 0)) 4471 4471 return; 4472 4472 4473 + if (cfs_rq->throttled) 4474 + return; 4473 4475 /* 4474 4476 * if we're unable to extend our runtime we resched so that the active 4475 4477 * hierarchy can be throttled ··· 4674 4672 rq_lock_irqsave(rq, &rf); 4675 4673 if (!cfs_rq_throttled(cfs_rq)) 4676 4674 goto next; 4675 + 4676 + /* By the above check, this should never be true */ 4677 + SCHED_WARN_ON(cfs_rq->runtime_remaining > 0); 4677 4678 4678 4679 runtime = -cfs_rq->runtime_remaining + 1; 4679 4680 if (runtime > remaining)