linux的软中断

原创 2012年03月28日 23:07:14

     本来没想到写这个的,但在研究linux的动态定时器时,发现动态定时器是用到软中断机制的,所以对软中断做一个浅显的了解:

     在分析过程中,愈加的觉得kernel是一个整体,想单单搞懂驱动是有难度的,因为kernel是个整体。你要懂驱动,就要对驱动模型,就要对文件系统、内存管理和进程调度等等有一定了解。

     下面来分析soft irq:

kernel/softirq.c中:

staticstruct softirq_action softirq_vec[NR_SOFTIRQS]__cacheline_aligned_in_smp;

这就是软中断的中断向量表。

还有一个枚举变量:

enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ,	/*Preferable RCU should always be the last softirq */

NR_SOFTIRQS
};

内核用这些从0开始的索引来表示一种相对优先级。索引号小的软中断在索引号大的软中断之前执行。
TIMER_SOFTIRQ的索引值是1,优先值是很高的。
软中断的注册:
open_softirq(TIMER_SOFTIRQ, run_timer_softirq);

void open_softirq(int nr, void (*action)(struct softirq_action *))
{
	softirq_vec[nr].action = action;
}


这里将TIMER_SOFTIRQ软中断索引号与run_timer_softirq中断处理程序联系起来。


软中断的触发:

内核在硬件时钟中断发生后执行定时器,定时器作为软中断在下半部上下文中执行。具体的情况是:时钟中断处理程序会执行update_process_times()函数,该函数调用run_local_timers()函数:

void run_local_timers(void)
{
	hrtimer_run_queues();
	raise_softirq(TIMER_SOFTIRQ);
	softlockup_tick();
}

inline void raise_softirq_irqoff(unsigned int nr)
{
	__raise_softirq_irqoff(nr);

	/*
	 * If we're in an interrupt or softirq, we're done
	 * (this also catches softirq-disabled code). We will
	 * actually run the softirq once we return from
	 * the irq or softirq.
	 *
	 * Otherwise we wake up ksoftirqd to make sure we
	 * schedule the softirq soon.
	 */
	if (!in_interrupt())
		wakeup_softirqd();
}

void raise_softirq(unsigned int nr)
{
	unsigned long flags;

	local_irq_save(flags);
	raise_softirq_irqoff(nr);
	local_irq_restore(flags);
}



在注释中有这么一句:Otherwise we wake up ksoftirqd to make sure we schedule the softirq soon

唤醒ksoftirqd内核线程来保证调度立即执行softirq


软中断的执行:

kernel/softirq.c中:

staticint __cpuinit cpu_callback(struct notifier_block *nfb,

unsigned long action,

void *hcpu)

中,建立一个ksoftirqd内核线程来执行软中断:

kthread_create(run_ksoftirqd,hcpu, "ksoftirqd/%d", hotcpu);



run_ksoftirqd当中,

run_ksoftirqd-->do_softirq-->__do_softirq

__do_softirq函数的核心部分如下:

	h = softirq_vec;

	do {
		if (pending & 1) {
			int prev_count = preempt_count();
			kstat_incr_softirqs_this_cpu(h - softirq_vec);

			trace_softirq_entry(h, softirq_vec);
			h->action(h);
			trace_softirq_exit(h, softirq_vec);
			if (unlikely(prev_count != preempt_count())) {
				printk(KERN_ERR "huh, entered softirq %td %s %p"
				       "with preempt_count %08x,"
				       " exited with %08x?\n", h - softirq_vec,
				       softirq_to_name[h - softirq_vec],
				       h->action, prev_count, preempt_count());
				preempt_count() = prev_count;
			}

			rcu_bh_qs(cpu);
		}
		h++;
		pending >>= 1;
	} while (pending);






大致看出这个过程是循环遍历每一个待处理的软中断,调用它们的中断处理程序。

这样,利用了软中断,我们的run_timer_softirq这个中断处理程序得以运行。

对这个linux软中断的分析比较简单,仅仅为linux的动态定时器做了铺垫。后面还需要再仔细分析linux的软中断。











                

浅析Linux的软中断的实现

作者:独孤九贱 平台:2.6.31.13 + x86 32位 供仅讨论学习之处,不对错误之处负责,转载请注明出处。 1、软中断 软中断的原理就略过了,讲内核的书上都有,此处省略1500...
  • fivedoumi
  • fivedoumi
  • 2014年04月29日 10:37
  • 1516

linux下软中断[si]负载均衡

最近在生产环境的服务器上发现如下问题: 多进程服务的用户负载[us]可以均匀分配在各个CPU上运行,但软中断负载[si]只集中在CPU0上,导致CPU0的[si]段的负载达到70%,而其他几个核...
  • vipzhxsh
  • vipzhxsh
  • 2016年06月24日 17:06
  • 1439

Linux内核修炼之软中断分析

====本文系本站原创,欢迎转载! 转载请注明出处:http://blog.csdn.net/yyplc====  基于内核:linux-2.6.30.4   arm平台分析. 中断分成硬中断和软...
  • yyplc
  • yyplc
  • 2012年05月19日 22:27
  • 3396

Linux kernel 软中断机制之触发软中断执行

在前面介绍中,我们知道如何对软中断的简单初始化,软中断需要触发,然后软中断处理函数才能被执行:   内核提供__raise_softirq_irqoff()类函数对指定的软中设置标志位。与此相关的函数...
  • sunlei0625
  • sunlei0625
  • 2017年03月08日 08:03
  • 457

软中断过高问题如何解决

原文:http://os.51cto.com/art/201310/414482.htm 前些天发现XEN虚拟机上的Nginx服务器存在一个问题:软中断过高,而且大部分都集中在同一个CPU,...
  • rainharder
  • rainharder
  • 2017年06月14日 08:39
  • 1100

Linux kernel 软中断机制之软中断处理时机

local_bh_enable_ip    local_bh_enable        |      |        ------...
  • sunlei0625
  • sunlei0625
  • 2017年03月08日 08:06
  • 178

linux进程(软中断通信)

父进程创建两个子进程,接收到Ctrl+\后向两个子进程发送信号16和17 ,结束子进程生命周期...
  • u010710760
  • u010710760
  • 2014年12月05日 18:36
  • 1095

linux内核模块中 软中断的 例子

直接上例子吧。只是捕获某个设备的中断而已。。。 该文件的名字是irq.c #include #include #include #include #include #define DEBUG#ifde...
  • silence1214
  • silence1214
  • 2010年05月22日 18:38
  • 2429

Linux 硬中断和软中断

概述   从本质上来讲,中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给中断控制器。 如果中断的线是激活的,中断控制器就把电信号发送给处理器的某个特定...
  • u010827484
  • u010827484
  • 2015年10月11日 10:53
  • 2482

对Linux 网卡软中断做负载均衡

测试中发现服务器整体负载较低,但有cpu负载特别高,其中一个cpu几乎一半是软中断si,特别忙,而还有的cpu特别空闲。 Java代码   top - 16:12:08 up ...
  • weiyuefei
  • weiyuefei
  • 2016年07月18日 16:40
  • 1336
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux的软中断
举报原因:
原因补充:

(最多只允许输入30个字)