Linux RT (2) - 하 드 실시 간 Linux (RT - Preempt Patch) 의 중단 스 레 드 화
스 레 드 인 터 럽 트 지원 은 2009 년 에 Linux 공식 커 널 에 들 어 갔 습 니 다. Thomas Gleixner 의 patch 를 참조 하 십시오.
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3aa551c9b4c40018f0e261a178e3d25478dc04a9
이 패 치 는 구동 이 통과 할 수 있 는 능력 을 제공 합 니 다.
int request_threaded_irq(unsigned int irq, irq_handler_t <strong>handler</strong>,
irq_handler_t <strong>thread_fn</strong>, unsigned long irqflags,
const char *devname, void *dev_id)
스 레 드 화 된 IRQ 를 신청 합 니 다. kernel 은 인 터 럽 트 된 기본 버 전에 irq /% d -% s 라 는 스 레 드 를 만 들 고% d 는 인 터 럽 트 번호 에 대응 합 니 다.그 중 절반 (하 드 인 터 럽 트)handler 는 필요 한 처리 작업 을 마치 고 IRQ 로 돌아 갑 니 다.WAKE_THREAD, 이후 kernel 은 irq /% d -% s 스 레 드 를 깨 우 고 이 kernel 스 레 드 는 호출 됩 니 다.
thread_fn 함수, 따라서 이 스 레 드 는 바닥 부분 이 됩 니 다.후속 유지보수 과정 에서 필 자 는 이 기능 을 더욱 보완 하 는 토론 에 참 여 했 고 후속 패 치 는 nested, oneshot 등의 지원 을 포함 하 며 상세 한 것 은 패 치 를 보십시오.
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=399b5da29b9f851eb7b96e2882097127f003e87c
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=70aedd24d20e75198f5a0b11750faabbb56924e2
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b25c340c195447afb1860da580fe2a85a6b652c5
이 기 제 는 현재 kernel 에서 매우 광범 위 하 게 사용 되 고 있 으 며, softirq (tasklet 포함) 와 work quue 에 이 어 또 하나의 중간 부분 을 부 러 뜨리 는 방식 이 라 고 볼 수 있다.
상단: 강제 스 레 드 화
Linux RT - Preempt 을 사용 하면 기본적으로 request 를 강제로 통과 합 니 다.irq () 가 신청 한 IRQ 의 상단 함수 가 스 레 드 에서 실 행 됩 니 다. requestirq 의 원형 은:
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
이 는 request 를 통 해irq () 가 신청 한 IRQ 는 Rt - Preepmt 가 없 는 상태 에서 kernel 은 irq 스 레 드 를 만 들 지 않 습 니 다. 마지막 으로 request 를 호출 하기 때 문 입 니 다.threaded_irq () 때 전 달 했 어 요.thread_fn
NULL。
RT - Preempt Patch 를 사용 할 수 있 는 경우, 그 중의 genirq - force - threading. patch 는 ARM 에 threaded irq 를 강제로 사용 합 니 다.
Index: linux-stable/arch/arm/Kconfig
===================================================================
--- linux-stable.orig/arch/arm/Kconfig
+++ linux-stable/arch/arm/Kconfig
@@ -40,6 +40,7 @@ config ARM
select GENERIC_IRQ_SHOW
select ARCH_WANT_IPC_PARSE_VERSION
select HARDIRQS_SW_RESEND
+ select IRQ_FORCED_THREADING
select CPU_PM if (SUSPEND || CPU_IDLE)
select GENERIC_PCI_IOMAP
select HAVE_BPF_JIT
RT - Preempt Patch 에서 사용 할 수 있 는 IRQFORCED_THREADING 의 경우 스 레 드 화 IRQ 가 없 었 던 이 케이스 를 강제 스 레 드 화 합 니 다. 코드 는 참조setup_irq(): 887 static int
888 __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
889 {
890 ...
903
904 /*
905 * Check whether the interrupt nests into another interrupt
906 * thread.
907 */
908 nested = irq_settings_is_nested_thread(desc);
909 if (nested) {
910 ...
920 } else {
921 if (irq_settings_can_thread(desc))
922 irq_setup_forced_threading(new);
923 }
925 /*
926 * Create a handler thread when a thread function is supplied
927 * and the interrupt does not nest into another interrupt
928 * thread.
929 */
930 if (new->thread_fn && !nested) {
931 struct task_struct *t;
932
933 t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
934 new->name);
935 ...
939 /*
940 * We keep the reference to the task struct even if
941 * the thread dies to avoid that the interrupt code
942 * references an already freed task_struct.
943 */
944 get_task_struct(t);
945 new->thread = t;
946 }
그 중의 921 줄 을 중점적으로 살 펴 보 자. 867 static void irq_setup_forced_threading(struct irqaction *new)
868 {
869 if (!force_irqthreads)
870 return;
871 if (new->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT))
872 return;
873
874 new->flags |= IRQF_ONESHOT;
875
876 if (!new->thread_fn) {
877 set_bit(IRQTF_FORCED_THREAD, &new->thread_flags);
878 new->thread_fn = new->handler;
879 new->handler = irq_default_primary_handler;
880 }
881 }
878 줄 과 879 줄 은 원래 의handler 복사
thread_fn, 그리고 강제로 원래 의
handler 변경
irq_default_primary_handler (), 이 함 수 는 사실 신 마 는 하지 않 고 IRQ 로 돌아 갑 니 다.WAKE_THREAD:
613 /*
614 * Default primary interrupt handler for threaded interrupts. Is
615 * assigned as primary handler when request_threaded_irq is called
616 * with handler == NULL. Useful for oneshot interrupts.
617 */
618 static irqreturn_t irq_default_primary_handler(int irq, void *dev_id)
619 {
620 return IRQ_WAKE_THREAD;
621 }
874 번 째 IRQF원 스 핫 은 우리 가 앞에서 말 한 원 샷 기능 을 사용 했다.그래서 RT - prempt 는 실제 적 으로 원래 의 윗부분 과 밑부분 을 녹 였 는데 지금 은 가짜 윗부분 을 위 조 했 습 니 다. 이것 은 IRQ 로 직접 돌아 갈 뿐 입 니 다.WAKE_THREAD 태그 일 뿐 이 야.
인 터 럽 트 가 발생 한 후 리 눅 스 RT - prempt 가 처리 하 는 전 과정 을 살 펴 보 겠 습 니 다. 먼저 넘 어 갑 니 다.
arch/arm/kernel/entry-armv.S arch/arm/include/asm/entry-macro-multi.S
어 셈 블 리 입구, arm / kernel / irq. c 아래 asmdo_IRQ 、handle_IRQ, 이후 generic handleirq_event_percpu () 호출 됨:
133 handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
134 {
135 irqreturn_t retval = IRQ_NONE;
136 unsigned int flags = 0, irq = desc->irq_data.irq;
137
138 do {
139 irqreturn_t res;
140
141 trace_irq_handler_entry(irq, action);
142 res = action->handler(irq, action->dev_id);
143 trace_irq_handler_exit(irq, action, res);
144
145 if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts
",
146 irq, action->handler))
147 local_irq_disable();
148
149 switch (res) {
150 case IRQ_WAKE_THREAD:
151 /*
152 * Catch drivers which return WAKE_THREAD but
153 * did not set up a thread function
154 */
155 if (unlikely(!action->thread_fn)) {
156 warn_no_thread(irq, action);
157 break;
158 }
159
160 irq_wake_thread(desc, action);
161
162 /* Fall through to add to randomness */
163 case IRQ_HANDLED:
164 flags |= action->flags;
165 break;
166
167 default:
우 리 는 그 중의 142 번 째 줄 에 관심 을 가지 는데 본질 적 으로 irq 를 호출 하 는 것 이다.default_primary_handler (), 150 줄 받 았 습 니 다. irq 때문에default_primary_handler () 가 IRQ 를 되 돌려 주 었 습 니 다.WAKE_THREAD, 따라서 generic 의 중단 처리 절 차 는 irq 를 실행 합 니 다.wake_thread(desc, action);앞의 irq /% d -% s 스 레 드 를 깨 우 십시오. 이 스 레 드 의 코드 는?789 static int irq_thread(void *data)
790 {
791 static const struct sched_param param = {
792 .sched_priority = MAX_USER_RT_PRIO/2,
793 };
794 struct irqaction *action = data;
795 struct irq_desc *desc = irq_to_desc(action->irq);
796 irqreturn_t (*handler_fn)(struct irq_desc *desc,
797 struct irqaction *action);
798
799 if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD,
800 &action->thread_flags))
801 handler_fn = irq_forced_thread_fn;
802 else
803 handler_fn = irq_thread_fn;
804
805 sched_setscheduler(current, SCHED_FIFO, ¶m);
806 current->irq_thread = 1;
807
808 while (!irq_wait_for_interrupt(action)) {
809 irqreturn_t action_ret;
810
811 irq_thread_check_affinity(desc, action);
812
<strong> 813 action_ret = handler_fn(desc, action);</strong>
814 if (!noirqdebug)
815 note_interrupt(action->irq, desc, action_ret);
816
817 wake_threads_waitq(desc);
818 }
819
820 /*
821 * This is the regular exit path. __fr
그 중 813 길드 는 최종 할당 값 을 thread 에 호출 합 니 다.fn 의 원래 handler, 이렇게 원래 중단 의 절반 은 irq 에 있 습 니 다.thread 에서 실행 되 었 습 니 다. 이른바 상단 의 스 레 드 화 를 실현 하 였 습 니 다.
정상 반 부 를 돌아 가 는 스 레 드 화 는 물론 RT - Preempt 을 할 수 있 는 상황 에서 우 리 는 정상 반 부 를 돌아 가 는 스 레 드 화 과정 을 통 해 앞의 강력 한 변경 을 피 할 수 있 습 니 다. 중단 을 신청 할 때 IRQ 를 설정 할 수 있 습 니 다.NOTHREAD 로고, 예 를 들 어 patch:
Subject: arm: Mark pmu interupt IRQF_NO_THREAD
From: Thomas Gleixner <[email protected]>
Date: Wed, 16 Mar 2011 14:45:31 +0100
PMU interrupt must not be threaded. Remove IRQF_DISABLED while at it
as we run all handlers with interrupts disabled anyway.
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/arm/kernel/perf_event.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-stable/arch/arm/kernel/perf_event.c
===================================================================
--- linux-stable.orig/arch/arm/kernel/perf_event.c
+++ linux-stable/arch/arm/kernel/perf_event.c
@@ -430,7 +430,7 @@ armpmu_reserve_hardware(struct arm_pmu *
}
err = request_irq(irq, handle_irq,
- IRQF_DISABLED | IRQF_NOBALANCING,
+ IRQF_NOBALANCING | IRQF_NO_THREAD,
"arm-pmu", armpmu);
if (err) {
r_err("unable to request IRQ%d for ARM PMU counters
",
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Exception in thread main java.lang. NoClassDefFoundError 오류 해결 방법즉,/home/hadoop/jarfile) 시스템은 Hello World 패키지 아래의class라는 클래스 파일을 실행하고 있다고 오인하여 시스템의 CLASSPATH 아래 (일반적으로 현재 디렉터리를 포함) Hell...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.