network: tc introduce sfq - Stochastic Fairness Queueing

Stochastic Fairness Queueing is a classless queueing discipline.
SFQ does not shape traffic but only schedules the transmission of packets, based on 'flows'.
The goal is to ensure fairness so that each flow is able to send data in turn,
thus preventing any single flow from drowning out the rest.
This commit is contained in:
Susant Sahani 2019-11-27 12:42:21 +01:00 committed by Yu Watanabe
parent 1b628c4f64
commit 9942b71089
8 changed files with 137 additions and 9 deletions

View File

@ -2395,6 +2395,13 @@
</listitem>
</varlistentry>
<varlistentry>
<term><varname>StochasticFairnessQueueingPerturbPeriodSec=</varname></term>
<listitem>
<para>Specifies the interval in seconds for queue algorithm perturbation. Defaults to unset.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -109,6 +109,8 @@ sources = files('''
tc/netem.h
tc/qdisc.c
tc/qdisc.h
tc/sfq.c
tc/sfq.h
tc/tbf.c
tc/tbf.h
tc/tc-util.c

View File

@ -244,15 +244,16 @@ CAN.BitRate, config_parse_si_size,
CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point)
CAN.RestartSec, config_parse_sec, 0, offsetof(Network, can_restart_us)
CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling)
TrafficControlQueueingDiscipline.Parent, config_parse_tc_qdiscs_parent, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_tc_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_tc_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_tc_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_tc_network_emulator_packet_limit, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterRate, config_parse_tc_token_buffer_filter_size, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterBurst, config_parse_tc_token_buffer_filter_size, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterLatencySec, config_parse_tc_token_buffer_filter_latency, 0, 0
TrafficControlQueueingDiscipline.Parent, config_parse_tc_qdiscs_parent, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_tc_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_tc_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_tc_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_tc_network_emulator_packet_limit, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterRate, config_parse_tc_token_buffer_filter_size, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterBurst, config_parse_tc_token_buffer_filter_size, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterLatencySec, config_parse_tc_token_buffer_filter_latency, 0, 0
TrafficControlQueueingDiscipline.StochasticFairnessQueueingPerturbPeriodSec, config_parse_tc_stochastic_fairness_queueing_perturb_period, 0, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)

View File

@ -161,6 +161,16 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
return r;
}
if (qdisc->has_stochastic_fairness_queueing) {
r = free_and_strdup(&tca_kind, "sfq");
if (r < 0)
return log_oom();
r = stochastic_fairness_queueing_fill_message(link, &qdisc->sfq, req);
if (r < 0)
return r;
}
if (tca_kind) {
r = sd_netlink_message_append_string(req, TCA_KIND, tca_kind);
if (r < 0)

View File

@ -7,6 +7,7 @@
#include "networkd-link.h"
#include "networkd-network.h"
#include "networkd-util.h"
#include "sfq.h"
#include "tbf.h"
typedef struct QDisc {
@ -22,9 +23,11 @@ typedef struct QDisc {
bool has_network_emulator:1;
bool has_token_buffer_filter:1;
bool has_stochastic_fairness_queueing:1;
NetworkEmulator ne;
TokenBufferFilter tbf;
StochasticFairnessQueueing sfq;
} QDisc;
void qdisc_free(QDisc *qdisc);

87
src/network/tc/sfq.c Normal file
View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2019 VMware, Inc. */
#include <linux/pkt_sched.h>
#include "alloc-util.h"
#include "conf-parser.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "qdisc.h"
#include "sfq.h"
#include "string-util.h"
int stochastic_fairness_queueing_new(StochasticFairnessQueueing **ret) {
StochasticFairnessQueueing *sfq = NULL;
sfq = new0(StochasticFairnessQueueing, 1);
if (!sfq)
return -ENOMEM;
*ret = TAKE_PTR(sfq);
return 0;
}
int stochastic_fairness_queueing_fill_message(Link *link, const StochasticFairnessQueueing *sfq, sd_netlink_message *req) {
struct tc_sfq_qopt_v1 opt = {};
int r;
assert(link);
assert(sfq);
assert(req);
opt.v0.perturb_period = sfq->perturb_period / USEC_PER_SEC;
r = sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(struct tc_sfq_qopt_v1));
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_OPTIONS attribute: %m");
return 0;
}
int config_parse_tc_stochastic_fairness_queueing_perturb_period(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(network, filename, section_line, &qdisc);
if (r < 0)
return r;
if (isempty(rvalue)) {
qdisc->sfq.perturb_period = 0;
qdisc = NULL;
return 0;
}
r = parse_sec(rvalue, &qdisc->sfq.perturb_period);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
qdisc->has_stochastic_fairness_queueing = true;
qdisc = NULL;
return 0;
}

17
src/network/tc/sfq.h Normal file
View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2019 VMware, Inc. */
#pragma once
#include "sd-netlink.h"
#include "conf-parser.h"
#include "networkd-link.h"
typedef struct StochasticFairnessQueueing {
usec_t perturb_period;
} StochasticFairnessQueueing;
int stochastic_fairness_queueing_new(StochasticFairnessQueueing **ret);
int stochastic_fairness_queueing_fill_message(Link *link, const StochasticFairnessQueueing *sfq, sd_netlink_message *req);
CONFIG_PARSER_PROTOTYPE(config_parse_tc_stochastic_fairness_queueing_perturb_period);

View File

@ -273,3 +273,4 @@ NetworkEmulatorPacketLimit=
TokenBufferFilterRate=
TokenBufferFilterBurst=
TokenBufferFilterLatencySec=
StochasticFairnessQueueingPerturbPeriodSec=