Linux Tasklet

1. Tasklet的处理

在上一博客有关软中断的处理中,TASKLET_SOFTIRQ对应的处理函数 tasklet_action。

kernel/softirq.c

476 static void tasklet_action(struct softirq_action *a)
477 {
478         struct tasklet_struct *list;
479
480         local_irq_disable();
481         list = __this_cpu_read(tasklet_vec.head);
482         __this_cpu_write(tasklet_vec.head, NULL);
483         __this_cpu_write(tasklet_vec.tail, &__get_cpu_var(tasklet_vec).head);
484         local_irq_enable();
485
486         while (list) {
487                 struct tasklet_struct *t = list;
488
489                 list = list->next;
490
491                 if (tasklet_trylock(t)) {
492                         if (!atomic_read(&t->count)) {
493                                 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
494                                         BUG();
495                 mt_trace_tasklet_start(t->func);
496                                 t->func(t->data);
497                 mt_trace_tasklet_end(t->func);
498                                 tasklet_unlock(t);
499                                 continue;
500                         }
501                         tasklet_unlock(t);
502                 }
503
504                 local_irq_disable();
505                 t->next = NULL;
506                 *__this_cpu_read(tasklet_vec.tail) = t;
507                 __this_cpu_write(tasklet_vec.tail, &(t->next));
508                 __raise_softirq_irqoff(TASKLET_SOFTIRQ);
509                 local_irq_enable();
510         }
511 }

491 试图上锁,意味着同时只有一个tasklet在工作。

496  调用相应的处理函数。

504-509 上锁不成功,重新加入队列,触发TASKLET_SOFTIRQ软中断。

2. tasklet接口函数


549 void tasklet_init(struct tasklet_struct *t,
550                   void (*func)(unsigned long), unsigned long data)
551 {
552         t->next = NULL;
553         t->state = 0;
554         atomic_set(&t->count, 0);
555         t->func = func;
556         t->data = data;
557 }

设置相应的成员


static inline void tasklet_schedule(struct tasklet_struct *t)
{
        if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
                __tasklet_schedule(t);
}

437 void __tasklet_schedule(struct tasklet_struct *t)
438 {
439         unsigned long flags;
440
441         local_irq_save(flags);
442         t->next = NULL;
443         *__this_cpu_read(tasklet_vec.tail) = t;
444         __this_cpu_write(tasklet_vec.tail, &(t->next));
445         raise_softirq_irqoff(TASKLET_SOFTIRQ);
446         local_irq_restore(flags);
447 }

加入tasklet列表,触发TASKLET_SOFTIRQ软中断。


561 void tasklet_kill(struct tasklet_struct *t)
562 {
563         if (in_interrupt())
564                 printk("Attempt to kill tasklet from interrupt\n");
565
566         while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
567                 do {
568                         yield();
569                 } while (test_bit(TASKLET_STATE_SCHED, &t->state));
570         }
571         tasklet_unlock_wait(t);
572         clear_bit(TASKLET_STATE_SCHED, &t->state);
573 }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值