10
add_timer
API로 생성 된 타이머가 만료되고 타이머 구조에서 할당 된 기능이 실행되면 어떤 상황에서 실행됩니까? 컨텍스트 또는 커널 프로세스 컨텍스트를 인터럽트합니까? 그것은 인터럽트 상황에서 물론이다Linux 커널 타이머 기능은 어떤 컨텍스트에서 실행됩니까?
add_timer
API로 생성 된 타이머가 만료되고 타이머 구조에서 할당 된 기능이 실행되면 어떤 상황에서 실행됩니까? 컨텍스트 또는 커널 프로세스 컨텍스트를 인터럽트합니까? 그것은 인터럽트 상황에서 물론이다Linux 커널 타이머 기능은 어떤 컨텍스트에서 실행됩니까?
, 더 정확하게, 현재 softirq 맥락에서 (커널/타이머 .c) 아래 참조 :
당신이 무슨 말을하는거야 OSstatic inline void __run_timers(struct tvec_base *base)
{
struct timer_list *timer;
spin_lock_irq(&base->lock);
while (time_after_eq(jiffies, base->timer_jiffies)) {
struct list_head work_list;
struct list_head *head = &work_list;
int index = base->timer_jiffies & TVR_MASK;
/*
* Cascade timers:
*/
if (!index &&
(!cascade(base, &base->tv2, INDEX(0))) &&
(!cascade(base, &base->tv3, INDEX(1))) &&
!cascade(base, &base->tv4, INDEX(2)))
cascade(base, &base->tv5, INDEX(3));
++base->timer_jiffies;
list_replace_init(base->tv1.vec + index, &work_list);
while (!list_empty(head)) {
void (*fn)(unsigned long);
unsigned long data;
bool irqsafe;
timer = list_first_entry(head, struct timer_list,entry);
fn = timer->function;
data = timer->data;
irqsafe = tbase_get_irqsafe(timer->base);
timer_stats_account_timer(timer);
base->running_timer = timer;
detach_expired_timer(timer, base);
if (irqsafe) {
spin_unlock(&base->lock);
call_timer_fn(timer, fn, data); // <=========== HERE
spin_lock(&base->lock);
} else {
spin_unlock_irq(&base->lock);
call_timer_fn(timer, fn, data); // <============ HERE
spin_lock_irq(&base->lock);
}
}
}
base->running_timer = NULL;
spin_unlock_irq(&base->lock);
}
/*
* This function runs timers and the timer-tq in bottom half context.
*/
static void run_timer_softirq(struct softirq_action *h)
{
struct tvec_base *base = __this_cpu_read(tvec_bases);
hrtimer_run_pending();
if (time_after_eq(jiffies, base->timer_jiffies))
__run_timers(base);
}
void __init init_timers(void)
{
int err;
/* ensure there are enough low bits for flags in timer->base pointer */
BUILD_BUG_ON(__alignof__(struct tvec_base) & TIMER_FLAG_MASK);
err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
init_timer_stats();
BUG_ON(err != NOTIFY_OK);
register_cpu_notifier(&timers_nb);
open_softirq(TIMER_SOFTIRQ, run_timer_softirq); // <============= HERE
}
? 리눅스와 그 커널 타이머를 뜻한다면'linux/timer.c '의'add_timer()'에 대한 코멘트가 인터럽트 컨텍스트이다 : "커널은 -> 함수 (-> 데이터) 콜백을 할 것이다 ** 미래의 -> 만료 시점에서 타이머 인터럽트 **에서. " 인터럽트 핸들러는 커널의 프로세스 컨텍스트에서 실행될 수 있지만, 나는 카운트하지 않는 것이 좋습니다. – Eugene
안녕하세요, 물론 Linux 커널입니다. 감사. – user1977760