免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1596 | 回复: 3

[内核模块] 同一个tasklet不能同时运行在不同CPU上,why? [复制链接]

论坛徽章:
0
发表于 2014-03-04 00:15 |显示全部楼层
在看中断下半部时,大部分资料讲软中断softirq和tasklet的区别时:
softirq必须是重入的,可以同时运行在不同的CPU上;
而同一个tasklet不能同时运行在不同的CPU上,不同的tasklet可以同时运行在不同的CPU上;

目前是知其然而不知其所以然,有大牛帮忙讲解一下为什么可以,为什么又不可以吗?最好能拿着例子讲解一下,多谢多谢

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
发表于 2014-03-04 00:42 |显示全部楼层
就是这么设计的,参见LKD软中断一章。

老版的BH接口完全串行化,只要有一个CPU在执行下半部,其它CPU都不能执行下半部。编码简单,只可能跟中断race,效率低,扩展性不好。
后来改成了softirq,完全并行化,扩展性好,但要写代码时要考虑中断race和所有softirq间的race。
Tasklet是折衷的设计,同类型串行,不同类型并行,需要考虑中断race以及不同类型softirq间的race,不用考虑同类型softirq间的race。适用于大多数驱动。

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-03-04 08:40 |显示全部楼层
完全同意

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
发表于 2014-03-04 09:05 |显示全部楼层
回复 1# Huntsmen

以前也回答过这个问题,顺手粘贴过来:)

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

static void tasklet_action(struct softirq_action *a)
{
        struct tasklet_struct *list;

        local_irq_disable();
        list = __this_cpu_read(tasklet_vec.head);
        __this_cpu_write(tasklet_vec.head, NULL);
        __this_cpu_write(tasklet_vec.tail, &__get_cpu_var(tasklet_vec).head);
        local_irq_enable();

        while (list) {
                struct tasklet_struct *t = list;

                list = list->next;

                if (tasklet_trylock(t)) {
                        if (!atomic_read(&t->count)) {
                                if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
                                        BUG();
                                t->func(t->data);
                               tasklet_unlock(t);
                                continue;
                        }
                        tasklet_unlock(t);
                }

                local_irq_disable();
                t->next = NULL;
                *__this_cpu_read(tasklet_vec.tail) = t;
                __this_cpu_write(tasklet_vec.tail, &(t->next));
                __raise_softirq_irqoff(TASKLET_SOFTIRQ);
                local_irq_enable();
        }
}

1. 从tasklet_schedule()红色代码那里可以看到,一旦同一个tasklet被schedule,直到tasklet_action()蓝色部分清除TASKLET_STATE_SCHED之前,tasklet不允许再次schedule
2. 从橘黄色tasklet_trylock()开始到绿色tasklet_unlock(t)期间,同一个tasklet不允许再次运行!
3. 从蓝色到绿色部分,同一个tasklet允许schedule,但是不允许运行!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP