kern/157657: ksched_setscheduler interprets TS priority as RT priority

Dmitry V. Krivenok krivenok.dmitry at gmail.com
Mon Jun 6 11:50:12 UTC 2011


>Number:         157657
>Category:       kern
>Synopsis:       ksched_setscheduler interprets TS priority as RT priority
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 06 11:50:12 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry V. Krivenok
>Release:        CURRENT
>Organization:
>Environment:
FreeBSD csx-spb-freebsd9.sspg.lab.emc.com 9.0-CURRENT FreeBSD 9.0-CURRENT #0 r222722M: Mon Jun  6 14:31:25 MSD 2011     root at csx-spb-freebsd9.sspg.lab.emc.com:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
At line 209 of ksched_setscheduler function TS priority is interpreted as RT priority:

205                 case SCHED_OTHER:
206                 if (param->sched_priority >= 0 &&
207                         param->sched_priority <=
(PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) {
208                         rtp.type = RTP_PRIO_NORMAL;
209                         rtp.prio = p4prio_to_rtpprio(param->sched_priority);
210                         rtp_to_pri(&rtp, td);
211                 } else
212                         e = EINVAL;

I think that p4prio_to_tsprio should be used instead of p4prio_to_rtpprio.
>How-To-Repeat:
Compile the following program:
gcc -Wall setscheduler_bug.c -o setscheduler_bug

#include <assert.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char** argv)
{
  int r;
  struct sched_param param;
  assert(argc == 2);
  r = sched_getscheduler(getpid());
  assert(r != -1);
  printf("Initial policy: %d\n", r);
  r = sched_getparam(getpid(), &param);
  assert(r != -1);
  printf("Initial priority: %d\n", param.sched_priority);

  param.sched_priority = atoi(argv[1]);
  r = sched_setscheduler(getpid(), SCHED_OTHER, &param);
  assert(r != -1);

  r = sched_getparam(getpid(), &param);
  assert(r != -1);
  printf("New priority: %d\n", param.sched_priority);

  return 0;
}

and run it with root permissions:

$ sudo ./setscheduler_bug 32
Initial policy: 2
Initial priority: 100
New priority: 100
$ sudo ./setscheduler_bug 0
Initial policy: 2
Initial priority: 100
New priority: 72
$

As you can see new priorities are wrong.
>Fix:
Apply the following patch and rebuild the kernel

Index: sys/kern/ksched.c
===================================================================
--- sys/kern/ksched.c   (revision 222722)
+++ sys/kern/ksched.c   (working copy)
@@ -206,7 +206,7 @@
                if (param->sched_priority >= 0 &&
                        param->sched_priority <= (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) {
                        rtp.type = RTP_PRIO_NORMAL;
-                       rtp.prio = p4prio_to_rtpprio(param->sched_priority);
+                       rtp.prio = p4prio_to_tsprio(param->sched_priority);
                        rtp_to_pri(&rtp, td);
                } else
                        e = EINVAL;


Then run the same program again and you should see expected priorities:

$ sudo ./setscheduler_bug 32
Initial policy: 2
Initial priority: 100
New priority: 32
$ sudo ./setscheduler_bug 0
Initial policy: 2
Initial priority: 100
New priority: 0
$

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list