Shtsh 22.01.2010 14:51

How-to`sРешение проблемы с медленной записью на USB Flash drive

Довольно частой проблемой, встречающейся у пользователей linux, является проблема с записью на флешки.

Проблема заключается в том, что когда идёт запись на флешку, скорость очень низкая (сначала, когда пишет в кэш, всё хорошо, но потом она падает до ~500-700 кбайт/с и система начинает довольно сильно тормозить. Причем тормоза настолько сильные, что иногда иксы виснут намертво на несколько минут.

Как выяснилось эмпирически, это случается из-за переключения процессоров и блокировок при использовании общего блока памяти. Логично решение указать, чтобы процессоры не переключались при обработки прерываний, на которых находятся usb.

Сначала нужно узнать, какие прерывания используются usb
для этого делаем
1
2
3
4
grep usb /proc/interrupts
21: 45801 9374917 IO-APIC-fasteoi ehci_hcd:usb2, HDA Intel
22: 1 28 IO-APIC-fasteoi ohci_hcd:usb4
23: 1827 188061 IO-APIC-fasteoi ehci_hcd:usb1, ohci_hcd:usb3


То есть, у нас используются прерывания 21,22,23
на каждое прерывание указывается на каком процессоре оно висит, за это отвечает параметр smp_affinity
1
2
3
4
5
6
cat /proc/irq/21/smp_affinity 
3
cat /proc/irq/22/smp_affinity
3
cat /proc/irq/22/smp_affinity
3


Теперь, что это значит
3 в шестнадцатеричной системе = 00000000.00000011 в двоичной (так как ядро скомпилировано с поддержкой 16 процессоров)
то есть обрабатыватся на CPU0, CPU1
Если нам нужно указать, чтобы обработка шла только на CPU0, то нужно задать 00000000.00000001, то есть 1
Если же нужно указать, чтобы обработка шла только на CPU1, то нужно задать 00000000.00000010, то есть 2

Теперь укажем, что будем обрабатывать на CPU0 все прерывания с висящими на них usb, естественно, всё делать нужно под рутом
1
2
3
echo 1 > /proc/irq/21/smp_affinity 
echo 1 > /proc/irq/22/smp_affinity
echo 1 > /proc/irq/23/smp_affinity



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

Собственно, вот скрипт, который детектит прерывания, на которых висят usb и указывает, какой процессор выполняет работу с ними. Нужно скопировать его в /usr/local/bin и засунуть его в загрузку системы (например, прописать /usr/local/bin/setusbwrite в /etc/init.d/rc.local)
1
2
3
4
5
6
#!/bin/sh

for interruption in `grep usb /proc/interrupts| awk '{print $1}'| sed -e 's/\://g'` ; do
echo "Setting 1 in /proc/irq/${interruption}/smp_affinity";
echo 1 > /proc/irq/${interruption}/smp_affinity;
done



В результате, запись идёт на скорости несколько Мбайт/с и ничего не тормозит.


Тэги: how-to smp_affinity usb usb flash drive
+ 14 -
Похожие Поделиться

predator 22.01.2010 15:07 #
никогда не замечал
Shtsh 22.01.2010 15:09 #
Тебе повезло :) В интернете это довольно распространённый вопрос, и особо нету вразумительных ответов. У меня на нескольких компьютерах было
Username 22.01.2010 15:43 #
а у меня просто медленная флешка
Shtsh 22.01.2010 15:49 #
просто у меня было плохо независимо от флешки :)
pioner14 22.01.2010 15:47 #
Оооо...
Это старая проблема.
Неужели это решение действительно заработает!
Сейчас попробую.
pioner14 22.01.2010 16:52 #
не работает
После команды

sudo echo 1 > /proc/irq/20/smp_affinity

Выдает сообщение

Файл существует: /proc/irq/20/smp_affinity

Запись стопорится на секунд 5-10, потом возобновляется.
Скрипт соответственно тоже не работает.
Жаль.
ZogG 22.01.2010 16:55 #
cat /proc/interrupts | grep usb и номера посмотри, туда и пиши. но мне скрипт не помог все равно.
pioner14 22.01.2010 17:04 #
cat /proc/interrupts | grep usb
20: 118 22083 IO-APIC-fasteoi ehci_hcd:usb1
23: 294 135747 IO-APIC-fasteoi sata_nv, ohci_hcd:usb2

Shtsh 22.01.2010 16:58 #
во-первых, просто с sudo работать не будет делай сначала sudo su
во-вторых, сначала посмотри, действительно ли это твои прерывания
pioner14 22.01.2010 17:15 #

во-первых, просто с sudo работать не будет делай сначала sudo su


Прерывания мои



во-первых, просто с sudo работать не будет делай сначала sudo su

Действительно через su сообщений об ошибке не выдает, но ситуация не изменилась - скорость записи скатывается к 0 через несколько секунд после начала а потом возобновляется.

pioner14 22.01.2010 17:22 #
Извиняюсь за ошибку при цитировании
digiwhite 22.01.2010 21:21 #
А у вас многоядерный процессор?
pioner14 22.01.2010 21:27 #
Да
AMD Athlon(tm) 64 X2 Dual Core Processor 3800+
Shtsh 22.01.2010 21:37 #
глупый вопрос. а как копируешь? можно попробовать измерить скорость при помощи rsync --stats --progress что-нибудь_большое папка_с_флешкой
pioner14 22.01.2010 21:49 #
Копирую по разному как удобно в какой то момент времени. Иногда в Mc, но чаще в Dolphin Копировать > Вставить.
Сейчас измерю.
pioner14 22.01.2010 22:55 #
ну наконец то закачался попутно вешая систему.
Вот результат:
rsync --stats --progress /mnt/2hard/Video2/Фильмы/Детектив/Шерлок_Холмс_Sherlock_Holmes_2009_DVDScr.avi /media/disk/
Шерлок_Холмс_Sherlock_Holmes_2009_DVDScr.avi
2200547328 100% 766.41kB/s 0:46:43 (xfer#1, to-check=0/1)

Number of files: 1
Number of files transferred: 1
Total file size: 2200547328 bytes
Total transferred file size: 2200547328 bytes
Literal data: 2200547328 bytes
Matched data: 0 bytes
File list size: 71
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 2200816069
Total bytes received: 31

sent 2200816069 bytes received 31 bytes 767771.18 bytes/sec
total size is 2200547328 speedup is 1.00
Shtsh 22.01.2010 23:01 #
и cat /proc/interrupts | grep usb
pioner14 22.01.2010 23:04 #
cat /proc/interrupts | grep usb
22: 88055 120959 IO-APIC-fasteoi sata_nv, ohci_hcd:usb2
23: 303862 399386 IO-APIC-fasteoi sata_nv, ehci_hcd:usb1
Shtsh 22.01.2010 23:09 #
а почему тут usb висят на этих же прерываниях, что и sata?
Может, дело в этом? и, заметь, эти прерывания обрабатываются обоими ядрами. Почему? Не отправил туда 1 или 2?
pioner14 22.01.2010 23:12 #
а почему тут usb висят на этих же прерываниях, что и sata?

хороший вопрос, может и в этом.
Почему? Не отправил туда 1 или 2?

отправлял 1
pioner14 22.01.2010 23:12 #
отправлял, все делал как в инструкции.
Shtsh 22.01.2010 23:15 #
отправлял, все делал как в инструкции.

sudo su
echo 1 > /proc/irq/22/smp_affinity
echo 1 > /proc/irq/23/smp_affinity

если послал бы туда 1, второе и третье значения были что-то вроде
20: 76052 27 IO-APIC-fasteoi ohci_hcd:usb2
21: 18030 3 IO-APIC-fasteoi ehci_hcd:usb1
Видишь, у меня обрабатываются только 1м процем (первое значение намного больше второго). У тебя же работают оба ядра
Shtsh 22.01.2010 23:10 #
если послал бы туда 1, второе и третье значения были что-то вроде
20: 76052 27 IO-APIC-fasteoi ohci_hcd:usb2
21: 18030 3 IO-APIC-fasteoi ehci_hcd:usb1
pioner14 22.01.2010 23:21 #
Посылаю еще раз и ...
sudo su
# echo 1 > /proc/irq/22/smp_affinity
# echo 1 > /proc/irq/23/smp_affinity
# exit
nick:~$ cat /proc/interrupts | grep usb
22: 96815 120959 IO-APIC-fasteoi sata_nv, ohci_hcd:usb2
23: 334481 399386 IO-APIC-fasteoi sata_nv, ehci_hcd:usb1
Shtsh 22.01.2010 23:28 #
сделай
cat /proc/irq/22/smp_affinity
cat /proc/irq/23/smp_affinity
22: 96815 120959 IO-APIC-fasteoi sata_nv, ohci_hcd:usb2
23: 334481 399386 IO-APIC-fasteoi sata_nv, ehci_hcd:usb1

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

pioner14 22.01.2010 23:30 #
sudo su
# cat /proc/irq/22/smp_affinity
1
# cat /proc/irq/23/smp_affinity
1
pioner14 22.01.2010 23:31 #
запускаю копирование опять - та же песня: тормоза системы и уход скорости копирования в 0
pioner14 22.01.2010 23:37 #
это во время копирования которое сейчас происходит
cat /proc/interrupts | grep usb
22: 107800 120959 IO-APIC-fasteoi sata_nv, ohci_hcd:usb2
23: 391051 399386 IO-APIC-fasteoi sata_nv, ehci_hcd:usb1
Shtsh 23.01.2010 00:14 #
собственно, судя по всему, сейчас работает только одно ядро для этих прерываний. Мне мозгов хватает только предположить, что дело в том, что sata и usb на одном прерывании. Но чувствую, дело не в этом :( Потому что по идее, это не должно влиять
pioner14 23.01.2010 00:39 #
Спасибо что попытался помочь.
Shtsh 23.01.2010 00:42 #
пожалуйста, будем надеяться, что сюда кто-то более умный заглянет...
idler 23.01.2010 01:57 #
Мдя.... И после этого мы все, включая меня, говорим, что Линукс давно готов к десктопу...

Секретутка например совсем другое подумает при слове "перерывания" ...
Shtsh 23.01.2010 02:02 #
Папулька сказал, что даже в его молодости до такого количества абортов никто не доходил
(с) Экслер, Записки невесты программиста
idler 23.01.2010 02:07 #
Вот, вот... :)
Murz 23.01.2010 15:05 #
У меня на Kubuntu Karmic проблема решилась сменой элеватора:
Задал в параметрах загрузки ядра
elevator=noop
и после этого скорость стала стабильной!
Ещё можно попробовать elevator=deadline, но пока время не нашёл потестить :(
digiwhite 23.01.2010 15:41 #
Глядя на welinux, что-то стал задумываться: "Тут народ более адекватно решает проблемы, чем на многих форумах. Может какую-нибудь базу знаний замутить?":)
al1e 23.01.2010 19:56 #
а почему бы и нет?
digiwhite 23.01.2010 20:03 #
Дык ведь и я думаю, почему нет. Просто база знаний - это не так все просто :).
Shtsh 24.01.2010 00:52 #
так exelens же что-то делает по этому поводу. нужно поинтересоваться, как там дела
digiwhite 24.01.2010 00:53 #
Он вроде как по другому вопросу :).
Shtsh 24.01.2010 01:11 #
Он вроде тот, кто это организовывает. Появится в джаббере - спрошу, что делать с этой идеей
viggo 04.02.2010 11:17 #
Сразу не сориентировался, простите. Не надо было постить в теме, где уже вопрос в стадии<Решено>, поэтому продублирую своё сообщение здесь.

С фиксированием прерываний вручную (не используя скрипта для автоматизации) ситуация с моей флешкой не изменилась. Даже обычный архив с нтфс-раздела (виндовый) на 400 Мб устаю ждать, когда докопируется.

Мне интересно, почему же с сентября месяца, когда я только поставил линукс, ничего подобного не наблюдалось. Только последний месяц (январь) стал таким ужасным для копирования файлов на флешку. У меня сейчас стоит убунту 9.10, копирую в Тунаре (xfce4).

Пока не понадобилось скопировать 4 Гиг-овый образ на флешку, она была форматирована в ФАТ. Переформатировал в нтфс, но это было месяца три назад, и после этого таких зависаний при копировании не наблюдалось, вплоть до последнего месяца.
Shtsh 04.02.2010 11:28 #
Собственно, я сталкивался со следующими советами в Интернете.
1. Отключить в BIOS USB Legcy Support
2. Попробовать другие I/O шедулеры. Например, при загрузке передавать ядру параметр elevator=noop

Кстати, а если переключиться в консоль (например, Ctrl+Alt+F1) и скопировать mc, то что происходит?
viggo 04.02.2010 12:29 #
Не понял про МС. В тту1 запустить МС и скопировать на флешку или с неё большой файл?
Shtsh 04.02.2010 17:04 #
Да, запиши на флешку большой файл, только размер хотя бы гига 2
viggo 05.02.2010 09:00 #
что-то страшное случилось :) - вся кирилица в МС превратилась в нечитаемые символы, рамки окон нарушились. Попытался через Ф5 сделать копирование, но чего-то на красном фоне вылезло и строчки из крякозяблов во всю длину экрана и невозможно понять о чём речь.
Shtsh 05.02.2010 10:37 #
rsync --stats --progress что-нибудь_большое папка_с_флешкой

попробуй так измерить
вся кирилица в МС превратилась в нечитаемые символы, рамки окон нарушились.

Попробуй установить/запустить console-cyrillic
viggo 10.02.2010 09:05 #
Установка консоли-кирилик ситуацию с крякозяблами не решила. Устанавливал в убунте, после переключения в тту1 и запуска МС те же самые нечитаемые символы вместо русских букв. При запуске консоли-кирилик в тту1 пишет, что неправильная команда или нот-фаунд.

Помимо этого ещё одна беда. Проблема с удалением файлов. Надо было место почистить на диске. Диск виндовый с нтфс. При удалении нескольких файлов разом, появлялось сообщение, что невозможно такой-то файл скопировать в корзину. Некоторые ссылки (где удаляемый файл размещается) в этом сообщении имели вид буквы-проценты (такое бывает когда ссылку с русской вики вставить в какой-нибудь простой блокнот). Несколько раз чистил корзину, удалял часть файлов, чистил корзину. Это разве нормально. Ладно. Удаляю ещё два файла 1.9 Гиг и 200 Мб (вместе отметил для удаления). 8 минут удалялись, при этом вся убунта так повисла, что даже намлук не реагировал, будто клава вырубилась. Однократное нажатие на кнопку "power" никакого эффекта не давало. Несколько однократных нажатий - и через несколько секунд диод намлука на клаве загорался, а курсор мыши мог чуть двигаться и снова в летаргический сон вся система.

Никаких экзекуций с системой не производил. Работаю в браузере, получаю почту, слушаю музыку, общаюсь по аське.

Неужели я поломал линукс? И что теперь делать? Переустановка убунты поможет?
Shtsh 10.02.2010 10:10 #
А оформить отдельный пост с вопросом лучше не будет разве?
wiz 16.02.2010 11:27 #
stop piping cats!
Shtsh 16.02.2010 11:36 #
Поправил

#!/bin/sh

for interruption in `grep usb /proc/interrupts| awk '{print $1}'| sed -e 's/\://g'` ; do
echo "Setting 1 in /proc/irq/${interruption}/smp_affinity";
echo 1 > /proc/irq/${interruption}/smp_affinity;
done
kstep 18.01.2012 16:54 #
Тогда уже однострочником:

1
grep usb /proc/interrupts | awk -v FS=':' '{ print $1 }' | xargs -I{} sh -c 'echo 1 | sudo tee /proc/irq/{}/smp_affinity > /dev/null'

Masaki 09.07.2010 16:45 #
Спасибо огромное, скорость возросла.
А в /etc/rc.local просто ссылка на скрипт сойдет? Ну, будет ли он выполняться с нужными правами при старте системы?
Shtsh 09.07.2010 16:47 #
При старте системы скрипты выполняются с правами рута
chestr 01.12.2011 00:50 #
добавил в параметры ядра elevator=cfq, попутно отключил в биосе usb legacy support, использовал опции монтирования flush,async и скорость стала приемлемой - начинает с 30 Мбс и ооочень плавно снижается до 7-8 Мбс
а при переключении обработки прерываний на отдельное ядро скорость в самом начале 30 Мбс, потом небольшой ступор, потом 5-6, потом 1-2 и так с великим трудом ползет до конца...

ну и вот еще
chestr-gentoo chestr # grep usb /proc/interrupts
16: 43313 0 IO-APIC-fasteoi uhci_hcd:usb3, nvidia
18: 26090 0 IO-APIC-fasteoi pata_jmicron, ata_piix, ata_piix, ehci_hcd:usb1, uhci_hcd:usb7, eth0
19: 0 0 IO-APIC-fasteoi uhci_hcd:usb6
21: 0 0 IO-APIC-fasteoi uhci_hcd:usb4
23: 52417 0 IO-APIC-fasteoi ehci_hcd:usb2, uhci_hcd:usb5

щас проверял на юсб-хабе, напрямую в комп воткнуть щас нет возожности - далеко лезть, темно, шума много будет, а в таше щас 1:45 ночи... завтра вернусь с работы и проверю на портах матери, очень надеюсь что бага поправится...
ядро 3.0.6 амд64 - гента

ЗЫ грузанул как то раз для эксперимента убунту 9.10, так там все было в порядке, завтра грузану опять и посматрю какие там модули на каких прерываниях висят... и как с ядрами
xandry 17.01.2012 20:28 #
У меня на втором этапе некая загвоздка.
sudo cat /proc/irq/22/smp_affinity
f

Процессор четырёхядерный AMD Phenom 9450e.
kstep 18.01.2012 16:57 #
Всё правильно. У тебя четыре ядра, f в 16-й системе 15, в двоичной 1111, то есть указано, что все четыре ядра могут обрабатывать это прерывание. В статью стоило бы добавить, что в smp_affinity значения идут в 16-й системе, тогда такого недопонимания бы не было.
kstep 18.01.2012 17:00 #
Тебе надо выбирать из значений (шестнадцетеричная, это записывай в smp_affinity = двоичная для ориентировки):

1 = 0001 - первое ядро,
2 = 0010 - второе ядро,
4 = 0100 - третье ядро,
8 = 1000 - четвёртое ядро.