class_scheduling(4)class_scheduling(4)NAME
class_scheduling, class.h - Allocate CPU resources based on scheduling
classes
SYNOPSIS
#include <sys/class.h>
DESCRIPTION
The class scheduling features included in the operating system software
let you restrict the percentage of CPU time allowed different kinds of
users and tasks. This helps you allocate CPU resources so that the most
important work receives the processing time it requires. For example,
you might want to run two versions of a production database on your
system. One version is used as part of your business operations, while
the other is a test copy, with different tuning parameters. The test
database can be assigned to a class that has a lower percentage of CPU
time so that your daily operations are not impacted by the testing. As
another example, you might want to give background daemons, such as the
print spooler, less access time to CPUs to improve response time for
interactive users.
By using the class_admin utility, you can: Create and maintain one or
more databases of scheduling classes, each of which has a specified
percentage of CPU time. The databases are typically stored in the
/etc/class directory and cannot be edited manually. You can set up dif‐
ferent class databases for different time intervals during a 24-hour
period (for example, one database that favors interactive users during
the day and another that favors batch jobs at night). A class_admin
load command can then be included as a cron job to load the appropriate
database into shared memory at a certain time. Assign members to dif‐
ferent classes. Members assigned to a particular class can be users,
groups, processes, process groups, sessions, or some combination of
these. Enable and disable the daemon that schedules execution of dif‐
ferent tasks according to what you've defined in the database currently
loaded into memory. Among the configuration parameters you supply dur‐
ing setup of the class database is a time interval that controls how
often the daemon refreshes the structure used by the kernel to imple‐
ment your class scheduling priorities.
You cannot use the class_admin utility to add application names to a
class. However, after defining a class in the current database and
enabling class scheduling, you can use runclass commands to launch pro‐
grams in that class. When you do this, identifiers for all the applica‐
tion processes are automatically added as members of the specified
class. The runclass command is particularly useful as a cron job that
executes after the one that enables class scheduling and loads a par‐
ticular class database into memory.
The libclass library provides programming routines for setting up and
using class scheduling. The name for each routine in this library uses
the format class_operation, for example class_create(). A complete list
of routines is provided in the SEE ALSO section.
How Class Scheduling Works
The kernel has very little internal knowledge of class scheduling.
Much of the work done by the class scheduler is done in user space. To
the kernel, a class is simply an element in an array of integers, each
specifying a number of clock ticks that are available for a certain
time interval. The time interval is set when the class scheduling data‐
base is configured, and the integer values vary, depending on the CPU
percentage specified for the different classes. A thread that is sub‐
ject to class scheduling has an index into the array. Each time the
thread uses CPU time, the kernel decrements the number of clock ticks
used from the array element. When the count reaches zero, the thread is
prevented from running.
A class database can be configured to impose CPU percentages in either
a hard or soft way. Hard percentages (the default) mean that, once a
thread uses its allotted percentage of CPU time, it is prevented from
running until the next time interval. Soft percentages mean that thread
execution can continue after the CPU percentage is reached if the sys‐
tem has idle CPUs (if there is no contention for CPU time among users).
Hard percentages risk wasting CPU cycles; however, they are appropriate
for a system on which users contract and pay for a certain allocation
of system resources..
When the class scheduler daemon is started, it loads the database into
memory, creates an initial array of clock-tick integers used by the
kernel, and writes this array to the kernel. Along with the array, the
daemon gives the kernel the time interval during which integers in the
array are to be decremented. Then the daemon alternately sleeps and
wakes up to refresh the array. The daemon calculates the total number
of clock ticks in the interval during which it sleeps by using the fol‐
lowing formula:
interval_in_seconds * clock_ticks_per_second * number_of_CPUs
The deamon then allocates the total number of clock ticks among classes
according to the specified percentages, creates the array of integers,
and writes the array to the kernel. Should the daemon terminate or fail
to wake up, the kernel automatically disables class scheduling after
twice the specified time interval has passed. If this happens, pro‐
cesses belonging to scheduling classes then run freely, no longer sub‐
ject to their CPU percentage restrictions.
Class scheduling always operates in the context of a soft partition,
which is currently mapped to a processor set. (See processor_sets(4).)
This means that “number_of_CPUs” in the preceding formula represents
the number of CPUs in the partition associated with the class database.
If user-defined partitions do not exist on the system, all system CPUs
belong to the default partition (processor set 0), and the system can
have only one active database and one instance of a class scheduler
daemon. If system CPUs have been allocated into different partitions,
you have the option of setting up class scheduling on one or more of
the available partitions.
By default, the class_admin utility operates on the system default par‐
tition; however, the utility includes the setp subcommand to change
partition context for subsequent subcommands. For each partition where
you want class scheduling to be implemented, you must create at least
one class scheduling database and enable class scheduling. See
class_admin(8) for details.
A process may be represented in a class database by members in more
than one class. For example, the group ID representing the group staff
might be a member of class A and the user ID representing the user
guest might be a member of class B. If user guest belongs to group
staff, the user belongs to two classes. In such cases, the class con‐
taining the most restrictive type of ID applies to the process. For
the example just described, user ID is more restrictive than group ID,
so the process for user guest would execute in class B. When member
types are ranked from least to most restrictive, the order is as fol‐
lows: group ID, user ID, session ID, process group ID, process ID.
Class scheduling is subject to the following limits, as defined in the
class.h header file: Maximum of partitions (class database/daemon
pairs) per system: 100 Maximum number of classes per database: 100 Max‐
imum number of members across all classes: 2500 Maximum number of char‐
acters in a class database pathname (for save and load subcommands): 80
Maximum number of characters in a class name: 20
Class scheduling is subject to the following restrictions: You must be
superuser to invoke the class_admin utility. Users cannot use the run‐
class command to raise an application's priority above what it would
otherwise have through definitions in the class database. In other
words, a user who is a member of a class entitled to a certain percent‐
age of CPU time cannot use the runclass command to start applications
at a higher priority than what the user is entitled to. For most oper‐
ations that applications perform by using routines in the libclass
library, root permission is required.
Using Class Scheduling
To implement class scheduling, you must first create a database file
and populate the file with one or more classes. You assign each class
a percentage of the total CPU time available. One or more applications
or groups of applications can be assigned to a class, specified by the
appropriate identifying number, such as a GID, UID, or PID. Any identi‐
fiers that are temporary, such as a PID, do not persist across a reboot
and cease to exist when a task is completed. Therefore, they have no
effect when the system or task is restarted. For this reason, the mem‐
bers you add to the database when first creating it are usually user
and group identifiers.
After the database is established, you can start the class scheduling
daemon to put the CPU access restrictions into effect. The class_admin
utility has subcommands that let you review classes, change members and
CPU percentages, delete members or entire classes, and review assigned
CPU percentages against actual use. You can invoke the utility either
interactively or by using a script.
Once a class scheduling database is configured and its corresponding
daemon enabled, you can start applications in any of the existing
classes by using the runclass command. This allows you to indirectly
add entirely new processes to a class. It also allows you to temporar‐
ily lower or (if you have superuser privilege) increase the CPU per‐
centages for processes that otherwise startup in a class with a differ‐
ent CPU percentage. For example, you might set a value for interactive
operations that is much higher than background processes such as print
daemons. If it is later necessary to temporarily use the higher value
for a particular print job, you can use the runclass command to execute
the lpd daemon in the same class as interactive operations. After the
print job has completed, the class_admin delete subcommand can be used
to remove the process identifier for lpd from the class.
The following sections suggest a systematic approach to using class
scheduling, although you can use it equally well to quickly fix a CPU
resource sharing problem.
Planning CPU Resource Allocation
How you allocate CPU resources will depend on your system environment
and which resources and priorities must be considered. A typical sce‐
nario is to assign a higher priority to interactive tasks so that users
do not encounter long response times. Most batch or background pro‐
cesses will be assigned a lower priority, while some specific back‐
ground processes may require a higher priority. For example, if a
nightly backup is being performed, you might not want it to have such a
low priority that it does not complete in a reasonable time.
An alternative scenario is if there are critical realtime tasks, such
as in process-control applications, that should take priority over
interactive processes. For this scenario, you should design a baseline,
assigning processes to classes and then monitor tasks and user feedback
to tune the database by moving tasks from class to class or changing
the CPU access time of the classes.
While thinking about CPU resource allocation, you need to decide
whether you should use class scheduling, a user-defined processor set,
or both on your system. CPUs in a user-defined processor set cannot be
used by any process that is not explicitly run on that processor set.
Sometimes reserving specific CPUs for use only by certain applications,
such as those doing realtime process control, is warranted. For criti‐
cal applications, a processor set can provide a better guarantee of
immediate CPU availability than class scheduling if the system load is
high and load patterns are not always predictable. When running
selected applications in a non-default processor set, you trade off
potential waste of CPU resources to guarantee that CPUs are available
for the applications running in that processor set. Setting “soft” CPU
percentages for scheduling classes allows the kernel to apply only the
idle CPUs in the processor set for which the class database was cre‐
ated. The kernel cannot use idle CPUs in one processor set to ease CPU
contention by processes running in another processor set. This means
that the performance of less critical applications might not be accept‐
able after they are restricted to the reduced number of CPUs in the
default processor set. Using class scheduling in a processor set to
better control CPU access is not likely to help when there are simply
too few CPUs to do the required amount of work.
Sometimes your site might be running an application that incorrectly
spawns large numbers of threads that immediately grab more CPU
resources than the application needs. Until the application can be cor‐
rected, you can define a new processor set, populate it with a subset
of the system CPUs, and use the runon command to start the application
in the new processor set. In this case, it might or might not be worth‐
while to use class scheduling in the default processor set where
remaining applications are run and interactive user processes are run‐
ning.
If your intention is simply to apply a more appropriate allocation of
CPU resources than the kernel applies by default, try class scheduling
by itself (on the default processor set while it contains all system
CPUs) to see if this approach accomplishes what you want. Consider
defining and using an additional processor set in order to meet the
requirements of applications with unusual requirements.
Steps for Setting Up and Using Class Scheduling
The usual process for setting up class scheduling is as follows: Decide
how you want to allocate the CPU resources (decide on class groupings
of users and tasks). Use the class_admin utility's subcommands to set
up and maintain the class database: Configure the database. For this
step, you specify: whether you want a default class for processes
(other than those for UID 0) that are not members of the classes you
define, whether you want hard or soft enforcement of CPU percentages,
and how frequently the scheduler checks CPU usage by classes. Create
classes and add any users and groups to classes by using the create and
add subcommands. When creating classes, keep in mind the 20-character
restriction on class names and the fact that CPU percentages for all
your classes cannot add up to more than 100 percent. Verify class
entries with the show subcommand. Use the save subcommand to write
database entries to /etc/class/filename. Keep in mind the 80-character
pathname restriction if you prefer your own directory locations and
names for class databases. Use the enable subcommand to start the
scheduler.
Applications are usually added to classes after class scheduling
is enabled by using the runclass command, which is not a subcom‐
mand in the class_admin utility. Use the stats subcommand to
check target and actual CPU usages for the different classes.
The following example shows an interactive class_admin session that
sets up two class databases (daytime and nighttime) for the default
partition. In this example, both databases have the same two classes
(interactive_users and batch_jobs), however, the CPU percentages for
these classes and the time interval for resetting class usage are set
differently. After the two databases are created and saved to disk, the
daytime database is loaded into memory, the scheduler daemon is
enabled, and runtime statistics are checked: # class_admin
Class Scheduler Administration configure:
Shall processes that have not been explicitly assigned to a defined
class be assigned to a 'default' class? Enter (yes/no) [no]:
Enforce class scheduling when the CPU is otherwise idle? (yes/no)
[yes]: no
How often do you want the system to reset class usage? Enter number of
seconds (1): class> show Configuration:
-Processes not explicitly defined in the database are not
class scheduled.
-If the processor has some idle time, class scheduled processes are
allowed to exceed their cpu percentage.
-The class scheduler will check class CPU usage every 1 seconds.
current partition: 0 current database: /etc/class/part.default Class
scheduler status: disabled
classes:
class> create interactive_users 50 interactive_users created at 50% cpu
usage class> create batch_jobs 10 batch_jobs created at 10% cpu usage
class> add interactive_users uid 234 457 235 uid 234 457 235 added to
interactive_users. class> save /etc/class/daytime database
/etc/class/daytime saved class> modify interactive_users 10 interac‐
tive_users targeted at 10% usage class> modify batch_jobs 50 batch_jobs
targeted at 50% class> configure Shall processes that have not been
explicitly assigned to a defined class be assigned to a 'default'
class? Enter (yes/no) [no]:
Enforce class scheduling when the CPU is otherwise idle? (yes/no)
[yes]: no
How often do you want the system to reset class usage? Enter number of
seconds (1): 5 class> save /etc/class/nighttime database
/etc/class/nighttime saved class> load /etc/class/daytime
The following warning and prompt is displayed because this session has
not saved any changes to the /etc/class/part.default file, which is the
database to which context was set at the beginning of the interactive
session. However, all permanent changes were saved to databases with
more meaningful names, and there is no intention to put the
/etc/class/part.default database into use. Therefore, the utility is
told to continue with the load operation: current database modified and
not saved load new database anyway? (yes/no) [yes]: yes database
/etc/class/daytime loaded class> enable class scheduler enabled class>
In another terminal window, the runclass command is used to start one
or two low-priority applications in the batch_jobs class. For example:
# runclass batch_jobs program_name
Then, runtime statistics can be checked in the window of the
class_admin session: class> stats
Class scheduler status: enabled
class name target percentage actual percentage
interactive_users 50% 40.0%
batch_jobs 10% 9.0% class>
While the database is loaded and class scheduling enabled, you can mod‐
ify the database dynamically to achieve the results you want by using
the configure, change, add, and destroy subcommands, interspersed with
the show and stats subcommands to check results. Enter a final save
/etc/class/filename subcommand when you are satisfied with your modifi‐
cations.
When run in interactive mode, the class_admin utility asks on exit or
quit whether you want to write database changes to disk if you have not
explicitly saved them during your session. If the utility is run from a
script, any changes to the class database are saved to disk automati‐
cally. The changes that are saved to disk do not include changes in
class membership for temporary identifiers (process IDs, process group
IDs, and session IDs) because these do not persist across system
reboots. It is always a good idea to do explicit save operations when
you intend to create or modify class databases that have non-default
names or that are stored in directories other than /etc/class.
You also have the programming option of using the class_* routines in
the libclass library to do the operations discussed in this section.
FILES
Default directory and name for the class database in the system default
partition (processor set 0). Default directory and name for a class
database in a user-defined partition (processor set number 2 and
higher). Header file defining the prototypes for routines in the lib‐
class library, as well as the type, structure, and other kinds of defi‐
nitions used by those routines. Class scheduler daemon.
SEE ALSO
Commands: runclass(1), class_admin(8)
Files: processor_sets(4)
Functions: class_add(3), class_change(3), class_change_name(3),
class_close(3), class_configure(3), class_create(3), class_data‐
base_file_exists(3), class_database_modified(3), class_data‐
base_name(3), class_delete(3), class_destroy(3), class_disable(3),
class_get_class_members(3), class_get_classes(3), class_get_con‐
fig_stats(3), class_load_database(3), class_open(3),
class_restore_database(3), class_save_database(3)class_scheduling(4)