다른 코어의 특정 지점에서 실행중인 스레드를 확인해야하는 커널 드라이버를 작성 중입니다. 드라이버는 코어 당 하나의 커널 스레드를 실행하며 특정 작업을 수행하기 위해 때때로 스레드 중 일부를 동기화해야합니다. 디버깅 로그에서 관찰 할 수있는 것은 때때로 한 스레드가 다른 스레드를 너무 많이 기다리는 경우입니다. 나는 다른 코어에 __preempt_count
을 저장하여 softirq/hardirq 또는 preemption disabled가 스레드를 지연시키는 지 확인하는 패치를 작성했습니다. 또한 FTRACE를 사용하여 irqsoff 및 preemptirqsoff를 검사하여 IRQ의 최대 지속 시간을 해제하고 선매를 사용하지 않도록 설정했습니다.SMP 기반 Linux 시스템에서 다른 CPU의 "current_task"포인터에 액세스
지금까지 20 밀리 초 이하의 인터럽트를 비활성화하는 kerneloops 스레드를 발견 할 수 있었는데, 너무 오래 발견되었습니다. systemctl disable kerneloops
을 신고이 문제를 해결했습니다.
이제 일부 선매 해제 된 창을 처리하는 것처럼 보입니다. 나중에이 드라이버를 분석하기 위해 다른 코어에서 특정 시점에 어떤 스레드가 실행되고 있는지 파악하는 방법이 필요합니다. 나는 IRQ entry/exit 이벤트와 함께 FTRACE를 주로 사용하려고 노력하고 있는데, trace_printk
을 사용하여 ftrace 버퍼의 일부 디버그 로그를 하나의 로그 등에 넣을 수 있습니다.
(current
ptr) current_task
구조에 액세스하여 작업 이름 (또는 pid 값)을 제공하는 comm
필드를 인쇄하십시오. 하지만이 일을 처리하는 데 어려움을 겪고 있습니다.
__preempt_count
위해 나는 아무 문제가 없었다 :
int *p = per_cpu_ptr(&__preempt_count,cpu);
pr_info("Preempt count of cpu%u is 0x%08x\n",cpu,*p);
지금까지 내가 선언 또는 CPU 변수에 따라 접근 아무 문제가 없었다,하지만 액세스하려고 할 때 어떤 이유로 current_task
포인터가 페이지 오류를 트리거합니다.
char buf[10];
struct task_struct *task = per_cpu_ptr(current_task,cpu);
snprintf(buf,8,"%s",task->comm);
pr_info("Task name: %s",buf);
위의 코드는 항상 페이지 오류, NULL ptr bla bla를 트리거합니다. 지금까지 그 이유를 찾지 못했습니다. task
에 대한 포인터 값을 인쇄하려했는데 같은 페이지 오류가 발생했습니다.
다른 코어가 주소에 액세스 할 수 없기 때문에 이럴 수 있습니까? 커널 공간에서 afaik 경우가 아니어야합니다. 나는 또한 핵심 변수마다 지금까지 아무런 문제도 없었으며 이것으로 많은 것을 해냈다.
결론 : 다른 코어의 current_task
에 액세스하고 comm/pid 필드를 인쇄하는 올바른 방법은 무엇입니까?
많은 감사,
다니엘