Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:3
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:7
Форум » starterkit.ru » Embedded Linux
прожёрливые демоны
Dub
Добавлено 07.06.2012 13:05
0
Сообщение: 1
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
после установки драйвера от AD в системе появились демоны
"ksoftirqd" и "kworker", которые поочерёдно жрут более 70 процентов времени CPU (смотрел через top).
как можно бороться?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 07.06.2012 13:24 Редактировалось 07.06.2012 14:15 Сообщение: 2
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Только один метод - править руки драйверописателям AD или смотреть - возможно что-то не так установили/настроили/подключили. В контексте softirq выполняются (в том числе) "нижние половины" (bottom half) обработчиков прерываний, что так долго делают там драйверы AD - надо разбираться. Возможно все нормально с драйверами и настройкой просто объем данных по SPI достаточно большой, например spi emac ks8851 тоже нехило процессор нагружает когда непрерывно данные идут, как известно сетевая подсистема тоже в контексте softirq работает (по крайней мере ф-ция передачи буфера драйвера emac точно в контексте softirq вызывается ядром) и там наблюдается подобная картина.
Спуститься к концу Подняться к началу
Персональная информация
Dub
Добавлено 14.08.2012 10:34 Сообщение: 3
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
Решил поднять старую тему, так как сейчас пришлось писать драйвер самому и тема стала актуальна.
Планируется в прерываниях драйвера проделывать приём данных по SPI.
Т.е.:

[обработчик прерывания] {
[забираем 16байт данных по SPI - 128 клоков]
}

Сильно ли это будет тормозить систему и как будет сделать выгоднее с точки зрения накладных расходов?
Может просто в прерывании выставлять флаг готовности данных, а в самом драйвере уже забирать данные? Но как второе проделать незнаю...
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 14.08.2012 11:34 Редактировалось 14.08.2012 11:36 Сообщение: 4
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата

Может просто в прерывании выставлять флаг готовности данных


в обработчике отключать прерывание и запускать тасклет или рабочую очередь. Если собираетесь использовать стандартные средства Linux для работы с spi типа spi_sync то только рабочая очередь - эти ф-ции (кроме spi_async котрая для вас будет бесполезна скорей всего) требуют контекст который может переходить в состояние ожидания, что недопустимо в контексте прерываний и соответственно в тасклете тоже, рабочие очереди работают в контексте обычного процесса.
Спуститься к концу Подняться к началу
Персональная информация
Dub
Добавлено 14.08.2012 15:41 Сообщение: 5
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
Цитата

в обработчике отключать прерывание и запускать тасклет или рабочую очередь. Если собираетесь использовать стандартные средства Linux для работы с spi типа spi_sync то только рабочая очередь - эти ф-ции (кроме spi_async котрая для вас будет бесполезна скорей всего) требуют контекст который может переходить в состояние ожидания, что недопустимо в контексте прерываний и соответственно в тасклете тоже, рабочие очереди работают в контексте обычного процесса.


спасибо.
Пока всё что вы описали - непревычно немного)
А если сделать так: в обработчике выставлять флаг, который будет опрашиваться в функции, а функция соответственно запустится через kthread_run(...).
Получается создаем в ядре поток, в котором опрашивается бесконечно флаг готовности данных, если флаг выставлен, то запускается приём данных.

P.S. Собирался не использовать стандартные средства Linux, а использовать библиотеку из IAR для прямого доступа к регистрам.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 14.08.2012 18:45 Редактировалось 14.08.2012 18:49 Сообщение: 6
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата

Получается создаем в ядре поток, в котором опрашивается бесконечно флаг готовности данных, если флаг выставлен, то запускается приём данных.


тогда какой смысл прерывания использовать если в этом потоке можно опрашивать то что вы в прерывании делаете - зачем в таком случае нужен левый промежуточный флаг ? тасклеты - это нижние половины, выполняются сразу после того как отработают все верхние половины, т.е. получаете максимально быстрый отклик для обработки события, с поллингом в потоке вы такого никогда не получите, рабочие очереди выполняются после обработчиков прерываний и тасклетов (softirq), но перед обычными процессами - т.е. они тоже предпочтительней отдельных потоков. Если будете использовать регистры напрямую - тасклеты для вас наилучший вариант не угробить отзывчивость системы - я так понимаю у вас кроме приема данных по spi они же обрабываются еще и сохраняются/передаются - иначе вам бы atmega хватило какой-нибуть :)

PS кстати создавать свои потоки в драйверах в пространстве ядра - не рекомендуется и считается плохим стилем.
Спуститься к концу Подняться к началу
Персональная информация
Dub
Добавлено 14.08.2012 19:09 Редактировалось 14.08.2012 19:40 Сообщение: 7
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
Спасибо за ответ.
Данные принимаемые по SPI просто буферизируются в драйвере и отдаются в юзерспейс.

Вообще прерывание нужно использовать для того чтобы понять, что данные готовы. А использовать поток я хотел чтобы не сидеть долго в прерывании.

Стало быть, если мне нужно только данные принять по SPI и сложить их в большой буфер - то можно и в прерывании это сделать?

P.S. Для такой простой задачи ATMEGA не годится - нужен буфер в ядре в 1МБ
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 14.08.2012 19:50 Редактировалось 14.08.2012 20:05 Сообщение: 8
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата

А использовать поток я хотел чтобы не сидеть долго в прерывании.


именно для этого в Linux и созданы специальные средства - tasklets и work queues, первые для максимально быстрого завершения обработки прерываний, второй - используют там где тасклеты невозможно использовать, т.е. требуется контекст обычного процесса или требуется задержка обработки, при этом специальный процесс для каждого драйвера не создается - ф-ции всех драйверов обрабатываются в одном процессе пространства ядра в порядке очереди. Вот хорошие статьи по теме
http://www.ibm.com/developerworks/linux/library/l-tasklets/index.html
http://www.linuxjournal.com/article/6916
Спуститься к концу Подняться к началу
Персональная информация
Dub
Добавлено 14.08.2012 20:14 Сообщение: 9
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
Спасибо за очень полезные советы.
Я если требуетс просто сложить данные в буфер, приняв их по SPI_PDC, может просто прерыванием обойтись?
как думаете исходя из опыта?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 14.08.2012 20:46 Редактировалось 14.08.2012 21:31 Сообщение: 10
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Перечитал про PDC - не совсем понятно там с указателями.
Цитата

When the current transfer counter reaches zero, the channel checks its next transfer
counter. If the value of next counter is zero, the channel stops transferring data and sets the
appropriate flag. But if the next counter value is greater then zero, the values of the next
pointer/next counter are copied into the current pointer/current counter
and the channel resumes
the transfer whereas next pointer/next counter get zero/zero as values. At the end of this trans-
fer the PDC channel sets the appropriate flags in the Peripheral Status Register.


т.е. теоретически в прерывании можно перенастраивать указатель/счетчик на следующий буфер чтобы во время обработки прерывания по завершению текущего буфера чтение spi не прекращалось и корректировать указатели откуда читать и сколько для юзерспейс, тогда латентность прерывания будет побоку и процесс будет непрерывным. Можно выделить например 10 буферов одинаковой длины и в обработчике переключать указатели - если буферы будут достачной длины чтобы не сказывалась латентность прерываний Linux то все будет нормально работать. Собственно нижние половины тут вообще не нужны в принципе - все можно делать в самом обработчике.

Возможно я неправильно понял - как внешнее устройство (котрое вроде мастером на шине как вы говорите) передает данные устройству которое должно их принимать - сигнализирует каким-то пином что данные готовы или передает команду или непрерывно отдает данные по шине управляя слейв-устройством посредство CS ? А то мне подозрительны ваши слова стали - "Вообще прерывание нужно использовать для того чтобы понять, что данные готовы. "
Вообще лучше бы сказали что за устройство - как оформить драйвер и частности с управлением буферами - надо исходить из этого, можно сделать кучей разных способов.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux