LINUX.ORG.RU

и снова (но давайте более теоретически!?) про тормоза с USB-флешкой вопрос

 , freezing, ,


4

3

добрый день!

друзья!

этот вопрос задавался миллионы раз — но всегда появляется кто-то кто начинает давать *практические* советы как это исправить. пожалуйста, друзья, давайте на этот раз не будем тут писать практические советы (ими заполнен четь более чем весь интернет!).

вопрос: почему во время копирования больших файлов на медленный USB-накопитель (даже из не основного диска) — вся система начинает переодически подзависать включая курсор мыши?

интересует сугубо *технические* (теоретические) детали этого механизма, а не рецепты исправления этого. да(!) я хочу чтобы оно и дальше тормозило (не хочу это исправлять!), но при этом лучше понимать природу этих явлений.

понятное дело что вероятность появления тормозов зависят от железок. давайте разберём ситуации у людей, которым повезло заиметь соответствующие такие железки (такая мат-плата, и такая USB-флешка).

сможете помочь? заранее спасибо!

★★★★★

Последнее исправление: Deleted (всего исправлений: 1)

Тред не читал.

У кого проявляется 12309 на флешках - вот это не помогает?

vm.dirty_bytes = 2097152
vm.dirty_background_bytes = 2097152

Deleted
()
Ответ на: комментарий от ZenitharChampion

Ну давай расскажи, как связаны подвисания в подсистеме страничного кэша и планировщик потоков.

Deleted
()
Ответ на: комментарий от anonymous

Потому что без всякой записи на флэшки при нехватке памяти всё колом встаёт.

Ну, это не 12309, конечно.

Чтобы это пофиксить, нужен либо per-process контроль рабочего набора, либо куча эвристик в алгоритме kswapd (а может, и то, и другое). В линукс этого, к сожалению, так и не завезли.

Deleted
()
Ответ на: комментарий от Deleted

Чтобы это пофиксить, нужен либо per-process контроль рабочего набора, либо куча эвристик в алгоритме kswapd

Это невозможно пофиксить на уровне системы. Только на уровне администратора.

tailgunner ★★★★★
()
Ответ на: комментарий от ZenitharChampion

Никак не помогает от флэшкотормозов или кончающейся памяти.

anonymous
()
Ответ на: комментарий от Deleted

Помогает, ценой умеренного снижения скорости записи.

intelfx ★★★★★
()

Почти все вышеотписавшиеся — идиоты.

Технические причины: любая запись (в т. ч. на медленную флешку) ведётся в режиме write-back. Ядро возвращается из write(), как только данные попадают в write-back кэш, в итоге он очень быстро насыщается и включается режим синхронного сброса кэша. Кстати, этот кэш один на все процессы и устройства. Вот и всё — следующая программа, которой приспичило записать что-либо на диск, пусть даже пару байт, блокируется на своём write() до тех пор, пока медленная флешка не соизволит записать на себя очередной блок.

Кстати, вопрос аудитории: как обстоит дело с MMIO? Если я маплю в память какую-нибудь видеокарту и пишу туда, это попадает в page cache? Или сразу гонится на шину?

intelfx ★★★★★
()
Ответ на: комментарий от anonymous

Не, вопрос был про page cache, а не про кэш на процессоре. Ну, впрочем да, я ступил. Если я маплю в память видеокарту, то я сразу пишу в её физические адреса.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Это невозможно пофиксить на уровне системы. Только на уровне администратора.

Ты еще скажи, что оценку значения /proc/*/oom_score невозможно провести на уровне системы. Сидит встроенный китайский администратор в каждом Linux-боксе и оценивает.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)

что значит большие - система в районе 4 гигов залиывется на флешку 15 - 20 минут, ничего в этот момент не тормозит и не подвисает...

amd_amd ★★★★★
()
Ответ на: комментарий от amd_amd

Ну если у Твоего Величества в данный момент всё нормально, то да - проблема выдуманная

anonymous
()
Ответ на: комментарий от intelfx

любая запись (в т. ч. на медленную флешку) ведётся в режиме write-back. Ядро возвращается из write(), как только данные попадают в write-back кэш, [...]. Кстати, этот кэш один на все процессы и устройства

спасибо, это теперь всё объясняет исчерпывающе

user_id_68054 ★★★★★
() автор топика
Ответ на: комментарий от intelfx

но всё-таки не доконца ясна мотивация разработчиков :-)

Кстати, этот кэш один на все процессы и устройства.

1. почему кэш один на-всё-про-всё? их не сделали несколько — из-за экономии памяти чтоль? (или чтоб не переусложнять реализацию?).. почему не сделали квоты относительно каждого блочного устройства?

2. если мы предполагаем что — да(!) — один кэш на-всё-про-всё — и якобы это не баг (не недоработка), а хорошее годное поведение... то выходит что массовые копирования являются (даже чисто формально) опасной штукой и *просто-обязаны* быть сделаны с умом на прикладном уровне.

например Файловый Магнагер зная что может всё испортить должен постоянно делать fsync(fd) после каждого деятка мегобайта копируемого файла? разве нет?

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

user_id_68054 ★★★★★
() автор топика
Последнее исправление: user_id_68054 (всего исправлений: 1)
Ответ на: комментарий от intelfx

Кстати, этот кэш один на все процессы и устройства. Вот и всё — следующая программа, которой приспичило записать что-либо на диск, пусть даже пару байт, блокируется на своём write() до тех пор, пока медленная флешка не соизволит записать на себя очередной блок.

И как предлагается писать, допустим файловый менеджер, под это говно (Linux)? Открывать файлы на флешках с O_SYNC? O_DIRECT? Чтобы работал верно прогрессбар и не вставало всё остальное из-за засранного кэша.

d_a ★★★★★
()

почему кэш один на-всё-про-всё? <...> почему не сделали квоты относительно каждого блочного устройства?

Спроси.

если мы предполагаем что — да(!) — один кэш на-всё-про-всё — и якобы это не баг (не недоработка)

Это недоработка. Просто всем, как водится, пофиг.

например Файловый Магнагер зная что может всё испортить должен постоянно делать fsync(fd) после каждого деятка мегобайта копируемого файла? разве нет?

Ну, вообще в таком случае всё равно остаётся проблема трешинга чистого кэша. Но близко. Не знаю, каков полностью правильный способ копировать файлы в линуксе, но да, его никто не соблюдает (хинт: потому что он ни хера не очевидный). Наверное, fadvise(POSIX_FADV_SEQUENTIAL) + fadvise(POSIX_FADV_NOREUSE) + fdatasync() + fadvise(POSIX_FADV_DONTNEED). Но из этих как минимум про NOREUSE явно сказано, что это no-op, так что я вообще хз.

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

И да, и нет. С одной стороны, ядро уже даёт по этому поводу какой-то API, поэтому прикладные программы должны бы его юзать. А с другой стороны, ядро должно давать адекватный API, а не такой, который могут правильно использовать только три с половиной гика, при этом предварительно перечитав половину manpages, заглянув в исходники ядра и посоветовавшись с мейнтейнером подсистемы.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 7)
Ответ на: комментарий от d_a

И как предлагается писать, допустим файловый менеджер, под это говно (Linux)?

О, а это хороший вопрос. :)

См. выше, я там предположил. Но вообще говно, да.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

почему кэш один на-всё-про-всё? <...> почему не сделали квоты относительно каждого блочного устройства?

Спроси.

25.08.1981:

... and it probably never will support anything other than AT-harddisks, as that’s all I have :-(

Действительно, зачем каждому блочному устройству кеш на запись, когда этих устройств было, по-видимому, всего одна штука.

если мы предполагаем что — да(!) — один кэш на-всё-про-всё — и якобы это не баг (не недоработка)

Это недоработка. Просто всем, как водится, пофиг.

В итоге анекдот про форматирование дискетки в мультизадачной винде подходит и линуксу: подожди, сейчас только что-то дозапишется...

gag ★★★★★
()
Ответ на: комментарий от Deleted

Похоже это железоспецефично. На каких-то компах всё и так хорошо, на каких-то фикс помогает, тут в ветке утверждают, что это не помогает (хотя мб и попробовать поленились) вообще.

Deleted
()
Ответ на: комментарий от intelfx

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

Если бы это было так, было бы еще неплохо.

Кстати, вопрос аудитории: как обстоит дело с MMIO? Если я маплю в память какую-нибудь видеокарту и пишу туда, это попадает в page cache?

то, что ты называешь write-back cache, относится только к блочным устройствам (точнее, к VFS и ФС, что обычно подразумевает блочное устройство), а запись в character-oriented специальные файлы идет мимо всего этого.

P.S. человек, который не знает таких базовых фактов, не должен называть других идиотами :)

tailgunner ★★★★★
()
Ответ на: комментарий от Deleted

Это невозможно пофиксить на уровне системы. Только на уровне администратора.

Ты еще скажи, что [...]

Но ведь я этого не сказал.

что оценку значения /proc/*/oom_score невозможно провести на уровне системы

Там можно придумать эвристики - например, не убивать login и ssh. Но да, в общем случае это невозможно - именно поэтому /proc/*/oom_score и существует.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

как выяснилось, в лине, *просто* даже память в куче не зарезервировать

Тот, кому это не просто, 1) глуп 2) застрял во временах DOS..

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

то, что ты называешь write-back cache, относится только к блочным устройствам (точнее, к VFS и ФС, что обычно подразумевает блочное устройство), а запись в character-oriented специальные файлы идет мимо всего этого.

Я не говорил про character devices. Я говорил про MMIO. И да, я уже поправил себя, как видишь.

Если бы это было так, было бы еще неплохо.

Окей, а как тогда?

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Я не говорил про character devices. Я говорил про MMIO

MMIO автоматически подразумевает character device (просто потому, что MMIO - это не обязательно память). В принципе, можно сделать поверх MMIO и блочное устройство, но я знаю единственную реализацию этого во времена, о которых мало кто помнит.

Окей, а как тогда?

Менеджер VM пытается освободить память и система уходит в thrashing.

P.S. 12309 - это зонтик, под которым собраны баги с описанием «Linux тормазит!!!11», хотя они имеют разную природу. Некоторые из этих багов не имеют отношения к менеджеру VM.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Oom score - это reasonable default. Плюс есть adjust чтобы отрегулировать работу для случаев, когда дефолта не достаточно.

В подкачке анонимной памяти же, увы, нет ни резолабл дефолтов, ни ручек, за которые можно подергать ядро. Это недоработка, которую у кого-нибудь когда-нибудь дойдут руки пофиксить; но не неотъемлемое свойство подсистемы страничной памяти.

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

Deleted
()
Ответ на: комментарий от Deleted

В подкачке анонимной памяти же, увы, нет ни резолабл дефолтов, ни ручек, за которые можно подергать ядро. Это недоработка, которую у кого-нибудь когда-нибудь дойдут руки пофиксить

Reasonable default не существует в природе. Thrashing при исчерпании ресурсов неизбежен.

А ручки, за которые дергать, есть - они называются cgroup memory controller. Или, внезапно sys/vm/overcommit_memory.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

MMIO автоматически подразумевает character device

Может быть и (нестандартный) сисколл. Но это спор ни о чём.

Менеджер VM пытается освободить память и система уходит в thrashing.

Непохоже на правду. Симптомы возникают даже тогда, когда ограничение на размер dirty memory мало. Стало быть, это не трешинг, а именно борьба за место в dirty memory.

P.S. 12309 - это зонтик, под которым собраны баги с описанием «Linux тормазит!!!11», хотя они имеют разную природу. Некоторые из этих багов не имеют отношения к менеджеру VM.

Я знаю. Но здесь мы обсуждаем один конкретный баг.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

MMIO автоматически подразумевает character device

Может быть и (нестандартный) сисколл.

Нерелевантно.

Но это спор ни о чём.

Доо.

это не трешинг, а именно борьба за место в dirty memory.

фейспалм.бмп

tailgunner ★★★★★
()

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

алсо выделение еще немного памяти это != новой аллокации. можно просто по отсвопаной памяти попасть. дабы этого не было, надо ограничивать объем буфера записи.

ckotinko ☆☆☆
()
Ответ на: комментарий от tailgunner

Thrashing при исчерпании ресурсов неизбежен.

Основной импакт этого трашинга можно ограничить его виновниками.

Deleted
()
Ответ на: комментарий от intelfx

это не трешинг, а именно борьба за место в dirty memory.

фейспалм.бмп

Please elaborate.

Это _ты_ должен объяснять, чем «борьба за место в dirty memory» отличается от thrashing. Не скажу, что меня сильно интересует самопальная терминология, но всё же немного любопытно.

tailgunner ★★★★★
()
Ответ на: комментарий от Deleted

Thrashing при исчерпании ресурсов неизбежен.

Основной импакт этого трашинга можно ограничить его виновниками.

Для анонимной памяти? Можно, лимитами. См. memory controller.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Можно и лимитами. Но лимиты и приоритеты - это разные вещи. Лимит использования CPU и приоритет исполнения потока - не одно и то же. Лимит скорости соединения и приоритет пакетов - не одно и то же.

Deleted
()
Ответ на: комментарий от Deleted

лимиты и приоритеты - это разные вещи

Да, Капитан, конечно же. Но, поскольку я ничего не говорил о приоритетах - о каких приоритетах говоришь ты и какакую задачу они помогут решить? Thrashing при использовании анонимной памяти или разновидность 12309 - забивание памяти writeback cache, который предназначен медленному устройству, и последующий уход системы в thrashing?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Это и не терминология вовсе. А thrashing, насколько я помню — состояние, в котором значительная часть процессорного времени уходит на постоянный обмен данными между памятью и диском. Вот:

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

thrashing occurs when a computer's virtual memory subsystem is in a constant state of paging, rapidly exchanging data in memory for data on disk <...>

А здесь у тебя просто бутылочное горлышко из одного ресурса, из-за которого не получается зашедулить интерактивные процессы. Нет никакого thrashing, просто всё висит в D-state, а процессор простаивает.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от tailgunner

Thrashing при использовании анонимной памяти или разновидность 12309 - забивание памяти writeback cache, который предназначен медленному устройству, и последующий уход системы в thrashing?

Первое. Или несколько шире: Thrashing, вызванный тем, что суммарный рабочий набор перестал вписываться в ОЗУ.

о каких приоритетах говоришь ты и какую задачу они помогут решить

Задачу приоритетного разделения ресурса ОЗУ между вычислительными задачами. Точно так же, как (нереалтаймовая) задача не может оказать критического эффекта на функционирование системы, когда потребляет время CPU в максимальных объемах, она не должна оказывать критического эффекта при попытке потреблять ОЗУ в максимальных объемах.

Можно сформулировать в терминах «баг - желаемое поведение»:

Текущее поведение (баг) :

Пусть объема озу не хватает для размещения суммарного рабочего набора всех запущенных процессов. В текущей реализации это может приводить к замедлению работы всех процессов вплоть до невозможности выполнения каких-либо административных действий.

Желаемое поведение (шаг 1) :

Каждый процесс имеет сопоставленный ему приоритет использования ОЗУ. Более приоритетные процессы могут увеличивать свой рабочий набор за счёт вытеснения страниц из рабочих наборов менее приоритетных процессов. Таким образом на работу приоритетных процессов трашинг не окажет критического влияния.

Желаемое поведение (шаг 2) :

Ядро использует эвристику для автоматического регулирования этого приоритета. Процессы, имеющие малый рабочий набор и не стремящиеся его расширять получают бонус к приоритету. Процессы, имеющие большой рабочий набор и стремящиеся его расширить, получают штраф к приоритету.

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

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от greenman

Прикольно. Только я хотел писать набросок такого демона, а он уже есть. Спасибо, гляну.

Но мне хотелось бы видеть более грамотное решение на уровне ядра. См мой пост выше.

Deleted
()
Ответ на: комментарий от intelfx

А thrashing, насколько я помню — состояние, в котором значительная часть процессорного времени уходит на постоянный обмен данными между памятью и диском

Даже в приведенных тобой цитатах ничего не говорится о затратах «процессорного времени».

А здесь у тебя просто бутылочное горлышко из одного ресурса, из-за которого не получается зашедулить интерактивные процессы

Если в этом наборе жаргонизмов и есть смысл, от меня он ускользнул.

Нет никакого thrashing, просто всё висит в D-state, а процессор простаивает.

В этом предложении условно истинным является только последнее утверждение. Thrashing есть, а в D-state висит разве что kswapd.

Учись, а то пока твой потолок - топить за systemd.

tailgunner ★★★★★
()
Ответ на: комментарий от Deleted

То есть ты предлагаешь некий «paging priority» процесса, и процесс с более низким paging priority не может вытеснить страницы процесса с более высоким. Процессы с более высоким, насколько я понимаю, могут вытеснить страницы процесса с более низким? Наверное, это будет работать в том смысле, что thrashing ограничится только процессом, которому нужно много памяти. Осталось только назначить приоритеты.

Ядро использует эвристику для автоматического регулирования этого приоритета. Процессы, имеющие малый рабочий набор и не стремящиеся его расширять получают бонус к приоритету. Процессы, имеющие большой рабочий набор и стремящиеся его расширить, получают штраф к приоритету.

И какова эвристика? Пока что я вижу, что процесс, который не выделяет памяти, фактически сделал себе mlock. Например, запустил я Firefox, он сожрал всю доступную память и прекратил ее требовать. После чего я пытаюсь запустить видеоредактор, при попытках выделить память система его штрафует, и он уходит в thrashing.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

процесс, который не выделяет памяти, фактически сделал себе mlock.

Не совсем. Рабочий набор определяется как характеристика во времени. Если процесс просто спит на сокете часами, то его рабочий набор пустой.

На практике это означает, что если процессы долго спят не потому, что засели в обработчике страничного исключения в условиях трашинга, а по своим «личным» причинам, система может отбирать у них страницы. Всякие sshd могут быть вытеснены на диск. Но при пробуждении благодаря своему высокому приоритету быстро восстановят рабочий набор и долго не будут его терять.

Deleted
()
Ответ на: комментарий от Deleted

Если процесс просто спит на сокете часами, то его рабочий набор пустой [...] Если процессы долго спят не потому, что засели в обработчике страничного исключения в условиях трашинга, а по своим «личным» причинам, система может отбирать у них страницы

Firefox из моего приемера не спит. Будем считать, что он постоянно ходит по своим страницам, но новых не выделяет.

Еще мне кажется, что у тебя возможен deadlock - два примерно равноприоритетных процесса пытаются выделять память, и ни один из них никуда не продвигается. Это тот же thrashing, но уже у двух процессов; это же относится и к случаю, когда процессов больше двух.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Firefox из моего приемера не спит. Будем считать, что он постоянно ходит по своим страницам, но новых не выделяет.

Он их выделяет постольку, поскольку система сокращает ему рабочий набор, а он страничными исключениями просит вернуть как было.

два примерно равноприоритетных процесса пытаются выделять память, и ни один из них никуда не продвигается. Это тот же thrashing, но уже у двух процессов; это же относится и к случаю, когда процессов больше двух.

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

Если процессов больше двух, и у них все разные приоритеты, самый приоритетный будет щемить остальных, второй по приоритетности - щемиться первым, но щемить всех оставшихся и так далее. Это именно то, что интуитивно и хочется получить: оболочка в голом терминале или в ssh работает быстро, всякие xfce-panel тормозят, но шевелятся, ну а жирнолис сожрал десяток гигабайт и завис (т.е. на самом деле замедлился на многие порядки) в бесконечной подкачке.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 3)
Ответ на: комментарий от Deleted

Два примерно равноприоритетных процесса пытаются выделять память, и ни один из них никуда не продвигается. Это тот же thrashing, но уже у двух процессов; это же относится и к случаю, когда процессов больше двух.

Это ситуация классического thrashing-а без приоритетов.

То есть в твоей схеме thrashing возможен, но ограничен группой процессов, чьи приоритеты примерно равны.

Если выставленные вручную приоритеты равны

Я думал, пойнт в том, чтобы _не_ выставлять их вручную. Если ты не возражаешь против ручной рабты, все инструменты уже есть.

Если процессов больше двух, и у них все разные приоритеты

У процессов с примерно равным поведением и приоритеты будут примерно равны.

и хочется получить: оболочка в голом терминале или в ssh работает быстро, всякие xfce-panel тормозят, но шевелятся, ну а жирнолис сожрал десяток гигабайт и завис (т.е. на самом деле замедлился на многие порядки) в бесконечной подкачке.

Схема «большой процесс обслуживается в последнюю очередь» работает в том случае, когда у тебя есть четкое упорядочение по размеру (т.е. процессы различаются достаточно сильно); если этого нет - схема не работает. Когда группа примерно равных по размеру процессов исчерпает память - они все уйдут в thrashing. Ну да, для случая «desktop без лишней памяти» схема будет работать, но чем это лучше (тут я теоретизирую) иерархии memcg-sys -> memcg-xfce -> memcg-others?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от tailgunner

Если ты не возражаешь против ручной рабты, все инструменты уже есть.

Тогда почему они не используются? Почему у login и sshd приоритет стандартный и они виснут вместе со всем остальным линуксом? Хреновые инструменты? Или «не нужно»?

legolegs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.