Ядро Linux wait_for_completion - Пик задержки - PullRequest
0 голосов
/ 27 сентября 2019

Я отслеживаю основную причину задержки деактивации выбора микросхемы после передачи по шине Spi Bus в ядре Linux.

Я использую freescale imx6ull, работающий на частоте 400 МГц, в настоящее время актуальный наветка ядра 4.14.2-imx здесь:

https://github.com/Freescale/linux-fslc/tree/4.14-2.0.x-imx

То, что мы наблюдаем сейчас:

  1. Задержка между включением выбора микросхемы (опускание вниз)и начало передачи менее 10 мкс
  2. SPI передача занимает от 5 до 6 мс
  3. Задержка между отключением выбора микросхемы (подтягиванием) варьируется в пределах 10 мс и 7 мс

Я добавил следующие блоки кода для отслеживания обратного вызова dma для уменьшения задержки в drivers / spi / spi-imx.c

static void spi_imx_dma_tx_callback(void *cookie)
{
  struct spi_imx_data *spi_imx = (struct spi_imx_data *)cookie;
  struct timespec now;

  complete(&spi_imx->dma_tx_completion);
  getnstimeofday(&now);
  if(now.tv_sec == spi_imx->transfer_start_time.tv_sec)
  {
    int delta_ns;
    // Calculate some callback stats
    delta_ns = now.tv_nsec - spi_imx->transfer_start_time.tv_nsec;
    if(delta_ns > 7000000) {
       spi_imx->transfer_nb_cnt++;
       printk(KERN_ALERT "%s %d - dma_tx_callback took :%i, cnt: %i \n", __FUNCTION__,__LINE__, delta_ns, spi_imx->transfer_nb_cnt);
    }
    if(delta_ns > spi_imx->max_completion_time_ns) {
       spi_imx->max_completion_time_ns = delta_ns;
       printk(KERN_ALERT "%s %d - delta_ns greater max_completion_time: %i \n", __FUNCTION__,__LINE__, spi_imx->max_completion_time_ns);
    }
 }
}

Я вижу здесь, в обратном вызове, что время передачи является постоянным, поэтомузадержка, кажется, происходит после обратного вызова.Однако все, что есть после обратного вызова, - это цепочка вызовов wait_for_completion, таких как:

timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion,
                    transfer_timeout);

Я добавил подобные блоки кода вокруг wait_for_completion_call, чтобы посмотреть, сколько времени они потребляют, увидеть следующие трассировки:

spi_imx_dma_tx_callback 1288 - delta_ns больший max_completion_time: 5285666 spi_imx_dma_transfer 1401 - wait_for_completion_tx потребовалось: 12413333

Подводя итоги, между 235 начала и начала обратного вызова: между суммой возврата к началу и окончанием пересылки было получено 525666.Между началом передачи и моментом пробуждения первого wait_for_completion после обратного вызова потребовалось 12413333 наносекунды.Разница в 7мс, что, конечно, мешает следующей передаче.

Я посылаю 100 шин в секунду, и эти пики задержки происходят в среднем один раз каждые 10 секунд.Среднее использование процессора составляет около 10%.

Что может быть основной причиной этого?

...