커널

포스트: 228|조회수: 0|CIVILIZATION
Items

Posts

228 posts

[라즈베리파이] 비트 처리 __test_and_set_bit() __test_and_clear_bit() 함수 동작 원리

Guillermo Austin Kim|2018년 8월 19일

리눅스 커널과 드라이버에서 __test_and_set_bit()와 __test_and_clear_bit() 함수를 많이 씁니다. 두 함수 중 test_and_set_bit()를 써서 비트를 처리하는 코드를 보겠습니다.다음은 워크를 워크큐에 큐잉하는 queue_work_on() 함수입니다.[kernel/workqueue.c]1 bool queue_work_on(int cpu, struct workqueue_struct *wq,2 struct work_struct *work)3 {4 bool ret = false;5 unsigned long flags;67 local_irq_save(flags);89 if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_dat

[라즈베리파이] 워크큐(Workqueue) 소개

Guillermo Austin Kim|2018년 8월 16일

워크큐는 인터럽트 후반부 처리 기법으로 많이 알려져 있는데 커널 전반에서 후반부를 처리하는 기법입니다. 인터럽트 후반부는 물론이고 프로세스 컨택스트 후반부 처리 용도로도 많이 씁니다. 즉, 어떤 코드에서도 워크큐를 써서 후반부 처리를 할 수 있다는 의미입니다. 그동안 배웠던 IRQ Thread와 Soft IRQ 와 같은 인터럽트 후반부 처리 기법과 워크큐를 비교하면서 워크큐의 특징을 알아보겠습니다. IRQ Thread는 인터럽트 후반부 처리 전용 쓰레드이며 threaded IRQ 방식으로 인터럽트 후반부 처리를 할 수 있습니다. 마찬가지로 워크큐도 인터럽트 후반부 용도로 쓸 수 있습니다. 그런데 인터럽트 발생 빈도가 높거나 더 안정적인 코드 유지 보수를 위해서 IRQ Thread 기법 적용을 선호합니다.

[라즈베리파이] 커널 타이머 -동적 타이머는 누가 언제 호출하나? (1)

Guillermo Austin Kim|2018년 8월 15일

이전에 동적 타이머를 설정하는 코드 흐름까지 알아봤습니다. 이 과정을 요약하면 다음과 같습니다. 1. 동적 타이머를 표현하는 자료 구조인 struct timer_list 구조체에 기본 정보를 채운 다음 add_time() 혹은 mod_time() 함수를 호출합니다. 동적 타이머 기본 정보는 타이머 만료 시각(HZ단위)과 동적 타이머 핸들러 함수와 매개 변수입니다. 2. 동적 타이머를 초기화했을 때 실행했던 CPU 번호 기준으로 per-cpu 오프셋을 적용해서 timer_base 주소를 읽습니다. 이 주소에는 struct timer_base 구조체 멤버가 있는데 타이머 벡터 해시 인덱스에 동적 타이머를 등록했습니다. 이어서 이번에는 동적 타이머를 누가 언제 처리하는지 살펴봅니다. 동적 타이머는 커널 시스

[Kernel][Workqueue] flush_work(), 배리어 워크(barrier_work, wq_barrier)

Guillermo Austin Kim|2018년 8월 13일

barrier work에 대해서 알아보겠습니다. flush_work 함수는 두 가지 상황에서 쓰입니다. 두 가지 경우에 barrier work가 어떻게 쓰이는지 알아볼게요. 1. 현재 다른 워커 쓰레드에서 동일한 워크가 실행 중에 동일한 work을 flush한 경우 -386 [001] ...1 143.380287: workqueue_execute_start: work struct e880e910: function sdhci_pm_qos_cpu_unvote_work//... mmc-cmdqd/0-339 [000] ...1 143.381065: flush_work