ESPN DeportesMéxico: Calificaciones tras el empate ante PerúESPNBottom 10: Time not on Michigan's side in this oneRTP DesportoNoite de tréguas na Seleção PortuguesaThe Jerusalem PostIranian Airlines plane seized by Turkey over millions in unpaid debts, stranding Iranian passengersPunchFollow official visa application process, Germany warns NigeriansDaily MaverickTake shelter! The wave of AI mania is about to break20 MinutenRiesenzoff um Cristiano Ronaldo – Verbandsboss muss schlichtenStraits Times SportPhysical: Asia’s Dominic Di Tommaso believes Singapore could stand out in the Netflix reality seriesRMF24Zabić szachistę. Moskwa poluje na Garriego KasparowaIl Fatto QuotidianoPerché Alessandro Di Battista è così amato? Chi come me lo segue sa dare la risposta
The Daily Newsstand · Free, Always
Wednesday, September 30, 2026

Lossless Ethernet или жизнь без потерь: PFC, буферы и тонкая настройка

Translate

Привет, меня зовут Александр Шереметьев, я старший инженер по разработке ПО для коммутатора KORNFELD в YADRO. Мы привыкли, что Ethernet — среда с доставкой по мере возможности. Если возник затор, пакет дропается, а Transmission Control Protocol  потом разбирается сам. Но сегодня мы строим сети для AI-кластеров и распределенных систем хранения, где задержка в несколько миллисекунд на ретрансмит пакета — это катастрофа, которая просаживает производительность всей системы на 30–40%.

Сегодня мы разберем, как прокачать Ethernet до уровня Lossless, чтобы по надежности он не уступал Fibre Channel, но оставался гибким и быстрым. Мы залезем под капот коммутатора и посмотрим, как математически рассчитываются буферы и почему настройка одной лишь технологии PFC — это только верхушка айсберга.

Почему классический Ethernet не тянет?

TCP (Transmission Control Protocol) справляется с потерями через ретрансмиты, но это вызывает лавинообразный рост задержек и падение пропускной способности. К тому же появляются новые игроки RoCE v2 (RDMA over Converged Ethernet), NVMe-oF, AI Training (GPU-to-GPU) и диктуют требование: Zero Packet Loss. Если упадет хоть один пакет в RDMA-сессии, вся передача встает на паузу, пока работает механизм Go-Back-N. Какое решение мы можем предложить? Data Center Bridging (DCB) — набор стандартов для превращения Ethernet в надежную транспортную среду.

Оставить все как есть не можем, потому что есть проблема в протоколах RDMA (RoCE v2), которые сейчас используют все — от NVIDIA до Microsoft. В отличие от TCP, RDMA не умеет эффективно справляться с потерями. При потере одного пакета срабатывает механизм Go-Back-N: передатчик должен переотправить все, что было послано после потерянного пакета.

В сетях 100G, 400G и 800G это вызывает эффект Incast, когда множество отправителей забивают буфер одного порта. Если мы допустим потерю пакета, вся вычислительная мощь GPU будет простаивать, ожидая пересылки данных. Наша задача — создать затор без потерь: остановить отправителя до того, как буфер переполнится.

Простыми словами, Go-Back-N — стратегия переотправки данных в протоколах передачи, когда при потере одного пакета отправитель вынужден «вернуться назад» и заново отправить вообще все, что было послано после этого пакета.

В контексте нашего разговора про Lossless Ethernet это критически важно, потому что именно так работает RoCE v2 (RDMA over Converged Ethernet) на аппаратном уровне сетевых карт.

Как это работает

Представим, что мы отправляем другу пронумерованные коробки: 1, 2, 3, 4, 5.

  1. Мы отправили все пять коробок одну за другой, не дожидаясь подтверждения (это называется «окно передачи»).

  2. Друг получил коробку №1. Все хорошо.

  3. Коробка №2 потерялась (дроп на коммутаторе).

  4. Друг получает коробку №3. Но по логике Go-Back-N он обязан ее выбросить,  потому что она пришла не по порядку. Он ждет №2.

  5. Коробки №4 и №5 он тоже выбрасывает в мусор, даже если они доехали в идеальном состоянии.

  6. Мы как отправитель понимаем, что подтверждения  на коробку №2 нет.

  7. Мы возвращаемся к N (где N — это №2) и заново отправляем 2, 3, 4 и 5.

Это важно, потому что в современных высокоскоростных сетях (100G/400G) количество данных, которые мы успеваем выплюнуть в кабель до получения подтверждения, может быть огромным. Последствия печальные:

  • Мы тратим ресурсы на переотправку данных, которые на самом деле уже успешно долетели до получателя, но были им отброшены из-за логики протокола.

  • Пока идет переотправка, полезная работа задерживается.

  • Если сеть уже перегружена, повторная отправка целой пачки пакетов создает еще большую нагрузку, вызывая новые дропы.

Хотите работать со сложными системами в направлении Enterprise в YADRO? Откликайтесь на вакансию старшего инженера. На позиции оценят уверенное владение Linux и знание Go.

Почему TCP умнее, а RDMA — нет?

Но ведь в обычном интернете пакеты иногда теряются, и все не так плохо? Да, современный TCP умеет говорить: «Я получил 1, 3, 4 и 5. Пришли мне только номер 2». Это называется выборочным подтверждением. Работает эффективно, но требует много памяти и мощного процессора для обработки очереди на стороне получателя.

Тем временем, чтобы добиться сверхнизких задержек, логика RDMA / RoCE v2 зашита прямо в железо сетевой карты (ASIC NIC). Чтобы сделать чип дешевым, простым и быстрым, разработчики выбрали максимально простую логику: Go-Back-N. Она не требует сложного управления памятью на сетевой карте.

Мы не можем позволить себе дропнуть даже один пакет RoCE. Из-за механизма Go-Back-N потеря одного пакета весом 1500 байт превращается в переотправку сотен килобайт трафика. Сеть начинает «заикаться», и наши GPU-кластеры вместо вычислений просто ждут, пока сетевые карты обработают старые данные.

Priority-based Flow Control — это база

Обычный Flow Control (802.3x) работает слишком грубо. Он останавливает весь трафик на линке. Но в дата-центре нам нужно, чтобы SSH и BGP продолжали работать, даже если трафик хранилища встал на паузу.

PFC (802.1Qbb) работает точечно. В системе предусмотрено 8 приоритетов. Например, третий приоритет может быть выделен под RoCE-трафик. Технология PFC применяется к unicast-трафику, поэтому коммутатор обрабатывает его в unicast-очереди на выходном порту.

Когда буфер очереди соответствующего приоритета переполняется, коммутатор отправляет соседнему коммутатору кадр PAUSE, содержащий номер приоритета и время, на которое необходимо приостановить передачу. Получив этот кадр, соседний коммутатор приостанавливает передачу трафика из очереди с указанным приоритетом, например, приоритетом 3. Остальные очереди продолжают передачу трафика независимо от состояния данной очереди.

Из чего состоит буфер коммутатора

Буфер в современном ASIC — самый дорогой ресурс. Из чего он складывается:

  • Ingress Admission Control — проверка, есть ли место, когда пакет входит в порт.

  • Shared Pool — разделяемый объем памяти, который динамически или статически, в зависимости от настройки, делится между физическими портами.

  • Reserved (Dedicated) Buffer — гарантированный минимум для каждого порта или очереди, чтобы избежать голодания.

Чтобы настроить Lossless, нужно понимать, как коммутатор распоряжается памятью. Память в современных чипах — дефицитный ресурс. Она делится на пулы, каждый пул имеет полный объем памяти, из которого выделяется буфер запаса.

Для каждого порта создается профиль. Профили используют ресурсы пула.

Профиль может быть статическим и динамическим. Эта настройка определяет, как будет выделяться память из пула для конкретного порта. Если профиль динамический, то настройка размера буфера определяется в процентах, если статическая, то в байтах. Другие настройки профиля включают зарезервированный размер, для входящего профиля — пороги XOFF, XON, XON-OFFSET.

Об этом поговорим дальше.

Что такое Headroom: «тормозной путь» пакета

Headroom — зарезервированная часть буфера для поглощения транзитных пакетов после отправки сигнала XOFF. Концепция важна, когда заполнение буфера достигает порога, коммутатор отправляет сигнал PAUSE, а пакеты все еще продолжают лететь по кабелю.

Из чего складывается Headroom:

  • скорость порта (чем выше скорость, тем больше нужно буфера)

  • время полета сигнала по оптике (туда и обратно).

  • время на генерацию и обработку кадра PAUSE.

  • размер полезной нагрузки.

  • различные заголовки.

Если Headroom слишком мал, пакеты дропнутся. Если слишком велик, мы потратим память впустую. Это важный момент. Представьте: буфер порта заполнился до критической отметки, и коммутатор отправил сигнал PAUSE. Но пакеты не остановятся мгновенно. Те пакеты, что уже находятся «в проводе» и те, что передатчик успел вытолкнуть до получения команды PAUSE, все равно долетят до нас.

Headroom как раз таки поглощает транзитные пакеты. Если неверно рассчитать Headroom для длинного кабеля, то пакеты просто отбросятся, и ваш Lossless Ethernet превратится в потерю потерь.

Управление буфером: пороги XOFF и XON

Управление буфером строится на превышении порогов:

  • XOFF Threshold — уровень заполнения буфера для входящих приоритетов, при достижении которого порт отправляет PAUSE соседнему устройству.

  • XON Threshold (Xon + xon-offset) — уровень, до которого должен опустеть буфер, чтобы порт отправил сигнал «продолжай передачу».

  • Hysteresis — разница между XOFF и XON, чтобы избежать дребезга (частой отправки мелких пауз).

XOFF Threshold — это верхний порог. Как только уровень данных во входящем приоритете достигает его, генерируется PFC PAUSE.

XON Threshold — нижний порог. Мы не разрешаем передачу сразу, как только освободился один байт. Мы ждем, пока буфер опустеет до уровня XON, чтобы избежать частого прерывания, остановки трафика и постоянной отправки мелких пауз, которые «рвут» трафик. Разница между ними называется гистерезисом. В высокопроизводительных сетях мы стараемся держать эти значения максимально близко, но без ущерба стабильности. Мы используем два порога xon и xon-offset. Какой достигается раньше, тот и срабатывает для отмены паузы.

В чем проблема обычного XON?

В классической схеме мы задаем статический порог XON. Например, «возобнови работу, когда в очереди останется 100 КБ». Но в современных коммутаторах буфер — это динамический общий ресурс. Размер доступной памяти постоянно меняется. Если общая нагрузка на коммутатор очень высокая, свободная память в пуле может закончиться глобально.

Риск «липкой паузы» (Sticky Pause)

Если используем статический XON, может возникнуть ситуация, когда очередь порта немного освободилась. Но из-за того, что общий буфер чипа переполнен другими портами, уровень заполнения очереди никогда не опустится до статического порога XON. Порт «зависнет» в состоянии паузы навсегда, хотя он готов принимать данные. Это одна из причин PFC Deadlock, когда вся сеть ждет друг друга и трафик не передается по нужному приоритету.

Что такое XON-OFFSET?

Порог XOFF может быть настроен как статически, так и динамически. В наших реализациях используется динамическое управление порогом. Поэтому для определения момента возобновления приёма трафика используется комбинация двух параметров — XON и XON-OFFSET. Такой подход снижает вероятность переполнения буфера и позволяет использовать два условия для выхода из состояния паузы.

XON-OFFSET — это относительная величина, которая определяет порог возобновления передачи (XON) относительно порога остановки (XOFF).

XON = XOFF - XON_OFFSET

Вместо того чтобы ждать, пока буфер опустеет до какой-то абсолютной отметки (например, 100 КБ), мы говорим коммутатору: «Как только порт освободит N килобайт после отправки команды PAUSE, сразу отправляй XON».

Главные преимущества:

  • Гарантированный выход из паузы. Поскольку XON привязан к XOFF, мы гарантируем, что как только порт вытолкнул из себя объем данных, равный OFFSET, он отправит сигнал возобновления. Нам неважно, сколько памяти осталось в общем пуле чипа. Мы смотрим только на дельту (изменение) внутри конкретной очереди.

  • Минимизация джиттера. Маленький OFFSET позволяет порту очень быстро «включаться» обратно. Это делает поток данных более плавным.

  • Защита от Shared Pool Starvation. Даже если другие порты «съели» весь общий буфер, наш порт сможет продолжать работу короткими итерациями, потому что его порог XON всегда достижим.

То же самое и в обратной ситуации, при практически полной заполняемости буфера может оказаться, что XON_OFFSET ниже XON. Тогда выйти из ситуации Shared Pool Starvation поможет xon. Поэтому отправка сигнала «возобнови работу» происходит при достижении любого из порогов. Все зависит от настройки буферов памяти для конкретного приоритета.

Priority Groups: логика обслуживания

На входном порту трафик попадает в Priority Groups. Это логические контейнеры. Мы должны четко разделить: PG0 — для обычного трафика, где нет Headroom и возможны дропы. Например, PG3 — для Lossless-трафика. Важно строго соблюдать маппинг: PCP/DSCP -> TC -> PG -> Queue. Ошибка на любом этапе ломает lossless-цепочку.

Есть нюанс: если вы на входе пометили трафик как Lossless, вы обязаны пронести эту информацию через всю вашу сеть. Если на каком-то промежуточном коммутаторе маппинг настроен неверно, трафик попадет в общую очередь без PFC-защиты, и вы получите непредсказуемые потери, которые будет крайне сложно отладить.

Тонкая настройка

В настройках современных коммутаторах есть параметр Alpha. Это коэффициент, который определяет агрессивное использования Shared Pool.

  • Большая Alpha — порт может агрессивно забирать память.

  • Малая Alpha — изоляция портов выше, но общая утилизация буфера хуже.

Формула проста: Free_Space * Alpha / (1 + Alpha). Если Alpha большая, например 8, порт может занять почти весь буфер. Это хорошо для коротких всплесков, но плохо для честного распределения ресурсов.

В таблице показан процент от свободного места в разделяемом буфере, который может занять группа приоритетов:

Процент

Alpha

0.78%

1/128

1.5%

1/ 64

3%

1/32

6%

1/16

11%

1/8

20%

1/4

33%

1/2

50%

1

66%

2

80%

4

89%

8

Для Lossless-очередей мы часто используем статические лимиты или очень консервативные значения Alpha, чтобы гарантировать, что грязный трафик из соседней очереди не съест буфер, предназначенный для RDMA

Лучшие практики от KORNFELD

Техническое задание

  • Настроить коммутатор D1156 для поддержки Lossless так, чтобы разделяемый буфер коммутатора был максимальным, что позволит сглаживать трафик на всех портах.

  • В порты Ethernet 1–5 подключатся сервера, требующие передачу трафика без потерь.

  • Сервера используют сетевые карты со скоростью 25 Гбит/с.

  • В качестве аплинков используются порт Ethernet 48–49 объединенные в агрегацию.

  • Длина кабелей до серверов 10 метров, аплинки 100 метров.

  • Для передачи lossless трафика используется приоритет 3.

  • Использовать оптимальные настройки профилей для используемых портов.

  • Остальные порты и приоритеты используются только для lossy трафика.

  • Расчет производить для RoCEv2 с размером полезной нагрузки 1024 байта.

  • Порты к серверам и аплинки используются в режиме транк (dot1q).

Решение

Для начала рассчитаем параметры буфера запаса Headroom для пула. 

Для этого надо рассчитать параметры xoff  для порта к серверу и для аплинка, в данном случае это размер буфера запаса для профиля, используемого группой приоритетов.

Используя методику, рассчитаем xoff для порта 25 Гбит/с, длины кабеля 10 метров.

latency = 1000 нс

delay_{media} = 100 нс

length_{cable} = 10 метров

cell size = 256 байт на коммутаторе Broadcom Trident 3

М = 64 для Broadcom коммутатора

delay_{propagation} = 5 нс на 1 метр

Расчет количества ячеек, которое требуется для хранения одного пакета полезной нагрузки RoCEv2.

size_{packet} = BTH + RoCEv2-PAYLOAD + ICRC = 12 + 1024 + 4 = 1040

PacketToCells=ceiling[(size_{packet} + M) / size_{cell}] = ceiling((1040 + 64) / 256) = 5

Расчет времени, которое пройдет между моментом превышением порога xoff профиля и остановкой отправки трафика.

t = 2*(latency + delay_{media} + length_{cable}*delay_{propagation}) = 2  (1000 + 100 + 10  5) =  2300 нс

Умножение на 2 требуется, так как пакет проходит сериализацию дважды: один раз на отправляющей стороне, второй – на принимающей. 

После превышения порога xoff пакет паузы проходит через кабель от приемника трафика до передатчика, а после остановки передачи, отправленные пакеты проходят через кабель от передатчика до приемника.

Расчитаем pps:

L3PACKET состоит из IPv4-L3-HEADER = 20 байт, UDP-HEADER = 8 байт и полезной нагрузки size_{packet} = 1040.

FRAMESIZE_{L1} = Preamble + SFD + L2-HEADER + VLAN-TAG + L3PACKET + FCS + IGP = 7 + 1 + 14 + 4 + 20 + 8 + 1040 + 4 + 12 = 1110 байт
pps = IntfSpeed / FRAMESIZE_{L1} = 25000000000 / (1110 * 8) = 2815315

Расчет количества пакетов, которые будут переданы за время t:

PacketsInline = ceiling(t / 10^{9}  pps) = ceiling(2300 / 10^{9}  2815315) = 7 пакетов

Итог: XOFF25G_{server} = PacketsInline PacketToCells size_{cell} = 7 5 256 = 8960 байт

Проделаем тот же расчет для порта 100Гбит/с и длины кабеля 100 метров.

XOFF100G_{uplink} = 47360 байт.

Размер Headroom пула будет суммой используемых XOFF-профилей.

HEADROOM_{pool} = NumberOfServerPorts  XOFF25G_{server} + NumberOfUPlinkPorts  
XOFF100G_{uplink} = 5  8960 + 2  47360 = 139520

Расчет завершен, переходим к настройке. Порты к серверам и аплинки уже настроены, настраиваем только буферы. Определим текущий пресет:

   kornfeld# show qos buffer preset
   Current presets: default

Настройки буферов возможно только при использовании пресета custom, текущий пресет default. Требуется перевести коммутатор в пресет custom.

   kornfeld# configure terminal
   kornfeld(config)# qos buffer preset custom
   %Warning: Traffic will be stopped before ending process!
   kornfeld(config)# exit
   kornfeld# show qos buffer preset
   Current presets: custom
   kornfeld#

Создаются пулы и профили, профили привязываются к группам приоритетов и очередям:

   kornfeld# show running-configuration qos buffer
   !
   qos buffer preset custom
   !
   qos buffer pool egress_lossless_pool
    size 16777216
   !
   qos buffer pool egress_lossy_pool
    size 15409152
   !
   qos buffer pool ingress_lossless_pool
    size 16777216
    Headroom 9863168
   !
   qos buffer pool ingress_lossy_pool
    size 15788800
   !
   qos buffer profile egress_lossless_profile pool egress_lossless_pool type dynamic
    shared-size 66
   !
   qos buffer profile ingress_lossless_profile pool ingress_lossless_pool type dynamic
    shared-size 33
    xoff 88064
    xon 9472
    xon-offset 25600
   kornfeld# show qos buffer interface Ethernet 1 priority-group

   Ethernet1
   ---------------------------------------
   Priority-group    Profile
   ----------------  ---------------------
   0                 ingress_lossy_profile
   1                 ingress_lossy_profile
   2                 ingress_lossy_profile
   3                 ingress_lossy_profile
   4                 ingress_lossy_profile
   5                 ingress_lossy_profile
   6                 ingress_lossy_profile
   7                 ingress_lossy_profile
   kornfeld# show qos buffer interface Ethernet 1 unicast-queue

   Ethernet1
   -----------------------------
   Queue    Profile
   -------  --------------------
   UC0      egress_lossy_profile
   UC1      egress_lossy_profile
   UC2      egress_lossy_profile
   UC3      egress_lossy_profile
   UC4      egress_lossy_profile
   UC5      egress_lossy_profile
   UC6      egress_lossy_profile
   UC7      egress_lossy_profile
   kornfeld#

Изменим пул, предназначенный для lossless. Настроим Headroom согласно расчету. 

   kornfeld# show qos buffer pool
   ----------------------------------------------------------------
   Pool                   Type     Size (Byte)    Headroom (Byte)

  ---------------------  -------  -------------  -----------------
   egress_lossless_pool   egress        16777216                  0
   egress_lossy_pool      egress        15409152                  0
   ingress_lossless_pool  ingress       16777216            9863168
   ingress_lossy_pool     ingress       15788800                  0
   kornfeld# configure terminal
   kornfeld(config)# qos buffer pool ingress_lossless_pool
   kornfeld(config-pool)# Headroom 139520
   kornfeld(config-pool)# show configuration
   !
   qos buffer pool ingress_lossless_pool
    size 16777216
    Headroom 139520
   kornfeld(config-pool)# exit
   kornfeld(config)# exit
   kornfeld# show qos buffer pool
   ----------------------------------------------------------------
   Pool                   Type     Size (Byte)    Headroom (Byte)
   ---------------------  -------  -------------  -----------------
   egress_lossless_pool   egress        16777216                  0
   egress_lossy_pool      egress        15409152                  0
   ingress_lossless_pool  ingress       16777216             139520
   ingress_lossy_pool     ingress       15788800                  0
   kornfeld#

Пул изменился.  Создадим профиль для входящего трафика для портов к серверам. Как пример, будем использовать предустановленный профиль ingress_lossless_profile.

Тип пула dynamic, XON и XON-OFFSET оставим рекомендованные производителем:

kornfeld# show qos buffer profile ingress_lossless_profile
   --------------------------------------------------------------------------------------------------------------------------------------------------------------
   Profile                   Pool                   Reserved Size(Byte)    Shared Mode    Shared Size(Byte or %)    Xoff(Byte)    Xon(Byte)    Xon-offset(Byte)
   ------------------------  ---------------------  ---------------------  -------------  ------------------------  ------------  -----------  ------------------
   ingress_lossless_profile  ingress_lossless_pool                      0  dynamic                             33%         88064         9472               25600
   kornfeld#
   kornfeld# configure terminal
   kornfeld(config)# qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
   kornfeld(config-profile)#

У созданного профиля выставлены настройки по умолчанию, но они не подходят для реализации технического задания:

kornfeld(config-profile)# do show qos buffer profile SERVERS-profile
   -----------------------------------------------------------------------------------------------------------------------------------------------------
   Profile          Pool                   Reserved Size(Byte)    Shared Mode    Shared Size(Byte or %)    Xoff(Byte)    Xon(Byte)    Xon-offset(Byte)
   ---------------  ---------------------  ---------------------  -------------  ------------------------  ------------  -----------  ------------------
   SERVERS-profile  ingress_lossless_pool                      0  dynamic                             66%             0            0                   0
   kornfeld(config-profile)#

Изменим настройки профиля и проверим параметры созданного профиля:

   kornfeld(config)# qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
   kornfeld(config-profile)# shared-size 33
   kornfeld(config-profile)# xon 9472
   kornfeld(config-profile)# xon-offset 25600
   kornfeld(config-profile)# xoff 8960
   kornfeld(config-profile)# show configuration
   !
   qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
    shared-size 33
    xoff 8960
    xon 9472
    xon-offset 25600
   kornfeld(config-profile)# exit
   kornfeld(config)# exit
   kornfeld# show qos buffer profile SERVERS-profile
   -----------------------------------------------------------------------------------------------------------------------------------------------------
   Profile          Pool                   Reserved Size(Byte)    Shared Mode    Shared Size(Byte or %)    Xoff(Byte)    Xon(Byte)    Xon-offset(Byte)
   ---------------  ---------------------  ---------------------  -------------  ------------------------  ------------  -----------  ------------------
   SERVERS-profile  ingress_lossless_pool                      0  dynamic                             33%          8960         9472               25600
   kornfeld#

По аналогии, создадим профиль для входящего трафика для портов аплинков:

   kornfeld(config)# qos buffer profile UPLINK-profile pool ingress_lossless_pool type dynamic
   kornfeld(config-profile)# shared-size 33
   kornfeld(config-profile)# xoff 47360
   kornfeld(config-profile)# xon 9472
   kornfeld(config-profile)# xon-offset 25600
   kornfeld(config-profile)# show configuration
   !
   qos buffer profile UPLINK-profile pool ingress_lossless_pool type dynamic
    shared-size 33
    xoff 47360
    xon 9472
    xon-offset 25600
   kornfeld(config-profile)# show qos buffer profile UPLINK-profile
   ----------------------------------------------------------------------------------------------------------------------------------------------------
   Profile         Pool                   Reserved Size(Byte)    Shared Mode    Shared Size(Byte or %)    Xoff(Byte)    Xon(Byte)    Xon-offset(Byte)
   --------------  ---------------------  ---------------------  -------------  ------------------------  ------------  -----------  ------------------
   UPLINK-profile  ingress_lossless_pool                      0  dynamic                             33%         47360         9472               25600
   kornfeld(config-profile)#

Также по рекомендации для KornfeldOS 1.9.0 требуется настроить входящий пул и входящий профиль для lossy-трафика согласно документации и привязать этот профиль на все группы приоритетов для lossy. По нашему техническому заданию это 0–2, 4–7, так как третий приоритет для lossless.

Настроим пул:

kornfeld(config)# qos buffer pool ingress_lossy_pool

kornfeld(config-pool)# size 32566016

kornfeld(config-pool)# show configuration

!

qos buffer pool ingress_lossy_pool

 size 32566016

kornfeld(config-pool)# exit

kornfeld(config)# do show qos buffer pool ingress_lossy_pool

-------------------------------------------------------------

Pool                Type     Size (Byte)    Headroom (Byte)

------------------  -------  -------------  -----------------

ingress_lossy_pool  ingress       32566016                  0

Настроим профиль:

kornfeld(config)# qos buffer profile ingress_lossy_profile_opt pool ingress_lossy_pool type static

kornfeld(config-profile)# shared-size 32546560

kornfeld(config-profile)# show configuration

!

qos buffer profile ingress_lossy_profile_opt pool ingress_lossy_pool type static

 shared-size 32546560

kornfeld(config-profile)# exit

kornfeld(config)# do show qos buffer profile ingress_lossy_profile_opt

------------------------------------------------------------------------------------------------------------------------------------------------------------

Profile                    Pool                Reserved Size(Byte)    Shared Mode    Shared Size(Byte or %)    Xoff(Byte)    Xon(Byte)    Xon-offset(Byte)

-------------------------  ------------------  ---------------------  -------------  ------------------------  ------------  -----------  ------------------

ingress_lossy_profile_opt  ingress_lossy_pool                      0  static                         32546560             0            0                   0

Привяжем этот профиль ко всем портам всего коммутатора:

kornfeld# configure terminal

kornfeld(config)# interface range Ethernet 1-82

%Info: Configuring only existing interfaces in range

kornfeld(conf-if-range-eth**)# qos-buffer priority-group 0-2,4-7 profile ingress_lossy_profile_opt

kornfeld(conf-if-range-eth**)# exit

kornfeld(config)# do show qos buffer interface Ethernet 1 priority-group

Ethernet1

-------------------------------------------

Priority-group    Profile

----------------  -------------------------

0                 ingress_lossy_profile_opt

1                 ingress_lossy_profile_opt

2                 ingress_lossy_profile_opt

3                 ingress_lossy_profile

4                 ingress_lossy_profile_opt

5                 ingress_lossy_profile_opt

6                 ingress_lossy_profile_opt

7                 ingress_lossy_profile_opt

Привяжем профили UPLINK-profile и SERVERS-profil к группе приоритета 3 у портов к серверам и аплинкам:

 kornfeld(config)# interface range Ethernet 1-5
   %Info: Configuring only existing interfaces in range
   kornfeld(conf-if-range-eth**)# qos-buffer priority-group 3 profile SERVERS-profile
   kornfeld(conf-if-range-eth**)# interface range Ethernet 48-49
   %Info: Configuring only existing interfaces in range
   kornfeld(conf-if-range-eth**)# qos-buffer priority-group 3 profile UPLINK-profile
   kornfeld(conf-if-range-eth**)# exit
   kornfeld(config)#

Привяжем профиль egress_lossless_profile к очереди 3 у портов к серверам и аплинкам:

kornfeld(config)# interface range Ethernet 1-5,48-49
   %Info: Configuring only existing interfaces in range
   kornfeld(conf-if-range-eth**)# qos-buffer unicast-queue 3 profile egress_lossless_profile
   kornfeld(conf-if-range-eth**)#

Проверим настройки на портах на примере двух портов:

kornfeld# show qos buffer interface Ethernet 1 priority-group

Ethernet1

-------------------------------------------

Priority-group    Profile

----------------  -------------------------

0                 ingress_lossy_profile_opt

1                 ingress_lossy_profile_opt

2                 ingress_lossy_profile_opt

3                 SERVERS-profile

4                 ingress_lossy_profile_opt

5                 ingress_lossy_profile_opt

6                 ingress_lossy_profile_opt

7                 ingress_lossy_profile_opt

kornfeld# show qos buffer interface Ethernet 1 unicast-queue

Ethernet1

--------------------------------

Queue    Profile

-------  -----------------------

UC0      egress_lossy_profile

UC1      egress_lossy_profile

UC2      egress_lossy_profile

UC3      egress_lossless_profile

UC4      egress_lossy_profile

UC5      egress_lossy_profile

UC6      egress_lossy_profile

UC7      egress_lossy_profile

kornfeld# show qos buffer interface Ethernet 48 priority-group

Ethernet48

-------------------------------------------

Priority-group    Profile

----------------  -------------------------

0                 ingress_lossy_profile_opt

1                 ingress_lossy_profile_opt

2                 ingress_lossy_profile_opt

3                 UPLINK-profile

4                 ingress_lossy_profile_opt

5                 ingress_lossy_profile_opt

6                 ingress_lossy_profile_opt

7                 ingress_lossy_profile_opt

kornfeld# show qos buffer interface Ethernet 48 unicast-queue

Ethernet48

--------------------------------

Queue    Profile

-------  -----------------------

UC0      egress_lossy_profile

UC1      egress_lossy_profile

UC2      egress_lossy_profile

UC3      egress_lossless_profile

UC4      egress_lossy_profile

UC5      egress_lossy_profile

UC6      egress_lossy_profile

UC7      egress_lossy_profile

Все верно. Оценим ограничения примененных настроек:

kornfeld# show qos buffer limits

Total buffer size in bytes: 33030000

Pools Headroom limits:

Total - Total Headroom size in pool in bytes, Used - Sum xoff size using by profiles,

Percent - The percentage of the used size of the Headroom buffer by profiles, Status - Normal or Warning if overbooking

-----------------------------------------------------------

Pools name            Total    Used    Percent    Status

---------------------  -------  ------  ---------  --------

ingress_lossless_pool   139520  139520       100%  Warning

Pools reserved size limits (Byte):

Total - Total pool size without Headroom, Reserved - Total reserved size using by profiles, Shared - Total shared size using for profiles

-----------------------------------------------------

Pools name               Total    Reserved    Shared

---------------------  --------  ----------  --------

egress_lossless_pool   16777216           0  16777216

egress_lossy_pool      15409152           0  15409152

ingress_lossless_pool  16637696           0  16637696

ingress_lossy_pool     32566016           0  32566016

В выводе видно, что Headroom для пула используется оптимально. Для поддержки lossless-трафика требуется включить PFC на тех приоритетах, по которым будет идти трафик. Включаем PFC для третьего приоритета на портах к серверам и аплинках:

kornfeld(config)# interface range Ethernet 1-5,48-49
   %Info: Configuring only existing interfaces in range
   kornfeld(conf-if-range-eth**)# pfc priority 3
   kornfeld(conf-if-range-eth**)#
   kornfeld(conf-if-range-eth**)# exit
   kornfeld(config)# exit
   kornfeld# show pfc interface
   ---------------------------
   PFC Interface    Priority
   ---------------  ----------
   Ethernet1        3
   Ethernet2        3
   Ethernet3        3
   Ethernet4        3
   Ethernet5        3
   Ethernet48       3
   Ethernet49       3

   Total: 7

Задача выполнена.

Что еще почитать о разработке коммутатора KORNFELD:

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.