Медленное чтение или медленная запись влияет на все диски
Я бегу Ubuntu 16.04
с RocketRaid 2720SGL HBA board
что я обновил прошивку, чтобы убрать обработчик RAID и просто использовать порты.
На плате есть два порта, которые позволят разделить четыре диска на порт или всего восемь дисков. У меня есть два диска на порт.
Когда система запускается, плата видит все четыре диска как 0, 1 для первого порта и 4, 5 для второго порта. Это отлично.
При перечислении дисков я вижу их как sdb, sdc, sdd и sde. В /dev/disk/by-path я вижу их как 0, 1, 4, 5. Я использую это, чтобы сообщить мне, какой фактический порт диска привязан к какому идентификатору устройства.
С четырьмя хорошими дисками емкостью 500 ГБ я могу стереть все четыре диска примерно за 70 - 80 минут, то есть времени, которое потребуется для очистки одного диска. я использую
if((RetVal = pthread_create(&DIptr->DI_ThreadFD, NULL, WipeTheDrive, DIptr)) != 0)
{
printf("WIPESINGLEDRIVE: ERROR: return code from pthread_create() is %d errno: [%d]\n", RetVal, errno);
}
выполнить четыре потока независимо. Если на дисках нет поврежденных секторов или каких-либо аномалий, стирание происходит очень хорошо. Я открываю диски, используя O_RDWR|O_DIRECT, и мои буферы установлены на правильной границе, чтобы я мог использовать DMA с помощью WipeBuffer[1048576] __attribute__ ((__aligned__ (1048576))));
Это все работает нормально, я проверил 240 дисков по этой логике одновременно на четырех дисках и никогда не было проблем.
Это ситуация, однако. Если один из четырех дисков имеет поврежденные сектора или имеет медленную запись или медленное чтение, это влияет на синхронизацию всех других дисков. Другими словами, если диск 1 имеет поврежденные секторы и находится в ожидании возвращения чтения или записи, тогда другие диски также будут сидеть и ждать. Он действует так, как будто они совместно используют некоторый тип очереди или буфера и все в очереди, ожидая своей очереди. У меня есть подпрограммы, которые оценивают диски по производительности чтения и записи, и я получаю ложный сбой, если на одном диске возникают проблемы.
С учетом всего сказанного, во-первых, я не знаю, что является причиной этого: операционная система ставит задачи в ядро, может ли это быть драйвером, хотя я не думаю, что это так. Я отправил электронное письмо специалистам службы технической поддержки Marvell, которые являются разработчиками прошивки, и они сказали мне, что каждый канал на плате независим от одного канала DMA на каждые четыре диска. Я разделил диски между двумя каналами DMA, и я по-прежнему получаю медленный на всех дисках, если один медленный.
Что я должен изменить, чтобы получить четыре независимых канала, не влияя на один другой?
================================================== =======================
После предложения использовать blktrace я установил его и запустил одновременно четыре диска. Трассировка выглядела отлично и, казалось, делилась записями довольно хорошо.
Затем я вытащил один из дисков, и след выглядел так
8,48 2 422 0,542202510 12017 Q WS 581826560 + 2048 [клиент]
8,48 2 423 0,542207566 12017 Q WS 581827584 + 1024 [клиент]
8,48 2 424 0,542208902 12017 G WS 581826560 + 1024 [клиент]
8,48 2 425 0,542213507 12017 G WS 581827584 + 1024 [клиент]
8,48 2 426 0,542214337 12017 I WS 581826560 + 1024 [клиент]
8,48 2 427 0,542214854 12017 I WS 581827584 + 1024 [клиент]
8,48 2 428 0,542221516 289 D WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 429 0,542228504 289 R WS 581826560 + 1024 [0]
8,48 2 430 0,542228808 289 I WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 431 0,542572302 289 D WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 432 0,542572979 289 R WS 581826560 + 1024 [0]
8,48 2 433 0,542573279 289 I WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 434 0,546583088 289 D WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 435 0,546583892 289 R WS 581826560 + 1024 [0]
8,48 2 436 0,546584227 289 I WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 437 0,550587702 289 D WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 438 0,550588397 289 R WS 581826560 + 1024 [0]
8,48 2 439 0,550588711 289 I WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 440 0,554580452 289 D WS 581826560 + 1024 [kworker / 2: 1H]
8,48 2 441 0,554581354 289 R WS 581826560 + 1024 [0]
8,48 2 442 0,554581664 289 I WS 581826560 + 1024 [kworker/2:1H]
Вы можете видеть, где "клиент", который является именем исполняемого файла, ставит в очередь записи, а затем процесс "kworker" просто остается и забивает диск, который я извлек. Это лишь небольшой пример, но он работает для страниц и страниц, и у клиента никогда не будет возможности выпустить какие-либо новые записи для трех других дисков. Насколько я понимаю, процесс 'kworker' - это процесс ядра, который работает с вводом / выводом устройств.
Итак, мой вопрос теперь состоит в том, как я могу заставить процесс 'kworker' не монополизировать весь процесс ввода-вывода и обмениваться каналами с остальными устройствами, когда диск отключается или имеет медленную запись или чтение.
1 ответ
Похоже, что драйвер не выдает более одного запроса за раз. Вы могли бы взглянуть на blktrace
инструмент для анализа того, что происходит в стеке ввода-вывода. Если драйвер работает правильно, вы должны увидеть несколько запросов в состоянии D(ispatch) одновременно. Если есть только один, то это проблема.