Page MenuHomeFreeBSD

sched_ule: fix invalid tdq_slice() and sched_slice_min
Needs ReviewPublic

Authored by mchoo on Fri, Sep 4, 5:41 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Sep 12, 1:13 PM
Unknown Object (File)
Sat, Sep 12, 1:11 PM
Unknown Object (File)
Fri, Sep 11, 10:29 PM
Unknown Object (File)
Fri, Sep 11, 9:11 PM
Unknown Object (File)
Fri, Sep 11, 9:04 PM
Unknown Object (File)
Thu, Sep 10, 11:30 PM
Unknown Object (File)
Thu, Sep 10, 7:09 PM
Unknown Object (File)
Thu, Sep 10, 3:51 AM
Subscribers

Details

Reviewers
jhb
olce
Group Reviewers
scheduler
Summary

sched_slice_min should always to be greater than zero. When modifying
sched_slice through sysctl, if the new value is less than
SCHED_SLICE_MIN_DIVISOR, sched_slice_min is computed to zero. Add
imax(1, ...) to prevent this.

tdq_slice() should not return a value less than sched_slice_min since
that will cause integer underflow of ts2->ts_slice in
sched_ule_fork_thread. SCHED_SLICE_MIN_DIVISOR is currently set to 6 so
when load is 5 and sched_slice is 4, the two if conditions in
tdq_slice() will pass and the function will return zero. Thus use imax()
so tdq_slice returns sched_slice_min at minimum.

MFC after: 2 weeks
MFC to: stable/14, stable/15
Sponsored by: FreeBSD Foundation

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
No Test Coverage
Build Status
Buildable 76666
Build 73549: arc lint + arc unit

Event Timeline

mchoo requested review of this revision.Fri, Sep 4, 5:41 PM

Slice is number of ticks a thread is allowed to run, thus having slice
value of 0 shouldn't be accepted as threads will never run. In
tdq_slice(), when sched_slice > load, the function will return 0.

You probably meant sched_slice < load, but anyway that is not true, as the first if is precisely here to avoid that.

Similarily in sysctl.kern.ule.{quantum,slice}, if sched_slice is set
less then SCHED_SLICE_MIN_DIVISOR, sched_slice_min is computated as
zero.

That's indeed a real problem. (In passing, "computated" => "computed".)

I like the change, not only because it fixes a problem, but also because it removes a comparison in tdq_slice().

This revision is now accepted and ready to land.Sun, Sep 6, 9:34 PM

Slice is number of ticks a thread is allowed to run, thus having slice
value of 0 shouldn't be accepted as threads will never run. In
tdq_slice(), when sched_slice > load, the function will return 0.

You probably meant sched_slice < load, but anyway that is not true, as the first if is precisely here to avoid that.

I meant sched_slice < load. sysctl_kern_slice() lets you set any slice greater or equal to 1. When sched_slice is set to 4 load is 5, the first if condition passes because SCHED_SLICE_MIN_DIVISOR is set to 6 by macro definition. Second if condition also passes and tdq_slice() returns 0.

sysctl_kern_slice() lets you set any slice greater or equal to 1. When sched_slice is set to 4 load is 5, the first if condition passes because SCHED_SLICE_MIN_DIVISOR is set to 6 by macro definition. Second if condition also passes and tdq_slice() returns 0.

Yes, of course, but what is written in the first paragraph gives the impression you are talking about tdq_slice()'s code only, mainly because you mention the "sched_slice > load" condition, which is not the full condition for that function to produce 0. Additionally, you're mentioning the real source bug only in the second paragraph, which is the indirect cause of tdq_slice()'s problem. So please amend the commit message to that the the reason for the bug and the conditions of occurrence are clear.

This revision now requires review to proceed.Tue, Sep 8, 3:38 PM
mchoo retitled this revision from sched_ule: fix invalid tdq_slice() and slice_min to sched_ule: fix invalid tdq_slice() and sched_slice_min.Tue, Sep 8, 3:39 PM
mchoo edited the summary of this revision. (Show Details)

@olce I now see the commit message was misleading. I updated it.