Твердотельные накопители от Samsung оправданы. Проблема оказалась в ядре Linux



    Помните перевод статьи «When Solid State Drives are not that solid»? В ней сотрудники компании Algolia возлагали вину за повреждение данных в конфигурации RAID0 на SSD от компании Samsung.

    Проблема все таки была решена в результате долгого разбирательства, в ходе которого сотрудникам Algolia пришлось даже написать ПО, эмулирующее их тип нагрузки на RAID, чтобы инженеры Samsung смогли повторить проблему на своем оборудовании. Исправление коснулось ядра Linux, а точнее — файла bio.c, отвечающего за основные операции блочного ввода-вывода.

    Проблема состояла в следующем — подсистема ввода-вывода ядра может разделять операцию блочного ввода-вывода (BIO) на несколько в тех случаях, когда это целесообразно. Для разделения используется функция bio_split(). При разделении создается новый объект BIO, а информация в старом корректируется с учетом того, что часть адресов, по которым происходит ввод-вывод, «переехала» в новый объект. В целях экономии памяти новый объект создается путем копирования значений из старого, при этом указатели в новом и старом объектах указывают на одну и ту же область памяти. Для операций чтения/записи это работает нормально, поскольку при выполнении этих операций содержимое полей объекта BIO, доступных через указатели, не изменяется. Однако для операции DISCARD это не так — поле bio_vec структуры bio содержит указатель на служебные данные, необходимые для выполнения команды (начальный адрес и размер стираемой области).

    Модули raid0 и raid10 ядра используют функцию bio_split() и посылают разделенные запросы драйверу SCSI/SATA, однако драйвер SCSI/SATA не предполагает что разные запросы могут использовать одну область памяти и перезаписывает содержимое по адресу, указанному в bio_vec. Поэтому следующий запрос приходит уже с указателем на некорректные данные, что и взывает DISCARD по некорректным адресам.

    Первый вариант патча, предложенный инженерами Samsung, предусматривал модификацию исходного кода драйвера raid0, однако в ядро вошел более общий вариант, который предусматривает полное копирование структуры bio вместе с занимаемыми ей страницами памяти в случае выполнения DISCARD.

    Данной проблеме подвержены все накопители, поддерживающие TRIM, независимо от модели, в конфигурации RAID0 или RAID10.

    Неясным остается вопрос, почему проблема не проявлялась на накопителях Intel. Возможно, дело в таймингах.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 24

      +25
      Шикарно, пацаны! Молодцы и Angolia, и Samsung, и коммитеры Oracle/FB!
        0
        Angolia Algolia
          0

          Эти тоже молодцы

        –29
        Вот это круто) Никогда ничего такого не было бы возможно в не опенсорс софте
          –21
          Я про нахождение и исправление ошибки в самой ОС, если что…
            +40
            «Такое» (исправление ошибок в софте при совместной работе вендора оборудования и производителя софта, иногда с вовлечением клиента) в проприентарном софте происходит столько, сколько вы на свете не живете, судя по вашему профилю.
              –3
              То есть Microsoft на ваш взгляд так же легко отдает исходники винды всем, у кого странные проблемы с ней?
                +9
                Большая часть проблем с оборудованием в любой приприетарной ОС решается засылом этого оборудования производителю ОС и дальнейшей совместной отладкой. Так делают все крупные игроки, и Intel, и MS, и WindRiver, и все остальные. Если вам действительно нужно и у вас контракт на тех. поддержку подписан давно и надолго — коммерческие компании вас один на один с проблемой не оставят.
                Исходники никто не раздает, т.к. разбираться в них инженеры разработчиков железа не обязаны и не будут — они в нем не понимают ничего, в отличие от тех, кто его писал и поддерживает. Понятно, что сначала заставят прогнать тесты Hardware Certification Kit'а, потом будет пару недель переписки из серии «попробуйте выключить и включить», но по итогу все проблемы, которые были у нас поддержкой оборудования со стороны MS удалось успошно решить.
                  0
                  Это, понятное дело, если у вас уже давно и очень долго есть деньги на подписание контракта на техподдержку. Много денег.
            –19
            Бред сивой кобылы. Сорри, но по-другому сказать — язык не поворачивается. Зачастую коммерческий софт написан… хотя, код закрыт. Я видел несколько корпоративных продуктов, код там до ужаса неадекватный. Конечно, далеко не у всех. А опенсорс — его смотрят тысячи, тут в любом случае код причесывается. Да и народ охотно поддерживает все опенсорсное. «Не опенсоср» — там, как правило, все очень и очень медленно исправляется, причем, в прямо-пропорциональной зависимости. Чем дороже продукт, тем больше клали на ваше «хочу». Ну кроме тех, кто за монету может все исправить дабы не потерять репутацию.

            Это мое имхо.
              +23
              Фраза «моё имхо» – самое маслянистое из всех маслянистых масельных масел. ИМХО.
                0
                Согласен, каюсь. Без сарказма.
                  +7
                  Нет, самое масло это «по моему скромному имхо» или «в этом ITT треде».
                    +7
                    IT-технологии — моё любимое.
                      +6
                      А как же CD-диск?
                        +3
                        АвтоВаз
                    +4
                    Прейскурант цен!
                +4
                драйвер SCSI/SATA не предполагает что разные запросы могут использовать одну область памяти и перезаписывает содержимое по адресу, указанному в bio_vec


                А это вообще законно для драйвера? Переписывать содержимое памяти, которое ему дают на вход.
                  +2
                  Подразумевается память на диске. А как ещё? Драйвер должен быть оракулом и сам догадаться по какому адресу потребовать у диска затереть данные?
                    +1
                    Ну, драйвер справедливо полагает, что раз запрос спустился на его уровень, то с памятью запроса можно делать что угодно.
                      0
                      Может, я что-то неправильно понял? Например, давайте посмотрим на системный вызов write(int fildes, const void *buf, size_t nbyte) — ему на вход дают указатель на буфер buf, из которого нужно взять данные для записи в файл. Я лично не могу представить себе ситуацию, когда в этот буфер будет что-нибудь записано операционной системой, «потому что это её буфер». Грубо говоря, вы можете спокойно разделять этот буфер с другими системными вызовами и не беспокоиться о сохранности данных. Почему для драйвера не используется тот же самый подход?
                        +1
                        В объявлении write() указатель const void *buf константный, что в какой-то мере защищает его от случайных изменений, а вот как объявлена функция драйвера, которая меняет содержимое в bio_vec — большой вопрос. А вообще, вопрос интересный: то что у нас драйвер меняет данные в команде — еще не худший вариант. Например данные, которые пишутся на диск, могут быть изменены извне в процессе исполнения диском команды записи. Процитирую уважаемого amarao:
                        В линуксе давным-давно идёт срач на тему персистентных страниц при записи. Другими словами, «можно ли писать в грязные страницы». Срач типовой для подобной ситуации — одних ужасает, что данные могут меняться в середине записи (и записываться непонятно как), других ужасает то, как дорого и медленно выглядит решение проблемы.

                        [Решение: полный отказ от кешей на запись любого уровня и переход на ssd].

                        при этом на lvm.net считают дефект чисто косметическим.

                    0
                    Этот комментарий стёрт, потому что тег <twitter> на Хабрахабре глючит и результат работы его непригляден.
                      0
                      Воистину, преждевременная оптимизация — корень всех зол.

                      Only users with full accounts can post comments. Log in, please.