|
class_scheduling(4)
Contents
|
class_scheduling, class.h - Allocate CPU resources based
on scheduling classes
#include <sys/class.h>
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 different
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
different 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 different tasks according
to what you've defined in the database currently loaded
into memory. Among the configuration parameters you supply
during setup of the class database is a time interval that
controls how often the daemon refreshes the structure used
by the kernel to implement 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 programs in that class.
When you do this, identifiers for all the application 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 particular 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 [Toc] [Back]
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
database is configured, and the integer values vary,
depending on the CPU percentage specified for the different
classes. A thread that is subject 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 system 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 clocktick
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 following 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,
processes belonging to scheduling classes then run
freely, no longer subject 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 userdefined
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 partition; 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
containing 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 follows:
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 Maximum number of members
across all classes: 2500 Maximum number of characters 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 runclass 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 percentage
of CPU time cannot use the runclass command to start
applications at a higher priority than what the user is
entitled to. For most operations that applications perform
by using routines in the libclass library, root permission
is required.
Using Class Scheduling [Toc] [Back]
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 identifiers 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 members
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 temporarily
lower or (if you have superuser privilege) increase the
CPU percentages for processes that otherwise startup in a
class with a different 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 [Toc] [Back]
How you allocate CPU resources will depend on your system
environment and which resources and priorities must be
considered. A typical scenario is to assign a higher priority
to interactive tasks so that users do not encounter
long response times. Most batch or background processes
will be assigned a lower priority, while some specific
background 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 userdefined
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 critical 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 created. 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 acceptable
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 corrected, 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 worthwhile to use class scheduling in the default
processor set where remaining applications are run and
interactive user processes are running.
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 [Toc] [Back]
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 subcommand 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 interactive_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 modify 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 modifications.
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 automatically. 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.
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 libclass
library, as well as the type, structure, and other kinds
of definitions used by those routines. Class scheduler
daemon.
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_database_file_exists(3),
class_database_modified(3), class_database_name(3),
class_delete(3), class_destroy(3), class_disable(3),
class_get_class_members(3), class_get_classes(3),
class_get_config_stats(3), class_load_database(3),
class_open(3), class_restore_database(3),
class_save_database(3)
class_scheduling(4)
[ Back ] |