网络子系统39_inet_peer缓存通用接口

简介:
//	查找inet_peer
//	参数:
//		daddr,ip地址
//		create,指示daddr不存在时,是否新建

//	注:inet_peer在内存中组织为平衡树的形式
1.1 struct inet_peer *inet_getpeer(__be32 daddr, int create)
{
	struct inet_peer *p, *n;
	struct inet_peer **stack[PEER_MAXDEPTH], ***stackptr;

	//获取读锁
	read_lock_bh(&peer_pool_lock);
	p = lookup(daddr, NULL);//执行查找
	if (p != peer_avl_empty)//有效节点
		atomic_inc(&p->refcnt);
	read_unlock_bh(&peer_pool_lock);

	if (p != peer_avl_empty) {
		unlink_from_unused(p);//如果节点在unused_list链表上,从其上取下
		return p;//返回
	}

	if (!create)//没有找到,并且不创建
		return NULL;//返回空

	//通过SLAB 分配一个inet_peer
	n = kmem_cache_alloc(peer_cachep, GFP_ATOMIC);
	if (n == NULL)
		return NULL;
	n->v4daddr = daddr;//ip地址
	atomic_set(&n->refcnt, 1);//引用技术
	atomic_set(&n->rid, 0);
	n->ip_id_count = secure_ip_id(daddr);//随机生成一个ip id的起始值
	n->tcp_ts_stamp = 0;

	write_lock_bh(&peer_pool_lock);//获取写锁,
	p = lookup(daddr, stack);//再一次查找,防止在之前的处理过程中,另一个并行路径,已经添加此inet_peer
	if (p != peer_avl_empty)
		goto out_free;//此地址被添加

	link_to_pool(n);//将此节点连接到avl数中
	INIT_LIST_HEAD(&n->unused);
	peer_total++;//系统中inet_peer总数
	write_unlock_bh(&peer_pool_lock);

	if (peer_total >= inet_peer_threshold)
		cleanup_once(0);//超过阀值,释放unused中第一个inet_peer

	return n;

out_free:
	atomic_inc(&p->refcnt);
	write_unlock_bh(&peer_pool_lock);
	unlink_from_unused(p);
	kmem_cache_free(peer_cachep, n);
	return p;
}

//	释放inet_peer引用计数
//	函数主要内容:
//		1.递减引用计数
//		2.如果引用计数=0,加入到unused_peers链表
//		3.更新inet_peer加入到unused_peers的时间戳

//	注:引用计数为0的inet_peer并不立即删除,而是挂载到unused_peers中, 由垃圾回收机制释放。
1.2 void inet_putpeer(struct inet_peer *p)
{
	//在递减引用计数前,获取unused_list锁,防止先递减后被并发路径递增,使引用计数非0的inet_peer被加入到链表中
	spin_lock_bh(&inet_peer_unused_lock);
	if (atomic_dec_and_test(&p->refcnt)) {//如果引用计数为0,则将其加入到链表中
		list_add_tail(&p->unused, &unused_peers);
		p->dtime = (__u32)jiffies;//加入到链表的时间戳
	}
	spin_unlock_bh(&inet_peer_unused_lock);//开锁,开软中断
}



//	异步垃圾回收
//	函数主要任务:
//		1.根据系统中inet_peer数量,确定清理对象的范围
//		2.同步清理符合范围的inet_peer
//		3.根据清理的情况,调整下次异步垃圾回收的时间
//			3.1 如果系统中剩余inet_peer仍然超过阈值,则定时器下一次尽快到期
//			3.2 否则在一定范围内随机化下一次的到期时间
2.1 static void peer_check_expire(unsigned long dummy)
{
	unsigned long now = jiffies;
	int ttl;
	//系统中inet_peer数量超过了阀值
	if (peer_total >= inet_peer_threshold)
		ttl = inet_peer_minttl;//确定未用时长的inet_peer作为清除对象
	else
		ttl = inet_peer_maxttl
				- (inet_peer_maxttl - inet_peer_minttl) / HZ *
					peer_total / inet_peer_threshold * HZ;
	while (!cleanup_once(ttl)) {//清除老化的inter_peer
		if (jiffies != now)//清除操作耗时超过了1个jiffies
			break;
	}

	if (peer_total >= inet_peer_threshold)//数量仍然超过阀值
		peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;//使gc尽快到期
	else
		peer_periodic_timer.expires = jiffies
			+ inet_peer_gc_maxtime
			- (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
				peer_total / inet_peer_threshold * HZ;
	add_timer(&peer_periodic_timer);
}

//	同步垃圾回收
//		参数:
//			ttl, 回收inet_peer的标准,如果inet_peer->dtime > jiffies+ttl,则回收此inet_peer
		
//	调用路径:peer_check_expire->cleanup_once

//	注:
//		1.unused_list上的inet_peer仍然保存在avl树中,当inet_peer再次被使用时(inet_getpeer),会从unused_list
//		上取下,因此一个inet_peer会进出unused_list数次
//		2.进入unused_list的inet_peer,refcnt=0

//	函数主要任务:
//		1.遍历unused_list,取下满足条件的inet_peer
//		2.从avl树中删除此inet_peer
2.2 static int cleanup_once(unsigned long ttl)
{
	struct inet_peer *p = NULL;

	spin_lock_bh(&inet_peer_unused_lock);//关软中断,获取锁
	if (!list_empty(&unused_peers)) {//存在未使用的inet_peer
		__u32 delta;

		p = list_first_entry(&unused_peers, struct inet_peer, unused);
		delta = (__u32)jiffies - p->dtime;

		if (delta < ttl) {//在unused_peers上度过的时间短于被清除的要求
			spin_unlock_bh(&inet_peer_unused_lock);
			return -1;//直接返回
		}

		list_del_init(&p->unused);//从unused链表上删除下来

		atomic_inc(&p->refcnt);//增加引用技术,防止被其他系统释放
	}
	spin_unlock_bh(&inet_peer_unused_lock);

	if (p == NULL)//没有空闲的inet_peer
		return -1;

	unlink_from_pool(p);//从avl树中删除inet_peer,调整avl树
	return 0;
}

目录
相关文章
|
2月前
|
机器学习/深度学习 计算机视觉 知识图谱
【YOLOv8改进】MobileViT 更换主干网络: 轻量级、通用且适合移动设备的视觉变压器 (论文笔记+引入代码)
MobileViT是针对移动设备的轻量级视觉Transformer网络,结合CNN的局部特征、Transformer的全局注意力和ViT的表示学习。在ImageNet-1k上,它以600万参数实现78.4%的top-1准确率,超越MobileNetv3和DeiT。MobileViT不仅适用于图像分类,还在目标检测等任务中表现出色,且优化简单,代码已开源。YOLOv8引入了MobileViT块,整合卷积和Transformer结构,提升模型性能。更多详情可参考相关专栏和链接。
|
11天前
|
数据采集 存储 缓存
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
|
13天前
|
JavaScript API
vue 异步网络请求 axios 【实用教程】(含访问本地接口)
vue 异步网络请求 axios 【实用教程】(含访问本地接口)
15 0
|
16天前
|
文字识别 开发工具 Android开发
视觉智能开放平台操作报错合集之使用人脸属性检测接口,出现报错:图片无法下载,请检查链接是否可访问和本地网络情况,该如何解决
在使用视觉智能开放平台时,可能会遇到各种错误和问题。虽然具体的错误代码和消息会因平台而异,但以下是一些常见错误类型及其可能的原因和解决策略的概述,包括但不限于:1. 认证错误、2. 请求参数错误、3. 资源超限、4. 图像质量问题、5. 服务不可用、6. 模型不支持的场景、7. 网络连接问题,这有助于快速定位和解决问题。
|
2月前
|
机器学习/深度学习
简单通用:视觉基础网络最高3倍无损训练加速,清华EfficientTrain++入选TPAMI 2024
【5月更文挑战第30天】清华大学研究团队提出的EfficientTrain++是一种新型训练方法,旨在加速视觉基础网络(如ResNet、ConvNeXt、DeiT)的训练,最高可达3倍速度提升,同时保持模型准确性。该方法基于傅里叶谱裁剪和动态数据增强,实现了课程学习的创新应用。在ImageNet-1K/22K数据集上,EfficientTrain++能有效减少多种模型的训练时间,且在自监督学习任务中表现出色。尽管面临适应性与稳定性的挑战,EfficientTrain++为深度学习模型的高效训练开辟了新途径,对学术和工业界具有重要意义。
41 4
|
2月前
|
缓存 NoSQL Java
用好缓存,让你的接口速度飞起来
本文是关于接口性能优化,特别是通过缓存来提升接口响应速度的探讨。作者是一名有六年经验的Java后端开发者,分享了自己避免线上系统因代码崩溃造成资损的经验,主要归功于业务的简单性、遵循代码规约和积累的实用技巧。文章重点讲解了缓存的两个方面:缓存预热(包括定时任务和启动预热)和缓存层次化(多级缓存和热点数据缓存),并提供了如何用代码实现这些思路的示例。作者还介绍了自定义缓存处理器的设计和实现,包括接口和抽象类的定义,以及使用函数式编程实现的缓存查询模板。最后提醒,缓存虽有益但需谨慎使用,应根据业务需求和数据特征定制策略。
85 1
|
2月前
|
Ubuntu 网络协议 Linux
|
1月前
|
缓存 安全 前端开发
(转)浅谈tomcat优化(内存,并发,缓存,安全,网络,系统等)
(转)浅谈tomcat优化(内存,并发,缓存,安全,网络,系统等)
|
1月前
|
XML 网络协议 Java
53. 【Android教程】Socket 网络接口
53. 【Android教程】Socket 网络接口
21 0
|
2月前
|
网络协议 Linux 开发工具
Linux中 /etc/sysconfig/network-scripts/ifcfg-<interface> 网络接口配置 详解 看这一篇够用
Linux中 /etc/sysconfig/network-scripts/ifcfg-<interface> 网络接口配置 详解 看这一篇够用

热门文章

最新文章