Jump to content
Калькуляторы

Linux, lan + interrupts

Имеется файловый сервер под управлением Debian 7 (samba), в задачи которого входит переодически раздавать один и тот же набор данных нескольким сотням клиентов(обычно 50-100Гб). Т.е. в час Х 300-400 клиентов(с 1Гбит линками) начинают хором тянуть одни и те же данные с сервера.

Сервер аппаратно из себя представляет IBM x3650 M4, с двумя 6-ти ядерными процами на борту, итого с гипертредингом получается 24 ядра. Оперативной памяти 200Гб(для кеширования).

Две сетевые платы(одна двухпортовая) по 10Гбит(Emulex OneConnect 10Gbps NIC), объединенные в bond-интерфейс, т.е. общая пропускная способность дожна быть около 20Гбит.

 

Столкнулся с проблемой, что у меня грузится один процессор на 100%

b8ee2a621227fa21117be42f2fd540ec.png

 

При этом на отдачу идет всего около 430мб/с

3f11027edd47d030d6791a803794c71f.png

 

дисковая подсистема не загружена вообще, все отдается из кеша в оперативке

http://s3.hostingkartinok.com/uploads/images/2014/01/b17105032ff8a956e144a54eb51e0c79.png

 

Из этого стало понятно, что дело в прерываниях

http://s3.hostingkartinok.com/uploads/images/2014/01/c2e97a5d9482303ec311d1cedcdfbed3.png

 

У сетевух по одной очереди на вход и выход

# ls -1 /sys/class/net/eth1/queues/
rx-0
tx-0

 

Все прерывания обрабатываются на нулевом ядре:

# cat /proc/interrupts | grep eth
130: 3374800647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  IR-PCI-MSI-edge      eth1-q0
131: 3059637112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  IR-PCI-MSI-edge      eth2-q0

 

Как в данном случае добиться производительности в 20Гбит?

 

И откуда у bond-интерфейсов больше, чем одна очередь?

# ls -1 /sys/class/net/bond0/queues/
rx-0
rx-1
rx-10
rx-11
rx-12
rx-13
rx-14
rx-15
rx-2
rx-3
rx-4
rx-5
rx-6
rx-7
rx-8
rx-9
tx-0
tx-1
tx-10
tx-11
tx-12
tx-13
tx-14
tx-15
tx-2
tx-3
tx-4
tx-5
tx-6
tx-7
tx-8
tx-9

Share this post


Link to post
Share on other sites

Модель сетевухи в студию.

Хотя попахивает заменой на "Правильную"

Коли на дисковую систему нареканий нету то вопрос про выборку из памяти и про прерывания

В соседней ветке "Linux softrouter" про это подробно разжевано.

Share this post


Link to post
Share on other sites

+1

 

Попутно глянуть на предмет более новых драйверов, задания оптимальных параметров модуля сетевухи и точно ли включено на этих сетевушках MSI-X

 

 

Share this post


Link to post
Share on other sites

Сетевуха вот такая Emulex Dual Port 10GbE SFP+ Embedded VFA III for IBM System x(сетевуха типа встроенной, ставилась как отдельный модуль на материнку, двухпортовая)

 

Попутно глянуть на предмет более новых драйверов

Я не ставил драйвера, какие были в ядре - те и подошли

 

задания оптимальных параметров модуля сетевухи

А как узнать, какой модуль у моей сетевухи и какие у него есть параметры?

 

точно ли включено на этих сетевушках MSI-X

Как проверить?

 

П.С. выяснилась интересная вещь:

# ls -1 /sys/class/net/eth1/queues/
rx-0
rx-1
rx-2
rx-3
rx-4
tx-0

 

# cat /proc/interrupts | grep eth1
118: 2140748214 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 IR-PCI-MSI-edge      eth1-q0
119:  152319516 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 IR-PCI-MSI-edge      eth1-q1
120: 1018353379 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0IR-PCI-MSI-edge      eth1-q2
121:   72500850 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0IR-PCI-MSI-edge      eth1-q3

 

у точно такой же сетевухи, на точно таком же сервере(оба сервера из одного заказа), но ОС не дебиан, а Red Hat Enterprise Linux Server release 6.5 (Santiago), как видим, уже четыре очереди, а не одна.

Получается у редхата в ядро встроен какой-то более новый драйвер или он загружается с другими параметрами?

 

Также, не смотря на 4 очереди, как видите, все прерывания обрабатываются на 0-ом ядре

Share this post


Link to post
Share on other sites

Только надо понимать, что softrouter - задача совсем другая и часть тамошних советов тут будет очень вредная. Например TSO под эту задачу просто необходим, всякие flow director'ы (если сетевая интел, на счет этой не знаю), DMA offload (если самба не zero-copy), правильный tcp congestion control, большие буферы на сокеты, flow-control (если есть дропы), если правильно настроены, тоже будут ощутимым бонусом. Jumbo frame тоже не помешает.

Share this post


Link to post
Share on other sites

Вот точно какая карта http://www.redbooks.ibm.com/abstracts/tips0844.html

у меня embended вариант

 

Вот тут http://www.emulex.com/artifacts/db7cf490-7c5a-4a7c-862b-4a0a1344d4c2/elx_ds_all_oc_vfaiii_systemx_ibm.pdf

значится

Architecture

· Dual-channel, 10Gb/s Ethernet Link speed

· PCIe Express 2.0 (x8, 5GT/s), MSI-X support

· Integrated data buffer and code space memory

Edited by metallic

Share this post


Link to post
Share on other sites

metallic прерывания раскидываются либо в ручную(рекомендуется, если есть поинмание), либо irqbalance(автоматика).

 

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

Edited by Tamahome

Share this post


Link to post
Share on other sites

metallic прерывания раскидываются либо в ручную(рекомендуется, если есть поинмание)

Т.е. есть у меня 4 очереди(вижу в /proc/interrupts), надо через /proc/irq/*/smp_affinity разрешить одной очереди обрабатываться на одном ядре, второй на втором и т.д., правильно?

 

либо irqbalance(автоматика).

Слышал про него и есть в репозитории, только пока не пробовал, его просто ставишь и запускаешь и все делает сам?

 

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

Так надо вначале узнать, что за модуль у меня? Я не знаю какой модуль за эту сетевуху отвечает.

 

MSI-edge

tx-0

 

драйвера.

Не понял, что имелось ввиду? Поставить драйвера для MSI-edge нужно?

Или то, что у меня сетевуха в MSI режиме работает, а нужен MSI-X ?

Share this post


Link to post
Share on other sites

 

Так надо вначале узнать, что за модуль у меня? Я не знаю какой модуль за эту сетевуху отвечает.

ethtool -i

Share this post


Link to post
Share on other sites

к интеловским драйверам идет скрипт, который раскидывает прерывания по ядрам.

Посмотрите комплект драйверов к вашей сетевухе.

Share this post


Link to post
Share on other sites

Смотрю на дебиане 7

 

root@ffr2:~# ethtool -i eth1
driver: be2net
version: 4.2.220u
firmware-version: 4.1.442.0
bus-info: 0000:0c:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: no
supports-priv-flags: no

 

Теперь понятно, что у меня be2net версии 4.2.220u

 

Смотрим что он умеет

root@ffr2:~# modinfo be2net
filename:       /lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/emulex/benet/be2net.ko
license:        GPL
author:         ServerEngines Corporation
description:    ServerEngines BladeEngine 10Gbps NIC Driver 4.2.220u
version:        4.2.220u
srcversion:     37BCB0144B22E0B05771D68
alias:          pci:v000010DFd00000720sv*sd*bc*sc*i*
alias:          pci:v000010DFd0000E228sv*sd*bc*sc*i*
alias:          pci:v000010DFd0000E220sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000710sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000700sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000221sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000211sv*sd*bc*sc*i*
depends:
intree:         Y
vermagic:       3.2.0-4-amd64 SMP mod_unload modversions
parm:           num_vfs:Number of PCI VFs to initialize (uint)
parm:           rx_frag_size:Size of a fragment that holds rcvd data. (ushort)

 

вот с редхата:

# modinfo be2net
filename:       /lib/modules/2.6.32-431.1.2.el6.x86_64/kernel/drivers/net/benet/be2net.ko
license:        GPL
author:         Emulex Corporation
description:    Emulex OneConnect 10Gbps NIC Driver 4.6.62.0r
version:        4.6.62.0r
srcversion:     8DB7FB78A4381C3AFCF23D3
alias:          pci:v000010DFd00000728sv*sd*bc*sc*i*
alias:          pci:v000010DFd00000720sv*sd*bc*sc*i*
alias:          pci:v000010DFd0000E228sv*sd*bc*sc*i*
alias:          pci:v000010DFd0000E220sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000710sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000700sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000221sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000211sv*sd*bc*sc*i*
depends:
vermagic:       2.6.32-431.1.2.el6.x86_64 SMP mod_unload modversions
parm:           num_vfs:Number of PCI VFs to initialize (uint)
parm:           multi_rxq:Obsolete and used only for compatibility (bool)
parm:           rx_frag_size:Size of a fragment that holds rcvd data. (ushort)

 

что дальше?

Edited by metallic

Share this post


Link to post
Share on other sites

что дальше?

Я бы собрал свежий драйвер в дебиан, на пробу.

Share this post


Link to post
Share on other sites

Я бы собрал свежий драйвер в дебиан, на пробу.

Да я вот что-то не могу найти сорцы драйвера на сайте

http://www-legacy.emulex.com/downloads/emulex.html

 

Есть готовые модули для дебиана 6, для убунты 12.04, для 7-го дебиана вот нет.

Зато для редхата есть src.rpm, сейчас вот на тестовый сервер накатываю центос 6.5, это x3650 M3 с такой же сетевухой, только не встроенная, а pci, буду там пробовать из src.rpm собирать

Share this post


Link to post
Share on other sites

Irqbalance не торт. Лучше руками прибить прерывания по ядрам. От этого балансера все скачет то там то сям, в итоге только хуже.

 

Так а попробуйте из src.rpm дернуть сырцы и не не применяя редхат-патчи(если они там есть) собрать под дебиан

Share this post


Link to post
Share on other sites

metallic

А что мешает повесить руками ваши 2 сетевки на разные ядра? Так по крайней мере 2 ядра будет загружено, в 2 раза больше прокачаете.

И как я понимаю, num_vfs в параметрах драйвера ваших сетевок как раз таки задает число очередей. Поставьте нужное число, раскидайте прерывания по ядрам и живите счастливо.

Edited by kayot

Share this post


Link to post
Share on other sites

Поставил на дебиане 7 последний драйвер(взял сорцы из src.rpm редхата, скомпилил и руками подменил модуль ядра, потом обновил initramfs), в опциях модуля добавил вот что

# cat /etc/modprobe.d/be2net.conf
options be2net num_vfs=8 rss_on_mc=1 num_rings=12

 

после перезагрузки увидел, что появилось по 4 очереди на каждом порту(раньше одна была и со старым драйвером эти опции никакого эффекта не давали), вообще за кол-во очередей вроде как отвечает опция rss_on_mc=1, она появилась в новой версии драйвера:

# modinfo be2net
filename:       /lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/emulex/benet/be2net.ko
supported:      external
license:        GPL
author:         Emulex Corporation
description:    Emulex OneConnect 10Gbps NIC Driver 4.6.148.0
version:        4.6.148.0
srcversion:     28D1C7E9833F004A081C39E
alias:          pci:v000010DFd0000E228sv*sd*bc*sc*i*
alias:          pci:v000010DFd0000E220sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000710sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000700sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000221sv*sd*bc*sc*i*
alias:          pci:v000019A2d00000211sv*sd*bc*sc*i*
depends:
vermagic:       3.2.0-4-amd64 SMP mod_unload modversions
parm:           rss_on_mc:Enable RSS in multi-channel functions with the capability. Disabled by default. (ushort)
parm:           tx_prio:Create priority based TX queues. Disabled by default (uint)
parm:           num_vfs:Number of PCI VFs to initialize (uint)
parm:           rx_frag_size:Size of receive fragment buffer - 2048 (default), 4096 or 8192 (ushort)
parm:           gro:Enable or Disable GRO. Enabled by default (uint)
parm:           emi_canceller:Enable or Disable EMI Canceller. Disabled by default (uint)
parm:           num_rings:Number of TX and RSS queues to create - 8 (default), 12 (Max)  (uint)

 

В документации вот что пишут

Screenshot_10_01_4.png

 

Попробовал вручную пораскидал прерывания по разным ядрам - помогло, скорость отдачи увеличилась до 1100Мб/сек

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

 

Осталась одна не ясность, зачем еще есть всякие /sys/class/net/eth1/queues/rx-0/rps_cpus ? Находил рецепты в интернете про

echo ffffff > /sys/class/net/eth1/queues/rx-0/rps_cpus

Пробовал, тоже лучше становилось, все процы начинали грузиться почти по полной, но первый все равно больше всех жрал, скорость где-то была около 900Мб/сек

Или это так называемые софтварные прерывания?

 

Получается если редактировать /proc/irq/_irq_num_/smp_affinity скорость возрастает даже чуть выше, но нагрузка на процы гораздо меньше, чем в случае с редактированием /sys/class/net/eth1/queues/rx-0/rps_cpus

 

И еще один вопрос, есть ли смысл в моей задаче в гипертрединге, зачем пилить ядра пополам? все равно я могу раскинуть прерывания только на 8 ядер(4 потока у двух портов)?

Share this post


Link to post
Share on other sites

num_vfs это вроде чтото специфичное для виртуалок и требует рабочего iommu/vt-d, нет? Оно вам наверное вообще не нужно, попробуйте его отключить.

на первом ядре у вас наверняка еще софт висит какой-то (самба мб?), поэтому оно больше загружено.

Почитайте мануал, он вроде ничего так написан, понятно все хорошо.

Share this post


Link to post
Share on other sites

ffffff

 

Это обработка прерывания всеми ядрами. Так лучше не делать. Лучше "гвоздями" к ядру прибить и забыть.

А гипертрединг можно попробовать наверно оставить, пущай его только узерспейс мучает(если конечно это не приведет к деградации работы кэша CPU, надо экспериментировать). К нему не прибивать прерывания.

Поскольку у вас отдача, можно попробовать раскидать TX-очереди по реальным ядрам, RX- к этим же ядрам

Ну и подтюнить ethtool -k всякие нужные офлоады rx/tx чексумминг и прочее

 

И кстати можно поиграться и раскидать прерывания у процессов через taskset, чтобы эффективно процессорные кэши использовать.

Edited by micol

Share this post


Link to post
Share on other sites

 

Это обработка прерывания всеми ядрами. Так лучше не делать. Лучше "гвоздями" к ядру прибить и забыть.

это не обработка прерываний, это RPS. Если сетевая ущербная, может существенно помочь.

Share this post


Link to post
Share on other sites

Если сетевая ущербная, может существенно помочь.

Или если PPPoE гоняется, а сетевая параллелит по IP...

Share this post


Link to post
Share on other sites

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

 

            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7       CPU8       CPU9       CPU10      CPU11
106:        204  335045318          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth3-q0
107:         29          0   18707647          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth3-q1
108:         17          0          0   18344933          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth3-q2
109:          3          0          0          0   22535725          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth3-q3
110:        197          0          0          0          0          0          0  310453611          0          0          0          0  IR-PCI-MSI-edge      eth4-q0
111:         22          0          0          0          0          0          0          0   18586813          0          0          0  IR-PCI-MSI-edge      eth4-q1
112:         16          0          0          0          0          0          0          0          0   18253597          0          0  IR-PCI-MSI-edge      eth4-q2
113:          5          0          0          0          0          0          0          0          0          0   22389317          0  IR-PCI-MSI-edge      eth4-q3

 

Centos 6.5, драйвер сетевухи 4.6.148.0, опции загрузки драйвера:

options be2net rss_on_mc=1 num_rings=12

 

Гипертрединг выключил, вот скрипт раскидывания прерывания(запускается при старте системы):

 

# cat /usr/local/startup/interrupts
#!/bin/bash

echo 2 > /proc/irq/106/smp_affinity
echo 4 > /proc/irq/107/smp_affinity
echo 8 > /proc/irq/108/smp_affinity
echo 10 > /proc/irq/109/smp_affinity
echo 80 > /proc/irq/110/smp_affinity
echo 100 > /proc/irq/111/smp_affinity
echo 200 > /proc/irq/112/smp_affinity
echo 400 > /proc/irq/113/smp_affinity

Edited by metallic

Share this post


Link to post
Share on other sites

Все хорошо, только для начала выясните какие ядра какому процу принадлежат, не факт что они идут по очереди! Очереди одной сетевой должны обрабатываться одним процом.

 

show-cpus.sh

#!/bin/bash

(cat /sys/devices/system/node/online | \
awk ' \
{ \
       split($1, parts, ","); \
       for (part in parts) { \
               split(parts[part], items, "-"); \
               seq_start = items[1]; \
               seq_end = items[2]; \
               if (seq_start == "") {seq_start = 0;}; \
               if (seq_end == "") {seq_end = seq_start;} \
               for (seq = seq_start; seq <= seq_end; seq++) {print seq;} \
       } \
}') | \
while read NODE
do
       echo "Node #$NODE"
       (cat /sys/devices/system/node/node${NODE}/cpulist | \
       awk ' \
       { \
               split($1, parts, ","); \
               for (part in parts) { \
                       split(parts[part], items, "-"); \
                       seq_start = items[1]; \
                       seq_end = items[2]; \
                       if (seq_start == "") {seq_start = 0;}; \
                       if (seq_end == "") {seq_end = seq_start;} \
                       for (seq = seq_start; seq <= seq_end; seq++) {print seq;} \
               } \
       }') | \
       while read CORE
       do
               echo -e "\tCore #$CORE"
       done
done

Пример вывода:

Node #0
       Core #0
       Core #1
       Core #2
       Core #3
       Core #8
       Core #9
       Core #10
       Core #11
Node #1
       Core #4
       Core #5
       Core #6
       Core #7
       Core #12
       Core #13
       Core #14
       Core #15

Edited by ThreeDHead

Share this post


Link to post
Share on other sites

Ну и конечно же скрипт, который должен написать каждый сетевой linux-администратор.

 

eth2smp.sh

#!/bin/bash

NUM=0
CPUS=
for ARG in "$@"
do
       if [ $NUM -eq 0 ]; then INTERFACE=$ARG; fi
       if [ $NUM -gt 0 ]; then CPUS[$[$NUM-1]]=$ARG; fi
       let NUM++
done

if [ "$INTERFACE" != "" ] && [ "${CPUS[0]}" -ge 0 ]
then
       CPU_INDEX=0
       for irq in `cat /proc/interrupts | grep $INTERFACE | awk '{print $1}' | sed s/\://g`
       do
               f="/proc/irq/$irq/smp_affinity"
               test -r "$f" || continue
               if [ "${CPUS[$CPU_INDEX]}" != "" ] && [ ${CPUS[$CPU_INDEX]} -ge 0 ]
               then
                       MASK=`printf %x $[2 ** ${CPUS[$CPU_INDEX]}]`
                       printf "Assign SMP affinity: %-5s  IRQ: %-2d  CPU: %2d  MASK: 0x%s\n" $INTERFACE $irq ${CPUS[$CPU_INDEX]} $MASK
                       echo "$MASK" > "$f"
               fi
               let CPU_INDEX++
       done
else
       echo "Usage  : $0 <INTERFACE> <CPU_LIST>"
       echo "Example: $0 eth0 0 1 2 3"
fi

Использовать так:

eth2smp eth0 0 1 2 3

раскидываем eth0 по ядрам 0, 1, 2, 3

 

Можно имя интерфейса даже так написать eth0-, это чтобы "попасть" прям на очереди, а не на устройство.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this