dante   Frontpage - Dante - Download - Status - Support - Modules - Docs - Links - Survey - GDPR
 

CPU real-time scheduling

This page describes how to configure options related to CPU scheduling and priority.

Dante supports the sched_setscheduler() and sched_setaffinity() system calls that make it possible to choose the scheduling algorithm, priority and CPUs to use. These system calls are available on platforms such as Linux and FreeBSD. SunOS has a related system call called processor_bind() which is currently not supported.

Using this functionality can have an effect on the performance and behavior of Dante. Especially in usage scenarios where there are other resource intensive applications running on the same machine as Dante there might be benefits from using this functionality. An analysis of some of the potential benefits can be found in the technical report Analysis of Real-Time scheduling functionality in Dante version 1.3.2.2.

The real-time functionality in Dante is divided into two groups: process scheduling/priority, and process CPU-affinity (CPU processor binding). Separate keywords exist for controlling each one. Common for either group is that the options are set globally and apply to all client connections, but separate values can be set for the different process types in Dante.

The different operations performed by Dante is spread among four different process types:

  • Mother Accepts connections from clients and forwards clients between the other Dante process types.
  • Monitor Monitors connection state and data rate.
  • Negotiate Handles SOCKS protocol negotiation and performs first level ACL checks (client-rules).
  • Request Verifies the SOCKS request, performs second level ACL checks (socks-rules) and opens connections to target hosts.
  • IO Handles the I/O (TCP, UDP, ICMP) between clients and targets.

It is possible to set different real-time scheduling values for each process type, but this may not always be beneficial.

Generally speaking, the settings of the mother, negotiate, and request processes will affect the session setup time; the time it takes to perform SOCKS protocol processing, establish a session to the remote server, and become ready to do the actual i/o. We recommend using the same settings for all these process types or leaving them unchanged. After completion of session setup, a client session will be managed by an io process, and the real-time settings of io processes will potentially affect the throughput and latency of the traffic forwarded by Dante.

Real-time scheduling/priority control

The scheduling algorithm and priority to use for the different Dante process types can be specified in the Dante server configuration file using the following syntax:

cpu.schedule.PROCTYPE: SCHED/PRIORITY

The above values are defined as follows:

  • PROCTYPE: Dante process type, which can be one of the following: mother, monitor, negotiate, request or io. Setting a value for the io process type is likely to have the largest impact on performance. Setting values for the other processes types may have an impact on the initial session establishment time, but the impact will normally be small.
  • SCHED: Real-time scheduling algorithm to use, with the following values usually being available: fifo, rr, other. Note that other is the standard, non-realtime, scheduling algorithm.
  • PRIORITY: A numeric value giving the process' scheduling priority.

Note that root privileges might be required to enable real-time scheduling.

The following shows an example where real-time scheduling is enabled for most Dante process types:

#when root access is needed to enable real-time scheduling
user.privileged: root

#set real-time scheduling (round-robin):
cpu.schedule.mother:    rr/10
cpu.schedule.negotiate: rr/10
cpu.schedule.request:   rr/10
cpu.schedule.io:        rr/15
We recommend that cpu affinity (see below) is used when real-time scheduling is enabled.

CPU affinity control

CPU affinity/process binding makes it possible to specify which CPUs the different Dante processes should use, via the sched_setaffinity() system call. This functionality can also be used to eliminate the possibility of Dante consuming all available CPU resources if real-time scheduling is enabled, by making sure that there is at least one CPU that will not be used by Dante even during heavy load. The syntax is as follows:

cpu.mask.PROCTYPE: CPUIDS

The above values are defined as follows:

  • PROCTYPE: Dante process type, which can be one of the following: mother, monitor, negotiate, request or io.
  • CPUIDS: A space-separated list of CPUs to which processes of the specified type should bind. CPUs are identified numerically, starting with the value 0 for the first CPU/core.

The following shows an example where CPU affinity is specified for all Dante process types:

#run io processes on CPUs 1 + 2, all other Dante processes on CPU 0.
#Assuming there are four CPUs on the machine, this leaves CPU #3 free 
#for other, non-Dante related, tasks.
cpu.mask.mother:    0
cpu.mask.monitor:   0
cpu.mask.negotiate: 0
cpu.mask.request:   0
cpu.mask.io:        1 2

Copyright © 1998-2024 Inferno Nettverk A/S