《深入理解linux网络》读书笔记一

最近也是刚刚拿到这本书,对于linux网络这块,自己也是小白一个,所以就以自己基础知识为零的起点,来做读数笔记。有不懂点也会查阅资料,来补充知识点。

书目录:第二章-内核是如何接收网络包的,这一章节的2.2.1 linux网络收包总览中的其中一段文章:

当网卡收到数据以后,以DMA的方式把网卡收到的帧写到内存里,再向CPU发起⼀个中断,以通知CPU有数据到达。当CPU收到中断请求后,会去调用网络设备驱动注册的中断处理函数。网卡的中断处理函数并不做过多工作,发出软中断请求,然后尽快释放CPU资源。ksoftirad内核线程检测到有软中断请求到达,调用poll开始轮询收包,收到后交由各级协议栈处理。对于TCP包来说,会被放到用户socker的接收队列中。

内核收包的路径⽰意图,从书中摘抄过来。

图片

根据上图,网络数据从网卡到用户空间的执行顺序整理出的链路:

1. 网卡接收数据

  • 网卡接收到外部网络发送的数据包。

2. 使用DMA将数据写入内存

  • 网卡通过DMA(直接内存访问)将接收到的数据包直接写入系统内存中,不经过CPU的处理,以提高效率。

3. 网卡向CPU发起硬中断

  • 网卡将数据写入内存后,向CPU发出一个硬中断请求,通知CPU有新的数据包需要处理。

4. CPU调用中断处理函数

  • CPU响应硬中断,调用网卡驱动程序中注册的中断处理函数。

  • 中断处理函数通常只做少量工作,如记录中断事件、标记需要进一步处理的任务,然后发起一个软中断请求,尽快释放CPU资源以继续处理其他任务。

5. 软中断请求处理

  • 内核中的ksoftirqd线程检测到有软中断请求,随后被唤醒。

  • ksoftirqd线程开始执行软中断处理,这个处理通常会涉及调用网卡驱动程序的poll方法。

6. poll轮询网卡的收包队列

  • poll轮询网卡的收包队列,从队列中读取到内存中的数据包。

7. 协议栈处理数据包

  • 数据包被传递到内核中的网络协议栈,经过各个协议层的处理(如IP层、TCP层等)。

  • 对于TCP数据包,最终会被放入用户socket的接收队列中。

8. 用户空间程序读取数据

  • 应用程序通过调用系统接口(如recvread)从socket的接收队列中读取数据包,完成整个数据接收过程。

  整个链路依次经过:网卡接收数据 -> DMA写入内存 -> 硬中断 -> 中断处理函数 -> 软中断请求 -> ksoftirqd线程处理 -> poll轮询 -> 协议栈处理 -> 用户socket接收队列 -> 应用程序读取数据


什么是poll轮询?

在Linux网络处理流程中,poll轮询(polling)是一种机制,用来检查网卡或其他设备的状态,看是否有数据包需要处理。具体来说,在网络数据接收流程中,poll轮询指的是ksoftirqd线程调用网卡驱动中的poll函数,以查看是否有新的数据包已经被接收到内存中并准备好进一步处理。

 poll轮询是ksoftirqd线程用来主动检查网卡状态的一种方法,它在网络数据包接收流程中扮演着关键角色,确保数据包能够及时从网卡传递到内核协议栈,最终到达用户空间应用程序。

poll 函数通常是由网卡驱动程序实现的,具体实现因不同的网络设备而异。不过,Linux内核中有一套通用的框架用于实现网络设备的 poll 处理,下面是一个简化的示例,展示了 poll 函数的基本结构和作用。


int my_poll(struct napi_struct *napi, int budget) {
    int work_done = 0;

    // 1. 轮询网卡接收队列,获取数据包
    while (work_done < budget) {
        struct sk_buff *skb = my_net_device_receive();
        
        if (!skb)
            break; // 没有更多数据包可处理

        // 2. 数据包处理,将其传递给内核协议栈
        netif_receive_skb(skb);
        
        work_done++;
    }

    // 3. 判断是否已经处理了所有数据包
    if (work_done < budget) {
        // 释放NAPI,以便可以再次被唤醒处理更多数据
        napi_complete_done(napi, work_done);
        // 重新启用网卡的中断
        enable_irq(napi->dev->irq);
    }

    return work_done;
}

ksoftirqd线程是Linux内核中的一个内核线程,它专门用于处理软中断(softirq)。软中断是一种比硬中断优先级低的中断机制,旨在将一些中断处理中的较为耗时的任务延后,以在合适的时机完成。ksoftirqd线程在Linux内核中是自动创建和管理的,它负责在系统空闲时处理这些被延迟的任务。

每个CPU核心都有一个对应的ksoftirqd线程,以便能够并行处理多核系统中的软中断任务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值