Планирование ядра Linux с критическими областями - PullRequest
0 голосов
/ 21 марта 2019

Я написал модуль ядра Linux для устройства USB.Драйвер USB предоставляет 2 символьных устройства только для чтения, которые могут быть открыты только одним процессом:

  • /dev/cdev_a
  • /dev/cdev_b

Устройство USB может обрабатывать только один запрос за один раз.

Установка теста следующая:

  • Процессы A считывают данные с 1-го устройства: dd if=/dev/cdev_a of=/tmp/a bs=X
  • Процессы B считывают данные со 2-го устройства: dd if=/dev/cdev_b of=/tmp/b bs=X
  • Процессы A и B выполняются параллельно
  • Через 10 секунд оба процесса завершаются и сравнивается размер обоих выходных файлов.

Для определенных значений X существует значительная разница в размере между двумя файлами, чего я не ожидаю.

При вызове чтения для драйвера выполняется следующее:

  1. mutex_lock_interruptible(iolock)
  2. usb_bulk_msg(dev, pipe, buf, X, timeout)
  3. mutex_unlock(iolock)
  4. copy_to_user(buf)

Что бы я хотеложидается следующее:

  1. Proc A: mutex_lock_interruptible(iolock)
  2. Proc A: usb_bulk_msg(dev, pipe, buf, X, timeout)
  3. Планирование: A -> B
  4. Proc B: mutex_lock_interruptible(iolock) -> блоки
  5. Планирование: B -> A
  6. Процесс A: mutex_unlock(iolock)
  7. Процесс A: copy_to_user(buf)
  8. Процесс A: mutex_lock_interruptible(iolock) -> блоки
  9. Планирование: A -> B
  10. Proc B: usb_bulk_msg(dev, pipe, buf, X, timeout)

Но с помощью ftrace я вижу, что на шаге 8 процесс A все еще продолжается.И кажется, что для определенных значений X время внутри критической области кратно временному интервалу, поэтому процесс B всегда получает временной интервал, когда критическая область блокируется.Что будет лучшим решением для этого?Я думал о том, чтобы звонить schedule() каждый раз после копирования в пространство пользователя или воспроизведения с хорошими значениями или использования wait_queues?

...