Files
poc-links/qdiscs.md
T
Сергей Маринкевич e2290e1b7a qosd: добавлены атрибуты узлов
Мне показалось, будет удобно использовать вложенную структуру в качестве
аргумента конструктора.
2025-10-08 19:18:38 +07:00

15 KiB
Raw Blame History

Классы внутреннего представления

  1. #HTB;
  2. #FIFO (хотя бы одну);
  3. #RED;
  4. #GRED;
  5. #SFQ.

HTB

Иерархичный TBF. Имеет классы, к которым могут подключаться другие дисциплины. Т.е. к ней могут быть подключены несколько других узлов.

Из дисциплины:

  • default — Минорная часть ID класса по умолчанию. Dunno, надо ли нам такое вообще. Я об этом не думал. Сейчас у нас всё на фильтры u32 завязано.

  • r2q — Кванты DRR (computed as rate in Bps/r2q). КМК, нам это не надо, мы этим никогда не пользовались. Единственное: мы раньше не пользовались DRR, а сейчас я хочу на этом построить Basic QoS. — UPD: Это можно в глобальной конфигурации задать.

  • debug — Какой-то "string of 16 numbers each 0-3", в душе не знаю, что это.

  • direct_qlen — Лимит прямой очереди в штуках пакетов. Мы этим вряд ли воспользуемся, т.к. у нас нет такого сценария, что какой-то пакет нужной пропускать мимо QoS. Ну, я таких сценариев не знаю. — UPD: В целом, можно вписать в мою архитектуру, если явно отобразить такой узел в дереве: будет класс, который матчит весь трафик (как в Complex QoS class-default), и в качестве дочернего узла у него некий DirectNode.

  • offload — Включение аппаратного QoS. У нас сейчас точно нигде поддержки нет. Вроде бы в новом SDK появилась какая-то поддержка на каких-то платформах Marvell. Для абстрактного дерева эта опция не подходит.

Из классов:

  • rate — Разрешённая полоса (можно заимствовать выше этой полосы). (обязательный)
  • burst — Кол-во токенов (байтов) TBF для этого класса.
  • mpu — "minimum packet size used in rate computations" — Мне кажется, что этот параметр вообще давно не работает: RTAB'ы померли, iproute2 заполняет их только для обратной совместимости (актуальные ядра сразу делают на них qdisc_put_rtab()).
  • overhead — Поправка размера пакета для вычислений. Не путать со STAB'ом: здесь это атрибут класса HTB, и он не влияет размер пакета за пределами класса. По сути, это поправка к введённым rate и ceil.
  • linklay — Протокол передачи. Кроме Ethenet по умолчанию знаю только "e.g. atm". Бесполезно.
  • ceil — Допустимая полоса (заимствовать нельзя).
  • cburst — Аналог burst для ceil.
  • mtu — В дисциплине TBF это что-то вроде микро-burst, используемы для peakrate. Но здесь это такая же бесполезная вещь, как и mpu. По тем же причинам.
  • prio — Приоритет. Определённо надо.
  • quantum — Позволяет настроить жадность опустошения очередей в процессе DRR. По дефолту r2q. В целом, наверно, надо. Сейчас мы это не настраиваем, но, как я писал выше, для Basic QoS может пригодиться.

У этой дисциплины может быть лишь одна дочерняя дисциплина.

FIFO

FIFO как настоящая очередь может быть только краевым узлом, то есть не имеет дочерних дисциплин и классов.

PFIFO

Очередь с ограничением в штуках пакетов. Дисциплина по умолчанию для классов HTB. Параметры дисциплины:

  • limit — Размер очереди, кол-во пакетов (по умолчанию1 qlen с интерфейса).

BFIFO

Очередь с ограничением в байтах. Дисциплина по умолчанию для TBF. Параметры дисциплины:

  • limit — Размер очереди, байты (по умолчанию1 limit с TBF).

RED

Random Early Detection.

Может быть только краевым узлом.

  • limit — Размер буфера, байты. (обязательный, используем)
  • min, max — Границы для разметки пакетов: до минимума вообще не метим пакеты; после максимума вероятность метки максимальная. Заполненность очереди, байты. (используем)
  • avpkt — Средний размер пакета. Байты. Используется для каких-то хитрых вычислений. (обязательный, используем)
  • burst — Всплеск. Смысл такой же, как и везде, но как именно он работает — мне неясно. Факт в том, что чем выше burst, тем дольше до RED доходит, что нужно маркировать трафик. Байты. (используем)
  • adaptive — Какая-то умная шняга для автоматической подгонки параметров под текущее поведение трафика. Мы это не используем, кстати. Гля adaptiveRed.pdf.
  • probability — Максимальная вероятность помаркать пакет. Число с плавающей точкой, континуум 0-1. (используем)
  • bandwidth — Не про шейпинг, но про скорость интерфейса, используется для расчёта средней длины очереди. Биты в секунду.
  • ecn — Включить именно маркировку пакетов, вместо отбрасывания, для сдерживания полосы потока. Пакет всё же будет отброшен, если длина очереди для этого потока превысит limit. Рекомендуемо, но мы этим не пользуемся.
  • harddrop — С этим параметром пакет будет отброшен, если длина очереди превысит max.
  • nodrop — С этим параметром дисциплина не будет отбрасывать пакеты, которые не может маркировать ("not ECN-capable"). По умолчанию такие пакеты дропаются.

Параметры, связанные с QEVENTS (man 8 tc), рассматривать точно не будем.

GRED

А это, типа, "Generalized RED". Что бы это не значило. Мы это как WRED используем. Литературы по нему мало.

Тут вводится понятие "виртуальной очереди" (VQ). И к самому Linux TC оно отношения не имеет. Оно даже к очередям отношение имеет опосредованное: никакой очереди фактически не выделяется, поэтому она и виртуальная. И настройка этих очередей довольно виктимная: нужно послать CHANGE на уже созданную дисциплину и в качестве параметра передать номер очереди, настройки которой мы хотим изменить.

В этом проекте присутствует как узел WRED. Узел WRED несёт в себе только глобальные настройки дисциплины. Для конфигурирования VQ к узлу WRED прикрепляются узлы RED.

  • vqs — Кол-во виртуальных очередей. (обязательно) — UPD: Вообще, нам это не нужно: мы и так можем посчитать, сколько VQ мы определили, по самим дочерним узлам.
  • default — Виртуальная очередь по умолчанию. (обязательно) — UPD: Это тоже не нужно, т.к. мы фильтрами на самой очереди скажем, что она дефолтная.
  • grio — Вкл. наследование буферов. Условно, приоритетный трафик затрагивает, в том числе, счётчики менее приоритетного трафика.
  • limit — Размер буфера, байты. Здесь, в отличие от RED и VQ, является необязательным. Ограничивает очередь мимо VQ, а также задаёт верхнюю планку для каждой VQ (больше этого limit нельзя задавать limit для VQ).
  • ecn — Возможность включить маркировку пакетов на всю дисциплину, либо включение только для отдельной VQ. Вроде бы, и там, и тут включить нельзя. Кроме того, на 4.14, например, эти флаги на VQ вообще не используются.
  • harddrop — С этим параметром пакет будет отброшен, если длина очереди превысит max. Аналогично ecn.

Ну и далее для VQ аналогично RED:

  • limit — Размер буфера, байты. (обязательный, используем)
  • min, max — Границы для разметки пакетов: до минимума вообще не метим пакеты; после максимума вероятность метки максимальная. Заполненность очереди, байты. (используем)
  • avpkt — Средний размер пакета. Байты. Используется для каких-то хитрых вычислений. (обязательный, используем)
  • burst — Всплеск. Смысл такой же, как и везде, но как именно он работает — мне неясно. Факт в том, что чем выше burst, тем дольше до RED доходит, что нужно маркировать трафик. Байты. (используем)
  • probability — Максимальная вероятность помаркать пакет. Число с плавающей точкой, континуум 0-1. (используем)
  • bandwidth — Не про шейпинг, но про скорость интерфейса, используется для расчёта средней длины очереди. Биты в секунду.

SFQ

Также может быть только краевым узлом.

Дисциплина работает по принципу "отобрать и поделить". Т.е. поток трафика на исходящем интерфейсе распределяется по множеству динамически создаваемых очередей на основании хэша пакета. Эти динамические очереди обслуживаются условным RR. За счёт такого подхода, гипотетически, никакая сессия не может монополизировать линк. Грубо говоря, социалистическая революция в рамках дисциплины на интерфейсе.

Несмотря на то, что у этой дисциплины при создании нет обязательных параметров, этих параметров всё же очень много:

  • limit — Кол-во пакетов, задерживаемое дисциплиной. Это суммарное ограничение по всем потокам.
  • depth — Кол-во пакетов, задерживаемое одним потоком.
  • divisor — Размер хэш-таблицы. Чем больше потоков дозволено, тем медленнее будет происходить поиск по ним, но увеличение размера таблицы сокращает время поиска. Должно быть степенью двойки, по умолчанию 1024.
  • perturb — Кол-во секунд для периода пертурбации, т.е. как часто изменять хэш-функцию (за счёт соли).
  • flows — Кол-во потоков. (единственное, что мы настраиваем в CLI; хотя brasd SFQ тоже пользуется и настраивает больше параметров!)
  • quantum — Порция трафика для одного раунда RR-процесса. Байты.
  • headdrop — Флаг для отбрасывания трафика из головы очереди, а не с хвоста. Гипотетически, так отклик TCP лучше.
  • redflowlimit — Ограничение в байтах на очередь потока. Заодно включает сам RED на каждом потоке SFQ. Да, но мы этим тоже не пользуемся.
  • Параметры RED третий раз перечислять не очень-то хочется. Но тут поддерживаются все параметры из #RED, кроме adaptive.

Параметры RED на SFQ конфигурируются аналогично WRED и VQ: к SFQ подключается RED, с которого и будет считываться конфигурация per-flow RED.


  1. Вообще, для FIFO по умолчанию параметр limit равен qlen или qlen * MTU. Т.е., HTB вообще никакой параметр туда не передаёт, а TBF передаёт свой же limit, который проецирует на дочернюю дисциплину, если это FIFO (даже если руками новую FIFO создать). ↩︎