免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: ocean390
打印 上一主题 下一主题

软中断是如何实现的? [复制链接]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
11 [报告]
发表于 2006-05-03 22:35 |只看该作者
"没有讲软件中断是怎么被调度的。 "

引入中断上下文之后也就是中断线程,调度与一般线程调度无异。不过它们的优先级比普通线程优先级高罢了。
具体实现可以参考freebsd设计与实现的4.3和4.4两节

论坛徽章:
0
12 [报告]
发表于 2006-05-03 22:40 |只看该作者
有点明白了

论坛徽章:
0
13 [报告]
发表于 2006-05-03 22:42 |只看该作者
1.3.2 网络软中断调用
        在分析图1-3中的netisr_register函数前,必须清楚的了解网络软中断调用的原理.网络软中断调用及初始化的代码在netisr.h头文件和netisr.c中.网络软中断共有以下图中15种:

#define        NETISR_POLL        0                /* 必须放置到第一位 */     ---netisr.h
#define        NETISR_IP        2                /* 在if_ethersubr.c中我们可以看到它,IP分组软中断 */
#define        NETISR_ROUTE        14                /* routing socket */
#define        NETISR_AARP        15                /* Appletalk ARP */
#define        NETISR_ATALK2        16                /* Appletalk phase 2 */
#define        NETISR_ATALK1        17                /* Appletalk phase 1 */
#define        NETISR_ARP        18                /* 也是在if_ethersubr.c中. */
#define        NETISR_IPX        23                /* same as AF_IPX */
#define        NETISR_USB        25                /* USB soft interrupt */
#define        NETISR_PPP        26                /* PPP soft interrupt */
#define        NETISR_IPV6        27#define        NETISR_NATM        28
#define        NETISR_ATM        29#define        NETISR_NETGRAPH        30
#define        NETISR_POLLMORE        31        /* 必须放到最后以测试POLL的效率 */     ---netisr.h
                                                     图 1-3-2
在讲述POLLING(轮询)软件中断技术之前,对以上软中断号比较熟悉的是NETISR_IP和NETISR_ARP软件中断.因为在我的《通用以太网络驱动程序代码详解》中已经介绍过。我们这里看到NETISR_POLL放在第一位置,NETISR_POLLMORE放在最后的位置.这样安排是为了POLLMORE可以查看POLL运行的结果,是否有剩余的residual_burst(在参数说明中的B.算法参数中).有则再进行POLL,也给中间部分的软中断(如NETISR_IP、NETISR_ROUTE…)有时间执行.
        图1-3-2中定义的值是针对一个32位的全局变量netisr的各个bit(位).如下图所示:
                                                              netisr
0        1        2        3        4        ……………………..        30        31
                                                            
NETISR_POLL  NETISR_IP                 NETISR_NETGRAPH     NETISR_POLLMORE
在系统初始化其间会加入一核心线程对该变量进行每一bit(位)的判断是否置位.如果置位.则调用位序号对应的netisrs结构数组中的支撑函数.这个过程就是网络的软中断过程. 图 1-3-2-1为网络软中断守护核心线程初始化过程.

static void                                                                                                                   ---netisr.cstart
_netisr(void *dummy){
        if (swi_add(NULL, "net", swi_net, NULL, SWI_NET, INTR_MPSAFE, &net_ih))                panic("start_netisr");}SYSINIT(start_netisr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_netisr, NULL)

图 1-3-2-1
        SYSINIT宏使系统在初始时执行start_netisr函数.swi_add函数则把swi_net函数加入到核心线程队列中.net_ih是一intrhand结构指针.函数在成功返回后,net_ih指向的结构包含了中断句柄结构,该结构指针被用于软件中断调用函数swi_sched中.关于swi_add函数和swi_sched函数,本文不准备讨论(在kern_intr.c文件中),因为他们属于核心中断和调度部分了.
        swi_net函数的作用是判断全局变量netisr各个位(bit)的置位情况.进而处理相关的输入队列和调用其中断处理函数.

swi_net(void *dummy)                                                                                     ---netisr.c
{        struct netisr *ni;        u_int bits;        int i;
#ifdef DEVICE_POLLING       
const int polling = 1;
#else        const int polling = 0;
#endif       
do {
                bits = atomic_readandclear_int(&netisr);
                if (bits == 0)
                        break;
                while ((i = ffs(bits)) != 0) {
                        isrstat.isrs_swi_count++;
                        i--;
                        bits &= ~(1 << i);
                        ni = &netisrs;
                        if (ni->ni_handler == NULL) {
                                printf("swi_net: unregistered isr %d.\n", i);                                continue;       
                }
                        if ((ni->ni_flags & NETISR_MPSAFE) == 0) {                                mtx_lock(&Giant);
                                if (ni->ni_queue == NULL)                                        ni->ni_handler(NULL);
                                else
                                        netisr_processqueue(ni);                                mtx_unlock(&Giant);
                        } else {
                                if (ni->ni_queue == NULL)                                        ni->ni_handler(NULL);
                                else
                                        netisr_processqueue(ni);                        }
                }
        }
while (polling);}
                                                                                                                            ---netisr.c
                                                          图 1-3-2-1
        图1-3-2-1是整个swi_net函数的代码,它被放入两个while循环当中.最外层的循环是为了轮询而设计的.当polling没有开启时.函数只是执行内层的while循环.该循环是读netisr的每一位(从低位到高位).ffs函数是一库支撑函数.位于:  
lib\libc\string\ffs.c中.用来从低位到高位读参数的每一位已经置位的序号放入到变量i中.如:当netisr为二进制的0000,0000,0000,0010时(即NETISR_IP置位),这时ffs(netisr)返回的结果为2.代表是第二位置了位.因为在C语言中,数组的成员都是从0开始.所以要引用netisrs结构数组中的成员,i的值必须减去1.这就是我们看到代码中i - -的原因.语句bits &= ~(1 << i)告诉我们已经处理了此位.在下次循环前我们把此位置换为0才不至于重复处理该位.在得到该位相对应的软中断结构的指针到ni后,先判断该软中断的钩子函数是否存在.当然,不存在的唯一原因是在该软中断发出中断消息后立刻进行了卸载. NETISR_MPSAFE宏代表在下面的代码中不需要使用GAINT锁(即对多CPU也是安全的).

[ 本帖最后由 xie_minix 于 2006-5-3 23:19 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2006-05-03 22:44 |只看该作者
???
怎么发出来的东西都变了?格式什么的都没了?
另外:
int 80是核心外(用户区)的软中断,和核心内的不一样.
核心内是一轻量级的线程序.freebsd通过
schednetisr
schednetisrbits
来调度,是个非常简单的例程
netbsd的软中断有点不一样,可以比较下看看,
kern_kcont.c和/sys/arch/x86/x86下的文件建议看看,都在那了.

[ 本帖最后由 xie_minix 于 2006-5-3 22:52 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2006-05-03 22:46 |只看该作者
原帖由 xie_minix 于 2006-5-3 22:44 发表
???
怎么发出来的东西都变了?格式什么的都没了?


老大用【code】功能编译一下?

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
16 [报告]
发表于 2006-05-03 22:46 |只看该作者
原帖由 xie_minix 于 2006-5-3 22:42 发表
1.3.2 网络软中断调用
        在分析图1-3中的netisr_register函数前,必须清楚的了解网络软中断调用的原理.网络软中断调用及初始化的代码在netisr.h头文件和netisr.c中.网络软中断共有以下图中15种:

#define        NETISR ...


报告,发现大牛牛xie_minix出现

论坛徽章:
0
17 [报告]
发表于 2006-05-03 22:49 |只看该作者
在没有引入中断线程时,系统时如何处理的呢?

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
18 [报告]
发表于 2006-05-03 22:53 |只看该作者
原帖由 ocean390 于 2006-5-3 22:49 发表
在没有引入中断线程时,系统时如何处理的呢?


在当前进程的上下文中处理。这部分也就是传统的组成原理中中断处理部分的内容。
我觉得除了去考试之外,对于这种上个世纪7,80年代的"过时"的东西,没有必要深究下去。

论坛徽章:
0
19 [报告]
发表于 2006-05-03 22:53 |只看该作者
我是在word下写的.哈哈
最近一直在分析NETBSD和FREEBSD的软件中断对
轮询技术性能的影响.嗯,应该是有问题的.
我们可以看看,在一个稍大一点的局域网内,由于ARP
和其他链路层广播的增加.对软中断驱动的POLLING
来说会有影响.到底会影响到什么程度,或构建一些特殊
的有规律的包是否会对POLLING造成攻击还不清楚.

[ 本帖最后由 xie_minix 于 2006-5-3 22:59 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2006-05-03 23:02 |只看该作者
这是freebsd的i386
/*
* 中断优先级别.
* 因为在tty,network,disk驱动中要使用free,所以imp优先权是要大于tty,net,bio的.
* 又因为运行队列可以在时钟中断态下操作,所以时钟又大于imp
*
* IPL_HIGH中断因其可以操作运行队列,所以也必须阻塞其他操作.
* 设备驱动程序连续性处理在最高优先权,所以连续性大于IP_HIGH
*
* 注意:各结构体系对此定义不同,可以参照HP300,HP700,POWERPC等体系看看
*/
#define        IPL_NONE        0x0        /* nothing */
#define        IPL_SOFTCLOCK        0x4        /* timeouts软件定时器看样子是最低的 */
#define        IPL_SOFTNET        0x5        /* 网络软件中断(这里是指由if_ethersubr中发出的ARP,IP,IPX各协议相关的软件中断) */
#define        IPL_BIO                0x6        /* 块设备 I/O */
#define        IPL_NET                0x7        /* 一般在网卡驱动程序的attach部分用pci_intr_establish建立硬件中断*/
                                                /*他调用pci_mathdep.c的intr_establish*/
#define        IPL_SOFTSERIAL        0x8        /* 好象是为了保持软中断的延续性的一中断*/
#define        IPL_TTY                0x9        /* 控制台*/
#define        IPL_VM                0xa        /* 内存分配 */
#define        IPL_AUDIO        0xb        /* 声音 */
#define        IPL_CLOCK        0xc        /* 时钟 */
#define IPL_SCHED        IPL_CLOCK  /*调度中断和时钟是同一级别*/
#define        IPL_HIGH        0xd        /* 该中断可屏蔽掉上面那些中断 */
#define        IPL_SERIAL        0xd        /* 应该是保持所要保护的其他中断延续性的最高级别 */
#define IPL_IPI                0xe        /* 处理器间中断,多CPU时用 */
#define        NIPL                16
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP