Укажите отработанное время

Отработанное время:
Продуктивное время:
Bug 6227 - Разработка non-direct режима работы модуля CIFS   Make a simular bug
Summary: Разработка non-direct режима работы модуля CIFS
Status: CLOSED FIXED
Alias: None
Product: CIFS@Etersoft
Classification: Продукты (Products)
Component: производительность (show other bugs)
Version: не указана
Hardware: PC All
: P2 major
Target Milestone: ---
Assignee: Pavel Shilovsky
QA Contact: Vitaly Lipatov
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 3032
  Show dependency treegraph
 
In work:
Reported: 2010-10-19 09:41 MSD by Pavel Shilovsky
Modified: 2011-02-22 20:25 MSK (History)
4 users (show)

See Also:
Заявки RT:
Связано с:
Дата напоминания:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pavel Shilovsky 2010-10-19 09:41:58 MSD
По мотивам баги http://bugs.etersoft.ru/show_bug.cgi?id=5442 решил переработать данный режим работы заново. Сюда предлагаю писать об этапах разработки и результатах тестирования.
Comment 1 Pavel Shilovsky 2010-10-26 09:20:13 MSD
Написал новые функции cifs_file_aio_read и cifs_file_aio_write, которые обрабатывают семантику блокировок Windows и работают с кешем согласно спецификации MS-CIFS.
Comment 2 Pavel Shilovsky 2010-10-26 15:24:29 MSD
Потестировал, нашёл некоторые баги - пофиксил. Пока закоммитил сюда: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/v2.6.32-rw
Comment 3 Pavel Shilovsky 2010-10-26 17:02:25 MSD
Нашёл ещё баг, поправил, потестировал - перезалил новый бранч форсом.
Comment 4 Pavel Shilovsky 2010-10-26 17:26:30 MSD
Отправил патчи на обсуждение в upstream.
Comment 5 Pavel Shilovsky 2010-10-31 22:50:23 MSK
После обсуждения патчей, поправил код и снова отправил на обсуждение.
Comment 6 Pavel Shilovsky 2010-11-02 12:09:10 MSK
Учитывая полученные замечания, поправил код и отправил в рассылку. Посмотреть можно тут: http://news.gmane.org/gmane.linux.kernel.cifs.
Comment 8 Pavel Shilovsky 2010-11-02 22:54:44 MSK
Исправил ошибку + сделал некоторые поправки, согласно обсуждению. Снова отправил в рассылку.
Comment 9 Pavel Shilovsky 2010-11-03 08:50:03 MSK
Один из патчей для non-direct режима принят в upstream:
http://git.kernel.org/?p=linux/kernel/git/sfrench/cifs-2.6.git;a=commit;h=e66673e39ac9d4749bd9676dd1caf928095409f5
Comment 10 Pavel Shilovsky 2010-11-04 10:04:11 MSK
У разработчиков возник вопрос, как в новой семантики strict cache будет вести себя вызов mmap_file. Занялся этим вопросом.
Comment 11 Pavel Shilovsky 2010-11-04 14:16:14 MSK
Выяснил, что mmap активно использует операции со страницами памяти (где сохраняется содержимое файла). Потому заставить его корректно работать с мандатори блокировками не представляется возможным без больших изменений в коде (возможно не только CIFS клиента, но и VFS). К тому же сама логика работы mmap подразумевает работу со страницами (даже файл в 1 байт будет занимать одну страницу - 4096 байт в памяти).

Потому предлагаю сделать только изменения, касающиеся 'mtime problem' (сервер может задерживать изменение времени модификации файла - тем самым мы не может ориентироваться на это значение при проверке является ли наша копия в кеше валидной или нет) - каждый раз при вызове mmap будет проверять на наличие оплока на чтение (запись+чтение) и помечать кеш невалидным в случае отсутствия оплока.
Comment 12 Pavel Shilovsky 2010-11-04 14:58:43 MSK
В итоге решено было добавить к предыдущему решению аналогичную проверку при msync  вызове на оплок и при его отсутствии пометить страницы памяти содержимого файла невалидными. Далее займусь реализацией.
Comment 13 Pavel Shilovsky 2010-11-05 11:36:10 MSK
Реализовал логику работы с mmap. Поправил write патч + добавил более подробное описание (read, write, close). Отправил в рассылку.
Comment 14 Pavel Shilovsky 2010-11-10 16:47:32 MSK
В процессе дальнейшего обсуждения выяснилось, что надо переписать патчи read, write и close. Если в первом надо лишь немного поправить стиль, то во втором и третьем надо сделать следующие изменения:
1) write - не сохранять в кеше информацию после записи, если у нас есть оплок на чтение, так как такая ситуация маловероятна, а в текущей реализации присутствуют трудно исправимые data racing.
2) close - решено было не обнулять весь кеш при закрытии последнего дескриптора на файл, а выставлять флаг invalid_mapping на inode.
Comment 15 Pavel Shilovsky 2010-11-10 18:15:27 MSK
Поправил код, согласно посту выше для 32 ядра. Выложил на git.eter. Дальше займусь накладыванием изменений на патчи для upstream.
Comment 16 Pavel Shilovsky 2010-11-10 18:57:20 MSK
Подготовил и отправил патчи в рассылку.
Comment 17 Pavel Shilovsky 2010-11-11 11:01:25 MSK
Сделал некоторые исправления в патче close.
Comment 18 Pavel Shilovsky 2010-11-15 09:42:00 MSK
Привёл в порядок и залил актуальные ветки rw-to-kernel и master на git.eter.
Comment 19 Pavel Shilovsky 2010-11-18 21:11:09 MSK
Исследовал проблему поднятую в обсуждении патча close. Нам действительно не надо дополнительно проверять флаг invalid_mapping при открытии файла, так как это делается до этого функцией cifs_d_revalidate при обращении к dentry файла. Проверял на 36 ядре - самое близкое к апстриму, что есть в рпм. Дальше буду проверять на 32 ядре.
Comment 20 Pavel Shilovsky 2010-11-18 22:44:48 MSK
Проверка на 32 ядре показала, что cifs_d_revalidate не всегда успевает закончить invalidate_remote_inode перед чтением из файла и приблизительно на 1 раз из 10 результат чтения ошибочный. Завтра ещё раз проверю на 36 ядре, и, в случае подтверждения различного поведения, посмотрю, чем отличается в этом контексте код 36 ядра от 32.
Comment 21 Pavel Shilovsky 2010-11-19 11:05:18 MSK
При более глубоком рассмотрении оказалось, что на 36 ядре такая же проблема - клиент порой (пару раз на 20 прогонов) не обнуляет кеш при invalidate_remote_inode (не успевает, обламывается, ...?). Поднял вопрос в рассылке. Посмотрим, как там прокомментируют это.

Сама функция invalidate_remote_inode не обнуляет кеш у страниц памяти, которые помечены как dirty, залочены, или находятся в таблице страниц.

Попробовал использовать функцию invalidate_inode_pages2, которая обнуляет все страницы, и проблема исчезла. Написал второе письмо в рассылку с этой информацией.
Comment 22 Pavel Shilovsky 2010-11-19 13:03:47 MSK
Заметил так же, что nfs клиент в ядре так же использует invalidate_inode_pages2 при обнулении страниц кеша:

 837 static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
 838 {
 839 >-------struct nfs_inode *nfsi = NFS_I(inode);
 840 >-------
 841 >-------if (mapping->nrpages != 0) {
 842 >------->-------int ret = invalidate_inode_pages2(mapping);
 843 >------->-------if (ret < 0)
 844 >------->------->-------return ret;
 845 >-------}

Так же написал об этом в рассылку.
Comment 23 Pavel Shilovsky 2010-11-19 15:02:57 MSK
Закоммитил изменения в etersoft-rw-cache и v2.6.32-rw и залил на git.eter. Создал ветку invalidate-patch - изменения в логике invalidate_mapping, основанные на ветке ядра.
Comment 24 Pavel Shilovsky 2010-11-19 22:42:48 MSK
Пытался найти в коде CIFS, где мы можем захватить страницу памяти, что её пропускает invalidate_remote_inode. Никаких подозрительныхт мест не нашёл. Возможно это какой-нибудь процесс VFS. В любом случае это не deadlock, так как invalidate_inode_pages2 не зависает (она используется lock_page для каждой страницы).
Comment 25 Pavel Shilovsky 2010-11-21 22:57:01 MSK
Переотправил патч close. Привёл в актуальное состояние ветки на git.eter.
Comment 26 Pavel Shilovsky 2010-11-28 11:19:37 MSK
В связи с возникшей путаницей в патчах, меня попросили переотправить всю группу. Разобрал патчи, выставил версии и отправил в рассылку. Так написал письмо для разяъяснения ситуации с процессом продвижения патчей - так как пока он мне не совсем ясен (касательно версий патчей, порядка отправки и прочего).
Comment 27 Pavel Shilovsky 2010-11-29 14:06:08 MSK
Встал вопрос, как соотносится данная семантика с fscache - возможностью кеширования данных файловой системой на локальный диск. Ознакомился с данным функционалом и пришёл к выводу, что эти опции strictcache и fscache должны быть взаимоисключаемыми. Написал об этом в рассылку.

Так же возник вопрос о том, что это будет плохо работать с short read - чтением, которое возвращает меньше байт, чем запрашивается. Пока не нашёл в чём так проблема и попросил прояснить ситуацию подробнее.
Comment 28 Pavel Shilovsky 2010-11-29 14:37:37 MSK
Выяснил в чём была проблема с векторным чтением. Отписался об этом в рассылку, чтобы люди зря не отвечали.

Проблема заключается в неправильном понимании логики работы aio_read/write вызовов. Буду смотреть, как это можно поправить.
Comment 29 Pavel Shilovsky 2010-11-29 16:39:06 MSK
Отправил патчи read, write, fsync, mmap заново с учётом всех замечаний (fscache, vectored i/o).
Comment 30 Pavel Shilovsky 2010-11-30 11:27:24 MSK
Поправил стиль комментариев в патчах read и write. Жду комментариев над текущим вариантом.
Comment 31 Pavel Shilovsky 2010-12-11 17:55:11 MSK
Получил комментарии по текущим патчам. Обнаружилось узкое место - когда пользователь указывает в векторном чтении/записи много маленьких запросов, мы отправляем их по очереди. Гораздо быстрее будет объединить их в несколько больших запросов. Далее займусь этим.
Comment 32 Pavel Shilovsky 2010-12-11 22:07:54 MSK
Сделал анализ существующих возможностей модуля для реализации вышеописанной идеи. Набросал пробный код. Далее займусь реализацией функций cifs_file_aio_read и cifs_file_aio_write.
Comment 33 Pavel Shilovsky 2010-12-11 22:50:31 MSK
Попробовал пробную реализацию в действии и обнаружил, что данная идея не может быть применена для strict cache режима из-за возможного наличия жёстких блокировок на одном из участков, что сломает всю запись (чтение), как будто бы блокировки присутствуют на всех участвахт вызова writev(readv). Написал об этом в рассылку. Жду комментариев.
Comment 34 Pavel Shilovsky 2010-12-12 12:23:17 MSK
Как мне разъяснили в рассылке, нам следует расценивать векторное чтение (запись) как обычную запись (чтение) только с участием нескольких буфферов для данных. Поэтому мы можем объединять маленькие запросы в большие для экономии траффика.

amorozov@, используется ли в wine операции readv и writev?
Comment 35 Александр Морозов 2010-12-12 17:00:13 MSK
> amorozov@, используется ли в wine операции readv и writev?

Для работы с обычными файлами не используются, writev используется для записи в пайп при взаимодействии запущенных в wine программ и wineserver.
Comment 36 Pavel Shilovsky 2010-12-12 19:23:19 MSK
(В ответ на comment #35)
> > amorozov@, используется ли в wine операции readv и writev?
> 
> Для работы с обычными файлами не используются, writev используется для записи в
> пайп при взаимодействии запущенных в wine программ и wineserver.

Ок, в таком случае можно реализовывать вариант объединения буфферов.

Переделал патчи, добавив туда новые структуры файловых операций для strict cache режима. Теперь они будут выбираться ещё во время монтирования, чтобы избежать дополнительных проверок в дальнейшем. Согласно этому обновил ветку rw-to-kernel на git.eter. Дальше попробую новую реализацию на тестах.
Comment 37 Pavel Shilovsky 2010-12-13 18:04:52 MSK
Потестировал, обнаржил ошибку и некоторые неточности - исправил. Перезалил форсом ветку на git.eter, подготовил и отправил патчи в рассылку.
Comment 38 Pavel Shilovsky 2010-12-13 19:42:36 MSK
Получил ответ. Рекомендуют избежать дополнительных копирований из памяти в память. Продумал и обсудил как этого избежать. Далее приступлю к реализации.
Comment 39 Pavel Shilovsky 2010-12-13 22:52:21 MSK
Написал реализация для операции чтения. Немного потестировал. Далее продолжу тестирование, потом приступлю к реализации операции записи.
Comment 40 Pavel Shilovsky 2010-12-13 23:54:55 MSK
Обсудил текущую ситуацию по патчам. На данный момент надо сделать следующее:
1) закончить чтение.
2) запись оставить такой же, только добавить комментарии для последующей реализации отправки напрямую в случае отсутствия подписи пакетов в сессии.
3) объединить патчи 2 и 3, заменив нереализованные новые функции старыми.
Comment 41 Pavel Shilovsky 2010-12-14 15:22:45 MSK
Сделал описанное в предыдущем посте. Оформил новые версии патчей и отправил в рассылку.
Comment 42 Pavel Shilovsky 2010-12-14 17:57:44 MSK
В ходе обсуждения обнаружились ошибка в данной модификации write патча, а так же некоторые недочёты в read и mmap патчах.
Comment 43 Pavel Shilovsky 2010-12-14 18:01:32 MSK
На данный момент следующие патчи согласованны:
1) close;
2) fsync;
6) mount option.
Comment 44 Pavel Shilovsky 2010-12-15 13:28:37 MSK
Поправил mmap и исправил read патчи.
Comment 45 Pavel Shilovsky 2010-12-16 10:54:56 MSK
Исправил сломавшуюся ветку (предположительно из-за коммитов в бранч без имени), проверил и отправил патчи read и mmap.  Начал работу над патчем write.
Comment 46 Pavel Shilovsky 2010-12-16 11:50:55 MSK
Набросал новый вариант функции cifs_strict_write с использованием отдельных страниц памяти. Дальше буду дописывать его и пробовать в работе.

Ознакомиться можно тут:
http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=04ef8111d4371549260496e3aaa0e68ca64645de
Comment 47 Pavel Shilovsky 2010-12-17 14:38:52 MSK
Написал работающий код cifs_strict_write:
http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=ea32baaa69273c9649c487cb17d2e12bcd8da1a2
Comment 48 Pavel Shilovsky 2010-12-17 14:40:07 MSK
Протестировал вышеописанный код, поправил, провёл некоторый рефакторинг. Дальше буду дорабатывать стиль, чтобы можно было оформить в патч.
Comment 49 Pavel Shilovsky 2010-12-17 15:50:45 MSK
Удалил ветку rw-to-kernel2, закоммитил последние изменения по cifs_strict_write в rw-to-kernel. Отправил патч в рассылку linux-cifs.
Comment 50 Pavel Shilovsky 2010-12-20 12:13:24 MSK
На данный момент согласованны следующие патчи:
1) close;
2) fsync;
3) mmap;
6) mount option.

Осталось разобраться с read и write.
Comment 51 Pavel Shilovsky 2010-12-22 22:35:17 MSK
Изучил комментарии по патчам read и write и провёл изучение стандартных средств для работы с векторами массивов. Как выяснилось, много из того, что я написал руками, можно заменить стандартными функциями ядра, что является более правильным. Собираюсь переписать патчи с использованием этих функций.
Comment 52 Pavel Shilovsky 2010-12-25 19:19:48 MSK
Переписал патчи read и write. После более тщательного тестирования отправлю в рассылку.
Comment 53 Pavel Shilovsky 2010-12-25 22:34:36 MSK
Обнаружил ошибки в write патче - исправил. Добился правильной работы на тестах чтения/записи. Возник вопрос, связанный с реализацией копирования копирования из вектора буфферов в страницу - отправил вопрос Jeff Layton'у. Пока оставил вариант, который применяется в ядре, но у меня вроде другая ситуация - страницы памяти локальные и другие потоки их не трогают.
Comment 54 Pavel Shilovsky 2010-12-26 12:18:41 MSK
Ознакомился с системой обработки pagefault в ядре. Поправил write патч - убрал atomic операцию копирования и pagefault_disable() и pagefaul_enable() вызовы до и после.
Comment 55 Pavel Shilovsky 2010-12-26 13:08:54 MSK
Провёл стресс тестирование (чтение/запись/чтение-проверка) ~5 гигабайтового файла. Ошибок не обнаружено. Отправил read и write патчи в рассылку.
Comment 56 Pavel Shilovsky 2010-12-27 18:44:58 MSK
Провёл небольшое исследование на тему переполнения в readv с использованием memcpy_toiovecend функции. Было сомнение, что данная функция переполняет int в readv вызове, но они не подтвердились - общая длина вектора ограничивается MAX_RW_COUNT функцией rw_copy_check_uvector в VFS, а 
MAX_RW_COUNT в свою очередь приводится к int.

read патч: http://article.gmane.org/gmane.linux.kernel.cifs/2160
write патч: http://article.gmane.org/gmane.linux.kernel.cifs/2161
Comment 57 Pavel Shilovsky 2010-12-27 19:25:44 MSK
Получил комментарии по патчам read и write:
1) read - всё ок, только надо сделать один глобальный вызов статичным (я планировал использовать его в дальнейшем, но лучше сделать его глобальным, именно когда он понадобится).
2) write - в цикле while (rc == -EAGAIN) {...} надо проверять на переустановку соединения.
Comment 58 Pavel Shilovsky 2010-12-27 21:16:21 MSK
Отправил патчи:
1) read - убрал глобльное определение, убрал проверку на NULL private data файла. http://article.gmane.org/gmane.linux.kernel.cifs/2191
2) write - убрал глобальное определение, добавил проверку на переустановку соединения и проверку на возможность записи. http://article.gmane.org/gmane.linux.kernel.cifs/2192
Comment 59 Pavel Shilovsky 2010-12-29 11:35:11 MSK
Все патчи получили reviewed-by тэг от Джефа Лэйтона. Отправил их Стиву Френчу для соединения с основной веткой.
Comment 60 Pavel Shilovsky 2011-01-13 14:57:38 MSK
Собрал strictcache под 37 ядро в etercifs-4.7.0-alt1 на ftp.
Comment 61 Pavel Shilovsky 2011-01-13 14:59:56 MSK
Нужно интегрировать в патч https://patchwork.kernel.org/patch/433271/ в ветку 37 ядра со strictcache и собрать новую сборку для тестирования (etercifs-4.7.1).
Comment 62 Pavel Shilovsky 2011-01-13 16:31:40 MSK
Интегрировал вышеописанный патч в исходники 37 ядра сборки 4.7.0. Собрал etercifs-4.7.1-alt1 на ftp.
Comment 63 Pavel Shilovsky 2011-01-19 17:23:53 MSK
Патч, исправляющий логику работы с оплоками уже в апстриме: http://git.kernel.org/?p=linux/kernel/git/sfrench/cifs-2.6.git;a=commitdiff;h=b9d53658f4c6b6a914baf5b47046fb2e1885d7bd;hp=a25cecce88194b2edf38b8c3b1665e9318eb2d22

Теперь надо собрать новые сборки etercifs-4.7.3 (без патча writepages) и 4.7.4 (с патчем writepages).
Comment 64 Pavel Shilovsky 2011-01-19 20:47:35 MSK
Собрал etercifs-4.7.2 (без writepages патчем) и etercifs-4.7.3 (с writepages патчем) - в предыдущем посте ошибся с нумерацией.
Comment 65 Pavel Shilovsky 2011-01-20 23:34:57 MSK
Портировал strict cache режим на ядро v2.6.35. http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/etersoft-strict-cache-2.6.35
Далее планирую собрать ветку etercifs и включить его в тестовые сборки.
Comment 66 Pavel Shilovsky 2011-01-26 23:02:09 MSK
strict cache режим в ветке апстрим. Обновил master на git.eter.
Comment 67 Pavel Shilovsky 2011-01-31 15:26:26 MSK
Поправил типы переменных в write и read патчах, по сообщению в рассылке о предупреждениях компилятора. Прокинул в соответствующие ветки и залил на git.eter.
Comment 68 Pavel Shilovsky 2011-01-31 15:59:56 MSK
Выяснилось, что предыдущий патч плохо накладывается на уже отправленный но не смерженный патч. Исправил и отправил снова.
Comment 69 Pavel Shilovsky 2011-02-04 23:22:11 MSK
Последний патч, исправляющий типы переменных, приняли в апстрим. Обновил master на git.eter.

Текущая бага решена. Дальнейшие работы внедрению кода в etercifs будут идти в отдельных багах, о которых будет писаться тут: http://bugs.etersoft.ru/show_bug.cgi?id=6765.
Comment 70 Pavel Shilovsky 2011-02-04 23:22:48 MSK
Решена.