网络子系统22_队列规则传输接口

简介:
//	调用路径:
//		1.dev_queue_xmit->qdisc_run
//		2.net_tx_action->qdisc_run

//	对于dev->tx_queue_len !=0 的设备,都会有一个与之关联的队列规则,按照队列规则,调用dev->hard_start_xmit

1.1 static inline void qdisc_run(struct net_device *dev)
{
	//设备传输队列没有被关闭,即__LINK_STATE_XOFF没有被设置
	//结合规则队列完成传输
	while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0);
}


//	结合设备关联的队列规则,完成数据传输
//	调用路径:qdisc_run->qdisc_restart

//	返回值:	=0  - queue is empty.
//			>0  - queue is not empty, but throttled.
//			<0  - queue is not empty. Device is throttled, if dev->tbusy != 0.

//	函数流程:
//		1.使用队列规则出队skb
//		2.对dev->xmit_lock加锁
//		3.检测死锁与冲突;
//			3.1 死锁:锁已被占用,占用者为本cpu,释放skb,返回
//			3.2 冲突:锁被占用,非本cpu,重入队skb,重调度设备
//		4.设置锁的拥有者为本cpu
//		5.对dev->queue_lock解锁
//		6.向ETH_P_ALL类型l3协议传递此skb
//		7.通过驱动程序hard_start_xmit完成传输
//		8.对dev->queue_lock加锁
//		9.对dev->xmit_lock解锁
1.2 int qdisc_restart(struct net_device *dev)
{
	//与设备相关的队列规则
	struct Qdisc *q = dev->qdisc;
	struct sk_buff *skb;

	//从规则队列出队skb
	if ((skb = q->dequeue(q)) != NULL) {
		//驱动特性:NETIF_F_LLTX,表明驱动在被调用hard_start_xmit时不需要上锁
		unsigned nolock = (dev->features & NETIF_F_LLTX);

		if (!nolock) {//需要上锁
			if (!spin_trylock(&dev->xmit_lock)) {//锁已经被获取
				collision:
					//死锁:
					//	锁被占用,但是拥有者为本cpu,将skb丢掉,直接返回-1
					if (dev->xmit_lock_owner == smp_processor_id()) {
						kfree_skb(skb);
						return -1;
					}

					//冲突:
					//	将skb重新入队
					goto requeue;
			}
			//获取锁,将锁的拥有者设置为本cpu
			dev->xmit_lock_owner = smp_processor_id();
		}
		
		{
			spin_unlock(&dev->queue_lock);
			if (!netif_queue_stopped(dev)) {//设备可以进行传输
				int ret;
				//netdev_nit表示ETH_P_ALL类型l3协议的个数
				if (netdev_nit)
					dev_queue_xmit_nit(skb, dev);
				//由驱动程序完成传输
				ret = dev->hard_start_xmit(skb, dev);
				if (ret == NETDEV_TX_OK) { 
					if (!nolock) {
						dev->xmit_lock_owner = -1;
						spin_unlock(&dev->xmit_lock);
					}
					spin_lock(&dev->queue_lock);
					return -1;
				}
				if (ret == NETDEV_TX_LOCKED && nolock) {
					spin_lock(&dev->queue_lock);
					goto collision; 
				}
			}

			if (!nolock) { 
				dev->xmit_lock_owner = -1;
				spin_unlock(&dev->xmit_lock);
			} 
			spin_lock(&dev->queue_lock);
			q = dev->qdisc;
		}

requeue:
		//将skb重新入队
		q->ops->requeue(skb, q);
		//调度设备
		netif_schedule(dev);
		return 1;
	}
	//返回规则队列中剩余的skb个数
	return q->q.qlen;
}

目录
相关文章
|
7天前
|
网络协议 算法 网络性能优化
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
计算机网络常见面试题(一):TCP/IP五层模型、应用层常见的协议、TCP与UDP的区别,TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议、ARP协议
|
9天前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
170 1
|
22天前
|
弹性计算 Kubernetes 网络协议
阿里云弹性网络接口技术的容器网络基础教程
阿里云弹性网络接口技术的容器网络基础教程
阿里云弹性网络接口技术的容器网络基础教程
|
17天前
|
存储 缓存 Ubuntu
配置网络接口的“IP”命令10个
【10月更文挑战第18天】配置网络接口的“IP”命令10个
43 0
|
2月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
111 5
|
29天前
|
网络协议 网络架构
【第三期】计算机网络常识/网络分层模型与数据包封装传输过程
【第三期】计算机网络常识/网络分层模型与数据包封装传输过程
43 0
|
3月前
|
安全 网络性能优化 网络安全
别再让网络瓶颈困扰你!掌握这十种交换机接口模式,提升你的网络布局技能
【8月更文挑战第23天】交换机作为网络核心,其接口模式直接影响网络布局与性能。本文介绍了十大常见接口模式及其配置实例,包括基础接入模式、优化布线的干道模式、动态学习相邻交换机VLAN信息的动态中继协议模式、固定分配VLAN的静态接入模式、确保语音优先传输的语音VLAN模式、指定默认VLAN的native模式、增加带宽与可靠性的链路聚合及EtherChannel模式、保障网络安全的端口安全模式以及确保关键业务流畅传输的QoS模式。理解并掌握这些模式对于构建高效稳定的网络至关重要。
78 1
|
3月前
|
监控 Linux
在Linux中,如何查看网络接口的状态?
在Linux中,如何查看网络接口的状态?
|
2月前
|
域名解析 负载均衡 网络协议
Linux网络接口配置不当所带来的影响
总而言之,Linux网络接口的恰当配置是保证网络稳定性、性能和安全性的基础。通过遵循最佳实践和定期维护,可以最大程度地减少配置错误带来的负面影响。
127 0
|
3月前
|
JSON 安全 网络协议
【Azure Policy】添加策略用于审计Azure 网络安全组(NSG)规则 -- 只能特定的IP地址允许3389/22端口访问
为了确保Azure虚拟机资源的安全管理,只有指定IP地址才能通过RDP/SSH远程访问。解决方案包括使用Azure Policy服务扫描所有网络安全组(NSG),检查入站规则中的3389和22端口,并验证源地址是否在允许的IP列表中。不符合条件的NSG规则将被标记为非合规。通过编写特定的Policy Rule并定义允许的IP地址参数,实现集中管控和合规性检查。

热门文章

最新文章