我的小米mix尊享版5尊享版怎样才能拥有新增的“双开”等一系列

| 您所在的位置: >
> Linux RT(2)-硬实时Linux(RT-Preempt Patch)的中断线程化Linux RT(2)-硬实时Linux(RT-Preempt Patch)的中断线程化更新:&&&&编辑:心迹&&&&来源:谷普原创&&&&人气:加载中...&&&&字号:|标签:&&&&&&&&&&&&
底半部:程化IRQ程化的支持在2009年已经进入内核,详见Thomas Gleixner的patch:?p=linux/kernel/git/torvalds/linux-2.6.a=h=3aa551c9b4ca178e3d2该patch提供一个能力,可以通过int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, 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函数,因此,该线程成为底半部。在后续维护的过程中,笔者曾参与进一步完善该功能的讨论,后续patch包括nested、oneshot等的支持,详见patch:?p=linux/kernel/git/torvalds/linux-2.6.a=h=399b5da29b9f851eb7b96ef003e87c?p=linux/kernel/git/torvalds/linux-2.6.a=h=70aedd24d20eb11750faabbb56924e2?p=linux/kernel/git/torvalds/linux-2.6.a=h=b25c340c195447afbfe2a85a6b652c5该机制目前在kernel中使用已经十分广泛,可以认为是继softirq(含tasklet)和workqueue之后的又一大中断底半部方式。顶半部:强制线程化在使能 RT-Preempt后,默认情况下会强制透过request_irq()申请的IRQ的顶半部函数在线程中执行,我们都request_irq的原型为: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 的情况下,其中的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 中,会针对使能了IRQ_FORCED_THREADING的情况,对这一原先没有线程化IRQ的case进行强制线程化,代码见__setup_irq(): 887 static int
888 __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
* Check whether the interrupt nests into another interrupt
nested = irq_settings_is_nested_thread(desc);
if (nested) {
if (irq_settings_can_thread(desc))
irq_setup_forced_threading(new);
* Create a handler thread when a thread function is supplied
* and the interrupt does not nest into another interrupt
if (new-&thread_fn && !nested) {
struct task_struct *t;
t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
new-&name);
* We keep the reference to the task struct even if
* the thread dies to avoid that the interrupt code
* references an already freed task_struct.
get_task_struct(t);
new-&thread =
}我们重点看一下其中的921行: 867 static void irq_setup_forced_threading(struct irqaction *new)
if (!force_irqthreads)
if (new-&flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT))
new-&flags |= IRQF_ONESHOT;
if (!new-&thread_fn) {
set_bit(IRQTF_FORCED_THREAD, &new-&thread_flags);
new-&thread_fn = new-&
new-&handler = irq_default_primary_
881 }第878行和879行,强制将原先的handler复制给thread_fn,而又强制把原来的handler变更为irq_default_primary_handler(),而这个函数,其实神马都不做,只是直接返回IRQ_WAKE_THREAD:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
分类选择您可能在找这些1091人阅读
中断管理(1)
前段时间一个培训项目遇到了所有网卡中断都跑在一个核上,造成负载不均衡的问题,解决思路如下:
1. 首先查看一下
irqbalance service是否正常运行,自动平衡irq负载的service
2. 可以用下面命令绑定不同irq到不同的cpu上,smp_affinity为cpu的位掩码,3(0x11)代表0号和1号cpu
# service irqbalance stop
# echo &3& & /proc/irq/irqnum/smp_affinity
3. 在注册irq时,可以参考kernel函数 irq_set_affinity直接将irq绑定到指定的cpu
int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
&&& struct irq_desc *desc = irq_to_desc(irq);
&&& if (!desc-&chip-&set_affinity)
&&& &&& return -EINVAL;
&&& &&& if (!desc-&chip-&set_affinity(irq, cpumask)) {
关于linux内核的实时性:
1. 实时性就是要求指定的任务可以在预期的时间内被处理,这在非实时的linux内核上没法保证,不论多么高优先级的实时任务都会被中断抢占,因此要保证实时就要把中断线程化,有其对应的优先级,将实时性要求高的任务的优先级设置为高于所有中断线程的优先级,那么该任务就不会被中断抢占。
2. 实现方法是:在注册irq时,如果没有设置IRQ_NODELAY标志,那么将为该irq创建一个内核线程,并可以设置线程的优先级范围为:25~50;在中断产生后,__do_irq将判断该中断是否已经线程化(flag:IRQ_NODELAY),没有线程化的中断在handle_irq_event中直接调用action-&handler进行处理,已经线程化将wake_up_process(action-&thread),唤醒该irq线程进行处理。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:14453次
排名:千里之外
原创:14篇
(3)(9)(1)(1)Linux RT(2)-硬实时Linux(RTPreempt Patch)的中断线程化
底半部:线程化IRQ
线程化中断的支持在2009年已经进入Linux官方内核,详见的patch:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.a=h=3aa551c9b4ca178e3d2
该patch提供一个能力,驱动可以通过
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函数,因此,该线程成为底半部。在后续维护的过程中,笔者曾参与进一步完善该功能的讨论,后续patch包括nested、oneshot等的支持,详见patch:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.a=h=399b5da29b9f851eb7b96ef003e87c
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.a=h=70aedd24d20eb11750faabbb56924e2
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.a=h=b25c340c195447afbfe2a85a6b652c5
该机制目前在kernel中使用已经十分广泛,可以认为是继softirq(含tasklet)和workqueue之后的又一大中断底半部方式。
顶半部:强制线程化
在使能Linux RT-Preempt后,默认情况下会强制透过request_irq()申请的IRQ的顶半部函数在线程中执行,我们都知道request_irq的原型为:
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中,会针对使能了IRQ_FORCED_THREADING的情况,对这一原先没有线程化IRQ的case进行强制线程化,代码见__setup_irq():
887 static int
888 __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
* Check whether the interrupt nests into another interrupt
nested = irq_settings_is_nested_thread(desc);
if (nested) {
if (irq_settings_can_thread(desc))
irq_setup_forced_threading(new);
* Create a handler thread when a thread function is supplied
* and the interrupt does not nest into another interrupt
if (new-&thread_fn && !nested) {
struct task_struct *t;
t = kthread_create(irq_thread, new, &irq/%d-%s&, irq,
new-&name);
* We keep the reference to the task struct even if
* the thread dies to avoid that the interrupt code
* references an already freed task_struct.
get_task_struct(t);
new-&thread =
}我们重点看一下其中的921行:
867 static void irq_setup_forced_threading(struct irqaction *new)
if (!force_irqthreads)
if (new-&flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT))
new-&flags |= IRQF_ONESHOT;
if (!new-&thread_fn) {
set_bit(IRQTF_FORCED_THREAD, &new-&thread_flags);
new-&thread_fn = new-&
new-&handler = irq_default_primary_
881 }第878行和879行,强制将原先的handler给thread_fn,而又强制把原来的handler变更为irq_default_primary_handler(),而这个函数,其实神马都不做,只是直接返回IRQ_WAKE_THREAD:
* Default primary interrupt handler for threaded interrupts. Is
* assigned as primary handler when request_threaded_irq is called
* with handler == NULL. Useful for oneshot interrupts.
618 static irqreturn_t irq_default_primary_handler(int irq, void *dev_id)
return IRQ_WAKE_THREAD;
621 }第874的IRQF_ONESHOT就用到了我们前面说的oneshot功能。
所以,RT-Preempt实际上是把原先的顶半部底半部化了,而现在伪造了一个假的顶半部,它只是直接返回一个IRQ_WAKE_THREAD标记而已。
我们来看一下一个中断发生后,Linux RT-Preempt处理的全过程,首先是会跳到
arch/arm/kernel/entry-armv.S
arch/arm/include/asm/entry-macro-multi.S
中的汇编入口,再进入arm/kernel/irq.c下的asm_do_IRQ 、handle_IRQ,之后generic的handle_irq_event_percpu()被调用:
133 handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
irqreturn_t retval = IRQ_NONE;
unsigned int flags = 0, irq = desc-&irq_data.
irqreturn_
trace_irq_handler_entry(irq, action);
res = action-&handler(irq, action-&dev_id);
trace_irq_handler_exit(irq, action, res);
if (WARN_ONCE(!irqs_disabled(),&irq %u handler %pF enabled interrupts\n&,
irq, action-&handler))
local_irq_disable();
switch (res) {
case IRQ_WAKE_THREAD:
* Catch drivers which return WAKE_THREAD but
* did not set up a thread function
if (unlikely(!action-&thread_fn)) {
warn_no_thread(irq, action);
irq_wake_thread(desc, action);
/* Fall through to add to randomness */
case IRQ_HANDLED:
flags |= action-&
我们关注其中的第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)
static const struct sched_param param = {
.sched_priority = MAX_USER_RT_PRIO/2,
struct irqaction *action =
struct irq_desc *desc = irq_to_desc(action-&irq);
irqreturn_t (*handler_fn)(struct irq_desc *desc,
struct irqaction *action);
if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD,
&action-&thread_flags))
handler_fn = irq_forced_thread_
handler_fn = irq_thread_
sched_setscheduler(current, SCHED_FIFO, ¶m);
current-&irq_thread = 1;
while (!irq_wait_for_interrupt(action)) {
irqreturn_t action_
irq_thread_check_affinity(desc, action);
&strong& 813
action_ret = handler_fn(desc, action);&/strong&
if (!noirqdebug)
note_interrupt(action-&irq, desc, action_ret);
wake_threads_waitq(desc);
* 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 &&
Date: Wed, 16 Mar :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 &&
arch/arm/kernel/perf_event.c |
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\n&,
更多相关文章
CNET科技资讯网 9月12日 国际报道:大多数分析师预计苹果明日发布的新款iPhone将是一款轰动产品.但市场研究公司NPD分析师斯蒂芬·贝克(Stephen Baker)在博文中表示,iPhone 5将面临iPhone 4甚至iPhone 4S从未遭遇过的严峻挑战环境. 美国智能手机市场正日趋饱 ...
nginx(发音同engine x)是一款由俄罗斯程序员Igor Sysoev所开发轻量级的网页服务器.反向代理服务器以及电子邮件(IMAP/POP3)代理服务器.起初是供俄国大型的门户网站及搜索引擎Rambler(俄语:Рамблер)使用.此软件BSD-like协议下发行,可以在UNIX.GNU ...
*标有 CT 的是配色 **主题中调用的字体和相配套的Sublime主程序图标可访问GitHub获取 Afterglow /YabataDesign/afterglow-theme 基于 Spacegray,暖色调的主题,Flat风格 Tomorrow(CT) h ...
注意,迭代器是比对象集更好的抽象,因为我们可以让InfiniteIterators,NoRewindIterators等,不用与普通数组阵列与一致,因此,Iterator缺少count()函数等功能.在PHP官方手册中可以找到完整的SPL迭代器列表.得益于对PHP的强力支持,使用迭代器模式的大部分工 ...
文章作者:吴杰 出自邪恶八进制信息安全团队 import _winregimport osimport shutil #自身shutil.copyfile(K3.exe,c:WINDOWSsystem32K3.exe) #把360启动改为自身run = _winreg.OpenKey(
很多微博和文章都说,股指期货的收盘价对第二天开盘价影响很大,因为股指多交易15分钟,因此对股市的第二天开盘价影响非常大,网上有一个文章是这样说的: “股指期货开盘早于股市15分钟,收盘又晚15分钟,国泰君安研究员曾统计,股指期货晚收盘15分钟的涨跌对于次日期指走势的预测准确率达到了70%.” 看看这 ...
1. 工作站开机出现红色检测硬盘对画框? 解决方法:工作站主板上有还原卡功能,请将还原功能关闭. 2. 进入游戏菜单,但游戏图标均为一样的电脑图标? 解决方法:游戏盘共享名设置不对,重新设置并修复安全性,或硬盘已接上 ...
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址, ...
从1998年开始,广东发展银行最初的网络安全体系就依据思科SAFE蓝图部署.SAFE主张,网络安全建设不能一蹴而就,而应该是一个动态的过程.所以在最初的部署中,思科主要协助广东发展银行解决了最突出的网络安全问题--网 ...
曾经常与同行高调叫板的当当网CEO李国庆,在今年二季度净亏损额收窄至4.3%之后反而很低调,只是在近日告诫业界,&规模只是优势而不是竞争门槛&,屡次被同行要挟的李国庆对此很有发言权,他甚至认为目前 ...
就一个类而言,应该仅有一个引起它变化的原因.通俗的说,一个类只负责一项职责.
问题的由来
手机的功能多,但是每一项的功能都不强:
拍摄功能--& ...
exchange2007共用文件夹迁移至exchange2010 如果把Exchange 2007的PF的所有内容和层次结构都移动到Exchange 2010的PF数据库,可按照如下操作: 1. 在Exchange
Ubuntu 12.04 LTS下安装文件传输远程桌面共享软件Teamviewer
TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一 ...
随着智能手机一步步深入普通大众的生活,伴随而来的除了强大的性能与丰富的应用以外,也有人们不愿意见到的东西,那就是恶意软件.俗话说树大招风,Android作为目前主流的移动操作系统之一,正成为越来越多恶意软件的目标.J ...
上辑:CSDN2007年英雄会札记 - 现场会的无聊和有趣
可能有点虎头蛇尾,我还是决定在今晚把这个札记草草收尾,再拖下去就有炒冷饭的嫌疑了.
CSDN举办的这次技术英雄大会,对于中国程序员来说,应该是值得记 ...
现在开始(Do It Now) 很多年前读大学的时候,我决定制定一个计划挑战自己:只用三个学期完成其他人通常花费四年的课程,能否毕业.这篇文章(此文为翻译)详细的说明了我在成功实现该目标过程中的所有时间管理技巧. 为 ...最近在为3.8版本的Linux内核打RT_PREEMPT补丁,并且优化系统实时性,这篇文章主要对RTlinux中中断线程化部分进行分析。我们知道在RT_PREEMPT补丁中之所以要将中断线程化就是因为硬中断的实时性太高,会影响实时进程的实时性,所以需要将中断处理程序线程化并设置优先级,使中断处理线程的优先级比实时进程优先级低,从而提高系统实时性。
网上看到一些网友说在2.6.25.8版本的内核,linux引入了中断线程化,具体是不是2.6.25.8版本开始引入中断线程化我没有去求证,因为版本比较老了改动很多,但据我的查证从2.6.30开始内核引入request_threaded_irq函数,从这个版本开始可以通过在申请中断时为request_irq设置不同的参数决定是否线程化该中断。而在2.6.39版内核__setup_irq引入irq_setup_forced_threading函数,开始可以通过#
&define force_irqthreads(true)强制使中断线程化,那么从这个版本开始想实现中断线程化就已经变得很简单了,让force_irqthreads为真即可,所以在3.8版本的实时补丁中,正是这一段代码实现了中断的线程化:
下面我们开始正式介绍中断线程化是怎么实现的。
Linux内核常见申请中断的函数request_irq,在内核源码include/linux/interrupt.h头文件中可以看到request_irq仅包含return request_threaded_irq(irq, handler, NULL, flags, name, dev);调用,request_threaded_irq函数在源码目录kernel/irq/manage.c文件中,下面通过分析manage.c中各个相关函数解读中断线程化的实现过程。
根据request_irq的调用,首先分析request_threaded_irq
request_threaded_irq函数基本上是将传入的参数放到action结构体,然后调用__setup_irq函数,线程化的具体过程在__setup_irq函数中
__setup_irq的内容比较多点,首先通过nested判断该中断是否属于其他中断进程,即和别的中断共享同一个中断号,如果不是,判断是否强制将该中断线程化,很明显打了实时补丁后使能强制线程化中断,强制线程化如果thread_fn为空会使thread_fn指向handler,而handler指向默认的句柄函数,其实在强制中断线程化没有开启的情况下,request_threaded_irq函数根据thread_fn是否为空判断是否将该中断线程化。这里强制线程化后thread_fn显然不会为空。
接下来因为是首次在该中断线创建处理函数,申请一个内核线程,设置线程调度策略(FIFO)和优先级(50),为了让使用该中断号的其他进程共享这条中断线,还必须建立一个中断处理进程action的单向链表,设置一些共享标识等。但是如果现在申请的这个中断与其他已经建立中断内核线程的中断共享中断线,那么就不需要再次建立内核线程和队列,只需在队列中找到空指针(一般是末尾)并插入队列即可。做完这些之后唤醒内核进程(kthread_create)创建的内核进程不能马上执行,需要唤醒。
在Linux中申请中断还可以通过request_any_context_irq、devm_request_threaded_irq等函数,他们最终都调用request_threaded_irq,request_threaded_irq函数的完整形式如下:
在没有强制中断线程化的时候,thread_fn不为空即可将该中断线程化。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5869次
排名:千里之外
(2)(2)(2)(7)(1)}

我要回帖

更多关于 小米6陶瓷尊享版 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信